]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
tegra: usb: phy: increase timeout for bus connect
authorVinayak Pane <vpane@nvidia.com>
Wed, 4 Jan 2012 23:41:31 +0000 (15:41 -0800)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 08:14:55 +0000 (01:14 -0700)
Increasing timeout to 25ms for bus connect and bus idle.
New bus_reset times out for the first time, fix this by
changing USB phy mode to HSIC.

Bug 922444
Reviewed-on: http://git-master/r/73367

Change-Id: I717c98a4e3e8d943a8a922c70442211a0f7fd9be
Signed-off-by: Vinayak Pane <vpane@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/78017
Reviewed-by: Automatic_Commit_Validation_User
Rebase-Id: R7387f2ae89ab6ff62e93b70ce4d22afcbb6962a6

drivers/usb/phy/phy-tegra-usb.c

index b2d34e648e27ee0c62aa008e9b2fad83ad0d9e61..dcda762baa2e8a4b2cd8a4c4e462f5ffc93a9e7f 100644 (file)
@@ -579,6 +579,8 @@ static u32 utmip_rctrl_val, utmip_tctrl_val;
 #define TDP_SRC_ON_MS   100
 #define TDPSRC_CON_MS   40
 
+#define CONNECT_DETECT_TIMEOUT         25000
+
 static DEFINE_SPINLOCK(utmip_pad_lock);
 static int utmip_pad_count;
 
@@ -789,6 +791,18 @@ static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result)
        return -1;
 }
 
+static int utmi_wait_register_timeout(void __iomem *reg, u32 mask, u32 result,
+       unsigned long timeout)
+{
+       do {
+               if ((readl(reg) & mask) == result)
+                       return 0;
+               udelay(1);
+               timeout--;
+       } while (timeout);
+       return -1;
+}
+
 static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
 {
        unsigned long val;
@@ -2732,7 +2746,10 @@ int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy)
                                        uhsic_config->usb_phy_ready())
                        return -EAGAIN;
 
-               if (utmi_wait_register(base + UHSIC_STAT_CFG0, UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT) < 0) {
+               /* connect detect on T30 requires extra wait */
+               if (utmi_wait_register_timeout(base + UHSIC_STAT_CFG0,
+                           UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT,
+                           CONNECT_DETECT_TIMEOUT) < 0) {
                        pr_err("%s: timeout waiting for hsic connect detect\n", __func__);
                        return -ETIMEDOUT;
                }
@@ -2754,6 +2771,17 @@ int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
        void __iomem *base = phy->regs;
 
        if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+               /* Change the USB controller PHY type to HSIC */
+               val = readl(base + HOSTPC1_DEVLC);
+               val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK);
+               val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
+               val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
+               val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
+               writel(val, base + HOSTPC1_DEVLC);
+               /* wait here, otherwise HOSTPC1_DEVLC_PSPD will timeout */
+               mdelay(5);
+#endif
                val = readl(base + USB_PORTSC1);
                val |= USB_PORTSC1_PTC(5);
                writel(val, base + USB_PORTSC1);
@@ -2780,7 +2808,9 @@ int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
                        return -ETIMEDOUT;
                }
 #elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
-               if (utmi_wait_register(base + HOSTPC1_DEVLC, HOSTPC1_DEVLC_PSPD(2), HOSTPC1_DEVLC_PSPD(2)) < 0) {
+               if (utmi_wait_register(base + HOSTPC1_DEVLC,
+                               HOSTPC1_DEVLC_PSPD(2),
+                               HOSTPC1_DEVLC_PSPD(2)) < 0) {
                        pr_err("%s: timeout waiting hsic high speed configuration\n", __func__);
                        return -ETIMEDOUT;
                }
@@ -2862,14 +2892,14 @@ int tegra_usb_phy_bus_idle(struct tegra_usb_phy *phy)
                                        uhsic_config->usb_phy_ready())
                        return -EAGAIN;
 
-               /* wait for connect detect */
-               if (utmi_wait_register(base + UHSIC_STAT_CFG0,
-                           UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT) < 0) {
+               /* connect detect on T30 requires extra wait */
+               if (utmi_wait_register_timeout(base + UHSIC_STAT_CFG0,
+                           UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT,
+                           CONNECT_DETECT_TIMEOUT) < 0) {
                        pr_err("%s: timeout waiting for hsic connect detect\n",
                                __func__);
                        return -ETIMEDOUT;
                }
-
        }
        return 0;
 }