diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c index 3ac56007c..536e90929 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c @@ -1068,6 +1068,36 @@ static int xhci_event_alloc ( struct xhci_host *xhci ) { return rc; } +/** + * Waits for as per specified amount of time + * for the "result" to match with "done" + * + * @param ptr pointer to the register to be read + * @param mask mask for the value read + * @param done value to be campared with result + * @param msec time to wait till + * @return 0 if handshake is success else < 0 on failure + */ +static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int msec) +{ + uint32_t result; + + do { + result = readl(ptr); + if (result == ~(uint32_t)0) + return -ENODEV; + result &= mask; + if (result == done) { + USB_LOG_DBG("XHCI handshake success ptr=%p result=%08x\n", ptr, result ); + return 0; + } + msec--; + usb_osal_msleep(1); + } while (msec > 0); + USB_LOG_DBG("XHCI handshake timeout ptr=%p result=%08x\n", ptr, result ); + return -ETIMEDOUT; +} + /** * Start xHCI device * @@ -1077,6 +1107,8 @@ static void xhci_run ( struct xhci_host *xhci ) { uint32_t config; uint32_t usbcmd; uint32_t runtime; + int halt_msec; + int ret; /* Configure number of device slots */ // config = readl ( xhci->op + XHCI_OP_CONFIG ); @@ -1102,6 +1134,15 @@ static void xhci_run ( struct xhci_host *xhci ) { // writel ( usbcmd, xhci->op + XHCI_OP_USBCMD ); writel ( usbcmd, xhci->op_addr + XHCI_OP_USBCMD ); + /* + * Wait for the HCHalted Status bit to be 0 to indicate the host is + * running. + */ + halt_msec = 16; + ret = handshake(xhci->op_addr + XHCI_OP_USBSTS, XHCI_USBSTS_HCH, 0, halt_msec); + if (ret) + USB_LOG_WRN("Host took too long to start, waited %u microseconds.\n", halt_msec); + USB_LOG_DBG("XHCI %s start running\n", xhci->name ); }