XHCI perform init sequence
This commit is contained in:
@@ -9,6 +9,11 @@
|
||||
#include <proc/reschedule.h>
|
||||
#include <proc/suspension_q.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/spin_lock.h>
|
||||
|
||||
/* REF:
|
||||
* https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
@@ -97,6 +102,37 @@ DEFINE_DEVICE_INIT (xhci_init) {
|
||||
uint32_t dboff = xhci_read32 (xhci->xhci_mmio_base, XHCI_DBOFF);
|
||||
xhci->xhci_doorbell_base = xhci->xhci_mmio_base + dboff;
|
||||
|
||||
DEBUG ("starting init sequence\n");
|
||||
|
||||
/* assert CNR is 0 */
|
||||
while (xhci_read32 (xhci->xhci_oper_base, XHCI_USBSTS) & (1 << 11))
|
||||
spin_lock_relax ();
|
||||
|
||||
/* STOP */
|
||||
uint32_t usbcmd = xhci_read32 (xhci->xhci_oper_base, XHCI_USBCMD);
|
||||
xhci_write32 (xhci->xhci_oper_base, XHCI_USBCMD, usbcmd & ~0x01);
|
||||
|
||||
/* wait for HCH bit */
|
||||
int timeout = 100000;
|
||||
while (!(xhci_read32 (xhci->xhci_oper_base, XHCI_USBSTS) & (1 << 12))) {
|
||||
if (--timeout == 0)
|
||||
break;
|
||||
|
||||
spin_lock_relax ();
|
||||
}
|
||||
|
||||
/* RESET */
|
||||
xhci_write32 (xhci->xhci_oper_base, XHCI_USBCMD, (1 << 1));
|
||||
|
||||
while (xhci_read32 (xhci->xhci_oper_base, XHCI_USBCMD) & (1 << 1))
|
||||
spin_lock_relax ();
|
||||
|
||||
/* Stall while controller not ready */
|
||||
while (xhci_read32 (xhci->xhci_oper_base, XHCI_USBSTS) & (1 << 11))
|
||||
spin_lock_relax ();
|
||||
|
||||
DEBUG ("XHCI init done\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user