summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJay Cheng <jacheng@nvidia.com>2011-01-07 02:03:46 -0500
committerBenoit Goby <benoit@android.com>2011-01-09 17:41:59 -0800
commite750de624e23fc8a8a6916c537394cbf3b38486c (patch)
tree3e758c97bde0c1da97a6384670f8c8a0a346ef81 /drivers
parentcfdeb3d801cfcdfbb17f7fd28bba00d4513c6558 (diff)
usb: ehci: tegra: continues driving FS-J during resume
To prevent USB glitch. Also only program PTC bits when resume from LP0 Change-Id: Iced668e33f986828d3a483b411055948b5b257e1 Signed-off-by: Jay Cheng <jacheng@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-tegra.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 0e9b6458da84..2341904808bc 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -253,6 +253,7 @@ static int tegra_usb_resume(struct usb_hcd *hcd)
struct tegra_ehci_context *context = &tegra->context;
struct ehci_regs __iomem *hw = tegra->ehci->regs;
unsigned long val;
+ int lp0_resume = 0;
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
tegra_ehci_power_up(ehci_to_hcd(tegra->ehci));
@@ -264,6 +265,13 @@ static int tegra_usb_resume(struct usb_hcd *hcd)
goto restart;
}
+ tegra_ehci_phy_restore_start(tegra->phy);
+
+ /* Check if the phy resume from LP0. When the phy resume from LP0
+ * USB register will be reset. */
+ if (!readl(&hw->async_next))
+ lp0_resume = 1;
+
/* Restore register context */
writel(TEGRA_USB_USBMODE_HOST, &hw->reserved[19]);
writel(context->otgsc, &hw->reserved[18]);
@@ -278,17 +286,19 @@ static int tegra_usb_resume(struct usb_hcd *hcd)
writel(val, &hw->port_status[0]);
udelay(10);
- /* Program the field PTC in PORTSC based on the saved speed mode */
- val = readl(&hw->port_status[0]);
- val &= ~(TEGRA_USB_PORTSC1_PTC(~0));
- if (context->port_speed == TEGRA_USB_PHY_PORT_HIGH)
- val |= TEGRA_USB_PORTSC1_PTC(5);
- else if (context->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL)
- val |= TEGRA_USB_PORTSC1_PTC(6);
- else if (context->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
- val |= TEGRA_USB_PORTSC1_PTC(7);
- writel(val, &hw->port_status[0]);
- udelay(10);
+ if (lp0_resume) {
+ /* Program the field PTC in PORTSC based on the saved speed mode */
+ val = readl(&hw->port_status[0]);
+ val &= ~(TEGRA_USB_PORTSC1_PTC(~0));
+ if (context->port_speed == TEGRA_USB_PHY_PORT_HIGH)
+ val |= TEGRA_USB_PORTSC1_PTC(5);
+ else if (context->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL)
+ val |= TEGRA_USB_PORTSC1_PTC(6);
+ else if (context->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
+ val |= TEGRA_USB_PORTSC1_PTC(7);
+ writel(val, &hw->port_status[0]);
+ udelay(10);
+ }
/* Disable test mode by setting PTC field to NORMAL_OP */
val = readl(&hw->port_status[0]);
@@ -330,9 +340,11 @@ static int tegra_usb_resume(struct usb_hcd *hcd)
}
}
+ tegra_ehci_phy_restore_end(tegra->phy);
return 0;
restart:
+ tegra_ehci_phy_restore_end(tegra->phy);
tegra_ehci_restart(hcd);
return 0;
}