diff options
author | Rakesh Bodla <rbodla@nvidia.com> | 2012-09-04 11:43:44 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-09-05 11:45:32 -0700 |
commit | 65ce999d1b22b01f6a2e6b3516be47e83d6d2584 (patch) | |
tree | 8b9106a2376e8e9c19b2ad9d08f04af632041d27 | |
parent | c8dff984ffd77183bbc01ab1beb8fbfe3019273f (diff) |
arm: tegra: phy: enable wakeup event for usb phy
If usb device already connected, should disable WKCN
in USB2D_PORTSC1, and enable WKDS in USB2D_PORTSC1,
during utmi phy power off. All the wakeup resource
should be cleared after the event happened.
Bug 1020021
Bug 1028429
Change-Id: I807ca76d4392318adf6adb808cb2bf290cd0d60c
Signed-off-by: Rakesh Bodla <rbodla@nvidia.com>
Reviewed-on: http://git-master/r/128547
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/tegra2_usb_phy.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_usb_phy.c | 38 |
2 files changed, 42 insertions, 13 deletions
diff --git a/arch/arm/mach-tegra/tegra2_usb_phy.c b/arch/arm/mach-tegra/tegra2_usb_phy.c index 892e3ba8ec71..0292ebb75083 100644 --- a/arch/arm/mach-tegra/tegra2_usb_phy.c +++ b/arch/arm/mach-tegra/tegra2_usb_phy.c @@ -613,13 +613,19 @@ static int utmi_phy_irq(struct tegra_usb_phy *phy) val &= ~USB_PHY_CLK_VALID_INT_ENB | USB_PHY_CLK_VALID_INT_STS; writel(val , (base + USB_SUSP_CTRL)); - pr_info("%s: usb device plugged-in\n", __func__); + val = readl(base + USB_USBSTS); if (!(val & USB_USBSTS_PCI)) return IRQ_NONE; + val = readl(base + USB_PORTSC); - val &= ~(USB_PORTSC_WKCN | USB_PORTSC_RWC_BITS); + if (val & USB_PORTSC_CCS) + val &= ~USB_PORTSC_WKCN; + else + val &= ~USB_PORTSC_WKDS; + val &= ~USB_PORTSC_RWC_BITS; writel(val , (base + USB_PORTSC)); + } else if (!phy->phy_clk_on) { return IRQ_NONE; } @@ -710,8 +716,12 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) enable_hotplug = (val & USB_ID_STATUS) ? false : true; } if (enable_hotplug) { + /* Enable wakeup event of device plug-in/plug-out */ val = readl(base + USB_PORTSC); - val |= USB_PORTSC_WKCN; + if (val & USB_PORTSC_CCS) + val |= USB_PORTSC_WKDS; + else + val |= USB_PORTSC_WKCN; writel(val, base + USB_PORTSC); val = readl(base + USB_SUSP_CTRL); @@ -726,6 +736,7 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) } } + /* Disable PHY clock */ if (phy->inst == 2) { val = readl(base + USB_PORTSC); val |= USB_PORTSC_PHCD; diff --git a/arch/arm/mach-tegra/tegra3_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c index 1020e5d35f89..66637f29b19c 100644 --- a/arch/arm/mach-tegra/tegra3_usb_phy.c +++ b/arch/arm/mach-tegra/tegra3_usb_phy.c @@ -1246,15 +1246,26 @@ static int utmi_phy_irq(struct tegra_usb_phy *phy) val &= ~USB_PHY_CLK_VALID_INT_ENB | USB_PHY_CLK_VALID_INT_STS; writel(val , (base + USB_SUSP_CTRL)); - pr_info("%s: usb device plugged-in\n", __func__); - val = readl(base + USB_USBSTS); - if (!(val & USB_USBSTS_PCI)) { - irq_status = IRQ_NONE; - goto exit; + + /* In case of remote wakeup PHY clock will not up + immediately, so should not access any controller + register but normal plug-in/plug-out should be + executed */ + if (!remote_wakeup) { + val = readl(base + USB_USBSTS); + if (!(val & USB_USBSTS_PCI)) { + irq_status = IRQ_NONE; + goto exit; + } + + val = readl(base + USB_PORTSC); + if (val & USB_PORTSC_CCS) + val &= ~USB_PORTSC_WKCN; + else + val &= ~USB_PORTSC_WKDS; + val &= ~USB_PORTSC_RWC_BITS; + writel(val , (base + USB_PORTSC)); } - val = readl(base + USB_PORTSC); - val &= ~(USB_PORTSC_WKCN | USB_PORTSC_RWC_BITS); - writel(val , (base + USB_PORTSC)); } else if (!phy->phy_clk_on) { if (remote_wakeup) irq_status = IRQ_HANDLED; @@ -1476,8 +1487,12 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) enable_hotplug = (val & USB_ID_STATUS) ? false : true; } if (enable_hotplug) { + /* Enable wakeup event of device plug-in/plug-out */ val = readl(base + USB_PORTSC); - val |= USB_PORTSC_WKCN; + if (val & USB_PORTSC_CCS) + val |= USB_PORTSC_WKDS; + else + val |= USB_PORTSC_WKCN; writel(val, base + USB_PORTSC); val = readl(base + USB_SUSP_CTRL); @@ -1491,6 +1506,7 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) } } + /* Disable PHY clock */ val = readl(base + HOSTPC1_DEVLC); val |= HOSTPC1_DEVLC_PHCD; writel(val, base + HOSTPC1_DEVLC); @@ -1679,7 +1695,9 @@ static void utmi_phy_restore_end(struct tegra_usb_phy *phy) val = readl(base + USB_PORTSC); udelay(1); if (wait_time_us == 0) { - PHY_DBG("%s PMC REMOTE WAKEUP FPR timeout val = 0x%x instance = %d\n", __func__, val, phy->inst); + PHY_DBG("%s PMC REMOTE WAKEUP FPR timeout" + "val = 0x%lx instance = %d\n", + __func__, val, phy->inst); utmip_phy_disable_pmc_bus_ctrl(phy); utmi_phy_post_resume(phy); return; |