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:58 -0800 |
commit | cfdeb3d801cfcdfbb17f7fd28bba00d4513c6558 (patch) | |
tree | dc712ea99339026482c83b790a82fa4108f3f421 | |
parent | edd66078f5a0d7e60adc03ed6d6fc92d5a764352 (diff) |
ARM: tegra: usb_phy: continues driving FS-J during resume
to prevent USB glitch.
Change-Id: Iced668e33f986828d3a483b411055948b5b257e1
Signed-off-by: Jay Cheng <jacheng@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/include/mach/usb_phy.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/usb_phy.c | 47 |
2 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h index 8b4beae773a7..bb16019256ec 100644 --- a/arch/arm/mach-tegra/include/mach/usb_phy.h +++ b/arch/arm/mach-tegra/include/mach/usb_phy.h @@ -83,6 +83,10 @@ int tegra_usb_phy_preresume(struct tegra_usb_phy *phy); int tegra_usb_phy_postresume(struct tegra_usb_phy *phy); +int tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy); + +int tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); + int tegra_usb_phy_close(struct tegra_usb_phy *phy); #endif //__MACH_USB_PHY_H diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c index f0d1ec803cfa..3dc3aed4c915 100644 --- a/arch/arm/mach-tegra/usb_phy.c +++ b/arch/arm/mach-tegra/usb_phy.c @@ -117,6 +117,12 @@ #define UTMIP_HS_DISCON_DISABLE (1 << 8) #define UTMIP_MISC_CFG0 0x824 +#define UTMIP_DPDM_OBSERVE (1 << 26) +#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) +#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) +#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) #define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) #define UTMIP_MISC_CFG1 0x828 @@ -499,6 +505,33 @@ static void utmi_phy_postresume(struct tegra_usb_phy *phy) writel(val, base + UTMIP_TX_CFG0); } +static void utmi_phy_restore_start(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UTMIP_MISC_CFG0); + val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; + writel(val, base + UTMIP_MISC_CFG0); + udelay(1); + + val = readl(base + UTMIP_MISC_CFG0); + val |= UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); +} + +static void utmi_phy_restore_end(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); +} + static void ulpi_viewport_write(struct tegra_usb_phy *phy, u8 addr, u8 data) { unsigned long val; @@ -704,6 +737,20 @@ int tegra_usb_phy_postresume(struct tegra_usb_phy *phy) return 0; } +int tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy) +{ + if (phy->instance != 1) + utmi_phy_restore_start(phy); + return 0; +} + +int tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) +{ + if (phy->instance != 1) + utmi_phy_restore_end(phy); + return 0; +} + int tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy) { if (phy->instance != 1) |