arm: tegra: usb: Fix First SOF corruption.
Suresh Mangipudi [Tue, 24 Jul 2012 07:16:47 +0000 (12:16 +0530)]
In ULPI phy first SOF after Reset may be corrupt. Fixing this issue.

Bug 1012500

Change-Id: I45ee1b4c8e0a29298c94813030d22291b79e417b
Signed-off-by: Suresh Mangipudi <smangipudi@nvidia.com>
Reviewed-on: http://git-master/r/117635
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

arch/arm/mach-tegra/tegra3_usb_phy.c
arch/arm/mach-tegra/tegra_usb_phy.h

index 3152bdf..0b8ab07 100644 (file)
@@ -2576,7 +2576,16 @@ static int ulpi_null_phy_init(struct tegra_usb_phy *phy)
 
 static int ulpi_null_phy_irq(struct tegra_usb_phy *phy)
 {
+       unsigned long val;
+       void __iomem *base = phy->regs;
+
        usb_phy_fence_read(phy);
+       if (phy->bus_reseting){
+               val = readl(base + USB_USBCMD);
+               val |= USB_USBCMD_RS;
+               writel(val, base + USB_USBCMD);
+               phy->bus_reseting = false;
+       }
        return IRQ_HANDLED;
 }
 
@@ -2602,6 +2611,23 @@ static int ulpi_null_phy_cmd_reset(struct tegra_usb_phy *phy)
        return 0;
 }
 
+static int ulpi_phy_bus_reset(struct tegra_usb_phy *phy)
+{
+       unsigned long val;
+       void __iomem *base = phy->regs;
+
+       DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+
+       /*DISABLE RUN BIT */
+
+       val = readl(base + USB_USBCMD);
+       val &= ~USB_USBCMD_RS;
+       writel(val, base + USB_USBCMD);
+       phy->bus_reseting = true;
+
+       return 0;
+}
+
 static int ulpi_null_phy_restore(struct tegra_usb_phy *phy)
 {
        struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi;
@@ -2774,6 +2800,7 @@ static int ulpi_null_phy_power_on(struct tegra_usb_phy *phy)
        }
        udelay(10);
 
+       phy->bus_reseting = false;
        phy->phy_clk_on = true;
        phy->hw_accessible = true;
 
@@ -2857,6 +2884,7 @@ static struct tegra_usb_phy_ops ulpi_null_phy_ops = {
        .resume = ulpi_null_phy_resume,
        .post_resume = ulpi_null_phy_post_resume,
        .reset          = ulpi_null_phy_cmd_reset,
+       .bus_reset      = ulpi_phy_bus_reset,
 };
 
 static struct tegra_usb_phy_ops ulpi_link_phy_ops;
index 731632d..7e85a4b 100644 (file)
@@ -96,6 +96,7 @@ struct tegra_usb_phy {
        bool hw_accessible;
        bool ulpi_clk_padout_ena;
        bool pmc_sleepwalk;
+       bool bus_reseting;
 };
 
 int usb_phy_reg_status_wait(void __iomem *reg, u32 mask,