1fe75646aSEmmanuel Vadot /*- 2fe75646aSEmmanuel Vadot * SPDX-License-Identifier: BSD-2-Clause 3fe75646aSEmmanuel Vadot * 4fe75646aSEmmanuel Vadot * Copyright (c) 2019 Emmanuel Vadot <manu@FreeBSD.Org> 5fe75646aSEmmanuel Vadot * Copyright (c) 2021-2022 Bjoern A. Zeeb <bz@FreeBSD.ORG> 6fe75646aSEmmanuel Vadot * 7fe75646aSEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 8fe75646aSEmmanuel Vadot * modification, are permitted provided that the following conditions 9fe75646aSEmmanuel Vadot * are met: 10fe75646aSEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 11fe75646aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 12fe75646aSEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 13fe75646aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 14fe75646aSEmmanuel Vadot * documentation and/or other materials provided with the distribution. 15fe75646aSEmmanuel Vadot * 16fe75646aSEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17fe75646aSEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18fe75646aSEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19fe75646aSEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20fe75646aSEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21fe75646aSEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22fe75646aSEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23fe75646aSEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24fe75646aSEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25fe75646aSEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26fe75646aSEmmanuel Vadot * SUCH DAMAGE. 27fe75646aSEmmanuel Vadot */ 28fe75646aSEmmanuel Vadot 29fe75646aSEmmanuel Vadot #include <sys/cdefs.h> 30fe75646aSEmmanuel Vadot #include "opt_platform.h" 31fe75646aSEmmanuel Vadot #include "opt_acpi.h" 32fe75646aSEmmanuel Vadot 33fe75646aSEmmanuel Vadot #include <sys/param.h> 34fe75646aSEmmanuel Vadot #include <sys/systm.h> 35fe75646aSEmmanuel Vadot #include <sys/bus.h> 36fe75646aSEmmanuel Vadot #include <sys/rman.h> 37fe75646aSEmmanuel Vadot #include <sys/condvar.h> 38fe75646aSEmmanuel Vadot #include <sys/kernel.h> 39fe75646aSEmmanuel Vadot #include <sys/module.h> 40fe75646aSEmmanuel Vadot #include <sys/mutex.h> 41fe75646aSEmmanuel Vadot #ifdef FDT 42fe75646aSEmmanuel Vadot #include <sys/gpio.h> 43fe75646aSEmmanuel Vadot #endif 44fe75646aSEmmanuel Vadot 45fe75646aSEmmanuel Vadot #include <machine/bus.h> 46fe75646aSEmmanuel Vadot 47fe75646aSEmmanuel Vadot #include <dev/usb/usb.h> 48fe75646aSEmmanuel Vadot #include <dev/usb/usbdi.h> 49fe75646aSEmmanuel Vadot 50fe75646aSEmmanuel Vadot #include <dev/usb/usb_core.h> 51fe75646aSEmmanuel Vadot #include <dev/usb/usb_busdma.h> 52fe75646aSEmmanuel Vadot #include <dev/usb/usb_process.h> 53fe75646aSEmmanuel Vadot 54fe75646aSEmmanuel Vadot #include <dev/usb/usb_controller.h> 55fe75646aSEmmanuel Vadot #include <dev/usb/usb_bus.h> 56fe75646aSEmmanuel Vadot #include <dev/usb/controller/generic_xhci.h> 57fe75646aSEmmanuel Vadot #include <dev/usb/controller/xhci.h> 58fe75646aSEmmanuel Vadot #include <dev/usb/controller/dwc3/dwc3.h> 59fe75646aSEmmanuel Vadot 60fe75646aSEmmanuel Vadot #ifdef FDT 61fe75646aSEmmanuel Vadot #include <dev/fdt/simplebus.h> 62fe75646aSEmmanuel Vadot 63fe75646aSEmmanuel Vadot #include <dev/fdt/fdt_common.h> 64fe75646aSEmmanuel Vadot #include <dev/ofw/ofw_bus.h> 65fe75646aSEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h> 66fe75646aSEmmanuel Vadot #include <dev/ofw/ofw_subr.h> 67fe75646aSEmmanuel Vadot 68be82b3a0SEmmanuel Vadot #include <dev/clk/clk.h> 69950a6087SEmmanuel Vadot #include <dev/phy/phy_usb.h> 70fe75646aSEmmanuel Vadot #endif 71fe75646aSEmmanuel Vadot 72fe75646aSEmmanuel Vadot #ifdef DEV_ACPI 73fe75646aSEmmanuel Vadot #include <contrib/dev/acpica/include/acpi.h> 74fe75646aSEmmanuel Vadot #include <contrib/dev/acpica/include/accommon.h> 75fe75646aSEmmanuel Vadot #include <dev/acpica/acpivar.h> 76fe75646aSEmmanuel Vadot #endif 77fe75646aSEmmanuel Vadot 78fe75646aSEmmanuel Vadot struct snps_dwc3_softc { 79fe75646aSEmmanuel Vadot struct xhci_softc sc; 80fe75646aSEmmanuel Vadot device_t dev; 81fe75646aSEmmanuel Vadot struct resource * mem_res; 82fe75646aSEmmanuel Vadot bus_space_tag_t bst; 83fe75646aSEmmanuel Vadot bus_space_handle_t bsh; 84fe75646aSEmmanuel Vadot uint32_t snpsid; 85fe75646aSEmmanuel Vadot uint32_t snpsversion; 86fe75646aSEmmanuel Vadot uint32_t snpsrevision; 87fe75646aSEmmanuel Vadot uint32_t snpsversion_type; 88fe75646aSEmmanuel Vadot #ifdef FDT 89fe75646aSEmmanuel Vadot clk_t clk_ref; 90fe75646aSEmmanuel Vadot clk_t clk_suspend; 91fe75646aSEmmanuel Vadot clk_t clk_bus; 92fe75646aSEmmanuel Vadot #endif 93fe75646aSEmmanuel Vadot }; 94fe75646aSEmmanuel Vadot 95fe75646aSEmmanuel Vadot #define DWC3_WRITE(_sc, _off, _val) \ 96fe75646aSEmmanuel Vadot bus_space_write_4(_sc->bst, _sc->bsh, _off, _val) 97fe75646aSEmmanuel Vadot #define DWC3_READ(_sc, _off) \ 98fe75646aSEmmanuel Vadot bus_space_read_4(_sc->bst, _sc->bsh, _off) 99fe75646aSEmmanuel Vadot 100fe75646aSEmmanuel Vadot #define IS_DMA_32B 1 101fe75646aSEmmanuel Vadot 102fe75646aSEmmanuel Vadot static void 103fe75646aSEmmanuel Vadot xhci_interrupt_poll(void *_sc) 104fe75646aSEmmanuel Vadot { 105fe75646aSEmmanuel Vadot struct xhci_softc *sc = _sc; 106fe75646aSEmmanuel Vadot 107fe75646aSEmmanuel Vadot USB_BUS_UNLOCK(&sc->sc_bus); 108fe75646aSEmmanuel Vadot xhci_interrupt(sc); 109fe75646aSEmmanuel Vadot USB_BUS_LOCK(&sc->sc_bus); 110fe75646aSEmmanuel Vadot usb_callout_reset(&sc->sc_callout, 1, (void *)&xhci_interrupt_poll, sc); 111fe75646aSEmmanuel Vadot } 112fe75646aSEmmanuel Vadot 113fe75646aSEmmanuel Vadot static int 114fe75646aSEmmanuel Vadot snps_dwc3_attach_xhci(device_t dev) 115fe75646aSEmmanuel Vadot { 116fe75646aSEmmanuel Vadot struct snps_dwc3_softc *snps_sc = device_get_softc(dev); 117fe75646aSEmmanuel Vadot struct xhci_softc *sc = &snps_sc->sc; 118fe75646aSEmmanuel Vadot int err = 0, rid = 0; 119fe75646aSEmmanuel Vadot 120fe75646aSEmmanuel Vadot sc->sc_io_res = snps_sc->mem_res; 121fe75646aSEmmanuel Vadot sc->sc_io_tag = snps_sc->bst; 122fe75646aSEmmanuel Vadot sc->sc_io_hdl = snps_sc->bsh; 123fe75646aSEmmanuel Vadot sc->sc_io_size = rman_get_size(snps_sc->mem_res); 124fe75646aSEmmanuel Vadot 125fe75646aSEmmanuel Vadot sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 126fe75646aSEmmanuel Vadot RF_SHAREABLE | RF_ACTIVE); 127fe75646aSEmmanuel Vadot if (sc->sc_irq_res == NULL) { 128fe75646aSEmmanuel Vadot device_printf(dev, "Failed to allocate IRQ\n"); 129fe75646aSEmmanuel Vadot return (ENXIO); 130fe75646aSEmmanuel Vadot } 131fe75646aSEmmanuel Vadot 132*5b56413dSWarner Losh sc->sc_bus.bdev = device_add_child(dev, "usbus", DEVICE_UNIT_ANY); 133fe75646aSEmmanuel Vadot if (sc->sc_bus.bdev == NULL) { 134fe75646aSEmmanuel Vadot device_printf(dev, "Failed to add USB device\n"); 135fe75646aSEmmanuel Vadot return (ENXIO); 136fe75646aSEmmanuel Vadot } 137fe75646aSEmmanuel Vadot 138fe75646aSEmmanuel Vadot device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); 139fe75646aSEmmanuel Vadot 140fe75646aSEmmanuel Vadot sprintf(sc->sc_vendor, "Synopsys"); 141fe75646aSEmmanuel Vadot device_set_desc(sc->sc_bus.bdev, "Synopsys"); 142fe75646aSEmmanuel Vadot 143fe75646aSEmmanuel Vadot if (xhci_use_polling() == 0) { 144fe75646aSEmmanuel Vadot err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 145fe75646aSEmmanuel Vadot NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl); 146fe75646aSEmmanuel Vadot if (err != 0) { 147fe75646aSEmmanuel Vadot device_printf(dev, "Failed to setup IRQ, %d\n", err); 148fe75646aSEmmanuel Vadot sc->sc_intr_hdl = NULL; 149fe75646aSEmmanuel Vadot return (err); 150fe75646aSEmmanuel Vadot } 151fe75646aSEmmanuel Vadot } 152fe75646aSEmmanuel Vadot 153fe75646aSEmmanuel Vadot err = xhci_init(sc, dev, IS_DMA_32B); 154fe75646aSEmmanuel Vadot if (err != 0) { 155fe75646aSEmmanuel Vadot device_printf(dev, "Failed to init XHCI, with error %d\n", err); 156fe75646aSEmmanuel Vadot return (ENXIO); 157fe75646aSEmmanuel Vadot } 158fe75646aSEmmanuel Vadot 159fe75646aSEmmanuel Vadot usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0); 160fe75646aSEmmanuel Vadot 161fe75646aSEmmanuel Vadot if (xhci_use_polling() != 0) { 162fe75646aSEmmanuel Vadot device_printf(dev, "Interrupt polling at %dHz\n", hz); 163fe75646aSEmmanuel Vadot USB_BUS_LOCK(&sc->sc_bus); 164fe75646aSEmmanuel Vadot xhci_interrupt_poll(sc); 165fe75646aSEmmanuel Vadot USB_BUS_UNLOCK(&sc->sc_bus); 166fe75646aSEmmanuel Vadot } 167fe75646aSEmmanuel Vadot 168fe75646aSEmmanuel Vadot err = xhci_start_controller(sc); 169fe75646aSEmmanuel Vadot if (err != 0) { 170fe75646aSEmmanuel Vadot device_printf(dev, "Failed to start XHCI controller, with error %d\n", err); 171fe75646aSEmmanuel Vadot return (ENXIO); 172fe75646aSEmmanuel Vadot } 173fe75646aSEmmanuel Vadot 174fe75646aSEmmanuel Vadot device_printf(sc->sc_bus.bdev, "trying to attach\n"); 175fe75646aSEmmanuel Vadot err = device_probe_and_attach(sc->sc_bus.bdev); 176fe75646aSEmmanuel Vadot if (err != 0) { 177fe75646aSEmmanuel Vadot device_printf(dev, "Failed to initialize USB, with error %d\n", err); 178fe75646aSEmmanuel Vadot return (ENXIO); 179fe75646aSEmmanuel Vadot } 180fe75646aSEmmanuel Vadot 181fe75646aSEmmanuel Vadot return (0); 182fe75646aSEmmanuel Vadot } 183fe75646aSEmmanuel Vadot 184fe75646aSEmmanuel Vadot #ifdef DWC3_DEBUG 185fe75646aSEmmanuel Vadot static void 186fe75646aSEmmanuel Vadot snsp_dwc3_dump_regs(struct snps_dwc3_softc *sc, const char *msg) 187fe75646aSEmmanuel Vadot { 188fe75646aSEmmanuel Vadot struct xhci_softc *xsc; 189fe75646aSEmmanuel Vadot uint32_t reg; 190fe75646aSEmmanuel Vadot 191fe75646aSEmmanuel Vadot if (!bootverbose) 192fe75646aSEmmanuel Vadot return; 193fe75646aSEmmanuel Vadot 194fe75646aSEmmanuel Vadot device_printf(sc->dev, "%s: %s:\n", __func__, msg ? msg : ""); 195fe75646aSEmmanuel Vadot 196fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GCTL); 197fe75646aSEmmanuel Vadot device_printf(sc->dev, "GCTL: %#012x\n", reg); 198fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUCTL); 199fe75646aSEmmanuel Vadot device_printf(sc->dev, "GUCTL: %#012x\n", reg); 200fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUCTL1); 201fe75646aSEmmanuel Vadot device_printf(sc->dev, "GUCTL1: %#012x\n", reg); 202fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUSB2PHYCFG0); 203fe75646aSEmmanuel Vadot device_printf(sc->dev, "GUSB2PHYCFG0: %#012x\n", reg); 204fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUSB3PIPECTL0); 205fe75646aSEmmanuel Vadot device_printf(sc->dev, "GUSB3PIPECTL0: %#012x\n", reg); 206fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_DCFG); 207fe75646aSEmmanuel Vadot device_printf(sc->dev, "DCFG: %#012x\n", reg); 208fe75646aSEmmanuel Vadot 209fe75646aSEmmanuel Vadot xsc = &sc->sc; 210fe75646aSEmmanuel Vadot device_printf(sc->dev, "xhci quirks: %#012x\n", xsc->sc_quirks); 211fe75646aSEmmanuel Vadot } 212fe75646aSEmmanuel Vadot 213fe75646aSEmmanuel Vadot static void 214fe75646aSEmmanuel Vadot snps_dwc3_dump_ctrlparams(struct snps_dwc3_softc *sc) 215fe75646aSEmmanuel Vadot { 216fe75646aSEmmanuel Vadot const bus_size_t offs[] = { 217fe75646aSEmmanuel Vadot DWC3_GHWPARAMS0, DWC3_GHWPARAMS1, DWC3_GHWPARAMS2, DWC3_GHWPARAMS3, 218fe75646aSEmmanuel Vadot DWC3_GHWPARAMS4, DWC3_GHWPARAMS5, DWC3_GHWPARAMS6, DWC3_GHWPARAMS7, 219fe75646aSEmmanuel Vadot DWC3_GHWPARAMS8, 220fe75646aSEmmanuel Vadot }; 221fe75646aSEmmanuel Vadot uint32_t reg; 222fe75646aSEmmanuel Vadot int i; 223fe75646aSEmmanuel Vadot 224fe75646aSEmmanuel Vadot for (i = 0; i < nitems(offs); i++) { 225fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, offs[i]); 226fe75646aSEmmanuel Vadot if (bootverbose) 227fe75646aSEmmanuel Vadot device_printf(sc->dev, "hwparams[%d]: %#012x\n", i, reg); 228fe75646aSEmmanuel Vadot } 229fe75646aSEmmanuel Vadot } 230fe75646aSEmmanuel Vadot #endif 231fe75646aSEmmanuel Vadot 232fe75646aSEmmanuel Vadot static void 233fe75646aSEmmanuel Vadot snps_dwc3_reset(struct snps_dwc3_softc *sc) 234fe75646aSEmmanuel Vadot { 235fe75646aSEmmanuel Vadot uint32_t gctl, ghwp0, phy2, phy3; 236fe75646aSEmmanuel Vadot 237fe75646aSEmmanuel Vadot ghwp0 = DWC3_READ(sc, DWC3_GHWPARAMS0); 238fe75646aSEmmanuel Vadot 239fe75646aSEmmanuel Vadot gctl = DWC3_READ(sc, DWC3_GCTL); 240fe75646aSEmmanuel Vadot gctl |= DWC3_GCTL_CORESOFTRESET; 241fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GCTL, gctl); 242fe75646aSEmmanuel Vadot 243fe75646aSEmmanuel Vadot phy2 = DWC3_READ(sc, DWC3_GUSB2PHYCFG0); 244fe75646aSEmmanuel Vadot phy2 |= DWC3_GUSB2PHYCFG0_PHYSOFTRST; 245fe75646aSEmmanuel Vadot if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) == 246fe75646aSEmmanuel Vadot DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE) 247fe75646aSEmmanuel Vadot phy2 &= ~DWC3_GUSB2PHYCFG0_SUSPENDUSB20; 248fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB2PHYCFG0, phy2); 249fe75646aSEmmanuel Vadot 250fe75646aSEmmanuel Vadot phy3 = DWC3_READ(sc, DWC3_GUSB3PIPECTL0); 251fe75646aSEmmanuel Vadot phy3 |= DWC3_GUSB3PIPECTL0_PHYSOFTRST; 252fe75646aSEmmanuel Vadot if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) == 253fe75646aSEmmanuel Vadot DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE) 254fe75646aSEmmanuel Vadot phy3 &= ~DWC3_GUSB3PIPECTL0_SUSPENDUSB3; 255fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB3PIPECTL0, phy3); 256fe75646aSEmmanuel Vadot 257fe75646aSEmmanuel Vadot DELAY(1000); 258fe75646aSEmmanuel Vadot 259fe75646aSEmmanuel Vadot phy2 &= ~DWC3_GUSB2PHYCFG0_PHYSOFTRST; 260fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB2PHYCFG0, phy2); 261fe75646aSEmmanuel Vadot 262fe75646aSEmmanuel Vadot phy3 &= ~DWC3_GUSB3PIPECTL0_PHYSOFTRST; 263fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB3PIPECTL0, phy3); 264fe75646aSEmmanuel Vadot 265fe75646aSEmmanuel Vadot gctl &= ~DWC3_GCTL_CORESOFTRESET; 266fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GCTL, gctl); 267fe75646aSEmmanuel Vadot 268fe75646aSEmmanuel Vadot } 269fe75646aSEmmanuel Vadot 270fe75646aSEmmanuel Vadot static void 271fe75646aSEmmanuel Vadot snps_dwc3_configure_host(struct snps_dwc3_softc *sc) 272fe75646aSEmmanuel Vadot { 273fe75646aSEmmanuel Vadot uint32_t reg; 274fe75646aSEmmanuel Vadot 275fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GCTL); 276fe75646aSEmmanuel Vadot reg &= ~DWC3_GCTL_PRTCAPDIR_MASK; 277fe75646aSEmmanuel Vadot reg |= DWC3_GCTL_PRTCAPDIR_HOST; 278fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GCTL, reg); 279fe75646aSEmmanuel Vadot 280fe75646aSEmmanuel Vadot /* 281fe75646aSEmmanuel Vadot * Enable the Host IN Auto Retry feature, making the 282fe75646aSEmmanuel Vadot * host respond with a non-terminating retry ACK. 283fe75646aSEmmanuel Vadot * XXX If we ever support more than host mode this needs a dr_mode check. 284fe75646aSEmmanuel Vadot */ 285fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUCTL); 286fe75646aSEmmanuel Vadot reg |= DWC3_GUCTL_HOST_AUTO_RETRY; 287fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUCTL, reg); 288fe75646aSEmmanuel Vadot } 289fe75646aSEmmanuel Vadot 290fe75646aSEmmanuel Vadot #ifdef FDT 291fe75646aSEmmanuel Vadot static void 292fe75646aSEmmanuel Vadot snps_dwc3_configure_phy(struct snps_dwc3_softc *sc, phandle_t node) 293fe75646aSEmmanuel Vadot { 294fe75646aSEmmanuel Vadot char *phy_type; 295fe75646aSEmmanuel Vadot uint32_t reg; 296fe75646aSEmmanuel Vadot int nphy_types; 297fe75646aSEmmanuel Vadot 298fe75646aSEmmanuel Vadot phy_type = NULL; 299fe75646aSEmmanuel Vadot nphy_types = OF_getprop_alloc(node, "phy_type", (void **)&phy_type); 300fe75646aSEmmanuel Vadot if (nphy_types <= 0) 301fe75646aSEmmanuel Vadot return; 302fe75646aSEmmanuel Vadot 303fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUSB2PHYCFG0); 304fe75646aSEmmanuel Vadot if (strncmp(phy_type, "utmi_wide", 9) == 0) { 305fe75646aSEmmanuel Vadot reg &= ~(DWC3_GUSB2PHYCFG0_PHYIF | DWC3_GUSB2PHYCFG0_USBTRDTIM(0xf)); 306fe75646aSEmmanuel Vadot reg |= DWC3_GUSB2PHYCFG0_PHYIF | 307fe75646aSEmmanuel Vadot DWC3_GUSB2PHYCFG0_USBTRDTIM(DWC3_GUSB2PHYCFG0_USBTRDTIM_16BITS); 308fe75646aSEmmanuel Vadot } else { 309fe75646aSEmmanuel Vadot reg &= ~(DWC3_GUSB2PHYCFG0_PHYIF | DWC3_GUSB2PHYCFG0_USBTRDTIM(0xf)); 310fe75646aSEmmanuel Vadot reg |= DWC3_GUSB2PHYCFG0_PHYIF | 311fe75646aSEmmanuel Vadot DWC3_GUSB2PHYCFG0_USBTRDTIM(DWC3_GUSB2PHYCFG0_USBTRDTIM_8BITS); 312fe75646aSEmmanuel Vadot } 313fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB2PHYCFG0, reg); 314fe75646aSEmmanuel Vadot OF_prop_free(phy_type); 315fe75646aSEmmanuel Vadot } 316fe75646aSEmmanuel Vadot #endif 317fe75646aSEmmanuel Vadot 318fe75646aSEmmanuel Vadot static void 319fe75646aSEmmanuel Vadot snps_dwc3_do_quirks(struct snps_dwc3_softc *sc) 320fe75646aSEmmanuel Vadot { 321fe75646aSEmmanuel Vadot struct xhci_softc *xsc; 322fe75646aSEmmanuel Vadot uint32_t ghwp0, reg; 323fe75646aSEmmanuel Vadot 324fe75646aSEmmanuel Vadot ghwp0 = DWC3_READ(sc, DWC3_GHWPARAMS0); 325fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUSB2PHYCFG0); 326fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis-u2-freeclk-exists-quirk")) 327fe75646aSEmmanuel Vadot reg &= ~DWC3_GUSB2PHYCFG0_U2_FREECLK_EXISTS; 328fe75646aSEmmanuel Vadot else 329fe75646aSEmmanuel Vadot reg |= DWC3_GUSB2PHYCFG0_U2_FREECLK_EXISTS; 330fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis_u2_susphy_quirk")) 331fe75646aSEmmanuel Vadot reg &= ~DWC3_GUSB2PHYCFG0_SUSPENDUSB20; 332fe75646aSEmmanuel Vadot else if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) == 333fe75646aSEmmanuel Vadot DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE) 334fe75646aSEmmanuel Vadot reg |= DWC3_GUSB2PHYCFG0_SUSPENDUSB20; 335fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis_enblslpm_quirk")) 336fe75646aSEmmanuel Vadot reg &= ~DWC3_GUSB2PHYCFG0_ENBLSLPM; 337fe75646aSEmmanuel Vadot else 338fe75646aSEmmanuel Vadot reg |= DWC3_GUSB2PHYCFG0_ENBLSLPM; 339fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB2PHYCFG0, reg); 340fe75646aSEmmanuel Vadot 341fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUCTL1); 342fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis-tx-ipgap-linecheck-quirk")) 343fe75646aSEmmanuel Vadot reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; 344fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUCTL1, reg); 345fe75646aSEmmanuel Vadot 346fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUSB3PIPECTL0); 347fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis-del-phy-power-chg-quirk")) 348fe75646aSEmmanuel Vadot reg &= ~DWC3_GUSB3PIPECTL0_DELAYP1TRANS; 349fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis_rxdet_inp3_quirk")) 350fe75646aSEmmanuel Vadot reg |= DWC3_GUSB3PIPECTL0_DISRXDETINP3; 351fe75646aSEmmanuel Vadot if (device_has_property(sc->dev, "snps,dis_u3_susphy_quirk")) 352fe75646aSEmmanuel Vadot reg &= ~DWC3_GUSB3PIPECTL0_SUSPENDUSB3; 353fe75646aSEmmanuel Vadot else if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) == 354fe75646aSEmmanuel Vadot DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE) 355fe75646aSEmmanuel Vadot reg |= DWC3_GUSB3PIPECTL0_SUSPENDUSB3; 356fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUSB3PIPECTL0, reg); 357fe75646aSEmmanuel Vadot 358fe75646aSEmmanuel Vadot /* Port Disable does not work on <= 3.00a. Disable PORT_PED. */ 359fe75646aSEmmanuel Vadot if ((sc->snpsid & 0xffff) <= 0x300a) { 360fe75646aSEmmanuel Vadot xsc = &sc->sc; 361fe75646aSEmmanuel Vadot xsc->sc_quirks |= XHCI_QUIRK_DISABLE_PORT_PED; 362fe75646aSEmmanuel Vadot } 363fe75646aSEmmanuel Vadot } 364fe75646aSEmmanuel Vadot 365fe75646aSEmmanuel Vadot static int 366fe75646aSEmmanuel Vadot snps_dwc3_probe_common(device_t dev) 367fe75646aSEmmanuel Vadot { 368fe75646aSEmmanuel Vadot char dr_mode[16] = { 0 }; 369fe75646aSEmmanuel Vadot ssize_t s; 370fe75646aSEmmanuel Vadot 371fe75646aSEmmanuel Vadot s = device_get_property(dev, "dr_mode", dr_mode, sizeof(dr_mode), 372fe75646aSEmmanuel Vadot DEVICE_PROP_BUFFER); 373fe75646aSEmmanuel Vadot if (s == -1) { 374fe75646aSEmmanuel Vadot device_printf(dev, "Cannot determine dr_mode\n"); 375fe75646aSEmmanuel Vadot return (ENXIO); 376fe75646aSEmmanuel Vadot } 377fe75646aSEmmanuel Vadot if (strcmp(dr_mode, "host") != 0) { 378fe75646aSEmmanuel Vadot device_printf(dev, 379fe75646aSEmmanuel Vadot "Found dr_mode '%s' but only 'host' supported. s=%zd\n", 380fe75646aSEmmanuel Vadot dr_mode, s); 381fe75646aSEmmanuel Vadot return (ENXIO); 382fe75646aSEmmanuel Vadot } 383fe75646aSEmmanuel Vadot 384fe75646aSEmmanuel Vadot device_set_desc(dev, "Synopsys Designware DWC3"); 385fe75646aSEmmanuel Vadot return (BUS_PROBE_DEFAULT); 386fe75646aSEmmanuel Vadot } 387fe75646aSEmmanuel Vadot 388fe75646aSEmmanuel Vadot static int 389fe75646aSEmmanuel Vadot snps_dwc3_common_attach(device_t dev, bool is_fdt) 390fe75646aSEmmanuel Vadot { 391fe75646aSEmmanuel Vadot struct snps_dwc3_softc *sc; 392fe75646aSEmmanuel Vadot #ifdef FDT 393fe75646aSEmmanuel Vadot phandle_t node; 394fe75646aSEmmanuel Vadot phy_t usb2_phy, usb3_phy; 395fe75646aSEmmanuel Vadot uint32_t reg; 396fe75646aSEmmanuel Vadot #endif 397fe75646aSEmmanuel Vadot int error, rid; 398fe75646aSEmmanuel Vadot 399fe75646aSEmmanuel Vadot sc = device_get_softc(dev); 400fe75646aSEmmanuel Vadot sc->dev = dev; 401fe75646aSEmmanuel Vadot 402fe75646aSEmmanuel Vadot rid = 0; 403fe75646aSEmmanuel Vadot sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 404fe75646aSEmmanuel Vadot RF_ACTIVE); 405fe75646aSEmmanuel Vadot if (sc->mem_res == NULL) { 406fe75646aSEmmanuel Vadot device_printf(dev, "Failed to map memory\n"); 407fe75646aSEmmanuel Vadot return (ENXIO); 408fe75646aSEmmanuel Vadot } 409fe75646aSEmmanuel Vadot sc->bst = rman_get_bustag(sc->mem_res); 410fe75646aSEmmanuel Vadot sc->bsh = rman_get_bushandle(sc->mem_res); 411fe75646aSEmmanuel Vadot 412fe75646aSEmmanuel Vadot sc->snpsid = DWC3_READ(sc, DWC3_GSNPSID); 413fe75646aSEmmanuel Vadot sc->snpsversion = DWC3_VERSION(sc->snpsid); 414fe75646aSEmmanuel Vadot sc->snpsrevision = DWC3_REVISION(sc->snpsid); 415fe75646aSEmmanuel Vadot if (sc->snpsversion == DWC3_1_IP_ID || 416fe75646aSEmmanuel Vadot sc->snpsversion == DWC3_2_IP_ID) { 417fe75646aSEmmanuel Vadot sc->snpsrevision = DWC3_READ(sc, DWC3_1_VER_NUMBER); 418fe75646aSEmmanuel Vadot sc->snpsversion_type = DWC3_READ(sc, DWC3_1_VER_TYPE); 419fe75646aSEmmanuel Vadot } 420fe75646aSEmmanuel Vadot if (bootverbose) { 421fe75646aSEmmanuel Vadot switch (sc->snpsversion) { 422fe75646aSEmmanuel Vadot case DWC3_IP_ID: 423fe75646aSEmmanuel Vadot device_printf(sc->dev, "SNPS Version: DWC3 (%x %x)\n", 424fe75646aSEmmanuel Vadot sc->snpsversion, sc->snpsrevision); 425fe75646aSEmmanuel Vadot break; 426fe75646aSEmmanuel Vadot case DWC3_1_IP_ID: 427fe75646aSEmmanuel Vadot device_printf(sc->dev, "SNPS Version: DWC3.1 (%x %x %x)\n", 428fe75646aSEmmanuel Vadot sc->snpsversion, sc->snpsrevision, 429fe75646aSEmmanuel Vadot sc->snpsversion_type); 430fe75646aSEmmanuel Vadot break; 431fe75646aSEmmanuel Vadot case DWC3_2_IP_ID: 432fe75646aSEmmanuel Vadot device_printf(sc->dev, "SNPS Version: DWC3.2 (%x %x %x)\n", 433fe75646aSEmmanuel Vadot sc->snpsversion, sc->snpsrevision, 434fe75646aSEmmanuel Vadot sc->snpsversion_type); 435fe75646aSEmmanuel Vadot break; 436fe75646aSEmmanuel Vadot } 437fe75646aSEmmanuel Vadot } 438fe75646aSEmmanuel Vadot #ifdef DWC3_DEBUG 439fe75646aSEmmanuel Vadot snps_dwc3_dump_ctrlparams(sc); 440fe75646aSEmmanuel Vadot #endif 441fe75646aSEmmanuel Vadot 442fe75646aSEmmanuel Vadot #ifdef FDT 443fe75646aSEmmanuel Vadot if (!is_fdt) 444fe75646aSEmmanuel Vadot goto skip_phys; 445fe75646aSEmmanuel Vadot 446fe75646aSEmmanuel Vadot node = ofw_bus_get_node(dev); 447fe75646aSEmmanuel Vadot 448fe75646aSEmmanuel Vadot /* Get the clocks if any */ 449fe75646aSEmmanuel Vadot if (ofw_bus_is_compatible(dev, "rockchip,rk3328-dwc3") == 1 || 450fe75646aSEmmanuel Vadot ofw_bus_is_compatible(dev, "rockchip,rk3568-dwc3") == 1) { 451fe75646aSEmmanuel Vadot if (clk_get_by_ofw_name(dev, node, "ref_clk", &sc->clk_ref) != 0) 452fe75646aSEmmanuel Vadot device_printf(dev, "Cannot get ref_clk\n"); 453fe75646aSEmmanuel Vadot if (clk_get_by_ofw_name(dev, node, "suspend_clk", &sc->clk_suspend) != 0) 454fe75646aSEmmanuel Vadot device_printf(dev, "Cannot get suspend_clk\n"); 455fe75646aSEmmanuel Vadot if (clk_get_by_ofw_name(dev, node, "bus_clk", &sc->clk_bus) != 0) 456fe75646aSEmmanuel Vadot device_printf(dev, "Cannot get bus_clk\n"); 457fe75646aSEmmanuel Vadot } 458fe75646aSEmmanuel Vadot 459fe75646aSEmmanuel Vadot if (sc->clk_ref != NULL) { 460fe75646aSEmmanuel Vadot if (clk_enable(sc->clk_ref) != 0) 461fe75646aSEmmanuel Vadot device_printf(dev, "Cannot enable ref_clk\n"); 462fe75646aSEmmanuel Vadot } 463fe75646aSEmmanuel Vadot if (sc->clk_suspend != NULL) { 464fe75646aSEmmanuel Vadot if (clk_enable(sc->clk_suspend) != 0) 465fe75646aSEmmanuel Vadot device_printf(dev, "Cannot enable suspend_clk\n"); 466fe75646aSEmmanuel Vadot } 467fe75646aSEmmanuel Vadot if (sc->clk_bus != NULL) { 468fe75646aSEmmanuel Vadot if (clk_enable(sc->clk_bus) != 0) 469fe75646aSEmmanuel Vadot device_printf(dev, "Cannot enable bus_clk\n"); 470fe75646aSEmmanuel Vadot } 471fe75646aSEmmanuel Vadot 472fe75646aSEmmanuel Vadot /* Get the phys */ 473fe75646aSEmmanuel Vadot usb2_phy = usb3_phy = NULL; 474fe75646aSEmmanuel Vadot error = phy_get_by_ofw_name(dev, node, "usb2-phy", &usb2_phy); 475fe75646aSEmmanuel Vadot if (error == 0 && usb2_phy != NULL) 476fe75646aSEmmanuel Vadot phy_enable(usb2_phy); 477fe75646aSEmmanuel Vadot error = phy_get_by_ofw_name(dev, node, "usb3-phy", &usb3_phy); 478fe75646aSEmmanuel Vadot if (error == 0 && usb3_phy != NULL) 479fe75646aSEmmanuel Vadot phy_enable(usb3_phy); 480fe75646aSEmmanuel Vadot if (sc->snpsversion == DWC3_IP_ID) { 481fe75646aSEmmanuel Vadot if (sc->snpsrevision >= 0x290A) { 482fe75646aSEmmanuel Vadot uint32_t hwparams3; 483fe75646aSEmmanuel Vadot 484fe75646aSEmmanuel Vadot hwparams3 = DWC3_READ(sc, DWC3_GHWPARAMS3); 485fe75646aSEmmanuel Vadot if (DWC3_HWPARAMS3_SSPHY(hwparams3) == DWC3_HWPARAMS3_SSPHY_DISABLE) { 486fe75646aSEmmanuel Vadot reg = DWC3_READ(sc, DWC3_GUCTL1); 487fe75646aSEmmanuel Vadot if (bootverbose) 488fe75646aSEmmanuel Vadot device_printf(dev, "Forcing USB2 clock only\n"); 489fe75646aSEmmanuel Vadot reg |= DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK; 490fe75646aSEmmanuel Vadot DWC3_WRITE(sc, DWC3_GUCTL1, reg); 491fe75646aSEmmanuel Vadot } 492fe75646aSEmmanuel Vadot } 493fe75646aSEmmanuel Vadot } 494fe75646aSEmmanuel Vadot snps_dwc3_configure_phy(sc, node); 495fe75646aSEmmanuel Vadot skip_phys: 496fe75646aSEmmanuel Vadot #endif 497fe75646aSEmmanuel Vadot 498fe75646aSEmmanuel Vadot snps_dwc3_reset(sc); 499fe75646aSEmmanuel Vadot snps_dwc3_configure_host(sc); 500fe75646aSEmmanuel Vadot snps_dwc3_do_quirks(sc); 501fe75646aSEmmanuel Vadot 502fe75646aSEmmanuel Vadot #ifdef DWC3_DEBUG 503fe75646aSEmmanuel Vadot snsp_dwc3_dump_regs(sc, "Pre XHCI init"); 504fe75646aSEmmanuel Vadot #endif 505fe75646aSEmmanuel Vadot error = snps_dwc3_attach_xhci(dev); 506fe75646aSEmmanuel Vadot #ifdef DWC3_DEBUG 507fe75646aSEmmanuel Vadot snsp_dwc3_dump_regs(sc, "Post XHCI init"); 508fe75646aSEmmanuel Vadot #endif 509fe75646aSEmmanuel Vadot 510fe75646aSEmmanuel Vadot #ifdef FDT 511fe75646aSEmmanuel Vadot if (error) { 512fe75646aSEmmanuel Vadot if (sc->clk_ref != NULL) 513fe75646aSEmmanuel Vadot clk_disable(sc->clk_ref); 514fe75646aSEmmanuel Vadot if (sc->clk_suspend != NULL) 515fe75646aSEmmanuel Vadot clk_disable(sc->clk_suspend); 516fe75646aSEmmanuel Vadot if (sc->clk_bus != NULL) 517fe75646aSEmmanuel Vadot clk_disable(sc->clk_bus); 518fe75646aSEmmanuel Vadot } 519fe75646aSEmmanuel Vadot #endif 520fe75646aSEmmanuel Vadot return (error); 521fe75646aSEmmanuel Vadot } 522fe75646aSEmmanuel Vadot 523fe75646aSEmmanuel Vadot #ifdef FDT 524fe75646aSEmmanuel Vadot static struct ofw_compat_data compat_data[] = { 525fe75646aSEmmanuel Vadot { "snps,dwc3", 1 }, 526fe75646aSEmmanuel Vadot { NULL, 0 } 527fe75646aSEmmanuel Vadot }; 528fe75646aSEmmanuel Vadot 529fe75646aSEmmanuel Vadot static int 530fe75646aSEmmanuel Vadot snps_dwc3_fdt_probe(device_t dev) 531fe75646aSEmmanuel Vadot { 532fe75646aSEmmanuel Vadot 533fe75646aSEmmanuel Vadot if (!ofw_bus_status_okay(dev)) 534fe75646aSEmmanuel Vadot return (ENXIO); 535fe75646aSEmmanuel Vadot 536fe75646aSEmmanuel Vadot if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 537fe75646aSEmmanuel Vadot return (ENXIO); 538fe75646aSEmmanuel Vadot 539fe75646aSEmmanuel Vadot return (snps_dwc3_probe_common(dev)); 540fe75646aSEmmanuel Vadot } 541fe75646aSEmmanuel Vadot 542fe75646aSEmmanuel Vadot static int 543fe75646aSEmmanuel Vadot snps_dwc3_fdt_attach(device_t dev) 544fe75646aSEmmanuel Vadot { 545fe75646aSEmmanuel Vadot 546fe75646aSEmmanuel Vadot return (snps_dwc3_common_attach(dev, true)); 547fe75646aSEmmanuel Vadot } 548fe75646aSEmmanuel Vadot 549fe75646aSEmmanuel Vadot static device_method_t snps_dwc3_fdt_methods[] = { 550fe75646aSEmmanuel Vadot /* Device interface */ 551fe75646aSEmmanuel Vadot DEVMETHOD(device_probe, snps_dwc3_fdt_probe), 552fe75646aSEmmanuel Vadot DEVMETHOD(device_attach, snps_dwc3_fdt_attach), 553fe75646aSEmmanuel Vadot 554fe75646aSEmmanuel Vadot DEVMETHOD_END 555fe75646aSEmmanuel Vadot }; 556fe75646aSEmmanuel Vadot 557fe75646aSEmmanuel Vadot DEFINE_CLASS_1(snps_dwc3_fdt, snps_dwc3_fdt_driver, snps_dwc3_fdt_methods, 558fe75646aSEmmanuel Vadot sizeof(struct snps_dwc3_softc), generic_xhci_driver); 559fe75646aSEmmanuel Vadot 560fe75646aSEmmanuel Vadot DRIVER_MODULE(snps_dwc3_fdt, simplebus, snps_dwc3_fdt_driver, 0, 0); 561fe75646aSEmmanuel Vadot MODULE_DEPEND(snps_dwc3_fdt, xhci, 1, 1, 1); 562fe75646aSEmmanuel Vadot #endif 563fe75646aSEmmanuel Vadot 564fe75646aSEmmanuel Vadot #ifdef DEV_ACPI 565fe75646aSEmmanuel Vadot static char *dwc3_acpi_ids[] = { 566fe75646aSEmmanuel Vadot "808622B7", /* This was an Intel PCI Vendor/Device ID used. */ 567fe75646aSEmmanuel Vadot "PNP0D10", /* The generic XHCI PNP ID needing extra probe checks. */ 568fe75646aSEmmanuel Vadot NULL 569fe75646aSEmmanuel Vadot }; 570fe75646aSEmmanuel Vadot 571fe75646aSEmmanuel Vadot static int 572fe75646aSEmmanuel Vadot snps_dwc3_acpi_probe(device_t dev) 573fe75646aSEmmanuel Vadot { 574fe75646aSEmmanuel Vadot char *match; 575fe75646aSEmmanuel Vadot int error; 576fe75646aSEmmanuel Vadot 577fe75646aSEmmanuel Vadot if (acpi_disabled("snps_dwc3")) 578fe75646aSEmmanuel Vadot return (ENXIO); 579fe75646aSEmmanuel Vadot 580fe75646aSEmmanuel Vadot error = ACPI_ID_PROBE(device_get_parent(dev), dev, dwc3_acpi_ids, &match); 581fe75646aSEmmanuel Vadot if (error > 0) 582fe75646aSEmmanuel Vadot return (ENXIO); 583fe75646aSEmmanuel Vadot 584fe75646aSEmmanuel Vadot /* 585fe75646aSEmmanuel Vadot * If we found the Generic XHCI PNP ID we can only attach if we have 586fe75646aSEmmanuel Vadot * some other means to identify the device as dwc3. 587fe75646aSEmmanuel Vadot */ 588fe75646aSEmmanuel Vadot if (strcmp(match, "PNP0D10") == 0) { 589fe75646aSEmmanuel Vadot /* This is needed in SolidRun's HoneyComb. */ 590fe75646aSEmmanuel Vadot if (device_has_property(dev, "snps,dis_rxdet_inp3_quirk")) 591fe75646aSEmmanuel Vadot goto is_dwc3; 592fe75646aSEmmanuel Vadot 593fe75646aSEmmanuel Vadot return (ENXIO); 594fe75646aSEmmanuel Vadot } 595fe75646aSEmmanuel Vadot 596fe75646aSEmmanuel Vadot is_dwc3: 597fe75646aSEmmanuel Vadot return (snps_dwc3_probe_common(dev)); 598fe75646aSEmmanuel Vadot } 599fe75646aSEmmanuel Vadot 600fe75646aSEmmanuel Vadot static int 601fe75646aSEmmanuel Vadot snps_dwc3_acpi_attach(device_t dev) 602fe75646aSEmmanuel Vadot { 603fe75646aSEmmanuel Vadot 604fe75646aSEmmanuel Vadot return (snps_dwc3_common_attach(dev, false)); 605fe75646aSEmmanuel Vadot } 606fe75646aSEmmanuel Vadot 607fe75646aSEmmanuel Vadot static device_method_t snps_dwc3_acpi_methods[] = { 608fe75646aSEmmanuel Vadot /* Device interface */ 609fe75646aSEmmanuel Vadot DEVMETHOD(device_probe, snps_dwc3_acpi_probe), 610fe75646aSEmmanuel Vadot DEVMETHOD(device_attach, snps_dwc3_acpi_attach), 611fe75646aSEmmanuel Vadot 612fe75646aSEmmanuel Vadot DEVMETHOD_END 613fe75646aSEmmanuel Vadot }; 614fe75646aSEmmanuel Vadot 615fe75646aSEmmanuel Vadot DEFINE_CLASS_1(snps_dwc3_acpi, snps_dwc3_acpi_driver, snps_dwc3_acpi_methods, 616fe75646aSEmmanuel Vadot sizeof(struct snps_dwc3_softc), generic_xhci_driver); 617fe75646aSEmmanuel Vadot 618fe75646aSEmmanuel Vadot DRIVER_MODULE(snps_dwc3_acpi, acpi, snps_dwc3_acpi_driver, 0, 0); 619fe75646aSEmmanuel Vadot MODULE_DEPEND(snps_dwc3_acpi, usb, 1, 1, 1); 620fe75646aSEmmanuel Vadot #endif 621