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:
parent
46249be267
commit
b8ef4c9a84
|
@ -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,39 +373,30 @@ 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]);
|
||||||
|
write32((unsigned long)&ehci_regs->port_status[port - 1],
|
||||||
|
portsc & ~(PORT_RWC_BITS | PORT_RESET));
|
||||||
|
|
||||||
|
loop = 100;
|
||||||
|
do {
|
||||||
|
dbgp_mdelay(1);
|
||||||
portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]);
|
portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]);
|
||||||
if (portsc & PORT_RESET) {
|
} while ((portsc & PORT_RESET) && (--loop > 0));
|
||||||
/* force reset to complete */
|
|
||||||
loop = 2;
|
|
||||||
write32((unsigned long)&ehci_regs->port_status[port - 1],
|
|
||||||
portsc & ~(PORT_RWC_BITS | PORT_RESET));
|
|
||||||
do {
|
|
||||||
dbgp_mdelay(delay_ms);
|
|
||||||
portsc = read32((unsigned long)&ehci_regs->port_status[port - 1]);
|
|
||||||
delay_time += delay_ms;
|
|
||||||
} 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))
|
||||||
return -1; //-ENOTCONN;
|
return -1; //-ENOTCONN;
|
||||||
|
|
||||||
/* bomb out completely if something weird happened */
|
/* bomb out completely if something weird happened */
|
||||||
if ((portsc & PORT_CSC))
|
if ((portsc & PORT_CSC))
|
||||||
return -2; //-EINVAL;
|
return -2; //-EINVAL;
|
||||||
|
|
||||||
|
/* If we've finished resetting, then break out of the loop */
|
||||||
|
if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* If we've finished resetting, then break out of the loop */
|
|
||||||
if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -3; //-EBUSY;
|
return -3; //-EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue