summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorSuresh Mangipudi <smangipudi@nvidia.com>2012-07-24 12:46:47 +0530
committerSimone Willett <swillett@nvidia.com>2012-07-24 17:32:53 -0700
commitb2010ea221679291ced813178b21efdae54b7baf (patch)
treed64666efa446159ba85e4c6dcaf111bc4b09a52c /arch/arm/mach-tegra
parentf94229cc7a6d469154145bd13add16a4cef0dc6a (diff)
arm: tegra: usb: Fix First SOF corruption.
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>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/tegra3_usb_phy.c28
-rw-r--r--arch/arm/mach-tegra/tegra_usb_phy.h1
2 files changed, 29 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra3_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c
index 3152bdf9e107..0b8ab076693d 100644
--- a/arch/arm/mach-tegra/tegra3_usb_phy.c
+++ b/arch/arm/mach-tegra/tegra3_usb_phy.c
@@ -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;
diff --git a/arch/arm/mach-tegra/tegra_usb_phy.h b/arch/arm/mach-tegra/tegra_usb_phy.h
index 731632d23679..7e85a4b02282 100644
--- a/arch/arm/mach-tegra/tegra_usb_phy.h
+++ b/arch/arm/mach-tegra/tegra_usb_phy.h
@@ -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,