1 /*- 2 * Copyright (c) 2016 Emmanuel Vadot <manu@freebsd.org> All rights reserved. 3 * Copyright (c) 2006 M. Warner Losh <imp@FreeBSD.org> 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /* 28 * Generic OHCI driver based on AT91 OHCI 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/bus.h> 34 #include <sys/rman.h> 35 #include <sys/condvar.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 39 #include <machine/bus.h> 40 #include <dev/ofw/ofw_bus.h> 41 #include <dev/ofw/ofw_bus_subr.h> 42 43 #include <dev/usb/usb.h> 44 #include <dev/usb/usbdi.h> 45 46 #include <dev/usb/usb_core.h> 47 #include <dev/usb/usb_busdma.h> 48 #include <dev/usb/usb_process.h> 49 #include <dev/usb/usb_util.h> 50 51 #include <dev/usb/usb_controller.h> 52 #include <dev/usb/usb_bus.h> 53 #include <dev/usb/controller/ohci.h> 54 #include <dev/usb/controller/ohcireg.h> 55 56 #include <dev/clk/clk.h> 57 #include <dev/hwreset/hwreset.h> 58 #include <dev/phy/phy.h> 59 #include <dev/phy/phy_usb.h> 60 61 #include "generic_usb_if.h" 62 63 struct clk_list { 64 TAILQ_ENTRY(clk_list) next; 65 clk_t clk; 66 }; 67 struct phy_list { 68 TAILQ_ENTRY(phy_list) next; 69 phy_t phy; 70 }; 71 struct hwrst_list { 72 TAILQ_ENTRY(hwrst_list) next; 73 hwreset_t rst; 74 }; 75 76 struct generic_ohci_softc { 77 ohci_softc_t ohci_sc; 78 79 TAILQ_HEAD(, clk_list) clk_list; 80 TAILQ_HEAD(, phy_list) phy_list; 81 TAILQ_HEAD(, hwrst_list) rst_list; 82 }; 83 84 static int generic_ohci_detach(device_t); 85 86 static int 87 generic_ohci_probe(device_t dev) 88 { 89 90 if (!ofw_bus_status_okay(dev)) 91 return (ENXIO); 92 93 if (!ofw_bus_is_compatible(dev, "generic-ohci")) 94 return (ENXIO); 95 96 device_set_desc(dev, "Generic OHCI Controller"); 97 98 return (BUS_PROBE_DEFAULT); 99 } 100 101 static int 102 generic_ohci_attach(device_t dev) 103 { 104 struct generic_ohci_softc *sc = device_get_softc(dev); 105 int err, rid; 106 int off; 107 struct clk_list *clkp; 108 struct phy_list *phyp; 109 struct hwrst_list *rstp; 110 clk_t clk; 111 phy_t phy; 112 hwreset_t rst; 113 114 sc->ohci_sc.sc_bus.parent = dev; 115 sc->ohci_sc.sc_bus.devices = sc->ohci_sc.sc_devices; 116 sc->ohci_sc.sc_bus.devices_max = OHCI_MAX_DEVICES; 117 sc->ohci_sc.sc_bus.dma_bits = 32; 118 119 /* get all DMA memory */ 120 if (usb_bus_mem_alloc_all(&sc->ohci_sc.sc_bus, 121 USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) { 122 return (ENOMEM); 123 } 124 125 rid = 0; 126 sc->ohci_sc.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 127 &rid, RF_ACTIVE); 128 if (sc->ohci_sc.sc_io_res == 0) { 129 err = ENOMEM; 130 goto error; 131 } 132 133 sc->ohci_sc.sc_io_tag = rman_get_bustag(sc->ohci_sc.sc_io_res); 134 sc->ohci_sc.sc_io_hdl = rman_get_bushandle(sc->ohci_sc.sc_io_res); 135 sc->ohci_sc.sc_io_size = rman_get_size(sc->ohci_sc.sc_io_res); 136 137 rid = 0; 138 sc->ohci_sc.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 139 RF_ACTIVE); 140 if (sc->ohci_sc.sc_irq_res == 0) { 141 err = ENXIO; 142 goto error; 143 } 144 sc->ohci_sc.sc_bus.bdev = device_add_child(dev, "usbus", DEVICE_UNIT_ANY); 145 if (sc->ohci_sc.sc_bus.bdev == 0) { 146 err = ENXIO; 147 goto error; 148 } 149 device_set_ivars(sc->ohci_sc.sc_bus.bdev, &sc->ohci_sc.sc_bus); 150 151 strlcpy(sc->ohci_sc.sc_vendor, "Generic", 152 sizeof(sc->ohci_sc.sc_vendor)); 153 154 err = bus_setup_intr(dev, sc->ohci_sc.sc_irq_res, 155 INTR_TYPE_BIO | INTR_MPSAFE, NULL, 156 (driver_intr_t *)ohci_interrupt, sc, &sc->ohci_sc.sc_intr_hdl); 157 if (err) { 158 sc->ohci_sc.sc_intr_hdl = NULL; 159 goto error; 160 } 161 162 TAILQ_INIT(&sc->clk_list); 163 /* Enable clock */ 164 for (off = 0; clk_get_by_ofw_index(dev, 0, off, &clk) == 0; off++) { 165 err = clk_enable(clk); 166 if (err != 0) { 167 device_printf(dev, "Could not enable clock %s\n", 168 clk_get_name(clk)); 169 goto error; 170 } 171 clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); 172 clkp->clk = clk; 173 TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next); 174 } 175 176 /* De-assert reset */ 177 TAILQ_INIT(&sc->rst_list); 178 for (off = 0; hwreset_get_by_ofw_idx(dev, 0, off, &rst) == 0; off++) { 179 err = hwreset_deassert(rst); 180 if (err != 0) { 181 device_printf(dev, "Could not de-assert reset\n"); 182 goto error; 183 } 184 rstp = malloc(sizeof(*rstp), M_DEVBUF, M_WAITOK | M_ZERO); 185 rstp->rst = rst; 186 TAILQ_INSERT_TAIL(&sc->rst_list, rstp, next); 187 } 188 189 /* Enable phy */ 190 TAILQ_INIT(&sc->phy_list); 191 for (off = 0; phy_get_by_ofw_idx(dev, 0, off, &phy) == 0; off++) { 192 err = phy_usb_set_mode(phy, PHY_USB_MODE_HOST); 193 if (err != 0) { 194 device_printf(dev, "Could not set phy to host mode\n"); 195 goto error; 196 } 197 err = phy_enable(phy); 198 if (err != 0) { 199 device_printf(dev, "Could not enable phy\n"); 200 goto error; 201 } 202 phyp = malloc(sizeof(*phyp), M_DEVBUF, M_WAITOK | M_ZERO); 203 phyp->phy = phy; 204 TAILQ_INSERT_TAIL(&sc->phy_list, phyp, next); 205 } 206 207 if (GENERIC_USB_INIT(dev) != 0) { 208 err = ENXIO; 209 goto error; 210 } 211 212 err = ohci_init(&sc->ohci_sc); 213 if (err == 0) 214 err = device_probe_and_attach(sc->ohci_sc.sc_bus.bdev); 215 if (err) 216 goto error; 217 218 return (0); 219 error: 220 generic_ohci_detach(dev); 221 return (err); 222 } 223 224 static int 225 generic_ohci_detach(device_t dev) 226 { 227 struct generic_ohci_softc *sc = device_get_softc(dev); 228 int err; 229 struct clk_list *clk, *clk_tmp; 230 struct phy_list *phy, *phy_tmp; 231 struct hwrst_list *rst, *rst_tmp; 232 233 /* during module unload there are lots of children leftover */ 234 device_delete_children(dev); 235 236 /* 237 * Put the controller into reset, then disable clocks and do 238 * the MI tear down. We have to disable the clocks/hardware 239 * after we do the rest of the teardown. We also disable the 240 * clocks in the opposite order we acquire them, but that 241 * doesn't seem to be absolutely necessary. We free up the 242 * clocks after we disable them, so the system could, in 243 * theory, reuse them. 244 */ 245 bus_space_write_4(sc->ohci_sc.sc_io_tag, sc->ohci_sc.sc_io_hdl, 246 OHCI_CONTROL, 0); 247 248 if (sc->ohci_sc.sc_irq_res && sc->ohci_sc.sc_intr_hdl) { 249 /* 250 * only call ohci_detach() after ohci_init() 251 */ 252 ohci_detach(&sc->ohci_sc); 253 254 err = bus_teardown_intr(dev, sc->ohci_sc.sc_irq_res, 255 sc->ohci_sc.sc_intr_hdl); 256 sc->ohci_sc.sc_intr_hdl = NULL; 257 } 258 if (sc->ohci_sc.sc_irq_res) { 259 bus_release_resource(dev, SYS_RES_IRQ, 0, 260 sc->ohci_sc.sc_irq_res); 261 sc->ohci_sc.sc_irq_res = NULL; 262 } 263 if (sc->ohci_sc.sc_io_res) { 264 bus_release_resource(dev, SYS_RES_MEMORY, 0, 265 sc->ohci_sc.sc_io_res); 266 sc->ohci_sc.sc_io_res = NULL; 267 } 268 usb_bus_mem_free_all(&sc->ohci_sc.sc_bus, &ohci_iterate_hw_softc); 269 270 /* Disable phy */ 271 TAILQ_FOREACH_SAFE(phy, &sc->phy_list, next, phy_tmp) { 272 err = phy_disable(phy->phy); 273 if (err != 0) 274 device_printf(dev, "Could not disable phy\n"); 275 phy_release(phy->phy); 276 TAILQ_REMOVE(&sc->phy_list, phy, next); 277 free(phy, M_DEVBUF); 278 } 279 280 /* Assert reset */ 281 TAILQ_FOREACH_SAFE(rst, &sc->rst_list, next, rst_tmp) { 282 hwreset_assert(rst->rst); 283 hwreset_release(rst->rst); 284 TAILQ_REMOVE(&sc->rst_list, rst, next); 285 free(rst, M_DEVBUF); 286 } 287 288 /* Disable clock */ 289 TAILQ_FOREACH_SAFE(clk, &sc->clk_list, next, clk_tmp) { 290 err = clk_disable(clk->clk); 291 if (err != 0) 292 device_printf(dev, "Could not disable clock %s\n", 293 clk_get_name(clk->clk)); 294 err = clk_release(clk->clk); 295 if (err != 0) 296 device_printf(dev, "Could not release clock %s\n", 297 clk_get_name(clk->clk)); 298 TAILQ_REMOVE(&sc->clk_list, clk, next); 299 free(clk, M_DEVBUF); 300 } 301 302 if (GENERIC_USB_DEINIT(dev) != 0) 303 return (ENXIO); 304 305 return (0); 306 } 307 308 static device_method_t generic_ohci_methods[] = { 309 /* Device interface */ 310 DEVMETHOD(device_probe, generic_ohci_probe), 311 DEVMETHOD(device_attach, generic_ohci_attach), 312 DEVMETHOD(device_detach, generic_ohci_detach), 313 314 DEVMETHOD(device_suspend, bus_generic_suspend), 315 DEVMETHOD(device_resume, bus_generic_resume), 316 DEVMETHOD(device_shutdown, bus_generic_shutdown), 317 318 DEVMETHOD_END 319 }; 320 321 driver_t generic_ohci_driver = { 322 .name = "ohci", 323 .methods = generic_ohci_methods, 324 .size = sizeof(struct generic_ohci_softc), 325 }; 326 327 DRIVER_MODULE(ohci, simplebus, generic_ohci_driver, 0, 0); 328 MODULE_DEPEND(ohci, usb, 1, 1, 1); 329