ARM: tegra: usb_phy: continues driving FS-J during resume
authorJay Cheng <jacheng@nvidia.com>
Fri, 7 Jan 2011 07:03:46 +0000 (02:03 -0500)
committerBenoit Goby <benoit@android.com>
Mon, 10 Jan 2011 01:41:58 +0000 (17:41 -0800)
to prevent USB glitch.

Change-Id: Iced668e33f986828d3a483b411055948b5b257e1
Signed-off-by: Jay Cheng <jacheng@nvidia.com>
arch/arm/mach-tegra/include/mach/usb_phy.h
arch/arm/mach-tegra/usb_phy.c

index 8b4beae773a7cd6df0f7b3d971fa340a485f0bd7..bb16019256ecf5cab97d85837f010e3805406497 100644 (file)
@@ -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
index f0d1ec803cfa4797f84a7decb2165f943389ccc2..3dc3aed4c915acef1cb4257ef0cfb38a35c75d4b 100644 (file)
 #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)