diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2013-08-12 21:35:20 +0300 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2014-11-23 20:36:16 +0100 |
commit | b8ef4c9a840ebf1549694db9967f101ab2211db6 (patch) | |
tree | 37ca70d162e9b790384c245f6e47a011e34e7c99 /src/drivers/usb | |
parent | 46249be26753319877d67b2958c5070f179b5937 (diff) |
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)
Diffstat (limited to 'src/drivers/usb')
-rw-r--r-- | src/drivers/usb/ehci_debug.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/src/drivers/usb/ehci_debug.c b/src/drivers/usb/ehci_debug.c index 55530b73b4..62b10c57ed 100644 --- a/src/drivers/usb/ehci_debug.c +++ b/src/drivers/usb/ehci_debug.c @@ -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) { u32 portsc; - u32 delay_time, delay_ms; int loop; /* Reset the usb debug port */ @@ -374,39 +373,30 @@ static int ehci_reset_port(struct ehci_regs *ehci_regs, int port) portsc |= PORT_RESET; write32((unsigned long)&ehci_regs->port_status[port - 1], portsc); - delay_ms = HUB_ROOT_RESET_TIME; - for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT; - delay_time += delay_ms) { - dbgp_mdelay(delay_ms); + dbgp_mdelay(HUB_ROOT_RESET_TIME); + 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]); - if (portsc & PORT_RESET) { - /* 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"); - } - } + } while ((portsc & PORT_RESET) && (--loop > 0)); - /* Device went away? */ - if (!(portsc & PORT_CONNECT)) - return -1; //-ENOTCONN; + /* Device went away? */ + if (!(portsc & PORT_CONNECT)) + return -1; //-ENOTCONN; - /* bomb out completely if something weird happened */ - if ((portsc & PORT_CSC)) - return -2; //-EINVAL; + /* bomb out completely if something weird happened */ + if ((portsc & PORT_CSC)) + 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; } |