summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/usb_phy.c
diff options
context:
space:
mode:
authorVinayak Pane <vpane@nvidia.com>2011-12-08 21:38:51 -0800
committerVarun Colbert <vcolbert@nvidia.com>2012-01-19 16:16:18 -0800
commit24f020cec2e6c3328620ad0c43e171c59f648370 (patch)
treecadc48b7ba445902ae2aacb1271921013d34632e /arch/arm/mach-tegra/usb_phy.c
parentac6e437face1760362fa97ee8a1b486dc63d6914 (diff)
arm: tegra: usb: Use T30 specific hsic bus reset
HSIC bus reset apparently needs a WAR. The ehci generic port reset is not enough for modem to connect in stress tests. Instead use pull-down pull-up on Strobe signal of USB HSIC bus. This is AP30 specific workaround. Bug 898008 Bug 912850 Bug 922444 Change-Id: I4f542d0398b05c388f6fa7e08477b65877dc705c Reviewed-on: http://git-master/r/73266 Signed-off-by: Vinayak Pane <vpane@nvidia.com> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/75879 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.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 5f7d3b69937a..197ede516283 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -210,6 +210,7 @@
#define USB_PORTSC1_WKCN (1 << 20)
#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
#define USB_PORTSC1_PP (1 << 12)
+#define USB_PORTSC1_LS(x) (((x) & 0x3) << 10)
#define USB_PORTSC1_SUSP (1 << 7)
#define USB_PORTSC1_RESUME (1 << 6)
#define USB_PORTSC1_PE (1 << 2)
@@ -346,6 +347,7 @@
#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7)
#define UHSIC_DETECT_SHORT_CONNECT (1 << 8)
#define UHSIC_FORCE_XCVR_MODE (1 << 15)
+#define UHSIC_DISABLE_BUSRESET (1 << 20)
#define UHSIC_MISC_CFG1 0xc18
#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2)
@@ -2135,6 +2137,10 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
val = readl(base + UHSIC_MISC_CFG0);
val |= UHSIC_SUSPEND_EXIT_ON_EDGE;
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ /* Disable generic bus reset, to allow AP30 specific bus reset*/
+ val |= UHSIC_DISABLE_BUSRESET;
+#endif
writel(val, base + UHSIC_MISC_CFG0);
val = readl(base + UHSIC_MISC_CFG1);
@@ -2653,7 +2659,6 @@ 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) {
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
val = readl(base + USB_PORTSC1);
val |= USB_PORTSC1_PTC(5);
writel(val, base + USB_PORTSC1);
@@ -2663,24 +2668,27 @@ int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
val &= ~USB_PORTSC1_PTC(~0);
writel(val, base + USB_PORTSC1);
udelay(2);
-#endif
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(0), 0) < 0) {
pr_err("%s: timeout waiting for SE0\n", __func__);
return -ETIMEDOUT;
}
-#endif
+
if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_CCS, USB_PORTSC1_CCS) < 0) {
pr_err("%s: timeout waiting for connection status\n", __func__);
return -ETIMEDOUT;
}
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_PSPD(2), USB_PORTSC1_PSPD(2)) < 0) {
pr_err("%s: timeout waiting hsic high speed configuration\n", __func__);
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) {
+ pr_err("%s: timeout waiting hsic high speed configuration\n", __func__);
+ return -ETIMEDOUT;
+ }
#endif
val = readl(base + USB_USBCMD);
val &= ~USB_USBCMD_RS;