diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2013-08-12 15:32:25 +0300 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2013-08-23 05:11:03 +0200 |
commit | 16c014578b9662bc2a0f099b77410e7ea3a793d1 (patch) | |
tree | fb06f62518dac433fd9fcc41970d1e2dc9447d62 | |
parent | 1cf85774da278229229fb77891326d645176d24d (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.c | 17 |
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); |