usb: ehci-omap: Reset the USB Host OMAP module

In commit bb1f327 we removed the UHH reset to fix NFS root (over usb
ethernet) problems with Beagleboard (3530 ES1.0). However, this
seems to cause USB detection problems for Pandaboard, about (3/8).

On further investigation, it seems that doing the UHH reset is not
the cause of the original Beagleboard problem, but in the way the reset
was done.

This patch adds proper UHH RESET mechanism for OMAP3 and OMAP4/5 based
on the UHH_REVISION register. This should fix the Beagleboard NFS
problem as well as the Pandaboard USB detection problem.

Reported-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
CC: Stefan Roese <sr@denx.de>
Reviewed-by: Stefan Roese <sr@denx.de>
Signed-off-by: Roger Quadros <rogerq@ti.com>
This commit is contained in:
Roger Quadros 2013-12-02 15:47:43 +02:00 committed by Tom Rini
parent f33b9bd398
commit 835a5559bd

View file

@ -28,21 +28,48 @@ static struct omap_ehci *const ehci = (struct omap_ehci *)OMAP_EHCI_BASE;
static int omap_uhh_reset(void)
{
/*
* Soft resetting the UHH module causes instability issues on
* all OMAPs so we just avoid it.
*
* See OMAP36xx Errata
* i571: USB host EHCI may stall when entering smart-standby mode
* i660: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
*
* On OMAP4/5, soft-resetting the UHH module will put it into
* Smart-Idle mode and lead to a deadlock.
*
* On OMAP3, this doesn't seem to be the case but still instabilities
* are observed on beagle (3530 ES1.0) if soft-reset is used.
* e.g. NFS root failures with Linux kernel.
*/
int timeout = 0;
u32 rev;
rev = readl(&uhh->rev);
/* Soft RESET */
writel(OMAP_UHH_SYSCONFIG_SOFTRESET, &uhh->sysc);
switch (rev) {
case OMAP_USBHS_REV1:
/* Wait for soft RESET to complete */
while (!(readl(&uhh->syss) & 0x1)) {
if (timeout > 100) {
printf("%s: RESET timeout\n", __func__);
return -1;
}
udelay(10);
timeout++;
}
/* Set No-Idle, No-Standby */
writel(OMAP_UHH_SYSCONFIG_VAL, &uhh->sysc);
break;
default: /* Rev. 2 onwards */
udelay(2); /* Need to wait before accessing SYSCONFIG back */
/* Wait for soft RESET to complete */
while ((readl(&uhh->sysc) & 0x1)) {
if (timeout > 100) {
printf("%s: RESET timeout\n", __func__);
return -1;
}
udelay(10);
timeout++;
}
writel(OMAP_UHH_SYSCONFIG_VAL, &uhh->sysc);
break;
}
return 0;
}