kernel/usb4bsd: Update pci drivers for HCIs
authorMarkus Pfeiffer <markus.pfeiffer@morphism.de>
Sun, 22 Feb 2015 00:28:57 +0000 (00:28 +0000)
committerMarkus Pfeiffer <markus.pfeiffer@morphism.de>
Sun, 22 Feb 2015 00:28:57 +0000 (00:28 +0000)
This adds support for 64bit DMA for chips that support it. This needs
further testing.

sys/bus/u4b/controller/ehci_pci.c
sys/bus/u4b/controller/xhci_pci.c
sys/bus/u4b/controller/xhcireg.h

index 8e0f3a3..1162a65 100644 (file)
@@ -28,6 +28,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+/* $FreeBSD: head/sys/dev/usb/controller/ehci_pci.c 276717 2015-01-05 20:22:18Z hselasky $ */
+
 /*
  * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
  *
@@ -114,6 +116,12 @@ ehci_pci_match(device_t self)
        case 0x43961002:
                return ("AMD SB7x0/SB8x0/SB9x0 USB 2.0 controller");
 
+       case 0x0f348086:
+               return ("Intel BayTrail USB 2.0 controller");
+       case 0x1d268086:
+               return ("Intel Patsburg USB 2.0 controller");
+       case 0x1d2d8086:
+               return ("Intel Patsburg USB 2.0 controller");
        case 0x1e268086:
                return ("Intel Panther Point USB 2.0 controller");
        case 0x1e2d8086:
@@ -152,6 +160,12 @@ ehci_pci_match(device_t self)
                return ("Intel Lynx Point USB 2.0 controller USB-A");
        case 0x8c2d8086:
                return ("Intel Lynx Point USB 2.0 controller USB-B");
+       case 0x8ca68086:
+               return ("Intel Wildcat Point USB 2.0 controller USB-A");
+       case 0x8cad8086:
+               return ("Intel Wildcat Point USB 2.0 controller USB-B");
+       case 0x9c268086:
+               return ("Intel Lynx Point LP USB 2.0 controller USB");
 
        case 0x00e01033:
                return ("NEC uPD 720100 USB 2.0 controller");
@@ -264,6 +278,7 @@ ehci_pci_attach(device_t self)
        sc->sc_bus.parent = self;
        sc->sc_bus.devices = sc->sc_devices;
        sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+       sc->sc_bus.dma_bits = 32;
 
        /* get all DMA memory */
        if (usb_bus_mem_alloc_all(&sc->sc_bus,
index 3f6ffbc..90795c6 100644 (file)
@@ -23,6 +23,8 @@
  * SUCH DAMAGE.
  */
 
+/* $FreeBSD: head/sys/dev/usb/controller/xhci_pci.c 276717 2015-01-05 20:22:18Z hselasky $ */
+
 #include <sys/stdint.h>
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -97,10 +99,15 @@ xhci_pci_match(device_t self)
        case 0x10421b21:
                return ("ASMedia ASM1042 USB 3.0 controller");
 
+       case 0x0f358086:
+               return ("Intel Intel BayTrail USB 3.0 controller");
+       case 0x9c318086:
        case 0x1e318086:
                return ("Intel Panther Point USB 3.0 controller");
        case 0x8c318086:
                return ("Intel Lynx Point USB 3.0 controller");
+       case 0x8cb18086:
+               return ("Intel Wildcat Point USB 3.0 controller");
 
        default:
                break;
@@ -144,6 +151,8 @@ static int
 xhci_pci_port_route(device_t self, uint32_t set, uint32_t clear)
 {
        uint32_t temp;
+       uint32_t usb3_mask;
+       uint32_t usb2_mask;
 
        temp = pci_read_config(self, PCI_XHCI_INTEL_USB3_PSSEN, 4) |
            pci_read_config(self, PCI_XHCI_INTEL_XUSB2PR, 4);
@@ -151,8 +160,12 @@ xhci_pci_port_route(device_t self, uint32_t set, uint32_t clear)
        temp |= set;
        temp &= ~clear;
 
-       pci_write_config(self, PCI_XHCI_INTEL_USB3_PSSEN, temp, 4);
-       pci_write_config(self, PCI_XHCI_INTEL_XUSB2PR, temp, 4);
+       /* Don't set bits which the hardware doesn't support */
+       usb3_mask = pci_read_config(self, PCI_XHCI_INTEL_USB3PRM, 4);
+       usb2_mask = pci_read_config(self, PCI_XHCI_INTEL_USB2PRM, 4);
+
+       pci_write_config(self, PCI_XHCI_INTEL_USB3_PSSEN, temp & usb3_mask, 4);
+       pci_write_config(self, PCI_XHCI_INTEL_XUSB2PR, temp & usb2_mask, 4);
 
        device_printf(self, "Port routing mask set to 0x%08x\n", temp);
 
@@ -165,29 +178,29 @@ xhci_pci_attach(device_t self)
        struct xhci_softc *sc = device_get_softc(self);
        int count, err, rid;
 
-       /* XXX check for 64-bit capability */
-
-       if (xhci_init(sc, self)) {
-               device_printf(self, "Could not initialize softc\n");
-               goto error;
-       }
-
-       pci_enable_busmaster(self);
-
        rid = PCI_XHCI_CBMEM;
        sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
            RF_ACTIVE);
        if (!sc->sc_io_res) {
                device_printf(self, "Could not map memory\n");
-               goto error;
+               return (ENOMEM);
        }
        sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
        sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
        sc->sc_io_size = rman_get_size(sc->sc_io_res);
 
+       if (xhci_init(sc, self)) {
+               device_printf(self, "Could not initialize softc\n");
+               bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM,
+                   sc->sc_io_res);
+               return (ENXIO);
+       }
+
+       pci_enable_busmaster(self);
+
        usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_lock, 0);
 
-       sc->sc_irq_rid = 0;
+       rid = 0;
        if (xhci_use_msi) {
                count = pci_msi_count(self);
                if (count >= 1) {
@@ -202,8 +215,9 @@ xhci_pci_attach(device_t self)
        sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ,
            &sc->sc_irq_rid, RF_SHAREABLE | RF_ACTIVE);
        if (sc->sc_irq_res == NULL) {
+               pci_release_msi(self);
                device_printf(self, "Could not allocate IRQ\n");
-               goto error;
+               /* goto error; FALLTHROUGH - use polling */
        }
        sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
        if (sc->sc_bus.bdev == NULL) {
@@ -218,23 +232,33 @@ xhci_pci_attach(device_t self)
                err = bus_setup_intr(self, sc->sc_irq_res, INTR_MPSAFE,
                    (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl, NULL);
                if (err != 0) {
+                       bus_release_resource(self, SYS_RES_IRQ,
+                           rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
+                       sc->sc_irq_res = NULL;
+                       pci_release_msi(self);
                        device_printf(self, "Could not setup IRQ, err=%d\n", err);
                        sc->sc_intr_hdl = NULL;
                }
        }
-       if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL ||
-           xhci_use_polling() != 0) {
-               device_printf(self, "Interrupt polling at %dHz\n", hz);
-               USB_BUS_LOCK(&sc->sc_bus);
-               xhci_interrupt_poll(sc);
-               USB_BUS_UNLOCK(&sc->sc_bus);
+       if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL) {
+               if (xhci_use_polling() != 0) {
+                       device_printf(self, "Interrupt polling at %dHz\n", hz);
+                       USB_BUS_LOCK(&sc->sc_bus);
+                       xhci_interrupt_poll(sc);
+                       USB_BUS_UNLOCK(&sc->sc_bus);
+               } else
+                       goto error;
        }
 
        /* On Intel chipsets reroute ports from EHCI to XHCI controller. */
        switch (pci_get_devid(self)) {
+       case 0x0f358086:        /* BayTrail */
+       case 0x9c318086:        /* Panther Point */
        case 0x1e318086:        /* Panther Point */
        case 0x8c318086:        /* Lynx Point */
+       case 0x8cb18086:        /* Wildcat Point */
                sc->sc_port_route = &xhci_pci_port_route;
+               sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP;
                break;
        default:
                break;
@@ -275,10 +299,8 @@ xhci_pci_detach(device_t self)
        /* during module unload there are lots of children leftover */
        device_delete_children(self);
 
-       if (sc->sc_io_res) {
-               usb_callout_drain(&sc->sc_callout);
-               xhci_halt_controller(sc);
-       }
+       usb_callout_drain(&sc->sc_callout);
+       xhci_halt_controller(sc);
 
        pci_disable_busmaster(self);
 
@@ -287,11 +309,10 @@ xhci_pci_detach(device_t self)
                sc->sc_intr_hdl = NULL;
        }
        if (sc->sc_irq_res) {
-               if (sc->sc_irq_rid == 1)
-                       pci_release_msi(self);
-               bus_release_resource(self, SYS_RES_IRQ, sc->sc_irq_rid,
-                   sc->sc_irq_res);
+               bus_release_resource(self, SYS_RES_IRQ,
+                   rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
                sc->sc_irq_res = NULL;
+               pci_release_msi(self);
        }
        if (sc->sc_io_res) {
                bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM,
index 85d989a..ec8f22a 100644 (file)
@@ -1,4 +1,4 @@
-/* $FreeBSD$ */
+/* $FreeBSD: head/sys/dev/usb/controller/xhcireg.h 268354 2014-07-07 05:17:16Z hselasky $ */
 
 /*-
  * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
@@ -35,7 +35,9 @@
 #define        PCI_XHCI_FLADJ          0x61    /* RW frame length adjust */
 
 #define        PCI_XHCI_INTEL_XUSB2PR  0xD0    /* Intel USB2 Port Routing */
+#define        PCI_XHCI_INTEL_USB2PRM  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 */
 #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 IRQs/second */
+#define        XHCI_IMOD_DEFAULT_LP    0x000003F8U     /* 4000 IRQs/second - LynxPoint */
 #define        XHCI_ERSTSZ(n)          (0x0028 + (0x20 * (n))) /* XHCI event ring segment table size */
 #define        XHCI_ERSTS_GET(x)       ((x) & 0xFFFF)
 #define        XHCI_ERSTS_SET(x)       ((x) & 0xFFFF)