diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-11-03 10:24:54 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-11-03 10:24:54 +0000 |
commit | fe49fc6e1c94b6c41d1d3844ca219a76da3c70dc (patch) | |
tree | 7aadfcbd4111252b69837268754c4852bb8f5d24 | |
parent | 72f26a17812d542d19fe2d09e3c2684f82c8cbbd (diff) | |
download | FreeBSD-src-fe49fc6e1c94b6c41d1d3844ca219a76da3c70dc.zip FreeBSD-src-fe49fc6e1c94b6c41d1d3844ca219a76da3c70dc.tar.gz |
MFC r285914, r289029 and r289560:
- Move the remainder of host controller capability registers reading from
xhci_start_controller() to xhci_init(). These values don't change at run-
time so there's no point of acquiring them on every USB_HW_POWER_RESUME
instead of only once during initialization. In r276717, reading the first
couple of registers in question already had been moved as a prerequisite
for the changes in that revision.
- Identify ASMedia ASM1042A controllers.
- Use NULL instead of 0 for pointers.
- Add quirks for USB 3.0 PCI devices.
PR: 203650
-rw-r--r-- | sys/dev/usb/controller/xhci.c | 124 | ||||
-rw-r--r-- | sys/dev/usb/controller/xhci_pci.c | 39 |
2 files changed, 81 insertions, 82 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index 6f5441a..3853ed1 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -380,54 +380,12 @@ xhci_start_controller(struct xhci_softc *sc) return (USB_ERR_IOERROR); } - if (!(XREAD4(sc, oper, XHCI_PAGESIZE) & XHCI_PAGESIZE_4K)) { - device_printf(sc->sc_bus.parent, "Controller does " - "not support 4K page size.\n"); - return (USB_ERR_IOERROR); - } - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS1); - - i = XHCI_HCS1_N_PORTS(temp); - - if (i == 0) { - device_printf(sc->sc_bus.parent, "Invalid number " - "of ports: %u\n", i); - return (USB_ERR_IOERROR); - } - - sc->sc_noport = i; - sc->sc_noslot = XHCI_HCS1_DEVSLOT_MAX(temp); - - if (sc->sc_noslot > XHCI_MAX_DEVICES) - sc->sc_noslot = XHCI_MAX_DEVICES; - /* set up number of device slots */ - DPRINTF("CONFIG=0x%08x -> 0x%08x\n", XREAD4(sc, oper, XHCI_CONFIG), sc->sc_noslot); XWRITE4(sc, oper, XHCI_CONFIG, sc->sc_noslot); - DPRINTF("Max slots: %u\n", sc->sc_noslot); - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); - - sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp); - - if (sc->sc_noscratch > XHCI_MAX_SCRATCHPADS) { - device_printf(sc->sc_bus.parent, "XHCI request " - "too many scratchpads\n"); - return (USB_ERR_NOMEM); - } - - DPRINTF("Max scratch: %u\n", sc->sc_noscratch); - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS3); - - sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) + - XHCI_HCS3_U2_DEL(temp) + 250 /* us */; - temp = XREAD4(sc, oper, XHCI_USBSTS); /* clear interrupts */ @@ -459,29 +417,13 @@ xhci_start_controller(struct xhci_softc *sc) XWRITE4(sc, oper, XHCI_DCBAAP_LO, (uint32_t)addr); XWRITE4(sc, oper, XHCI_DCBAAP_HI, (uint32_t)(addr >> 32)); - /* Setup event table size */ - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); - - DPRINTF("HCS2=0x%08x\n", temp); - - temp = XHCI_HCS2_ERST_MAX(temp); - temp = 1U << temp; - if (temp > XHCI_MAX_RSEG) - temp = XHCI_MAX_RSEG; - - sc->sc_erst_max = temp; - + /* set up event table size */ DPRINTF("ERSTSZ=0x%08x -> 0x%08x\n", - XREAD4(sc, runt, XHCI_ERSTSZ(0)), temp); + XREAD4(sc, runt, XHCI_ERSTSZ(0)), sc->sc_erst_max); - XWRITE4(sc, runt, XHCI_ERSTSZ(0), XHCI_ERSTS_SET(temp)); + XWRITE4(sc, runt, XHCI_ERSTSZ(0), XHCI_ERSTS_SET(sc->sc_erst_max)); - /* Check if we should use the default IMOD value */ - if (sc->sc_imod_default == 0) - sc->sc_imod_default = XHCI_IMOD_DEFAULT; - - /* Setup interrupt rate */ + /* set up interrupt rate */ XWRITE4(sc, runt, XHCI_IMOD(0), sc->sc_imod_default); usbd_get_page(&sc->sc_hw.root_pc, 0, &buf_res); @@ -508,8 +450,7 @@ xhci_start_controller(struct xhci_softc *sc) XWRITE4(sc, runt, XHCI_ERSTBA_LO(0), (uint32_t)addr); XWRITE4(sc, runt, XHCI_ERSTBA_HI(0), (uint32_t)(addr >> 32)); - /* Setup interrupter registers */ - + /* set up interrupter registers */ temp = XREAD4(sc, runt, XHCI_IMAN(0)); temp |= XHCI_IMAN_INTR_ENA; XWRITE4(sc, runt, XHCI_IMAN(0), temp); @@ -620,6 +561,12 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32) DPRINTF("xHCI version = 0x%04x\n", XREAD2(sc, capa, XHCI_HCIVERSION)); + if (!(XREAD4(sc, oper, XHCI_PAGESIZE) & XHCI_PAGESIZE_4K)) { + device_printf(sc->sc_bus.parent, "Controller does " + "not support 4K page size.\n"); + return (ENXIO); + } + temp = XREAD4(sc, capa, XHCI_HCSPARAMS0); DPRINTF("HCS0 = 0x%08x\n", temp); @@ -638,6 +585,55 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32) device_printf(self, "%d bytes context size, %d-bit DMA\n", sc->sc_ctx_is_64_byte ? 64 : 32, (int)sc->sc_bus.dma_bits); + temp = XREAD4(sc, capa, XHCI_HCSPARAMS1); + + /* get number of device slots */ + sc->sc_noport = XHCI_HCS1_N_PORTS(temp); + + if (sc->sc_noport == 0) { + device_printf(sc->sc_bus.parent, "Invalid number " + "of ports: %u\n", sc->sc_noport); + return (ENXIO); + } + + sc->sc_noport = sc->sc_noport; + sc->sc_noslot = XHCI_HCS1_DEVSLOT_MAX(temp); + + DPRINTF("Max slots: %u\n", sc->sc_noslot); + + if (sc->sc_noslot > XHCI_MAX_DEVICES) + sc->sc_noslot = XHCI_MAX_DEVICES; + + temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); + + DPRINTF("HCS2=0x%08x\n", temp); + + /* get number of scratchpads */ + sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp); + + if (sc->sc_noscratch > XHCI_MAX_SCRATCHPADS) { + device_printf(sc->sc_bus.parent, "XHCI request " + "too many scratchpads\n"); + return (ENOMEM); + } + + DPRINTF("Max scratch: %u\n", sc->sc_noscratch); + + /* get event table size */ + sc->sc_erst_max = 1U << XHCI_HCS2_ERST_MAX(temp); + if (sc->sc_erst_max > XHCI_MAX_RSEG) + sc->sc_erst_max = XHCI_MAX_RSEG; + + temp = XREAD4(sc, capa, XHCI_HCSPARAMS3); + + /* get maximum exit latency */ + sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) + + XHCI_HCS3_U2_DEL(temp) + 250 /* us */; + + /* Check if we should use the default IMOD value. */ + if (sc->sc_imod_default == 0) + sc->sc_imod_default = XHCI_IMOD_DEFAULT; + /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self), &xhci_iterate_hw_softc)) { diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c index c4295aa..e85ac6e 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -86,10 +86,9 @@ static driver_t xhci_driver = { static devclass_t xhci_devclass; -DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, 0, 0); +DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, NULL, NULL); MODULE_DEPEND(xhci, usb, 1, 1, 1); - static const char * xhci_pci_match(device_t self) { @@ -104,6 +103,8 @@ xhci_pci_match(device_t self) case 0x10421b21: return ("ASMedia ASM1042 USB 3.0 controller"); + case 0x11421b21: + return ("ASMedia ASM1042A USB 3.0 controller"); case 0x0f358086: return ("Intel BayTrail USB 3.0 controller"); @@ -114,6 +115,8 @@ xhci_pci_match(device_t self) return ("Intel Lynx Point USB 3.0 controller"); case 0x8cb18086: return ("Intel Wildcat Point USB 3.0 controller"); + case 0x9cb18086: + return ("Broadwell Integrated PCH-LP chipset USB 3.0 controller"); case 0xa01b177d: return ("Cavium ThunderX USB 3.0 controller"); @@ -200,17 +203,31 @@ xhci_pci_attach(device_t self) sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); sc->sc_io_size = rman_get_size(sc->sc_io_res); - /* check for USB 3.0 controllers which don't support 64-bit DMA */ switch (pci_get_devid(self)) { case 0x01941033: /* NEC uPD720200 USB 3.0 controller */ + case 0x00141912: /* NEC uPD720201 USB 3.0 controller */ + /* Don't use 64-bit DMA on these controllers. */ usedma32 = 1; break; case 0x10001b73: /* FL1000G */ /* Fresco Logic host doesn't support MSI. */ usemsi = 0; break; + case 0x0f358086: /* BayTrail */ + case 0x9c318086: /* Panther Point */ + case 0x1e318086: /* Panther Point */ + case 0x8c318086: /* Lynx Point */ + case 0x8cb18086: /* Wildcat Point */ + case 0x9cb18086: /* Broadwell Mobile Integrated */ + /* + * On Intel chipsets, reroute ports from EHCI to XHCI + * controller and use a different IMOD value. + */ + sc->sc_port_route = &xhci_pci_port_route; + sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP; + break; } - + if (xhci_init(sc, self, usedma32)) { device_printf(self, "Could not initialize softc\n"); bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM, @@ -269,20 +286,6 @@ xhci_pci_attach(device_t self) 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; - } - xhci_pci_take_controller(self); err = xhci_halt_controller(sc); |