summaryrefslogtreecommitdiff
path: root/payloads/libpayload
diff options
context:
space:
mode:
authorNico Huber <nico.huber@secunet.com>2013-07-19 14:03:47 +0200
committerNico Huber <nico.h@gmx.de>2013-09-30 10:42:53 +0200
commitc371442a2925e9bfc9ddc045bfd446db53f0a145 (patch)
tree1598d90e49ff6bdd47ed96228fb00e3e8025b1f1 /payloads/libpayload
parent681d17e0bf00a889f3c931d69b9af205c4ab674d (diff)
libpayload: Switch xHCI shared ports back to EHCI on shutdown
On Intel's Panther Point the xHCI ports are shared with an EHCI controller. Our xHCI driver switches them to xHCI, naturally. But we forgot to switch them back on shutdown, which left them unusable by a non-xHCI aware operating system. Change-Id: I70ef08655a603b42ee939935d50cf77ea97878a3 Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: http://review.coreboot.org/3791 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'payloads/libpayload')
-rw-r--r--payloads/libpayload/drivers/usb/xhci.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c
index c29d323175..51f9422ceb 100644
--- a/payloads/libpayload/drivers/usb/xhci.c
+++ b/payloads/libpayload/drivers/usb/xhci.c
@@ -110,6 +110,19 @@ xhci_switch_ppt_ports(pcidev_t addr)
}
}
+/* On Panther Point: switch all ports back to EHCI */
+static void
+xhci_switchback_ppt_ports(pcidev_t addr)
+{
+ if (pci_read_config32(addr, 0x00) == 0x1e318086) {
+ u32 reg32 = pci_read_config32(addr, 0xd0) & 0xf;
+ xhci_debug("Switching ports back: 0x%"PRIx32"\n", reg32);
+ pci_write_config32(addr, 0xd0, 0x00000000);
+ reg32 = pci_read_config32(addr, 0xd0) & 0xf;
+ xhci_debug("Still switched to xHCI: 0x%"PRIx32"\n", reg32);
+ }
+}
+
static long
xhci_handshake(volatile u32 *const reg, u32 mask, u32 wait_for, long timeout_us)
{
@@ -389,6 +402,8 @@ xhci_shutdown(hci_t *const controller)
xhci_stop(controller);
+ xhci_switchback_ppt_ports(controller->bus_address);
+
if (xhci->sp_ptrs) {
const size_t max_sp_bufs = xhci->capreg->Max_Scratchpad_Bufs;
for (i = 0; i < max_sp_bufs; ++i) {