To enable Intel XHCI host controller, re-route all of usb port to xhci
authoryuo <yuo@openbsd.org>
Sat, 12 Jul 2014 17:38:51 +0000 (17:38 +0000)
committeryuo <yuo@openbsd.org>
Sat, 12 Jul 2014 17:38:51 +0000 (17:38 +0000)
instead of connected to ehci.

ok mpi@

sys/dev/pci/xhci_pci.c
sys/dev/usb/xhcireg.h

index a908f61..9f175ed 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: xhci_pci.c,v 1.3 2014/04/07 23:32:41 brad Exp $ */
+/*     $OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp $ */
 
 /*
  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -87,6 +87,41 @@ xhci_pci_match(struct device *parent, void *match, void *aux)
        return (0);
 }
 
+static int
+xhci_pci_port_route(struct xhci_pci_softc *psc)
+{
+       pcireg_t val;
+
+       /* 
+        * Check USB3 Port Routing Mask register that indicates the ports
+        * can be changed from OS, and turn on by USB3 Port SS Enable register.
+        */ 
+       val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3PRM);
+       DPRINTF(("%s: USB3PRM / USB3.0 configurable ports: 0x%08x\n",
+           psc->sc.sc_bus.bdev.dv_xname, val));
+
+       pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN, val);
+       val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN);
+       DPRINTF(("%s: USB3_PSSEN / Enabled USB3.0 ports under xHCI: 0x%08x\n",
+           psc->sc.sc_bus.bdev.dv_xname, val));
+
+       /*
+        * Check USB2 Port Routing Mask register that indicates the USB2.0 
+        * ports to be controlled by xHCI HC, and switch them to xHCI HC.
+        */
+       val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PRM);
+       DPRINTF(("%s: XUSB2PRM / USB2.0 ports can switch from EHCI to xHCI:"
+           "0x%08x\n", psc->sc.sc_bus.bdev.dv_xname, val));
+
+       pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR, val);
+       val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR);
+       DPRINTF(("%s: XUSB2PR / USB2.0 ports under xHCI: 0x%08x\n",
+           psc->sc.sc_bus.bdev.dv_xname, val));
+
+       return (0);
+}
+
+
 void
 xhci_pci_attach(struct device *parent, struct device *self, void *aux)
 {
@@ -154,6 +189,17 @@ xhci_pci_attach(struct device *parent, struct device *self, void *aux)
                goto disestablish_ret;
        }
 
+       switch (PCI_VENDOR(pa->pa_id)) {
+       case PCI_VENDOR_INTEL:
+               switch (PCI_PRODUCT(pa->pa_id)) {
+               case PCI_PRODUCT_INTEL_8SERIES_XHCI:
+               case PCI_PRODUCT_INTEL_8SERIES_LP_XHCI:
+               case PCI_PRODUCT_INTEL_7SERIES_XHCI:
+                       xhci_pci_port_route(psc);
+                       break;
+               }
+       }
+
        /* Attach usb device. */
        config_found(self, &psc->sc.sc_bus, usbctlprint);
 
index e8ac28c..6ea8604 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhcireg.h,v 1.1 2014/03/08 14:34:11 mpi Exp $ */
+/* $OpenBSD: xhcireg.h,v 1.2 2014/07/12 17:38:51 yuo Exp $ */
 
 /*-
  * Copyright (c) 2014 Martin Pieuchot. All rights reserved.
@@ -44,7 +44,9 @@
 #define PCI_XHCI_FLADJ         0x61    /* RW frame length adjust */
 
 #define PCI_XHCI_INTEL_XUSB2PR 0xd0    /* Intel USB2 Port Routing */
+#define PCI_XHCI_INTEL_XUSB2PRM        0xd4    /* Intel USB2 Port Routing Mask */
 #define PCI_XHCI_INTEL_USB3_PSSEN 0xd8 /* Intel USB3 Port SuperSpeed Enable */
+#define PCI_XHCI_INTEL_USB3PRM 0xdc    /* Intel USB3 Port Routing Mask */
 
 /* XHCI capability registers */
 #define XHCI_CAPLENGTH         0x00    /* RO Capability reg. length field */
 #define  XHCI_IMOD_IVAL_SET(x) (((x) & 0xffff) << 0)   /* 250ns unit */
 #define  XHCI_IMOD_ICNT_GET(x) (((x) >> 16) & 0xffff)  /* 250ns unit */
 #define  XHCI_IMOD_ICNT_SET(x) (((x) & 0xffff) << 16)  /* 250ns unit */
-#define  XHCI_IMOD_DEFAULT     0x000003E8U             /* 8000 IRQ/second */
+#define  XHCI_IMOD_DEFAULT     0x000001F4U             /* 8000 IRQ/second */
+#define  XHCI_IMOD_DEFAULT_LP  0x000003E8U             /* 4000 IRQ/second */
 
 /* XHCI event ring segment table size */
 #define XHCI_ERSTSZ(n)         (0x0028 + (0x20 * (n)))