summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2013-08-12 21:35:20 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2014-11-23 20:36:16 +0100
commitb8ef4c9a840ebf1549694db9967f101ab2211db6 (patch)
tree37ca70d162e9b790384c245f6e47a011e34e7c99
parent46249be26753319877d67b2958c5070f179b5937 (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)
-rw-r--r--src/drivers/usb/ehci_debug.c48
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;
}