1 /* $NetBSD: ti_otg.c,v 1.2 2021/01/27 03:10:20 thorpej Exp $ */ 2 /* 3 * Copyright (c) 2013 Manuel Bouyer. All rights reserved. 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 ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: ti_otg.c,v 1.2 2021/01/27 03:10:20 thorpej Exp $"); 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/device.h> 32 #include <sys/conf.h> 33 #include <sys/bus.h> 34 #include <sys/proc.h> 35 #include <sys/kernel.h> 36 #include <sys/mutex.h> 37 #include <sys/condvar.h> 38 39 #include <arm/ti/ti_prcm.h> 40 #include <arm/ti/ti_otgreg.h> 41 42 #include <dev/fdt/fdtvar.h> 43 44 static const struct device_compatible_entry compat_data[] = { 45 { .compat = "ti,am33xx-usb" }, 46 DEVICE_COMPAT_EOL 47 }; 48 49 struct tiotg_softc { 50 device_t sc_dev; 51 bus_space_tag_t sc_iot; 52 bus_space_handle_t sc_ioh; 53 bus_dma_tag_t sc_dmat; 54 void * sc_ih; 55 }; 56 57 static int tiotg_match(device_t, cfdata_t, void *); 58 static void tiotg_attach(device_t, device_t, void *); 59 60 CFATTACH_DECL_NEW(ti_otg, sizeof(struct tiotg_softc), 61 tiotg_match, tiotg_attach, NULL, NULL); 62 63 static int 64 tiotg_match(device_t parent, cfdata_t match, void *aux) 65 { 66 struct fdt_attach_args * const faa = aux; 67 68 return of_compatible_match(faa->faa_phandle, compat_data); 69 } 70 71 static void 72 tiotg_attach(device_t parent, device_t self, void *aux) 73 { 74 struct tiotg_softc *sc = device_private(self); 75 struct fdt_attach_args * const faa = aux; 76 const int phandle = faa->faa_phandle; 77 bus_addr_t addr; 78 bus_size_t size; 79 uint32_t val; 80 81 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 82 aprint_error(": couldn't get registers\n"); 83 return; 84 } 85 86 sc->sc_iot = faa->faa_bst; 87 sc->sc_dmat = faa->faa_dmat; 88 sc->sc_dev = self; 89 90 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { 91 aprint_error(": couldn't map registers\n"); 92 return; 93 } 94 95 aprint_normal(": TI dual-port USB controller"); 96 97 #if 0 98 /* XXX this looks wrong */ 99 prcm_write_4(AM335X_PRCM_CM_WKUP, CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 100 CM_WKUP_CM_CLKDCOLDO_DPLL_PER_CLKDCOLDO_GATE_CTRL| 101 CM_WKUP_CM_CLKDCOLDO_DPLL_PER_CLKDCOLDO_ST); 102 103 prcm_write_4(AM335X_PRCM_CM_PER, CM_PER_USB0_CLKCTRL, 2); 104 while ((prcm_read_4(AM335X_PRCM_CM_PER, CM_PER_USB0_CLKCTRL) & 0x3) != 2) 105 delay(10); 106 107 while (prcm_read_4(AM335X_PRCM_CM_PER, CM_PER_USB0_CLKCTRL) & (3<<16)) 108 delay(10); 109 #endif 110 111 /* reset module */ 112 TIOTG_USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET); 113 while (TIOTG_USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET) 114 delay(10); 115 val = TIOTG_USBSS_READ4(sc, USBSS_REVREG); 116 aprint_normal(": version v%d.%d.%d.%d", 117 (val >> 11) & 15, (val >> 8) & 7, (val >> 6) & 3, val & 63); 118 aprint_normal("\n"); 119 120 /* enable clock */ 121 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 122 aprint_error(": couldn't enable module\n"); 123 return; 124 } 125 126 fdt_add_bus(self, phandle, faa); 127 } 128