Add function handshake to wait for the HCHalted Status bit to be 0

This commit is contained in:
songyanguang 2024-09-03 17:42:44 +08:00
parent df1a8fac3a
commit 636d4bf8c8
1 changed files with 41 additions and 0 deletions

View File

@ -1068,6 +1068,36 @@ static int xhci_event_alloc ( struct xhci_host *xhci ) {
return rc; 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 * Start xHCI device
* *
@ -1077,6 +1107,8 @@ static void xhci_run ( struct xhci_host *xhci ) {
uint32_t config; uint32_t config;
uint32_t usbcmd; uint32_t usbcmd;
uint32_t runtime; uint32_t runtime;
int halt_msec;
int ret;
/* Configure number of device slots */ /* Configure number of device slots */
// config = readl ( xhci->op + XHCI_OP_CONFIG ); // 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 + XHCI_OP_USBCMD );
writel ( usbcmd, xhci->op_addr + 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 ); USB_LOG_DBG("XHCI %s start running\n", xhci->name );
} }