From 1528ffa57cdc8bfbea80ce6d23b9acddef68614e Mon Sep 17 00:00:00 2001 From: Rajmohan Mani Date: Fri, 30 Oct 2015 17:00:24 -0700 Subject: [PATCH] libpayload: xhci: Add delay to get reset working more reliably Existing Intel xHCI controllers require a delay of 1 ms, after setting the CMD_RESET bit in command register, before accessing any HC registers. This allows the HC to complete the reset operation and be ready for HC register access. Without this delay, the subsequent HC register access, may result in a system hang, very rarely. Verified CherryView / Braswell platforms go through over 1000 warm reboot cycles (which was not possible without this patch), without any xHCI reset hang in depthcharge. BRANCH=None BUG=None TEST=Verified CherryView / Braswell platforms go through over 1000 warm reboot cycles, without any xHCI reset hang in depthcharge. Change-Id: I8eff5115ca52738bdcf8bc65fbfb2a5f60a0abe1 Signed-off-by: Patrick Georgi Original-Commit-Id: 3e7ea70df36e3bf35a6ee1297640900ee76bfdac Original-Change-Id: Id681a19d0eedb0e2c29e259c5467bcde577e3460 Original-Signed-off-by: Rajmohan Mani Original-Reviewed-on: https://chromium-review.googlesource.com/310022 Original-Reviewed-by: Patrick Georgi Reviewed-on: http://review.coreboot.org/12325 Reviewed-by: Stefan Reinauer Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- payloads/libpayload/drivers/usb/xhci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c index 71272c7133..d223d0f190 100644 --- a/payloads/libpayload/drivers/usb/xhci.c +++ b/payloads/libpayload/drivers/usb/xhci.c @@ -328,6 +328,17 @@ xhci_reset(hci_t *const controller) xhci_stop(controller); xhci->opreg->usbcmd |= USBCMD_HCRST; + + /* Existing Intel xHCI controllers require a delay of 1 ms, + * after setting the CMD_RESET bit, and before accessing any + * HC registers. This allows the HC to complete the + * reset operation and be ready for HC register access. + * Without this delay, the subsequent HC register access, + * may result in a system hang very rarely. + */ + if (IS_ENABLED(CONFIG_LP_ARCH_X86)) + mdelay(1); + xhci_debug("Resetting controller... "); if (!xhci_handshake(&xhci->opreg->usbcmd, USBCMD_HCRST, 0, 1000000L)) usb_debug("timeout!\n");