1 1.10 thorpej /* $NetBSD: ehci_mv.c,v 1.10 2021/08/07 16:19:13 thorpej Exp $ */ 2 1.1 kiyohara /* 3 1.1 kiyohara * Copyright (c) 2008 KIYOHARA Takashi 4 1.1 kiyohara * All rights reserved. 5 1.1 kiyohara * 6 1.1 kiyohara * Redistribution and use in source and binary forms, with or without 7 1.1 kiyohara * modification, are permitted provided that the following conditions 8 1.1 kiyohara * are met: 9 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright 10 1.1 kiyohara * notice, this list of conditions and the following disclaimer. 11 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the 13 1.1 kiyohara * documentation and/or other materials provided with the distribution. 14 1.1 kiyohara * 15 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.1 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 kiyohara * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 kiyohara * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 1.1 kiyohara * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 1.1 kiyohara * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 kiyohara * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 kiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 1.1 kiyohara * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 1.1 kiyohara * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 1.1 kiyohara * POSSIBILITY OF SUCH DAMAGE. 26 1.1 kiyohara */ 27 1.1 kiyohara 28 1.1 kiyohara #include <sys/cdefs.h> 29 1.10 thorpej __KERNEL_RCSID(0, "$NetBSD: ehci_mv.c,v 1.10 2021/08/07 16:19:13 thorpej Exp $"); 30 1.1 kiyohara 31 1.1 kiyohara #include <sys/param.h> 32 1.1 kiyohara #include <sys/bus.h> 33 1.1 kiyohara #include <sys/device.h> 34 1.1 kiyohara #include <sys/errno.h> 35 1.1 kiyohara #include <sys/systm.h> 36 1.1 kiyohara 37 1.1 kiyohara #include <dev/marvell/marvellreg.h> 38 1.1 kiyohara #include <dev/marvell/marvellvar.h> 39 1.1 kiyohara 40 1.1 kiyohara #include <dev/usb/usb.h> 41 1.1 kiyohara #include <dev/usb/usbdi.h> 42 1.1 kiyohara #include <dev/usb/usbdivar.h> 43 1.1 kiyohara #include <dev/usb/usb_mem.h> 44 1.1 kiyohara 45 1.1 kiyohara #include <dev/usb/ehcireg.h> 46 1.1 kiyohara #include <dev/usb/ehcivar.h> 47 1.1 kiyohara 48 1.1 kiyohara #include "locators.h" 49 1.1 kiyohara 50 1.1 kiyohara #ifdef EHCI_DEBUG 51 1.1 kiyohara #define DPRINTF(x) if (ehcidebug) printf x 52 1.1 kiyohara extern int ehcidebug; 53 1.1 kiyohara #else 54 1.1 kiyohara #define DPRINTF(x) 55 1.1 kiyohara #endif 56 1.1 kiyohara 57 1.1 kiyohara 58 1.4 kiyohara #define MARVELL_USB_SIZE 0x1000 59 1.1 kiyohara 60 1.1 kiyohara #define MARVELL_USB_NWINDOW 4 61 1.1 kiyohara 62 1.1 kiyohara #define MARVELL_USB_ID 0x000 63 1.1 kiyohara #define MARVELL_USB_HWGENERAL 0x004 64 1.1 kiyohara #define MARVELL_USB_HWHOST 0x008 65 1.1 kiyohara #define MARVELL_USB_HWDEVICE 0x00c 66 1.1 kiyohara #define MARVELL_USB_HWTXBUF 0x010 67 1.1 kiyohara #define MARVELL_USB_HWRXBUF 0x014 68 1.1 kiyohara #define MARVELL_USB_HWTTTXBUF 0x018 69 1.1 kiyohara #define MARVELL_USB_HWTTRXBUF 0x01c 70 1.1 kiyohara 71 1.1 kiyohara /* ehci generic registers */ 72 1.1 kiyohara #define MARVELL_USB_EHCI_BASE 0x100 73 1.4 kiyohara #define MARVELL_USB_EHCI_SIZE 0x100 74 1.1 kiyohara 75 1.2 kiyohara /* ehci vendor extension registers */ 76 1.2 kiyohara #define MARVELL_USB_EHCI_PS_PSPD 0x0c000000 /* Port speed */ 77 1.2 kiyohara #define MARVELL_USB_EHCI_PS_PSPD_FS 0x00000000 /* Full speed */ 78 1.2 kiyohara #define MARVELL_USB_EHCI_PS_PSPD_LS 0x04000000 /* Low speed */ 79 1.2 kiyohara #define MARVELL_USB_EHCI_PS_PSPD_HS 0x08000000 /* High speed */ 80 1.2 kiyohara 81 1.2 kiyohara #define MARVELL_USB_EHCI_USBMODE 0x68 82 1.2 kiyohara #define MARVELL_USB_EHCI_MODE_STRMDIS 0x00000008 /* RW straming disable */ 83 1.2 kiyohara #define MARVELL_USB_EHCI_MODE_BE 0x00000004 /* RW B/L endianness select*/ 84 1.2 kiyohara #define MARVELL_USB_EHCI_MODE_HDMASK 0x00000003 /* RW host/device Mask */ 85 1.2 kiyohara #define MARVELL_USB_EHCI_MODE_HOST 0x00000003 /* RW mode host */ 86 1.2 kiyohara #define MARVELL_USB_EHCI_MODE_DEVICE 0x00000002 /* RW mode device */ 87 1.2 kiyohara 88 1.1 kiyohara #define MARVELL_USB_DCIVERSION 0x120 89 1.1 kiyohara #define MARVELL_USB_DCCPARAMS 0x124 90 1.1 kiyohara #define MARVELL_USB_TTCTRL 0x15c 91 1.1 kiyohara #define MARVELL_USB_BURSTSIZE 0x160 92 1.1 kiyohara #define MARVELL_USB_TXFILLTUNING 0x164 93 1.1 kiyohara #define MARVELL_USB_TXTTFILLTUNING 0x168 94 1.1 kiyohara #define MARVELL_USB_OTGSC 0x1a4 95 1.1 kiyohara #define MARVELL_USB_USBMODE 0x1a8 96 1.1 kiyohara #define MARVELL_USB_USBMODE_MASK (3 << 0) 97 1.1 kiyohara #define MARVELL_USB_USBMODE_HOST (3 << 0) 98 1.1 kiyohara #define MARVELL_USB_USBMODE_DEVICE (2 << 0) 99 1.1 kiyohara #define MARVELL_USB_USBMODE_STREAMDISABLE (1 << 4) 100 1.1 kiyohara #define MARVELL_USB_ENPDTSETUPSTAT 0x1ac 101 1.1 kiyohara #define MARVELL_USB_ENDPTPRIME 0x1b0 102 1.1 kiyohara #define MARVELL_USB_ENDPTFLUSH 0x1b4 103 1.1 kiyohara #define MARVELL_USB_ENDPTSTATS 0x1b8 104 1.1 kiyohara #define MARVELL_USB_ENDPTCOMPLETE 0x1bc 105 1.1 kiyohara #define MARVELL_USB_ENDPTCTRL0 0x1c0 106 1.1 kiyohara #define MARVELL_USB_ENDPTCTRL1 0x1c1 107 1.1 kiyohara #define MARVELL_USB_ENDPTCTRL2 0x1c2 108 1.1 kiyohara #define MARVELL_USB_ENDPTCTRL3 0x1c3 109 1.1 kiyohara /* Bridge Control And Status Registers */ 110 1.1 kiyohara #define MARVELL_USB_BCR 0x300 /* Control */ 111 1.1 kiyohara /* Bridge Interrupt and Error Registers */ 112 1.1 kiyohara #define MARVELL_USB_BICR 0x310 /* Interrupt Cause */ 113 1.1 kiyohara #define MARVELL_USB_BIMR 0x314 /* Interrupt Mask */ 114 1.1 kiyohara #define MARVELL_USB_BIR_ADDRDECERR (1 << 0) 115 1.1 kiyohara #define MARVELL_USB_BEAR 0x31c /* Error Address */ 116 1.1 kiyohara /* Bridge Address Decoding Registers */ 117 1.1 kiyohara #define MARVELL_USB_WCR(n) (0x320 + (n) * 0x10) /* WinN Control */ 118 1.1 kiyohara #define MARVELL_USB_WCR_WINEN (1 << 0) 119 1.1 kiyohara #define MARVELL_USB_WCR_TARGET(t) (((t) & 0xf) << 4) 120 1.1 kiyohara #define MARVELL_USB_WCR_ATTR(a) (((a) & 0xff) << 8) 121 1.1 kiyohara #define MARVELL_USB_WCR_SIZE(s) (((s) - 1) & 0xffff0000) 122 1.1 kiyohara #define MARVELL_USB_WBR(n) (0x324 + (n) * 0x10) /* WinN Base */ 123 1.1 kiyohara #define MARVELL_USB_WBR_BASE(b) ((b) & 0xffff0000) 124 1.1 kiyohara /* IPG Metal Fix Register ??? */ 125 1.1 kiyohara #define MARVELL_USB_IPGR 0x360 126 1.1 kiyohara /* USB 2.0 PHY Register Map */ 127 1.1 kiyohara #define MARVELL_USB_PCR 0x400 /* Power Control */ 128 1.1 kiyohara #define MARVELL_USB_PCR_PU (1 << 0) /* Power Up */ 129 1.1 kiyohara #define MARVELL_USB_PCR_PUPLL (1 << 1) /*Power Up PLL*/ 130 1.1 kiyohara #define MARVELL_USB_PCR_SUSPENDM (1 << 2) 131 1.1 kiyohara #define MARVELL_USB_PCR_VBUSPWRFAULT (1 << 3) 132 1.1 kiyohara #define MARVELL_USB_PCR_PWRCTLWAKEUP (1 << 4) 133 1.1 kiyohara #define MARVELL_USB_PCR_PUREF (1 << 5) 134 1.1 kiyohara #define MARVELL_USB_PCR_BGVSEL_MASK (3 << 6) 135 1.1 kiyohara #define MARVELL_USB_PCR_BGVSEL_CONNECT_ANAGRP (1 << 6) 136 1.1 kiyohara #define MARVELL_USB_PCR_REGARCDPDMMODE (1 << 8) 137 1.1 kiyohara #define MARVELL_USB_PCR_REGDPPULLDOWN (1 << 9) 138 1.1 kiyohara #define MARVELL_USB_PCR_REGDMPULLDOWN (1 << 10) 139 1.1 kiyohara #define MARVELL_USB_PCR_UTMISESSION (1 << 23) 140 1.1 kiyohara #define MARVELL_USB_PCR_UTMIVBUSVALID (1 << 24) 141 1.1 kiyohara #define MARVELL_USB_PCR_UTMIAVALID (1 << 25) 142 1.1 kiyohara #define MARVELL_USB_PCR_UTMIBVALID (1 << 26) 143 1.1 kiyohara #define MARVELL_USB_PCR_TXBITSTUFF (1 << 27) 144 1.1 kiyohara /* USB PHY Tx Control Register */ 145 1.1 kiyohara #define MARVELL_USB_PTCR 0x420 146 1.1 kiyohara /* USB PHY Rx Control Register */ 147 1.1 kiyohara #define MARVELL_USB_PRCR 0x430 148 1.1 kiyohara /* USB PHY IVREFF Control Register */ 149 1.1 kiyohara #define MARVELL_USB_PIVREFFCR 0x440 150 1.1 kiyohara /* USB PHY Test Group Control Register */ 151 1.1 kiyohara #define MARVELL_USB_PTGCR 0x450 152 1.1 kiyohara 153 1.1 kiyohara 154 1.1 kiyohara struct mvusb_softc { 155 1.1 kiyohara ehci_softc_t sc; 156 1.1 kiyohara 157 1.1 kiyohara int sc_model; 158 1.1 kiyohara int sc_rev; 159 1.1 kiyohara 160 1.1 kiyohara bus_space_tag_t sc_iot; 161 1.1 kiyohara bus_space_handle_t sc_ioh; 162 1.1 kiyohara }; 163 1.1 kiyohara 164 1.1 kiyohara static int mvusb_match(device_t, cfdata_t, void *); 165 1.1 kiyohara static void mvusb_attach(device_t, device_t, void *); 166 1.1 kiyohara 167 1.5 kiyohara static void mvusb_init(struct mvusb_softc *, enum marvell_tags *); 168 1.5 kiyohara static void mvusb_wininit(struct mvusb_softc *, enum marvell_tags *); 169 1.1 kiyohara 170 1.2 kiyohara static void mvusb_vendor_init(struct ehci_softc *); 171 1.2 kiyohara static int mvusb_vendor_port_status(struct ehci_softc *, uint32_t, int); 172 1.2 kiyohara 173 1.1 kiyohara CFATTACH_DECL2_NEW(mvusb_gt, sizeof(struct mvusb_softc), 174 1.1 kiyohara mvusb_match, mvusb_attach, NULL, ehci_activate, NULL, ehci_childdet); 175 1.1 kiyohara CFATTACH_DECL2_NEW(mvusb_mbus, sizeof(struct mvusb_softc), 176 1.1 kiyohara mvusb_match, mvusb_attach, NULL, ehci_activate, NULL, ehci_childdet); 177 1.1 kiyohara 178 1.1 kiyohara 179 1.1 kiyohara /* ARGSUSED */ 180 1.1 kiyohara static int 181 1.1 kiyohara mvusb_match(device_t parent, cfdata_t match, void *aux) 182 1.1 kiyohara { 183 1.1 kiyohara struct marvell_attach_args *mva = aux; 184 1.1 kiyohara 185 1.1 kiyohara if (strcmp(mva->mva_name, match->cf_name) != 0) 186 1.1 kiyohara return 0; 187 1.1 kiyohara if (mva->mva_offset == MVA_OFFSET_DEFAULT || 188 1.1 kiyohara mva->mva_irq == MVA_IRQ_DEFAULT) 189 1.1 kiyohara return 0; 190 1.1 kiyohara 191 1.1 kiyohara mva->mva_size = MARVELL_USB_SIZE; 192 1.1 kiyohara return 1; 193 1.1 kiyohara } 194 1.1 kiyohara 195 1.1 kiyohara /* ARGSUSED */ 196 1.1 kiyohara static void 197 1.1 kiyohara mvusb_attach(device_t parent, device_t self, void *aux) 198 1.1 kiyohara { 199 1.1 kiyohara struct mvusb_softc *sc = device_private(self); 200 1.1 kiyohara struct marvell_attach_args *mva = aux; 201 1.1 kiyohara 202 1.1 kiyohara aprint_normal(": Marvell USB 2.0 Interface\n"); 203 1.1 kiyohara aprint_naive("\n"); 204 1.1 kiyohara 205 1.1 kiyohara sc->sc.sc_dev = self; 206 1.6 skrll sc->sc.sc_bus.ub_hcpriv = sc; 207 1.1 kiyohara 208 1.1 kiyohara sc->sc_model = mva->mva_model; 209 1.1 kiyohara sc->sc_rev = mva->mva_revision; 210 1.1 kiyohara sc->sc_iot = mva->mva_iot; 211 1.1 kiyohara 212 1.1 kiyohara /* Map I/O registers for marvell usb */ 213 1.1 kiyohara if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, mva->mva_offset, 214 1.1 kiyohara mva->mva_size, &sc->sc_ioh)) { 215 1.1 kiyohara aprint_error_dev(self, "can't map registers\n"); 216 1.1 kiyohara return; 217 1.1 kiyohara } 218 1.5 kiyohara mvusb_init(sc, mva->mva_tags); 219 1.1 kiyohara 220 1.1 kiyohara /* Map I/O registers for ehci */ 221 1.1 kiyohara sc->sc.sc_size = MARVELL_USB_EHCI_SIZE; 222 1.1 kiyohara if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, MARVELL_USB_EHCI_BASE, 223 1.1 kiyohara sc->sc.sc_size, &sc->sc.ioh)) { 224 1.1 kiyohara aprint_error_dev(self, "can't subregion registers\n"); 225 1.1 kiyohara return; 226 1.1 kiyohara } 227 1.1 kiyohara sc->sc.iot = sc->sc_iot; 228 1.6 skrll sc->sc.sc_bus.ub_dmatag = mva->mva_dmat; 229 1.1 kiyohara 230 1.1 kiyohara /* Disable interrupts, so we don't get any spurious ones. */ 231 1.1 kiyohara sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); 232 1.1 kiyohara DPRINTF(("%s: offs=%d\n", device_xname(self), sc->sc.sc_offs)); 233 1.1 kiyohara EOWRITE2(&sc->sc, EHCI_USBINTR, 0); 234 1.1 kiyohara 235 1.1 kiyohara marvell_intr_establish(mva->mva_irq, IPL_USB, ehci_intr, sc); 236 1.1 kiyohara 237 1.6 skrll sc->sc.sc_bus.ub_revision = USBREV_2_0; 238 1.1 kiyohara 239 1.2 kiyohara sc->sc.sc_vendor_init = mvusb_vendor_init; 240 1.2 kiyohara sc->sc.sc_vendor_port_status = mvusb_vendor_port_status; 241 1.2 kiyohara 242 1.6 skrll int err = ehci_init(&sc->sc); 243 1.6 skrll if (err) { 244 1.6 skrll aprint_error_dev(self, "init failed, error=%d\n", err); 245 1.1 kiyohara return; 246 1.1 kiyohara } 247 1.1 kiyohara 248 1.1 kiyohara /* Attach usb device. */ 249 1.9 thorpej sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint, 250 1.10 thorpej CFARGS_NONE); 251 1.1 kiyohara } 252 1.1 kiyohara 253 1.1 kiyohara static void 254 1.5 kiyohara mvusb_init(struct mvusb_softc *sc, enum marvell_tags *tags) 255 1.1 kiyohara { 256 1.1 kiyohara uint32_t reg; 257 1.1 kiyohara int opr_offs; 258 1.1 kiyohara 259 1.1 kiyohara /* Clear Interrupt Cause and Mask registers */ 260 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_BICR, 0); 261 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_BIMR, 0); 262 1.1 kiyohara 263 1.1 kiyohara opr_offs = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 264 1.1 kiyohara MARVELL_USB_EHCI_BASE + EHCI_CAPLENGTH); 265 1.1 kiyohara 266 1.1 kiyohara /* Reset controller */ 267 1.1 kiyohara reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 268 1.1 kiyohara MARVELL_USB_EHCI_BASE + opr_offs + EHCI_USBCMD); 269 1.1 kiyohara reg |= EHCI_CMD_HCRESET; 270 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, 271 1.1 kiyohara MARVELL_USB_EHCI_BASE + opr_offs + EHCI_USBCMD, reg); 272 1.1 kiyohara while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, 273 1.1 kiyohara MARVELL_USB_EHCI_BASE + opr_offs + EHCI_USBCMD) & EHCI_CMD_HCRESET); 274 1.1 kiyohara 275 1.1 kiyohara if (!((sc->sc_model == MARVELL_ORION_1_88F5181 && 276 1.1 kiyohara (sc->sc_rev <= 3 || sc->sc_rev == 8)) || 277 1.1 kiyohara (sc->sc_model == MARVELL_ORION_1_88F5182 && sc->sc_rev <= 1) || 278 1.1 kiyohara (sc->sc_model == MARVELL_ORION_2_88F5281 && sc->sc_rev <= 1))) { 279 1.1 kiyohara reg = 280 1.1 kiyohara bus_space_read_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_IPGR); 281 1.1 kiyohara /* 282 1.1 kiyohara * Change bits[14:8] - IPG for non Start of Frame Packets 283 1.1 kiyohara * from 0x9(default) to 0xc 284 1.1 kiyohara */ 285 1.1 kiyohara reg &= ~(0x7f << 8); 286 1.1 kiyohara reg |= (0x0c << 8); 287 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_IPGR, 288 1.1 kiyohara reg); 289 1.1 kiyohara } 290 1.3 rkujawa if (!(sc->sc_model == MARVELL_ARMADAXP_MV78460)) { 291 1.3 rkujawa reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_PCR); 292 1.3 rkujawa reg &= ~MARVELL_USB_PCR_BGVSEL_MASK; 293 1.3 rkujawa reg |= MARVELL_USB_PCR_BGVSEL_CONNECT_ANAGRP; 294 1.3 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_PCR, reg); 295 1.3 rkujawa 296 1.3 rkujawa reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 297 1.3 rkujawa MARVELL_USB_PTCR); 298 1.3 rkujawa if (sc->sc_model == MARVELL_ORION_1_88F5181 && sc->sc_rev <= 1) 299 1.3 rkujawa /* For OrionI A1/A0 rev: bit[21]=0 (TXDATA_BLOCK_EN=0) */ 300 1.3 rkujawa reg &= ~(1 << 21); 301 1.3 rkujawa else 302 1.3 rkujawa reg |= (1 << 21); 303 1.3 rkujawa /* bit[13]=1, (REG_EXT_RCAL_EN=1) */ 304 1.3 rkujawa reg |= (1 << 13); 305 1.3 rkujawa /* bits[6:3]=8 (IMP_CAL=8) */ 306 1.3 rkujawa reg &= ~(0xf << 3); 307 1.3 rkujawa reg |= (8 << 3); 308 1.3 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_PTCR, 309 1.3 rkujawa reg); 310 1.1 kiyohara 311 1.3 rkujawa reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 312 1.3 rkujawa MARVELL_USB_PRCR); 313 1.3 rkujawa /* bits[8:9] - (DISCON_THRESHOLD ) */ 314 1.3 rkujawa /* 315 1.3 rkujawa * Orion1-A0/A1/B0=11, Orion2-A0=10, 316 1.6 skrll * Orion1-B1 and Orion2-B0 later=00 317 1.3 rkujawa */ 318 1.3 rkujawa reg &= ~(3 << 8); 319 1.3 rkujawa if (sc->sc_model == MARVELL_ORION_1_88F5181 && sc->sc_rev <= 2) 320 1.3 rkujawa reg |= (3 << 8); 321 1.3 rkujawa else if (sc->sc_model == MARVELL_ORION_2_88F5281 && 322 1.3 rkujawa sc->sc_rev == 0) 323 1.3 rkujawa reg |= (2 << 8); 324 1.3 rkujawa /* bit[21]=0 (CDR_FASTLOCK_EN=0) */ 325 1.1 kiyohara reg &= ~(1 << 21); 326 1.3 rkujawa /* bits[27:26]=0 (EDGE_DET_SEL=0) */ 327 1.3 rkujawa reg &= ~(3 << 26); 328 1.8 msaitoh /* bits[31:30]=3 (RXDATA_BLOCK_LENGTH=3) */ 329 1.3 rkujawa reg |= (3 << 30); 330 1.3 rkujawa /* bits[7:4]=1 (SQ_THRESH=1) */ 331 1.3 rkujawa reg &= ~(0xf << 4); 332 1.3 rkujawa reg |= (1 << 4); 333 1.3 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_PRCR, 334 1.3 rkujawa reg); 335 1.3 rkujawa 336 1.3 rkujawa reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 337 1.3 rkujawa MARVELL_USB_PIVREFFCR); 338 1.3 rkujawa /* bits[1:0]=2 (PLLVDD12=2)*/ 339 1.3 rkujawa reg &= ~(3 << 0); 340 1.3 rkujawa reg |= (2 << 0); 341 1.3 rkujawa /* bits[5:4]=3 (RXVDD=3) */ 342 1.3 rkujawa reg &= ~(3 << 4); 343 1.3 rkujawa reg |= (3 << 4); 344 1.3 rkujawa /* bit[19] (Reserved) */ 345 1.3 rkujawa reg &= ~(1 << 19); 346 1.3 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, 347 1.3 rkujawa MARVELL_USB_PIVREFFCR, reg); 348 1.3 rkujawa 349 1.3 rkujawa reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 350 1.3 rkujawa MARVELL_USB_PTGCR); 351 1.3 rkujawa /* bit[15]=0 (REG_FIFO_SQ_RST=0) */ 352 1.3 rkujawa reg &= ~(1 << 15); 353 1.3 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, MARVELL_USB_PTGCR, 354 1.3 rkujawa reg); 355 1.3 rkujawa } 356 1.1 kiyohara 357 1.5 kiyohara mvusb_wininit(sc, tags); 358 1.1 kiyohara } 359 1.1 kiyohara 360 1.1 kiyohara static void 361 1.5 kiyohara mvusb_wininit(struct mvusb_softc *sc, enum marvell_tags *tags) 362 1.1 kiyohara { 363 1.1 kiyohara device_t pdev = device_parent(sc->sc.sc_dev); 364 1.1 kiyohara uint64_t base; 365 1.1 kiyohara uint32_t size; 366 1.1 kiyohara int window, target, attr, rv, i; 367 1.1 kiyohara 368 1.1 kiyohara for (window = 0, i = 0; 369 1.1 kiyohara tags[i] != MARVELL_TAG_UNDEFINED && window < MARVELL_USB_NWINDOW; 370 1.1 kiyohara i++) { 371 1.1 kiyohara rv = marvell_winparams_by_tag(pdev, tags[i], 372 1.1 kiyohara &target, &attr, &base, &size); 373 1.1 kiyohara if (rv != 0 || size == 0) 374 1.1 kiyohara continue; 375 1.1 kiyohara if (base > 0xffffffffULL) { 376 1.1 kiyohara aprint_error_dev(sc->sc.sc_dev, 377 1.1 kiyohara "tag %d address 0x%llx not support\n", 378 1.1 kiyohara tags[i], base); 379 1.1 kiyohara continue; 380 1.1 kiyohara } 381 1.1 kiyohara 382 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, 383 1.1 kiyohara MARVELL_USB_WCR(window), 384 1.1 kiyohara MARVELL_USB_WCR_WINEN | 385 1.1 kiyohara MARVELL_USB_WCR_TARGET(target) | 386 1.1 kiyohara MARVELL_USB_WCR_ATTR(attr) | 387 1.1 kiyohara MARVELL_USB_WCR_SIZE(size)); 388 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, 389 1.1 kiyohara MARVELL_USB_WBR(window), MARVELL_USB_WBR_BASE(base)); 390 1.1 kiyohara window++; 391 1.1 kiyohara } 392 1.1 kiyohara for (; window < MARVELL_USB_NWINDOW; window++) 393 1.1 kiyohara bus_space_write_4(sc->sc_iot, sc->sc_ioh, 394 1.1 kiyohara MARVELL_USB_WCR(window), 0); 395 1.1 kiyohara } 396 1.2 kiyohara 397 1.2 kiyohara static void 398 1.2 kiyohara mvusb_vendor_init(struct ehci_softc *sc) 399 1.2 kiyohara { 400 1.2 kiyohara uint32_t mode; 401 1.2 kiyohara 402 1.2 kiyohara /* put TDI/ARC silicon into EHCI mode */ 403 1.2 kiyohara mode = EOREAD4(sc, MARVELL_USB_EHCI_USBMODE); 404 1.2 kiyohara mode &= ~MARVELL_USB_EHCI_MODE_HDMASK; /* Host/Device Mask */ 405 1.2 kiyohara mode |= MARVELL_USB_EHCI_MODE_HOST; 406 1.2 kiyohara mode |= MARVELL_USB_EHCI_MODE_STRMDIS; 407 1.2 kiyohara EOWRITE4(sc, MARVELL_USB_EHCI_USBMODE, mode); 408 1.2 kiyohara } 409 1.2 kiyohara 410 1.2 kiyohara static int 411 1.2 kiyohara mvusb_vendor_port_status(struct ehci_softc *sc, uint32_t v, int i) 412 1.2 kiyohara { 413 1.2 kiyohara 414 1.2 kiyohara i &= ~UPS_HIGH_SPEED; 415 1.2 kiyohara if (v & EHCI_PS_CS) { 416 1.2 kiyohara switch (v & MARVELL_USB_EHCI_PS_PSPD) { 417 1.2 kiyohara case MARVELL_USB_EHCI_PS_PSPD_FS: 418 1.2 kiyohara break; 419 1.2 kiyohara case MARVELL_USB_EHCI_PS_PSPD_LS: 420 1.2 kiyohara i |= UPS_LOW_SPEED; 421 1.2 kiyohara break; 422 1.2 kiyohara case MARVELL_USB_EHCI_PS_PSPD_HS: 423 1.2 kiyohara default: 424 1.2 kiyohara i |= UPS_HIGH_SPEED; 425 1.2 kiyohara } 426 1.2 kiyohara } 427 1.2 kiyohara 428 1.2 kiyohara return i; 429 1.2 kiyohara } 430