summaryrefslogtreecommitdiff
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:58 -0800
commitcfdeb3d801cfcdfbb17f7fd28bba00d4513c6558 (patch)
treedc712ea99339026482c83b790a82fa4108f3f421
parentedd66078f5a0d7e60adc03ed6d6fc92d5a764352 (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.h4
-rw-r--r--arch/arm/mach-tegra/usb_phy.c47
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)