summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAbhishek Shukla <abhisheks@nvidia.com>2012-07-27 13:04:18 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2012-08-06 15:06:56 +0530
commitc24ffb2e5dc26693a03f17e1e723fb423d4b70e3 (patch)
tree5cbd3e4a864b5ffc10b4681b5be9d1c8af981f50 /arch
parent9bf9a6afa12a843897ba32fa2df3dfa65b7ca0d2 (diff)
ARM: tegra: usb_phy: Fix fake remote wakeup
1. Move hsic line value detectors power on config to the beginning of the sequence before enabling interrupt on hsic line wake event. This avoids any fake event caused by any glitches introduced by this switching. 2. Clear any prior interrupts for the line wake event before enabling interrupt for the line wake event. This also clears any fake events generated because of any glitches. 3. Fix wake event type to NONE in the disable routine during resume interrupt. Bug 1019619 Bug 1018416 Signed-off-by: Abhishek Shukla <abhisheks@nvidia.com> Change-Id: I934fa2514897c4c23bc62ff8365f6fffe7915bd0 Reviewed-on: http://git-master/r/116699 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/tegra3_usb_phy.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/arch/arm/mach-tegra/tegra3_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c
index 4561d87b55c8..41f77fbe0eb8 100644
--- a/arch/arm/mach-tegra/tegra3_usb_phy.c
+++ b/arch/arm/mach-tegra/tegra3_usb_phy.c
@@ -1881,6 +1881,30 @@ static void uhsic_setup_pmc_wake_detect(struct tegra_usb_phy *phy)
val |= UHSIC_PWR;
writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG);
+ /* Make sure nothing is happening on the line with respect to PMC */
+ val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE);
+ val &= ~UHSIC_STROBE_VAL;
+ val &= ~UHSIC_DATA_VAL;
+ writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE);
+
+ /* Clear walk enable */
+ val = readl(pmc_base + PMC_SLEEPWALK_CFG);
+ val &= ~UHSIC_LINEVAL_WALK_EN;
+ writel(val, pmc_base + PMC_SLEEPWALK_CFG);
+
+ /* Make sure wake value for line is none */
+ val = readl(pmc_base + PMC_SLEEP_CFG);
+ val &= ~UHSIC_WAKE_VAL(WAKE_VAL_ANY);
+ val |= UHSIC_WAKE_VAL(WAKE_VAL_NONE);
+ writel(val, pmc_base + PMC_SLEEP_CFG);
+
+ /* turn on pad detectors */
+ val = readl(pmc_base + PMC_USB_AO);
+ val &= ~(STROBE_VAL_PD_P0 | DATA_VAL_PD_P0);
+ writel(val, pmc_base + PMC_USB_AO);
+
+ /* Add small delay before usb detectors provide stable line values */
+ udelay(1);
/* Enable which type of event can trigger a walk,
* in this case usb_line_wake */
@@ -1897,19 +1921,16 @@ static void uhsic_setup_pmc_wake_detect(struct tegra_usb_phy *phy)
val |= UHSIC_DATA_RPD_A;
val &= ~UHSIC_STROBE_RPD_A;
val |= UHSIC_STROBE_RPU_A;
- writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
val &= ~UHSIC_DATA_RPD_B;
val |= UHSIC_DATA_RPU_B;
val &= ~UHSIC_STROBE_RPU_B;
val |= UHSIC_STROBE_RPD_B;
- writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
val &= ~UHSIC_DATA_RPD_C;
val |= UHSIC_DATA_RPU_C;
val &= ~UHSIC_STROBE_RPU_C;
val |= UHSIC_STROBE_RPD_C;
- writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
val &= ~UHSIC_DATA_RPD_D;
val |= UHSIC_DATA_RPU_D;
@@ -1917,19 +1938,21 @@ static void uhsic_setup_pmc_wake_detect(struct tegra_usb_phy *phy)
val |= UHSIC_STROBE_RPD_D;
writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
- /* turn on pad detectors */
- val = readl(pmc_base + PMC_USB_AO);
- val &= ~(STROBE_VAL_PD_P0 | DATA_VAL_PD_P0);
- writel(val, pmc_base + PMC_USB_AO);
- /* Add small delay before usb detectors provide stable line values */
- udelay(1);
-
phy->remote_wakeup = false;
- /* Turn over pad configuration to PMC for line wake events*/
+ /* Setting Wake event*/
val = readl(pmc_base + PMC_SLEEP_CFG);
- val &= ~UHSIC_WAKE_VAL(~0);
+ val &= ~UHSIC_WAKE_VAL(WAKE_VAL_ANY);
val |= UHSIC_WAKE_VAL(WAKE_VAL_SD10);
+ writel(val, pmc_base + PMC_SLEEP_CFG);
+
+ /* Clear the walk pointers and wake alarm */
+ val = readl(pmc_base + PMC_TRIGGERS);
+ val |= UHSIC_CLR_WAKE_ALARM_P0 | UHSIC_CLR_WALK_PTR_P0;
+ writel(val, pmc_base + PMC_TRIGGERS);
+
+ /* Turn over pad configuration to PMC for line wake events*/
+ val = readl(pmc_base + PMC_SLEEP_CFG);
val |= UHSIC_MASTER_ENABLE;
writel(val, pmc_base + PMC_SLEEP_CFG);
@@ -1948,14 +1971,10 @@ static void uhsic_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy)
DBG("%s (%d)\n", __func__, __LINE__);
val = readl(pmc_base + PMC_SLEEP_CFG);
- val &= ~UHSIC_WAKE_VAL(0x0);
+ val &= ~UHSIC_WAKE_VAL(WAKE_VAL_ANY);
val |= UHSIC_WAKE_VAL(WAKE_VAL_NONE);
writel(val, pmc_base + PMC_SLEEP_CFG);
- val = readl(pmc_base + PMC_TRIGGERS);
- val |= UHSIC_CLR_WAKE_ALARM_P0 | UHSIC_CLR_WALK_PTR_P0;
- writel(val, pmc_base + PMC_TRIGGERS);
-
val = readl(base + UHSIC_PMC_WAKEUP0);
val &= ~EVENT_INT_ENB;
writel(val, base + UHSIC_PMC_WAKEUP0);
@@ -1970,6 +1989,10 @@ static void uhsic_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy)
val |= (STROBE_VAL_PD_P0 | DATA_VAL_PD_P0);
writel(val, pmc_base + PMC_USB_AO);
+ val = readl(pmc_base + PMC_TRIGGERS);
+ val |= (UHSIC_CLR_WALK_PTR_P0 | UHSIC_CLR_WAKE_ALARM_P0);
+ writel(val, pmc_base + PMC_TRIGGERS);
+
phy->remote_wakeup = false;
}
@@ -1984,12 +2007,12 @@ static bool uhsic_phy_remotewake_detected(struct tegra_usb_phy *phy)
val = readl(pmc_base + UTMIP_UHSIC_STATUS);
if (UHSIC_WAKE_ALARM & val) {
val = readl(pmc_base + PMC_SLEEP_CFG);
- val &= ~UHSIC_WAKE_VAL(0x0);
+ val &= ~UHSIC_WAKE_VAL(WAKE_VAL_ANY);
val |= UHSIC_WAKE_VAL(WAKE_VAL_NONE);
writel(val, pmc_base + PMC_SLEEP_CFG);
val = readl(pmc_base + PMC_TRIGGERS);
- val |= UHSIC_CLR_WAKE_ALARM_P0 | UHSIC_CLR_WALK_PTR_P0;
+ val |= UHSIC_CLR_WAKE_ALARM_P0;
writel(val, pmc_base + PMC_TRIGGERS);
val = readl(base + UHSIC_PMC_WAKEUP0);