summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2013-08-12 15:32:25 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2013-08-23 05:11:03 +0200
commit16c014578b9662bc2a0f099b77410e7ea3a793d1 (patch)
treefb06f62518dac433fd9fcc41970d1e2dc9447d62
parent1cf85774da278229229fb77891326d645176d24d (diff)
usbdebug: Halt host controller before resetting it
Resetting an EHCI controller when it is not halted can have undefined behaviour. This mostly fixes a case where calling usbdebug_init() twice would fail to reset the USB dongle device properly. On amd/persimmon it still requires one extra retry, but at least it is now possible to have usbdebug enabled for both romstage and ramstage. Change-Id: Ib0e6e5a0167404f68af2edf112306fdb8def0be9 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/3862 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
-rw-r--r--src/lib/usbdebug.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/lib/usbdebug.c b/src/lib/usbdebug.c
index 53ba4db53c..a9a7e17597 100644
--- a/src/lib/usbdebug.c
+++ b/src/lib/usbdebug.c
@@ -448,6 +448,23 @@ try_next_port:
return -1;
}
+ /* Wait until the controller is halted */
+ status = read32((unsigned long)&ehci_regs->status);
+ if (!(status & STS_HALT)) {
+ cmd = read32((unsigned long)&ehci_regs->command);
+ cmd &= ~CMD_RUN;
+ write32((unsigned long)&ehci_regs->command, cmd);
+ loop = 100;
+ do {
+ dbgp_mdelay(10);
+ status = read32((unsigned long)&ehci_regs->status);
+ } while (!(status & STS_HALT) && (--loop > 0));
+ if (status & STS_HALT)
+ dprintk(BIOS_INFO, "EHCI controller halted successfully.\n");
+ else
+ dprintk(BIOS_INFO, "EHCI controller is not halted. Reset may fail.\n");
+ }
+
loop = 100;
/* Reset the EHCI controller */
cmd = read32((unsigned long)&ehci_regs->command);