1 /* $OpenBSD: octdwctwo.c,v 1.12 2019/07/28 12:57:09 visa Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Masao Uebayashi <uebayasi@tombiinc.com> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/device.h> 22 23 #include <machine/intr.h> 24 #include <machine/bus.h> 25 #include <machine/octeonreg.h> 26 #include <machine/octeonvar.h> 27 #include <machine/octeon_model.h> 28 29 #include <octeon/dev/iobusvar.h> 30 #include <octeon/dev/octhcireg.h> 31 32 #include <dev/usb/usb.h> 33 #include <dev/usb/usbdi.h> 34 #include <dev/usb/usbdivar.h> 35 36 #include <dev/usb/dwc2/dwc2var.h> 37 #include <dev/usb/dwc2/dwc2.h> 38 #include <dev/usb/dwc2/dwc2_core.h> 39 40 struct octdwctwo_softc { 41 struct dwc2_softc sc_dwc2; 42 43 /* USBN bus space */ 44 bus_space_tag_t sc_bust; 45 bus_space_handle_t sc_regh; 46 bus_space_handle_t sc_regh2; 47 48 void *sc_ih; 49 }; 50 51 int octdwctwo_match(struct device *, void *, void *); 52 void octdwctwo_attach(struct device *, struct device *, 53 void *); 54 int octdwctwo_activate(struct device *, int); 55 int octdwctwo_set_dma_addr(void *, dma_addr_t, int); 56 u_int64_t octdwctwo_reg2_rd(struct octdwctwo_softc *, bus_size_t); 57 void octdwctwo_reg2_wr(struct octdwctwo_softc *, bus_size_t, 58 u_int64_t); 59 void octdwctwo_reg_set(struct octdwctwo_softc *, bus_size_t, 60 u_int64_t); 61 void octdwctwo_reg_clear(struct octdwctwo_softc *, 62 bus_size_t, u_int64_t); 63 u_int32_t octdwctwo_read_4(bus_space_tag_t, bus_space_handle_t, 64 bus_size_t); 65 void octdwctwo_write_4(bus_space_tag_t, bus_space_handle_t, 66 bus_size_t, u_int32_t); 67 68 69 const struct cfattach octdwctwo_ca = { 70 sizeof(struct octdwctwo_softc), octdwctwo_match, octdwctwo_attach, 71 NULL, octdwctwo_activate 72 }; 73 74 struct cfdriver dwctwo_cd = { 75 NULL, "dwctwo", DV_DULL 76 }; 77 78 static struct dwc2_core_params octdwctwo_params = { 79 .otg_cap = 2, 80 .otg_ver = 0, 81 .dma_enable = 1, 82 .dma_desc_enable = 0, 83 .speed = 0, 84 .enable_dynamic_fifo = 1, 85 .en_multiple_tx_fifo = 0, 86 .host_rx_fifo_size = 456, 87 .host_nperio_tx_fifo_size = 912, 88 .host_perio_tx_fifo_size = 256, 89 .max_transfer_size = 65535, 90 .max_packet_count = 511, 91 .host_channels = 8, 92 .phy_type = 1, 93 .phy_utmi_width = 16, 94 .phy_ulpi_ddr = 0, 95 .phy_ulpi_ext_vbus = 0, 96 .i2c_enable = 0, 97 .ulpi_fs_ls = 0, 98 .host_support_fs_ls_low_power = 0, 99 .host_ls_low_power_phy_clk = 0, 100 .ts_dline = 0, 101 .reload_ctl = 0, 102 .ahbcfg = 0x7, 103 .uframe_sched = 1, 104 }; 105 106 static struct dwc2_core_dma_config octdwctwo_dma_config = { 107 .set_dma_addr = octdwctwo_set_dma_addr, 108 }; 109 110 /* 111 * This bus space tag adjusts register addresses to account for 112 * dwc2 using little endian addressing. dwc2 only does 32bit reads 113 * and writes, so only those functions are provided. 114 */ 115 bus_space_t octdwctwo_tag = { 116 .bus_base = PHYS_TO_XKPHYS(0, CCA_NC), 117 .bus_private = NULL, 118 ._space_read_4 = octdwctwo_read_4, 119 ._space_write_4 = octdwctwo_write_4, 120 ._space_map = iobus_space_map, 121 ._space_unmap = iobus_space_unmap, 122 ._space_subregion = generic_space_region, 123 ._space_vaddr = generic_space_vaddr 124 }; 125 126 int 127 octdwctwo_match(struct device *parent, void *match, void *aux) 128 { 129 int id; 130 131 id = octeon_get_chipid(); 132 switch (octeon_model_family(id)) { 133 case OCTEON_MODEL_FAMILY_CN30XX: 134 case OCTEON_MODEL_FAMILY_CN31XX: 135 case OCTEON_MODEL_FAMILY_CN50XX: 136 return (1); 137 default: 138 return (0); 139 } 140 } 141 142 void 143 octdwctwo_attach(struct device *parent, struct device *self, void *aux) 144 { 145 struct octdwctwo_softc *sc = (struct octdwctwo_softc *)self; 146 struct iobus_attach_args *aa = aux; 147 uint64_t clk; 148 int rc; 149 150 sc->sc_dwc2.sc_iot = &octdwctwo_tag; 151 sc->sc_dwc2.sc_bus.pipe_size = sizeof(struct usbd_pipe); 152 sc->sc_dwc2.sc_bus.dmatag = aa->aa_dmat; 153 sc->sc_dwc2.sc_params = &octdwctwo_params; 154 155 rc = bus_space_map(sc->sc_dwc2.sc_iot, USBC_BASE, USBC_SIZE, 156 0, &sc->sc_dwc2.sc_ioh); 157 KASSERT(rc == 0); 158 159 sc->sc_bust = aa->aa_bust; 160 rc = bus_space_map(sc->sc_bust, USBN_BASE, USBN_SIZE, 161 0, &sc->sc_regh); 162 KASSERT(rc == 0); 163 rc = bus_space_map(sc->sc_bust, USBN_2_BASE, USBN_2_SIZE, 164 0, &sc->sc_regh2); 165 KASSERT(rc == 0); 166 167 /* 168 * Clock setup. 169 */ 170 clk = bus_space_read_8(sc->sc_bust, sc->sc_regh, USBN_CLK_CTL_OFFSET); 171 clk |= USBN_CLK_CTL_POR; 172 clk &= ~(USBN_CLK_CTL_HRST | USBN_CLK_CTL_PRST | USBN_CLK_CTL_HCLK_RST | 173 USBN_CLK_CTL_ENABLE | USBN_CLK_CTL_P_C_SEL | USBN_CLK_CTL_P_RTYPE); 174 clk |= SET_USBN_CLK_CTL_DIVIDE(0x4ULL) 175 | SET_USBN_CLK_CTL_DIVIDE2(0x0ULL); 176 177 bus_space_write_8(sc->sc_bust, sc->sc_regh, USBN_CLK_CTL_OFFSET, clk); 178 bus_space_read_8(sc->sc_bust, sc->sc_regh, USBN_CLK_CTL_OFFSET); 179 180 /* 181 * Reset HCLK and wait for it to stabilize. 182 */ 183 octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_HCLK_RST); 184 delay(64); 185 186 octdwctwo_reg_clear(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_POR); 187 188 /* 189 * Wait for the PHY clock to start. 190 */ 191 delay(1000); 192 193 octdwctwo_reg_set(sc, USBN_USBP_CTL_STATUS_OFFSET, 194 USBN_USBP_CTL_STATUS_ATE_RESET); 195 delay(10); 196 197 octdwctwo_reg_clear(sc, USBN_USBP_CTL_STATUS_OFFSET, 198 USBN_USBP_CTL_STATUS_ATE_RESET); 199 octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_PRST); 200 201 /* 202 * Select host mode. 203 */ 204 octdwctwo_reg_clear(sc, USBN_USBP_CTL_STATUS_OFFSET, 205 USBN_USBP_CTL_STATUS_HST_MODE); 206 delay(1); 207 208 octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_HRST); 209 210 /* 211 * Enable clock. 212 */ 213 octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_ENABLE); 214 delay(1); 215 216 strlcpy(sc->sc_dwc2.sc_vendor, "Octeon", sizeof(sc->sc_dwc2.sc_vendor)); 217 218 rc = dwc2_init(&sc->sc_dwc2); 219 if (rc != 0) 220 return; 221 octdwctwo_dma_config.set_dma_addr_data = sc; 222 rc = dwc2_dma_config(&sc->sc_dwc2, &octdwctwo_dma_config); 223 if (rc != 0) 224 return; 225 226 printf("\n"); 227 228 sc->sc_dwc2.sc_child = config_found(&sc->sc_dwc2.sc_bus.bdev, 229 &sc->sc_dwc2.sc_bus, usbctlprint); 230 231 sc->sc_ih = octeon_intr_establish(CIU_INT_USB, IPL_USB | IPL_MPSAFE, 232 dwc2_intr, (void *)&sc->sc_dwc2, sc->sc_dwc2.sc_bus.bdev.dv_xname); 233 KASSERT(sc->sc_ih != NULL); 234 } 235 236 int 237 octdwctwo_activate(struct device *self, int act) 238 { 239 struct octdwctwo_softc *sc = (struct octdwctwo_softc *)self; 240 uint64_t clk; 241 int rv = 0; 242 243 switch (act) { 244 case DVACT_POWERDOWN: 245 /* 246 * Put the controller into reset mode. 247 * It appears necessary to hold this state for a moment. 248 * Otherwise subsequent attempts to reinitialize the controller 249 * may fail because of hanging or trapping access 250 * of DWC2 core registers. 251 */ 252 clk = bus_space_read_8(sc->sc_bust, sc->sc_regh, 253 USBN_CLK_CTL_OFFSET); 254 clk |= USBN_CLK_CTL_POR; 255 clk |= USBN_CLK_CTL_HCLK_RST; 256 clk |= USBN_CLK_CTL_ENABLE; 257 clk &= ~USBN_CLK_CTL_HRST; 258 clk &= ~USBN_CLK_CTL_PRST; 259 bus_space_write_8(sc->sc_bust, sc->sc_regh, 260 USBN_CLK_CTL_OFFSET, clk); 261 (void)bus_space_read_8(sc->sc_bust, sc->sc_regh, 262 USBN_CLK_CTL_OFFSET); 263 delay(50000); 264 break; 265 default: 266 break; 267 } 268 return rv; 269 } 270 271 int 272 octdwctwo_set_dma_addr(void *data, dma_addr_t dma_addr, int ch) 273 { 274 struct octdwctwo_softc *sc = data; 275 276 octdwctwo_reg2_wr(sc, 277 USBN_DMA0_INB_CHN0_OFFSET + ch * 0x8, dma_addr); 278 octdwctwo_reg2_wr(sc, 279 USBN_DMA0_OUTB_CHN0_OFFSET + ch * 0x8, dma_addr); 280 return 0; 281 } 282 283 u_int64_t 284 octdwctwo_reg2_rd(struct octdwctwo_softc *sc, bus_size_t offset) 285 { 286 u_int64_t value; 287 288 value = bus_space_read_8(sc->sc_bust, sc->sc_regh2, offset); 289 return value; 290 } 291 292 void 293 octdwctwo_reg2_wr(struct octdwctwo_softc *sc, bus_size_t offset, u_int64_t value) 294 { 295 bus_space_write_8(sc->sc_bust, sc->sc_regh2, offset, value); 296 /* guarantee completion of the store operation on RSL registers*/ 297 bus_space_read_8(sc->sc_bust, sc->sc_regh2, offset); 298 } 299 300 void 301 octdwctwo_reg_set(struct octdwctwo_softc *sc, bus_size_t offset, 302 u_int64_t bits) 303 { 304 u_int64_t value; 305 value = bus_space_read_8(sc->sc_bust, sc->sc_regh, offset); 306 value |= bits; 307 308 bus_space_write_8(sc->sc_bust, sc->sc_regh, offset, value); 309 bus_space_read_8(sc->sc_bust, sc->sc_regh, offset); 310 } 311 312 void 313 octdwctwo_reg_clear(struct octdwctwo_softc *sc, bus_size_t offset, 314 u_int64_t bits) 315 { 316 u_int64_t value; 317 value = bus_space_read_8(sc->sc_bust, sc->sc_regh, offset); 318 value &= ~bits; 319 320 bus_space_write_8(sc->sc_bust, sc->sc_regh, offset, value); 321 bus_space_read_8(sc->sc_bust, sc->sc_regh, offset); 322 } 323 324 u_int32_t 325 octdwctwo_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 326 { 327 return *(volatile u_int32_t *)(h + (o^4)); 328 } 329 330 void 331 octdwctwo_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 332 u_int32_t v) 333 { 334 *(volatile u_int32_t *)(h + (o^4)) = v; 335 } 336