summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra3_usb_phy.c
diff options
context:
space:
mode:
authorAbhishek Shukla <abhisheks@nvidia.com>2012-07-27 13:04:18 +0530
committerSimone Willett <swillett@nvidia.com>2012-08-01 17:39:00 -0700
commit50008402a6f093e48dee05fc88bc54750b97ae25 (patch)
tree36f1a8d1cb72e9063be233e9d5e725471e75e025 /arch/arm/mach-tegra/tegra3_usb_phy.c
parentce9fc97cf95c463dff8156dffd5632e5336e4adc (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/arm/mach-tegra/tegra3_usb_phy.c')
-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 f164b409d29b..ac87111dbd7d 100644
--- a/arch/arm/mach-tegra/tegra3_usb_phy.c
+++ b/arch/arm/mach-tegra/tegra3_usb_phy.c
@@ -1869,6 +1869,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 */
@@ -1885,19 +1909,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;
@@ -1905,19 +1926,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);
@@ -1936,14 +1959,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);
@@ -1958,6 +1977,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;
}
@@ -1972,12 +1995,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);