usbdebug: Reduce bus reset delays

According to EHCI specification, host controller software stops
the USB Reset condition by writing PORT_RESET=0. Software then
poll-waits this bit until controller hardware has completed USB
Reset sequence and read returns with PORT_RESET==0.

Change-Id: I6033c4d904c2af9eb16f5f3c1eb825776648cc1d
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/3863
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins)
This commit is contained in:
Kyösti Mälkki 2013-08-12 21:35:20 +03:00
parent 46249be267
commit b8ef4c9a84
1 changed files with 19 additions and 29 deletions

View File

@ -365,7 +365,6 @@ int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned devnum, int requ
static int ehci_reset_port(struct ehci_regs *ehci_regs, int port) static int ehci_reset_port(struct ehci_regs *ehci_regs, int port)
{ {
u32 portsc; u32 portsc;
u32 delay_time, delay_ms;
int loop; int loop;
/* Reset the usb debug port */ /* Reset the usb debug port */
@ -374,26 +373,17 @@ static int ehci_reset_port(struct ehci_regs *ehci_regs, int port)
portsc |= PORT_RESET; portsc |= PORT_RESET;
write32((unsigned long)&ehci_regs->port_status[port - 1], portsc); write32((unsigned long)&ehci_regs->port_status[port - 1], portsc);
delay_ms = HUB_ROOT_RESET_TIME; dbgp_mdelay(HUB_ROOT_RESET_TIME);
for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT;
delay_time += delay_ms) {
dbgp_mdelay(delay_ms);
portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]); portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]);
if (portsc & PORT_RESET) {
/* force reset to complete */
loop = 2;
write32((unsigned long)&ehci_regs->port_status[port - 1], write32((unsigned long)&ehci_regs->port_status[port - 1],
portsc & ~(PORT_RWC_BITS | PORT_RESET)); portsc & ~(PORT_RWC_BITS | PORT_RESET));
loop = 100;
do { do {
dbgp_mdelay(delay_ms); dbgp_mdelay(1);
portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]); portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]);
delay_time += delay_ms;
} while ((portsc & PORT_RESET) && (--loop > 0)); } while ((portsc & PORT_RESET) && (--loop > 0));
if (!loop) {
printk(BIOS_DEBUG, "ehci_reset_port forced done");
}
}
/* Device went away? */ /* Device went away? */
if (!(portsc & PORT_CONNECT)) if (!(portsc & PORT_CONNECT))
@ -406,7 +396,7 @@ static int ehci_reset_port(struct ehci_regs *ehci_regs, int port)
/* If we've finished resetting, then break out of the loop */ /* If we've finished resetting, then break out of the loop */
if (!(portsc & PORT_RESET) && (portsc & PORT_PE)) if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
return 0; return 0;
}
return -3; //-EBUSY; return -3; //-EBUSY;
} }