summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/usb_phy.c
diff options
context:
space:
mode:
authorVinayak Pane <vpane@nvidia.com>2012-01-04 15:41:31 -0800
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-02-03 05:17:28 -0800
commit868aee48300bb11f13e863f85fdedd50c886066b (patch)
tree10b3eda0725b347bb999d6d7e44349e61b2ccc79 /arch/arm/mach-tegra/usb_phy.c
parent25dfe647985b8e31294d22ea5cb5f0e8a049932e (diff)
tegra: usb: phy: increase timeout for bus connect
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
Diffstat (limited to 'arch/arm/mach-tegra/usb_phy.c')
-rw-r--r--arch/arm/mach-tegra/usb_phy.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 32ae3744b3ae..f9bbf5fcac6d 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -576,6 +576,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;
@@ -786,6 +788,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;
@@ -2688,7 +2702,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;
}
@@ -2710,6 +2727,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);
@@ -2736,7 +2764,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;
}
@@ -2818,14 +2848,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;
}