Lines Matching +full:usb +full:- +full:ehci
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2010-2012 Semihalf
36 * EHCI driver for Freescale i.MX SoCs which incorporate the USBOH3 controller.
50 #include <dev/usb/usb.h>
51 #include <dev/usb/usbdi.h>
52 #include <dev/usb/usb_busdma.h>
53 #include <dev/usb/usb_process.h>
54 #include <dev/usb/usb_controller.h>
55 #include <dev/usb/usb_bus.h>
56 #include <dev/usb/controller/ehci.h>
57 #include <dev/usb/controller/ehcireg.h>
71 * refers to them as "core" and "non-core" registers. A set of core register
72 * exists for each OTG or EHCI device. There is a single set of non-core
74 * related to the USB specs, such as whether interrupts from each of the core
78 * non-core registers by using a pair of resource address/size values (two
82 * whose reg property describes the non-core registers. The way we handle FDT
83 * data, this means that the resources (memory-mapped register range) for the
84 * non-core registers belongs to a device other than the echi devices.
86 * Because the main ehci device cannot access registers in a range that's
89 * control register for each of the 4 usb controller instances. That little
93 * separate device for each of the OTG or EHCI cores within the USBOH3. Each of
97 * two parts: a set of imx-specific registers at an offset of 0 from the
98 * beginning of the register range, and the standard USB (EHCI or OTG) registers
104 * USB registers, which we provide to the standard USB code in the ehci_softc.
106 * The following compat strings have been seen for the OTG and EHCI cores. The
111 * - "fsl,imx23-usb", "fsl,imx27-usb";
112 * - "fsl,imx25-usb", "fsl,imx27-usb";
113 * - "fsl,imx28-usb", "fsl,imx27-usb";
114 * - "fsl,imx51-usb", "fsl,imx27-usb";
115 * - "fsl,imx53-usb", "fsl,imx27-usb";
116 * - "fsl,imx6q-usb", "fsl,imx27-usb";
120 * - fsl,usbmisc = <&usbmisc 0>;
121 * - fsl,usbphy = <&usbphy0>;
123 * Some imx SoCs have FDT data related to USB PHY, some don't. We have separate
125 * imx-FDT-usb-related info in one place. Here are the usbphy compat strings
127 * - "nop-usbphy"
128 * - "usb-nop-xceiv";
129 * - "fsl,imx23-usbphy"
130 * - "fsl,imx28-usbphy", "fsl,imx23-usbphy";
131 * - "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
135 /*-----------------------------------------------------------------------------
137 *---------------------------------------------------------------------------*/
148 {"fsl,imx6q-usbmisc", true},
149 {"fsl,imx51-usbmisc", true},
150 {"fsl,imx25-usbmisc", true},
161 reg = bus_read_4(sc->mmio, index * sizeof(uint32_t));
162 bus_write_4(sc->mmio, index * sizeof(uint32_t), reg | bits);
173 reg = bus_read_4(sc->mmio, index * sizeof(uint32_t));
174 bus_write_4(sc->mmio, index * sizeof(uint32_t), reg & ~bits);
185 if (ofw_bus_search_compatible(dev, usbmisc_compat_data)->ocd_data) {
186 device_set_desc(dev, "i.MX USB Misc Control");
199 if (sc->mmio != NULL)
200 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mmio);
215 sc->mmio = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
217 if (sc->mmio == NULL) {
243 * This driver needs to start before the ehci driver, but later than the usual
244 * "special" drivers like clocks and cpu. Ehci starts at DEFAULT so
245 * DEFAULT-1000 seems good.
248 0, 0, BUS_PASS_DEFAULT - 1000);
250 /*-----------------------------------------------------------------------------
252 *---------------------------------------------------------------------------*/
255 * Each EHCI device in the SoC has some SoC-specific per-device registers at an
256 * offset of 0, then the standard EHCI registers begin at an offset of 0x100.
264 struct resource *ehci_mem_res; /* EHCI core regs. */
265 struct resource *ehci_irq_res; /* EHCI core IRQ. */
269 {"fsl,imx6q-usb", 1},
270 {"fsl,imx53-usb", 1},
271 {"fsl,imx51-usb", 1},
272 {"fsl,imx28-usb", 1},
273 {"fsl,imx27-usb", 1},
274 {"fsl,imx25-usb", 1},
275 {"fsl,imx23-usb", 1},
298 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
299 device_set_desc(dev, "Freescale i.MX integrated USB controller");
314 esc = &sc->ehci_softc;
320 if (esc->sc_flags & EHCI_SCFLG_DONEINIT)
322 if (esc->sc_intr_hdl != NULL)
323 bus_teardown_intr(dev, esc->sc_irq_res,
324 esc->sc_intr_hdl);
325 if (sc->ehci_irq_res != NULL)
327 sc->ehci_irq_res);
328 if (sc->ehci_mem_res != NULL)
330 sc->ehci_mem_res);
332 usb_bus_mem_free_all(&esc->sc_bus, &ehci_iterate_hw_softc);
347 node = ofw_bus_get_node(sc->dev);
351 device_printf(sc->dev, "failed to retrieve fsl,usbmisc "
358 device_printf(sc->dev, "usbmisc device not found, "
375 sc->dev = dev;
376 esc = &sc->ehci_softc;
381 sc->ehci_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
383 if (sc->ehci_mem_res == NULL) {
390 sc->ehci_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
392 if (sc->ehci_irq_res == NULL) {
398 esc->sc_io_tag = rman_get_bustag(sc->ehci_mem_res);
399 esc->sc_bus.parent = dev;
400 esc->sc_bus.devices = esc->sc_devices;
401 esc->sc_bus.devices_max = EHCI_MAX_DEVICES;
402 esc->sc_bus.dma_bits = 32;
405 if (usb_bus_mem_alloc_all(&esc->sc_bus, USB_GET_DMA_TAG(dev),
413 * Set handle to USB related registers subregion used by
414 * generic EHCI driver.
416 err = bus_space_subregion(esc->sc_io_tag,
417 rman_get_bushandle(sc->ehci_mem_res),
418 IMX_EHCI_REG_OFF, IMX_EHCI_REG_SIZE, &esc->sc_io_hdl);
426 err = bus_setup_intr(dev, sc->ehci_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
427 NULL, (driver_intr_t *)ehci_interrupt, esc, &esc->sc_intr_hdl);
437 if (OF_hasprop(ofw_bus_get_node(sc->dev), "disable-over-current"))
440 /* Add USB bus device. */
441 esc->sc_bus.bdev = device_add_child(dev, "usbus", DEVICE_UNIT_ANY);
442 if (esc->sc_bus.bdev == NULL) {
443 device_printf(dev, "Could not add USB device\n");
446 device_set_ivars(esc->sc_bus.bdev, &esc->sc_bus);
448 esc->sc_id_vendor = USB_VENDOR_FREESCALE;
449 strlcpy(esc->sc_vendor, "Freescale", sizeof(esc->sc_vendor));
452 * Set flags that affect ehci_init() behavior, and hook our post-reset
455 esc->sc_flags |= EHCI_SCFLG_NORESTERM | EHCI_SCFLG_TT;
456 esc->sc_vendor_post_reset = imx_ehci_post_reset;
457 esc->sc_vendor_get_port_speed = ehci_get_port_speed_portsc;
461 device_printf(dev, "USB init failed, usb_err_t=%d\n",
465 esc->sc_flags |= EHCI_SCFLG_DONEINIT;
468 err = device_probe_and_attach(esc->sc_bus.bdev);
501 "ehci",
507 MODULE_DEPEND(imx_ehci, usb, 1, 1, 1);