1 /* $NetBSD: ralink_ehci.c,v 1.3 2012/07/20 02:14:02 matt Exp $ */ 2 /*- 3 * Copyright (c) 2011 CradlePoint Technology, Inc. 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* ralink_ehci.c -- Ralink EHCI USB Driver */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: ralink_ehci.c,v 1.3 2012/07/20 02:14:02 matt Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 37 #include <dev/usb/usb.h> 38 #include <dev/usb/usbdi.h> 39 #include <dev/usb/usbdivar.h> 40 #include <dev/usb/usb_mem.h> 41 42 #include <dev/usb/ehcireg.h> 43 #include <dev/usb/ehcivar.h> 44 45 #include <mips/ralink/ralink_usbhcvar.h> 46 47 #include <mips/ralink/ralink_var.h> 48 #include <mips/ralink/ralink_reg.h> 49 50 #define RT3XXX_EHCI_BASE 0x101c0000 51 #define RT3XXX_BLOCK_SIZE 0x1000 52 53 struct ralink_ehci_softc { 54 struct ehci_softc sc_ehci; 55 void *sc_ih; 56 }; 57 58 static int ralink_ehci_match(device_t, cfdata_t, void *); 59 static void ralink_ehci_attach(device_t, device_t, void *); 60 static int ralink_ehci_detach(device_t, int); 61 62 CFATTACH_DECL2_NEW(ralink_ehci, sizeof(struct ralink_ehci_softc), 63 ralink_ehci_match, ralink_ehci_attach, ralink_ehci_detach, 64 ehci_activate, NULL, ehci_childdet); 65 66 static TAILQ_HEAD(, ralink_usb_hc) ralink_usb_alldevs = 67 TAILQ_HEAD_INITIALIZER(ralink_usb_alldevs); 68 69 #if 0 70 struct usb_hc_alldevs ralink_usb_alldevs = TAILQ_HEAD_INITIALIZER(ralink_usb_alldevs); 71 #endif 72 73 /* 74 * ralink_ehci_match 75 */ 76 static int 77 ralink_ehci_match(device_t parent, cfdata_t cf, void *aux) 78 { 79 80 return 1; 81 } 82 83 /* 84 * ralink_ehci_attach 85 */ 86 static void 87 ralink_ehci_attach(device_t parent, device_t self, void *aux) 88 { 89 struct ralink_ehci_softc * const sc = device_private(self); 90 const struct mainbus_attach_args *ma = aux; 91 struct ralink_usb_hc *ruh; 92 uint32_t r; 93 bus_space_handle_t sysctl_memh; 94 usbd_status status; 95 int error; 96 #ifdef RALINK_EHCI_DEBUG 97 const char *const devname = device_xname(self); 98 #endif 99 100 aprint_naive(": EHCI USB controller\n"); 101 aprint_normal(": EHCI USB controller\n"); 102 103 sc->sc_ehci.sc_dev = self; 104 sc->sc_ehci.sc_bus.hci_private = sc; 105 sc->sc_ehci.iot = ma->ma_memt; 106 sc->sc_ehci.sc_bus.dmatag = ma->ma_dmat; 107 108 /* Map Sysctl registers */ 109 if (((error = bus_space_map(ma->ma_memt, RA_SYSCTL_BASE, 0x10000, 110 0, &sysctl_memh) != 0)) != 0) { 111 aprint_error_dev(self, "can't map Sysctl registers, " 112 "error=%d\n", error); 113 return; 114 } 115 116 /* The USB block defaults PHY0 to device mode, change to host mode */ 117 r = bus_space_read_4(ma->ma_memt, sysctl_memh, RA_SYSCTL_CFG1); 118 r |= (1 << 10); 119 bus_space_write_4(ma->ma_memt, sysctl_memh, RA_SYSCTL_CFG1, r); 120 121 /* done with Sysctl regs */ 122 bus_space_unmap(ma->ma_memt, sysctl_memh, 0x10000); 123 124 /* Map EHCI registers */ 125 if ((error = bus_space_map(sc->sc_ehci.iot, RT3XXX_EHCI_BASE, 126 RT3XXX_BLOCK_SIZE, 0, &sc->sc_ehci.ioh)) != 0) { 127 aprint_error_dev(self, "can't map EHCI registers, " 128 "error=%d\n", error); 129 return; 130 } 131 132 sc->sc_ehci.sc_size = RT3XXX_BLOCK_SIZE; 133 sc->sc_ehci.sc_bus.usbrev = USBREV_2_0; 134 135 #ifdef RALINK_EHCI_DEBUG 136 printf("%s sc: %p ma: %p\n", devname, sc, ma); 137 printf("%s memt: %p dmat: %p\n", devname, ma->ma_memt, ma->ma_dmat); 138 printf("%s: EHCI HCCAPBASE=0x%x\n", devname, 139 EREAD4(&sc->sc_ehci, EHCI_CAPLENGTH)); 140 printf("%s: EHCI HCSPARAMS=0x%x\n", devname, 141 EREAD4(&sc->sc_ehci, EHCI_HCSPARAMS)); 142 printf("%s: EHCI HCCPARAMS=0x%x\n", devname, 143 EREAD4(&sc->sc_ehci, EHCI_HCCPARAMS)); 144 printf("%s: EHCI HCSP_PORTROUTE=0x%x\n", devname, 145 EREAD4(&sc->sc_ehci, EHCI_HCSP_PORTROUTE)); 146 #endif 147 148 /* Disable EHCI interrupts. */ 149 sc->sc_ehci.sc_offs = EREAD1(&sc->sc_ehci, EHCI_CAPLENGTH); 150 EOWRITE4(&sc->sc_ehci, EHCI_USBINTR, 0); 151 152 #ifdef RALINK_EHCI_DEBUG 153 printf("%s: EHCI USBCMD=0x%x\n", devname, 154 EOREAD4(&sc->sc_ehci, EHCI_USBCMD)); 155 printf("%s: EHCI USBSTS=0x%x\n", devname, 156 EOREAD4(&sc->sc_ehci, EHCI_USBSTS)); 157 printf("%s: EHCI USBINTR=0x%x\n", devname, 158 EOREAD4(&sc->sc_ehci, EHCI_USBINTR)); 159 #endif 160 161 /* Establish the MIPS level interrupt */ 162 sc->sc_ih = ra_intr_establish(RA_IRQ_USB, ehci_intr, sc, 1); 163 if (sc->sc_ih == NULL) { 164 aprint_error_dev(self, "unable to establish irq %d\n", 165 RA_IRQ_USB); 166 goto fail_0; 167 } 168 169 /* 170 * Find companion controllers. According to the spec they always 171 * have lower function numbers so they should be enumerated already. 172 */ 173 int ncomp = 0; 174 TAILQ_FOREACH(ruh, &ralink_usb_alldevs, next) { 175 aprint_normal_dev(self, "companion %s\n", 176 device_xname(ruh->usb)); 177 sc->sc_ehci.sc_comps[ncomp++] = ruh->usb; 178 if (ncomp >= EHCI_COMPANION_MAX) 179 break; 180 } 181 sc->sc_ehci.sc_ncomp = ncomp; 182 183 /* set vendor for root hub descriptor. */ 184 sc->sc_ehci.sc_id_vendor = 0x1814; /* XXX */ 185 strlcpy(sc->sc_ehci.sc_vendor, "Ralink", sizeof(sc->sc_ehci.sc_vendor)); 186 187 /* Initialize EHCI */ 188 status = ehci_init(&sc->sc_ehci); 189 if (status != USBD_NORMAL_COMPLETION) { 190 aprint_error_dev(self, "init failed, error=%d\n", status); 191 goto fail_1; 192 } 193 194 if (!pmf_device_register1(self, ehci_suspend, ehci_resume, 195 ehci_shutdown)) 196 aprint_error_dev(self, "couldn't establish power handler\n"); 197 198 /* Attach usb device. */ 199 sc->sc_ehci.sc_child = config_found(self, &sc->sc_ehci.sc_bus, 200 usbctlprint); 201 202 return; 203 204 fail_1: 205 ra_intr_disestablish(sc->sc_ih); 206 sc->sc_ih = NULL; 207 fail_0: 208 bus_space_unmap(sc->sc_ehci.iot, sc->sc_ehci.ioh, sc->sc_ehci.sc_size); 209 sc->sc_ehci.sc_size = 0; 210 } 211 212 static int 213 ralink_ehci_detach(device_t self, int flags) 214 { 215 struct ralink_ehci_softc * const sc = device_private(self); 216 int rv; 217 218 pmf_device_deregister(self); 219 220 rv = ehci_detach(&sc->sc_ehci, flags); 221 if (rv) 222 return rv; 223 224 if (sc->sc_ih != NULL) { 225 ra_intr_disestablish(sc->sc_ih); 226 sc->sc_ih = NULL; 227 } 228 229 if (sc->sc_ehci.sc_size != 0) { 230 bus_space_unmap(sc->sc_ehci.iot, sc->sc_ehci.ioh, 231 sc->sc_ehci.sc_size); 232 sc->sc_ehci.sc_size = 0; 233 } 234 235 return 0; 236 } 237 238 void 239 ralink_usb_hc_add(struct ralink_usb_hc *ruh, device_t usbp) 240 { 241 TAILQ_INSERT_TAIL(&ralink_usb_alldevs, ruh, next); 242 ruh->usb = usbp; 243 } 244 245 void 246 ralink_usb_hc_rem(struct ralink_usb_hc *ruh) 247 { 248 TAILQ_REMOVE(&ralink_usb_alldevs, ruh, next); 249 } 250