Arm: tegra: usb: reset IDDQ upon resume
Krishna Yarlagadda [Mon, 25 Mar 2013 07:04:36 +0000 (12:04 +0530)]
IDDQ mode has to be reset when resuming from lp0
or bus resume

Bug 1225060

Change-Id: I31b775d6778f9ab4646c65820e558606097a1b34
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Reviewed-on: http://git-master/r/212532
(cherry picked from commit 4ef3cbc51a27146f7d3e749c3b2178d843b136ba)
Reviewed-on: http://git-master/r/217871
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Venu Byravarasu <vbyravarasu@nvidia.com>

arch/arm/mach-tegra/include/mach/tegra_usb_pad_ctrl.h
arch/arm/mach-tegra/tegra_usb_pad_ctrl.c
drivers/usb/phy/tegra11x_usb_phy.c

index 585900e..4303284 100644 (file)
@@ -16,7 +16,8 @@
 #define _TEGRA_USB_PAD_CTRL_INTERFACE_H_
 
 #define UTMIPLL_HW_PWRDN_CFG0                  0x52c
-#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE    (1<<1)
+#define   UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE  (1<<1)
+#define   UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL     (1<<0)
 
 #define UTMIP_BIAS_CFG0                0x80c
 #define   UTMIP_OTGPD                  (1 << 11)
@@ -27,4 +28,5 @@
 
 int utmi_phy_pad_disable(void);
 int utmi_phy_pad_enable(void);
+int utmi_phy_iddq_override(bool set);
 #endif
index 3229197..0e34ec2 100644 (file)
@@ -23,6 +23,28 @@ static DEFINE_SPINLOCK(utmip_pad_lock);
 static int utmip_pad_count;
 static struct clk *utmi_pad_clk;
 
+int utmi_phy_iddq_override(bool set)
+{
+       unsigned long val, flags;
+       void __iomem *clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+
+       spin_lock_irqsave(&utmip_pad_lock, flags);
+       val = readl(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+       if (set && !utmip_pad_count)
+               val |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
+       else if (!set && utmip_pad_count)
+               val &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
+       else
+               goto out1;
+       val |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL;
+       writel(val, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+
+out1:
+       spin_unlock_irqrestore(&utmip_pad_lock, flags);
+       return 0;
+}
+
+
 int utmi_phy_pad_enable(void)
 {
        unsigned long val, flags;
@@ -54,7 +76,6 @@ int utmi_phy_pad_disable(void)
 {
        unsigned long val, flags;
        void __iomem *pad_base =  IO_ADDRESS(TEGRA_USB_BASE);
-       void __iomem *clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
 
        if (!utmi_pad_clk)
                utmi_pad_clk = clk_get_sys("utmip-pad", NULL);
@@ -72,12 +93,6 @@ int utmi_phy_pad_disable(void)
                val &= ~(UTMIP_HSSQUELCH_LEVEL(~0) | UTMIP_HSDISCON_LEVEL(~0) |
                        UTMIP_HSDISCON_LEVEL_MSB);
                writel(val, pad_base + UTMIP_BIAS_CFG0);
-
-               /* Put UTMIPLL in IDDQ mode once all UTMIP ports
-                  are in reset/suspend */
-               val = readl(clk_base + UTMIPLL_HW_PWRDN_CFG0);
-               val |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
-               writel(val, clk_base + UTMIPLL_HW_PWRDN_CFG0);
        }
 out:
        spin_unlock_irqrestore(&utmip_pad_lock, flags);
index 58240f1..eda2c5a 100644 (file)
@@ -1016,7 +1016,7 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy)
        }
 
        utmi_phy_pad_disable();
-
+       utmi_phy_iddq_override(true);
        phy->phy_clk_on = false;
        phy->hw_accessible = false;
 
@@ -1030,7 +1030,6 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
 {
        unsigned long val;
        void __iomem *base = phy->regs;
-       void __iomem *clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
        void __iomem *padctl_base = IO_ADDRESS(TEGRA_XUSB_PADCTL_BASE);
 #endif
@@ -1133,11 +1132,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
        writel(val, base + USB_SUSP_CTRL);
 
        /* Bring UTMIPLL out of IDDQ mode while exiting from reset/suspend */
-       val = readl(clk_base + UTMIPLL_HW_PWRDN_CFG0);
-       if (val & UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE) {
-               val &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
-               writel(val, clk_base + UTMIPLL_HW_PWRDN_CFG0);
-       }
+       utmi_phy_iddq_override(false);
 
        if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
                USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500))