diff options
author | Jay Cheng <jacheng@nvidia.com> | 2011-01-07 02:03:46 -0500 |
---|---|---|
committer | Benoit Goby <benoit@android.com> | 2011-01-09 17:41:59 -0800 |
commit | e750de624e23fc8a8a6916c537394cbf3b38486c (patch) | |
tree | 3e758c97bde0c1da97a6384670f8c8a0a346ef81 /drivers/usb/host | |
parent | cfdeb3d801cfcdfbb17f7fd28bba00d4513c6558 (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/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 34 |
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; } |