1 /* $OpenBSD: dwmmc.c,v 1.29 2023/07/01 08:27:26 jsing Exp $ */ 2 /* 3 * Copyright (c) 2017 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/kernel.h> 20 #include <sys/malloc.h> 21 #include <sys/systm.h> 22 23 #include <machine/bus.h> 24 #include <machine/fdt.h> 25 #include <machine/intr.h> 26 27 #include <dev/ofw/openfirm.h> 28 #include <dev/ofw/ofw_clock.h> 29 #include <dev/ofw/ofw_gpio.h> 30 #include <dev/ofw/ofw_pinctrl.h> 31 #include <dev/ofw/fdt.h> 32 33 #include <dev/sdmmc/sdmmcvar.h> 34 #include <dev/sdmmc/sdmmc_ioreg.h> 35 36 #define SDMMC_CTRL 0x0000 37 #define SDMMC_CTRL_USE_INTERNAL_DMAC (1 << 25) 38 #define SDMMC_CTRL_DMA_ENABLE (1 << 5) 39 #define SDMMC_CTRL_INT_ENABLE (1 << 4) 40 #define SDMMC_CTRL_DMA_RESET (1 << 2) 41 #define SDMMC_CTRL_FIFO_RESET (1 << 1) 42 #define SDMMC_CTRL_CONTROLLER_RESET (1 << 0) 43 #define SDMMC_CTRL_ALL_RESET (SDMMC_CTRL_CONTROLLER_RESET | \ 44 SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET) 45 #define SDMMC_PWREN 0x0004 46 #define SDMMC_CLKDIV 0x0008 47 #define SDMMC_CLKSRC 0x000c 48 #define SDMMC_CLKENA 0x0010 49 #define SDMMC_CLKENA_CCLK_LOW_POWER (1 << 16) 50 #define SDMMC_CLKENA_CCLK_ENABLE (1 << 0) 51 #define SDMMC_TMOUT 0x0014 52 #define SDMMC_CTYPE 0x0018 53 #define SDMMC_CTYPE_8BIT (1 << 16) 54 #define SDMMC_CTYPE_4BIT (1 << 0) 55 #define SDMMC_BLKSIZ 0x001c 56 #define SDMMC_BYTCNT 0x0020 57 #define SDMMC_INTMASK 0x0024 58 #define SDMMC_CMDARG 0x0028 59 #define SDMMC_CMD 0x002c 60 #define SDMMC_CMD_START_CMD (1U << 31) 61 #define SDMMC_CMD_USE_HOLD_REG (1 << 29) 62 #define SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY (1 << 21) 63 #define SDMMC_CMD_SEND_INITIALIZATION (1 << 15) 64 #define SDMMC_CMD_STOP_ABORT_CMD (1 << 14) 65 #define SDMMC_CMD_WAIT_PRVDATA_COMPLETE (1 << 13) 66 #define SDMMC_CMD_SEND_AUTO_STOP (1 << 12) 67 #define SDMMC_CMD_WR (1 << 10) 68 #define SDMMC_CMD_DATA_EXPECTED (1 << 9) 69 #define SDMMC_CMD_CHECK_REPONSE_CRC (1 << 8) 70 #define SDMMC_CMD_RESPONSE_LENGTH (1 << 7) 71 #define SDMMC_CMD_RESPONSE_EXPECT (1 << 6) 72 #define SDMMC_RESP0 0x0030 73 #define SDMMC_RESP1 0x0034 74 #define SDMMC_RESP2 0x0038 75 #define SDMMC_RESP3 0x003c 76 #define SDMMC_MINTSTS 0x0040 77 #define SDMMC_RINTSTS 0x0044 78 #define SDMMC_RINTSTS_SDIO (1 << 24) 79 #define SDMMC_RINTSTS_EBE (1 << 15) 80 #define SDMMC_RINTSTS_ACD (1 << 14) 81 #define SDMMC_RINTSTS_SBE (1 << 13) 82 #define SDMMC_RINTSTS_HLE (1 << 12) 83 #define SDMMC_RINTSTS_FRUN (1 << 11) 84 #define SDMMC_RINTSTS_HTO (1 << 10) 85 #define SDMMC_RINTSTS_DRTO (1 << 9) 86 #define SDMMC_RINTSTS_RTO (1 << 8) 87 #define SDMMC_RINTSTS_DCRC (1 << 7) 88 #define SDMMC_RINTSTS_RCRC (1 << 6) 89 #define SDMMC_RINTSTS_RXDR (1 << 5) 90 #define SDMMC_RINTSTS_TXDR (1 << 4) 91 #define SDMMC_RINTSTS_DTO (1 << 3) 92 #define SDMMC_RINTSTS_CD (1 << 2) 93 #define SDMMC_RINTSTS_RE (1 << 1) 94 #define SDMMC_RINTSTS_CDT (1 << 0) 95 #define SDMMC_RINTSTS_DATA_ERR (SDMMC_RINTSTS_EBE | SDMMC_RINTSTS_SBE | \ 96 SDMMC_RINTSTS_HLE | SDMMC_RINTSTS_FRUN | SDMMC_RINTSTS_DCRC) 97 #define SDMMC_RINTSTS_DATA_TO (SDMMC_RINTSTS_HTO | SDMMC_RINTSTS_DRTO) 98 #define SDMMC_STATUS 0x0048 99 #define SDMMC_STATUS_FIFO_COUNT(x) (((x) >> 17) & 0x1fff) 100 #define SDMMC_STATUS_DATA_BUSY (1 << 9) 101 #define SDMMC_FIFOTH 0x004c 102 #define SDMMC_FIFOTH_MSIZE_SHIFT 28 103 #define SDMMC_FIFOTH_RXWM_SHIFT 16 104 #define SDMMC_FIFOTH_RXWM(x) (((x) >> 16) & 0xfff) 105 #define SDMMC_FIFOTH_TXWM_SHIFT 0 106 #define SDMMC_CDETECT 0x0050 107 #define SDMMC_CDETECT_CARD_DETECT_0 (1 << 0) 108 #define SDMMC_WRTPRT 0x0054 109 #define SDMMC_TCBCNT 0x005c 110 #define SDMMC_TBBCNT 0x0060 111 #define SDMMC_DEBNCE 0x0064 112 #define SDMMC_USRID 0x0068 113 #define SDMMC_VERID 0x006c 114 #define SDMMC_HCON 0x0070 115 #define SDMMC_HCON_DATA_WIDTH(x) (((x) >> 7) & 0x7) 116 #define SDMMC_HCON_DMA64 (1 << 27) 117 #define SDMMC_UHS_REG 0x0074 118 #define SDMMC_RST_n 0x0078 119 #define SDMMC_BMOD 0x0080 120 #define SDMMC_BMOD_DE (1 << 7) 121 #define SDMMC_BMOD_FB (1 << 1) 122 #define SDMMC_BMOD_SWR (1 << 0) 123 #define SDMMC_PLDMND 0x0084 124 #define SDMMC_DBADDR 0x0088 125 #define SDMMC_IDSTS32 0x008c 126 #define SDMMC_IDSTS_NIS (1 << 8) 127 #define SDMMC_IDSTS_RI (1 << 1) 128 #define SDMMC_IDSTS_TI (1 << 0) 129 #define SDMMC_IDINTEN32 0x0090 130 #define SDMMC_IDINTEN_NI (1 << 8) 131 #define SDMMC_IDINTEN_RI (1 << 1) 132 #define SDMMC_IDINTEN_TI (1 << 0) 133 #define SDMMC_DSCADDR 0x0094 134 #define SDMMC_BUFADDR 0x0098 135 #define SDMMC_CLKSEL 0x009c 136 #define SDMMC_CARDTHRCTL 0x0100 137 #define SDMMC_CARDTHRCTL_RDTHR_SHIFT 16 138 #define SDMMC_CARDTHRCTL_RDTHREN (1 << 0) 139 #define SDMMC_BACK_END_POWER 0x0104 140 #define SDMMC_EMMC_DDR_REG 0x0108 141 #define SDMMC_FIFO_BASE 0x0200 142 143 #define SDMMC_DBADDRL 0x0088 144 #define SDMMC_DBADDRH 0x008c 145 #define SDMMC_IDSTS64 0x0090 146 #define SDMMC_IDINTEN64 0x0094 147 #define SDMMC_DSCADDRL 0x0098 148 #define SDMMC_DSCADDRH 0x009c 149 #define SDMMC_BUFADDRL 0x00a0 150 #define SDMMC_BUFADDRH 0x00a4 151 152 #define SDMMC_IDSTS(sc) \ 153 ((sc)->sc_dma64 ? SDMMC_IDSTS64 : SDMMC_IDSTS32) 154 155 #define HREAD4(sc, reg) \ 156 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 157 #define HWRITE4(sc, reg, val) \ 158 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 159 #define HSET4(sc, reg, bits) \ 160 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 161 #define HCLR4(sc, reg, bits) \ 162 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 163 164 struct dwmmc_desc32 { 165 uint32_t des[4]; 166 }; 167 168 struct dwmmc_desc64 { 169 uint32_t des[8]; 170 }; 171 172 #define DWMMC_NDESC (PAGE_SIZE / sizeof(struct dwmmc_desc64)) 173 #define DWMMC_MAXSEGSZ 0x1000 174 175 #define DES0_OWN (1U << 31) 176 #define DES0_CES (1 << 30) 177 #define DES0_ER (1 << 5) 178 #define DES0_CH (1 << 4) 179 #define DES0_FS (1 << 3) 180 #define DES0_LD (1 << 2) 181 #define DES0_DIC (1 << 1) 182 183 #define DES1_BS2(sz) (((sz) & 0x1fff) << 13) 184 #define DES1_BS1(sz) (((sz) & 0x1fff) << 0) 185 #define DES2_BS2(sz) DES1_BS2(sz) 186 #define DES2_BS1(sz) DES1_BS1(sz) 187 188 struct dwmmc_softc { 189 struct device sc_dev; 190 bus_space_tag_t sc_iot; 191 bus_space_handle_t sc_ioh; 192 bus_size_t sc_size; 193 bus_dma_tag_t sc_dmat; 194 bus_dmamap_t sc_dmap; 195 int sc_node; 196 197 void *sc_ih; 198 199 uint32_t sc_clkbase; 200 uint32_t sc_fifo_depth; 201 uint32_t sc_fifo_width; 202 void (*sc_read_data)(struct dwmmc_softc *, u_char *, int); 203 void (*sc_write_data)(struct dwmmc_softc *, u_char *, int); 204 int sc_blklen; 205 206 bus_dmamap_t sc_desc_map; 207 bus_dma_segment_t sc_desc_segs[1]; 208 caddr_t sc_desc; 209 int sc_dma64; 210 int sc_dmamode; 211 uint32_t sc_idsts; 212 213 uint32_t sc_gpio[4]; 214 int sc_sdio_irq; 215 uint32_t sc_pwrseq; 216 uint32_t sc_vdd; 217 218 struct device *sc_sdmmc; 219 }; 220 221 int dwmmc_match(struct device *, void *, void *); 222 void dwmmc_attach(struct device *, struct device *, void *); 223 224 const struct cfattach dwmmc_ca = { 225 sizeof(struct dwmmc_softc), dwmmc_match, dwmmc_attach 226 }; 227 228 struct cfdriver dwmmc_cd = { 229 NULL, "dwmmc", DV_DULL 230 }; 231 232 int dwmmc_intr(void *); 233 234 int dwmmc_host_reset(sdmmc_chipset_handle_t); 235 uint32_t dwmmc_host_ocr(sdmmc_chipset_handle_t); 236 int dwmmc_host_maxblklen(sdmmc_chipset_handle_t); 237 int dwmmc_card_detect(sdmmc_chipset_handle_t); 238 int dwmmc_bus_power(sdmmc_chipset_handle_t, uint32_t); 239 int dwmmc_bus_clock(sdmmc_chipset_handle_t, int, int); 240 int dwmmc_bus_width(sdmmc_chipset_handle_t, int); 241 void dwmmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *); 242 void dwmmc_card_intr_mask(sdmmc_chipset_handle_t, int); 243 void dwmmc_card_intr_ack(sdmmc_chipset_handle_t); 244 245 struct sdmmc_chip_functions dwmmc_chip_functions = { 246 .host_reset = dwmmc_host_reset, 247 .host_ocr = dwmmc_host_ocr, 248 .host_maxblklen = dwmmc_host_maxblklen, 249 .card_detect = dwmmc_card_detect, 250 .bus_power = dwmmc_bus_power, 251 .bus_clock = dwmmc_bus_clock, 252 .bus_width = dwmmc_bus_width, 253 .exec_command = dwmmc_exec_command, 254 .card_intr_mask = dwmmc_card_intr_mask, 255 .card_intr_ack = dwmmc_card_intr_ack, 256 }; 257 258 void dwmmc_pio_mode(struct dwmmc_softc *); 259 int dwmmc_alloc_descriptors(struct dwmmc_softc *); 260 void dwmmc_init_descriptors(struct dwmmc_softc *); 261 void dwmmc_transfer_data(struct dwmmc_softc *, struct sdmmc_command *); 262 void dwmmc_read_data32(struct dwmmc_softc *, u_char *, int); 263 void dwmmc_write_data32(struct dwmmc_softc *, u_char *, int); 264 void dwmmc_read_data64(struct dwmmc_softc *, u_char *, int); 265 void dwmmc_write_data64(struct dwmmc_softc *, u_char *, int); 266 void dwmmc_pwrseq_pre(uint32_t); 267 void dwmmc_pwrseq_post(uint32_t); 268 269 int 270 dwmmc_match(struct device *parent, void *match, void *aux) 271 { 272 struct fdt_attach_args *faa = aux; 273 274 return (OF_is_compatible(faa->fa_node, "hisilicon,hi3660-dw-mshc") || 275 OF_is_compatible(faa->fa_node, "hisilicon,hi3670-dw-mshc") || 276 OF_is_compatible(faa->fa_node, "rockchip,rk3288-dw-mshc") || 277 OF_is_compatible(faa->fa_node, "samsung,exynos5420-dw-mshc") || 278 OF_is_compatible(faa->fa_node, "snps,dw-mshc") || 279 OF_is_compatible(faa->fa_node, "starfive,jh7110-mmc")); 280 } 281 282 void 283 dwmmc_attach(struct device *parent, struct device *self, void *aux) 284 { 285 struct dwmmc_softc *sc = (struct dwmmc_softc *)self; 286 struct fdt_attach_args *faa = aux; 287 struct sdmmcbus_attach_args saa; 288 uint32_t freq = 0, div = 0; 289 uint32_t hcon, width; 290 uint32_t fifoth; 291 int error, timeout; 292 293 if (faa->fa_nreg < 1) { 294 printf(": no registers\n"); 295 return; 296 } 297 298 sc->sc_node = faa->fa_node; 299 sc->sc_iot = faa->fa_iot; 300 sc->sc_size = faa->fa_reg[0].size; 301 302 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 303 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 304 printf(": can't map registers\n"); 305 return; 306 } 307 308 pinctrl_byname(faa->fa_node, "default"); 309 310 clock_enable_all(faa->fa_node); 311 reset_deassert_all(faa->fa_node); 312 313 /* 314 * Determine FIFO width from hardware configuration register. 315 * We only support 32-bit and 64-bit FIFOs. 316 */ 317 hcon = HREAD4(sc, SDMMC_HCON); 318 switch (SDMMC_HCON_DATA_WIDTH(hcon)) { 319 case 1: 320 sc->sc_fifo_width = 4; 321 sc->sc_read_data = dwmmc_read_data32; 322 sc->sc_write_data = dwmmc_write_data32; 323 break; 324 case 2: 325 sc->sc_fifo_width = 8; 326 sc->sc_read_data = dwmmc_read_data64; 327 sc->sc_write_data = dwmmc_write_data64; 328 break; 329 default: 330 printf(": unsupported FIFO width\n"); 331 return; 332 } 333 334 sc->sc_fifo_depth = OF_getpropint(faa->fa_node, "fifo-depth", 0); 335 if (sc->sc_fifo_depth == 0) { 336 fifoth = HREAD4(sc, SDMMC_FIFOTH); 337 sc->sc_fifo_depth = SDMMC_FIFOTH_RXWM(fifoth) + 1; 338 } 339 340 if (hcon & SDMMC_HCON_DMA64) 341 sc->sc_dma64 = 1; 342 343 /* Some SoCs pre-divide the clock. */ 344 if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-dw-mshc")) 345 div = 1; 346 if (OF_is_compatible(faa->fa_node, "hisilicon,hi3660-dw-mshc") || 347 OF_is_compatible(faa->fa_node, "hisilicon,hi3670-dw-mshc")) 348 div = 7; 349 350 /* Force the base clock to 50MHz on Rockchip SoCs. */ 351 if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-dw-mshc")) 352 freq = 50000000; 353 354 freq = OF_getpropint(faa->fa_node, "clock-frequency", freq); 355 if (freq > 0) 356 clock_set_frequency(faa->fa_node, "ciu", (div + 1) * freq); 357 358 sc->sc_clkbase = clock_get_frequency(faa->fa_node, "ciu"); 359 /* if ciu clock is missing the rate is clock-frequency */ 360 if (sc->sc_clkbase == 0) 361 sc->sc_clkbase = freq; 362 if (sc->sc_clkbase == 0) { 363 printf(": no clock base\n"); 364 return; 365 } 366 div = OF_getpropint(faa->fa_node, "samsung,dw-mshc-ciu-div", div); 367 sc->sc_clkbase /= (div + 1); 368 369 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_BIO, 370 dwmmc_intr, sc, sc->sc_dev.dv_xname); 371 if (sc->sc_ih == NULL) { 372 printf(": can't establish interrupt\n"); 373 goto unmap; 374 } 375 376 OF_getpropintarray(faa->fa_node, "cd-gpios", sc->sc_gpio, 377 sizeof(sc->sc_gpio)); 378 if (sc->sc_gpio[0]) 379 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT); 380 381 sc->sc_sdio_irq = (OF_getproplen(sc->sc_node, "cap-sdio-irq") == 0); 382 sc->sc_pwrseq = OF_getpropint(sc->sc_node, "mmc-pwrseq", 0); 383 384 printf(": %d MHz base clock\n", sc->sc_clkbase / 1000000); 385 386 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_ALL_RESET); 387 for (timeout = 5000; timeout > 0; timeout--) { 388 if ((HREAD4(sc, SDMMC_CTRL) & SDMMC_CTRL_ALL_RESET) == 0) 389 break; 390 delay(100); 391 } 392 if (timeout == 0) 393 printf("%s: reset failed\n", sc->sc_dev.dv_xname); 394 395 /* Enable interrupts, but mask them all. */ 396 HWRITE4(sc, SDMMC_INTMASK, 0); 397 HWRITE4(sc, SDMMC_RINTSTS, 0xffffffff); 398 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE); 399 400 dwmmc_bus_width(sc, 1); 401 402 /* Start out in non-DMA mode. */ 403 dwmmc_pio_mode(sc); 404 405 sc->sc_dmat = faa->fa_dmat; 406 dwmmc_alloc_descriptors(sc); 407 dwmmc_init_descriptors(sc); 408 409 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, DWMMC_NDESC, 410 DWMMC_MAXSEGSZ, 0, BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW, &sc->sc_dmap); 411 if (error) { 412 printf(": can't create DMA map\n"); 413 goto unmap; 414 } 415 416 memset(&saa, 0, sizeof(saa)); 417 saa.saa_busname = "sdmmc"; 418 saa.sct = &dwmmc_chip_functions; 419 saa.sch = sc; 420 saa.dmat = sc->sc_dmat; 421 saa.dmap = sc->sc_dmap; 422 saa.caps |= SMC_CAPS_DMA; 423 424 if (OF_getproplen(sc->sc_node, "cap-mmc-highspeed") == 0) 425 saa.caps |= SMC_CAPS_MMC_HIGHSPEED; 426 if (OF_getproplen(sc->sc_node, "cap-sd-highspeed") == 0) 427 saa.caps |= SMC_CAPS_SD_HIGHSPEED; 428 429 width = OF_getpropint(faa->fa_node, "bus-width", 1); 430 if (width >= 8) 431 saa.caps |= SMC_CAPS_8BIT_MODE; 432 if (width >= 4) 433 saa.caps |= SMC_CAPS_4BIT_MODE; 434 435 sc->sc_sdmmc = config_found(self, &saa, NULL); 436 return; 437 438 unmap: 439 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); 440 } 441 442 int 443 dwmmc_alloc_descriptors(struct dwmmc_softc *sc) 444 { 445 int error, rseg; 446 447 /* Allocate descriptor memory */ 448 error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 449 PAGE_SIZE, sc->sc_desc_segs, 1, &rseg, 450 BUS_DMA_WAITOK | BUS_DMA_ZERO); 451 if (error) 452 return error; 453 error = bus_dmamem_map(sc->sc_dmat, sc->sc_desc_segs, rseg, 454 PAGE_SIZE, &sc->sc_desc, BUS_DMA_WAITOK | BUS_DMA_COHERENT); 455 if (error) { 456 bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, rseg); 457 return error; 458 } 459 error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 460 0, BUS_DMA_WAITOK, &sc->sc_desc_map); 461 if (error) { 462 bus_dmamem_unmap(sc->sc_dmat, sc->sc_desc, PAGE_SIZE); 463 bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, rseg); 464 return error; 465 } 466 error = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_map, 467 sc->sc_desc, PAGE_SIZE, NULL, BUS_DMA_WAITOK | BUS_DMA_WRITE); 468 if (error) { 469 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_map); 470 bus_dmamem_unmap(sc->sc_dmat, sc->sc_desc, PAGE_SIZE); 471 bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, rseg); 472 return error; 473 } 474 475 return 0; 476 } 477 478 void 479 dwmmc_init_descriptors32(struct dwmmc_softc *sc) 480 { 481 struct dwmmc_desc32 *desc; 482 bus_addr_t addr; 483 int i; 484 485 desc = (void *)sc->sc_desc; 486 addr = sc->sc_desc_map->dm_segs[0].ds_addr; 487 for (i = 0; i < DWMMC_NDESC; i++) { 488 addr += sizeof(struct dwmmc_desc32); 489 desc[i].des[3] = addr; 490 } 491 desc[DWMMC_NDESC - 1].des[3] = sc->sc_desc_map->dm_segs[0].ds_addr; 492 desc[DWMMC_NDESC - 1].des[0] = DES0_ER; 493 bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0, 494 PAGE_SIZE, BUS_DMASYNC_PREWRITE); 495 496 HWRITE4(sc, SDMMC_IDSTS32, 0xffffffff); 497 HWRITE4(sc, SDMMC_IDINTEN32, 498 SDMMC_IDINTEN_NI | SDMMC_IDINTEN_RI | SDMMC_IDINTEN_TI); 499 HWRITE4(sc, SDMMC_DBADDR, sc->sc_desc_map->dm_segs[0].ds_addr); 500 } 501 502 void 503 dwmmc_init_descriptors64(struct dwmmc_softc *sc) 504 { 505 struct dwmmc_desc64 *desc; 506 bus_addr_t addr; 507 int i; 508 509 desc = (void *)sc->sc_desc; 510 addr = sc->sc_desc_map->dm_segs[0].ds_addr; 511 for (i = 0; i < DWMMC_NDESC; i++) { 512 addr += sizeof(struct dwmmc_desc64); 513 desc[i].des[6] = addr; 514 desc[i].des[7] = (uint64_t)addr >> 32; 515 } 516 desc[DWMMC_NDESC - 1].des[6] = sc->sc_desc_map->dm_segs[0].ds_addr; 517 desc[DWMMC_NDESC - 1].des[7] = 518 (uint64_t)sc->sc_desc_map->dm_segs[0].ds_addr >> 32; 519 desc[DWMMC_NDESC - 1].des[0] = DES0_ER; 520 bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0, 521 PAGE_SIZE, BUS_DMASYNC_PREWRITE); 522 523 HWRITE4(sc, SDMMC_IDSTS64, 0xffffffff); 524 HWRITE4(sc, SDMMC_IDINTEN64, 525 SDMMC_IDINTEN_NI | SDMMC_IDINTEN_RI | SDMMC_IDINTEN_TI); 526 HWRITE4(sc, SDMMC_DBADDRL, sc->sc_desc_map->dm_segs[0].ds_addr); 527 HWRITE4(sc, SDMMC_DBADDRH, 528 (uint64_t)sc->sc_desc_map->dm_segs[0].ds_addr >> 32); 529 } 530 531 void 532 dwmmc_init_descriptors(struct dwmmc_softc *sc) 533 { 534 if (sc->sc_dma64) 535 dwmmc_init_descriptors64(sc); 536 else 537 dwmmc_init_descriptors32(sc); 538 } 539 540 int 541 dwmmc_intr(void *arg) 542 { 543 struct dwmmc_softc *sc = arg; 544 uint32_t stat; 545 int handled = 0; 546 547 stat = HREAD4(sc, SDMMC_IDSTS(sc)); 548 if (stat) { 549 HWRITE4(sc, SDMMC_IDSTS(sc), stat); 550 sc->sc_idsts |= stat; 551 wakeup(&sc->sc_idsts); 552 handled = 1; 553 } 554 555 stat = HREAD4(sc, SDMMC_MINTSTS); 556 if (stat & SDMMC_RINTSTS_SDIO) { 557 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_SDIO); 558 HCLR4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO); 559 sdmmc_card_intr(sc->sc_sdmmc); 560 handled = 1; 561 } 562 563 return handled; 564 } 565 566 void 567 dwmmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable) 568 { 569 struct dwmmc_softc *sc = sch; 570 571 if (enable) 572 HSET4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO); 573 else 574 HCLR4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO); 575 } 576 577 void 578 dwmmc_card_intr_ack(sdmmc_chipset_handle_t sch) 579 { 580 struct dwmmc_softc *sc = sch; 581 582 HSET4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO); 583 } 584 585 int 586 dwmmc_host_reset(sdmmc_chipset_handle_t sch) 587 { 588 printf("%s\n", __func__); 589 return 0; 590 } 591 592 uint32_t 593 dwmmc_host_ocr(sdmmc_chipset_handle_t sch) 594 { 595 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; 596 } 597 598 int 599 dwmmc_host_maxblklen(sdmmc_chipset_handle_t sch) 600 { 601 return 512; 602 } 603 604 int 605 dwmmc_card_detect(sdmmc_chipset_handle_t sch) 606 { 607 struct dwmmc_softc *sc = sch; 608 uint32_t cdetect; 609 610 /* XXX treat broken-cd as non-removable */ 611 if (OF_getproplen(sc->sc_node, "non-removable") == 0 || 612 OF_getproplen(sc->sc_node, "broken-cd") == 0) 613 return 1; 614 615 if (sc->sc_gpio[0]) { 616 int inverted, val; 617 618 val = gpio_controller_get_pin(sc->sc_gpio); 619 620 inverted = (OF_getproplen(sc->sc_node, "cd-inverted") == 0); 621 return inverted ? !val : val; 622 } 623 624 cdetect = HREAD4(sc, SDMMC_CDETECT); 625 return !(cdetect & SDMMC_CDETECT_CARD_DETECT_0); 626 } 627 628 int 629 dwmmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 630 { 631 struct dwmmc_softc *sc = sch; 632 uint32_t vdd = 0; 633 634 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) 635 vdd = 3300000; 636 637 if (sc->sc_vdd == 0 && vdd > 0) 638 dwmmc_pwrseq_pre(sc->sc_pwrseq); 639 640 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) 641 HSET4(sc, SDMMC_PWREN, 1); 642 else 643 HCLR4(sc, SDMMC_PWREN, 0); 644 645 if (sc->sc_vdd == 0 && vdd > 0) 646 dwmmc_pwrseq_post(sc->sc_pwrseq); 647 648 sc->sc_vdd = vdd; 649 return 0; 650 } 651 652 int 653 dwmmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing) 654 { 655 struct dwmmc_softc *sc = sch; 656 int div = 0, timeout; 657 uint32_t clkena; 658 659 HWRITE4(sc, SDMMC_CLKENA, 0); 660 HWRITE4(sc, SDMMC_CLKSRC, 0); 661 662 if (freq == 0) 663 return 0; 664 665 if (sc->sc_clkbase / 1000 > freq) { 666 for (div = 1; div < 256; div++) 667 if (sc->sc_clkbase / (2 * 1000 * div) <= freq) 668 break; 669 } 670 HWRITE4(sc, SDMMC_CLKDIV, div); 671 672 /* Update clock. */ 673 HWRITE4(sc, SDMMC_CMD, SDMMC_CMD_START_CMD | 674 SDMMC_CMD_WAIT_PRVDATA_COMPLETE | 675 SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY); 676 for (timeout = 1000; timeout > 0; timeout--) { 677 if ((HREAD4(sc, SDMMC_CMD) & SDMMC_CMD_START_CMD) == 0) 678 break; 679 } 680 if (timeout == 0) { 681 printf("%s: timeout\n", __func__); 682 return ETIMEDOUT; 683 } 684 685 /* Enable clock; low power mode only for memory mode. */ 686 clkena = SDMMC_CLKENA_CCLK_ENABLE; 687 if (!sc->sc_sdio_irq) 688 clkena |= SDMMC_CLKENA_CCLK_LOW_POWER; 689 HWRITE4(sc, SDMMC_CLKENA, clkena); 690 691 /* Update clock again. */ 692 HWRITE4(sc, SDMMC_CMD, SDMMC_CMD_START_CMD | 693 SDMMC_CMD_WAIT_PRVDATA_COMPLETE | 694 SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY); 695 for (timeout = 1000; timeout > 0; timeout--) { 696 if ((HREAD4(sc, SDMMC_CMD) & SDMMC_CMD_START_CMD) == 0) 697 break; 698 } 699 if (timeout == 0) { 700 printf("%s: timeout\n", __func__); 701 return ETIMEDOUT; 702 } 703 704 delay(1000000); 705 706 return 0; 707 } 708 709 int 710 dwmmc_bus_width(sdmmc_chipset_handle_t sch, int width) 711 { 712 struct dwmmc_softc *sc = sch; 713 714 switch (width) { 715 case 1: 716 HCLR4(sc, SDMMC_CTYPE, SDMMC_CTYPE_8BIT|SDMMC_CTYPE_4BIT); 717 break; 718 case 4: 719 HSET4(sc, SDMMC_CTYPE, SDMMC_CTYPE_4BIT); 720 HCLR4(sc, SDMMC_CTYPE, SDMMC_CTYPE_8BIT); 721 break; 722 case 8: 723 HSET4(sc, SDMMC_CTYPE, SDMMC_CTYPE_8BIT); 724 break; 725 default: 726 return EINVAL; 727 } 728 729 return 0; 730 } 731 732 void 733 dwmmc_pio_mode(struct dwmmc_softc *sc) 734 { 735 /* Disable DMA. */ 736 HCLR4(sc, SDMMC_CTRL, SDMMC_CTRL_USE_INTERNAL_DMAC | 737 SDMMC_CTRL_DMA_ENABLE); 738 739 /* Set FIFO thresholds. */ 740 HWRITE4(sc, SDMMC_FIFOTH, 2 << SDMMC_FIFOTH_MSIZE_SHIFT | 741 (sc->sc_fifo_depth / 2 - 1) << SDMMC_FIFOTH_RXWM_SHIFT | 742 (sc->sc_fifo_depth / 2) << SDMMC_FIFOTH_TXWM_SHIFT); 743 744 sc->sc_dmamode = 0; 745 sc->sc_blklen = 0; 746 } 747 748 void 749 dwmmc_dma_mode(struct dwmmc_softc *sc) 750 { 751 int timeout; 752 753 /* Reset DMA. */ 754 HSET4(sc, SDMMC_BMOD, SDMMC_BMOD_SWR); 755 for (timeout = 1000; timeout > 0; timeout--) { 756 if ((HREAD4(sc, SDMMC_BMOD) & SDMMC_BMOD_SWR) == 0) 757 break; 758 delay(100); 759 } 760 if (timeout == 0) 761 printf("%s: DMA reset failed\n", sc->sc_dev.dv_xname); 762 763 /* Enable DMA. */ 764 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_USE_INTERNAL_DMAC | 765 SDMMC_CTRL_DMA_ENABLE); 766 HSET4(sc, SDMMC_BMOD, SDMMC_BMOD_FB | SDMMC_BMOD_DE); 767 768 sc->sc_dmamode = 1; 769 } 770 771 void 772 dwmmc_dma_setup32(struct dwmmc_softc *sc, struct sdmmc_command *cmd) 773 { 774 struct dwmmc_desc32 *desc = (void *)sc->sc_desc; 775 uint32_t flags; 776 int seg; 777 778 flags = DES0_OWN | DES0_FS | DES0_CH | DES0_DIC; 779 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 780 bus_addr_t addr = cmd->c_dmamap->dm_segs[seg].ds_addr; 781 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len; 782 783 if (seg == cmd->c_dmamap->dm_nsegs - 1) { 784 flags |= DES0_LD; 785 flags &= ~DES0_DIC; 786 } 787 788 KASSERT((desc[seg].des[0] & DES0_OWN) == 0); 789 desc[seg].des[0] = flags; 790 desc[seg].des[1] = DES1_BS1(len); 791 desc[seg].des[2] = addr; 792 flags &= ~DES0_FS; 793 } 794 } 795 796 void 797 dwmmc_dma_setup64(struct dwmmc_softc *sc, struct sdmmc_command *cmd) 798 { 799 struct dwmmc_desc64 *desc = (void *)sc->sc_desc; 800 uint32_t flags; 801 int seg; 802 803 flags = DES0_OWN | DES0_FS | DES0_CH | DES0_DIC; 804 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 805 bus_addr_t addr = cmd->c_dmamap->dm_segs[seg].ds_addr; 806 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len; 807 808 if (seg == cmd->c_dmamap->dm_nsegs - 1) { 809 flags |= DES0_LD; 810 flags &= ~DES0_DIC; 811 } 812 813 KASSERT((desc[seg].des[0] & DES0_OWN) == 0); 814 desc[seg].des[0] = flags; 815 desc[seg].des[2] = DES2_BS1(len); 816 desc[seg].des[4] = addr; 817 desc[seg].des[5] = (uint64_t)addr >> 32; 818 flags &= ~DES0_FS; 819 } 820 } 821 822 void 823 dwmmc_dma_setup(struct dwmmc_softc *sc, struct sdmmc_command *cmd) 824 { 825 if (sc->sc_dma64) 826 dwmmc_dma_setup64(sc, cmd); 827 else 828 dwmmc_dma_setup32(sc, cmd); 829 830 bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0, PAGE_SIZE, 831 BUS_DMASYNC_PREWRITE); 832 833 sc->sc_idsts = 0; 834 } 835 836 void 837 dwmmc_dma_reset(struct dwmmc_softc *sc, struct sdmmc_command *cmd) 838 { 839 int timeout; 840 841 /* Reset DMA unit. */ 842 HSET4(sc, SDMMC_BMOD, SDMMC_BMOD_SWR); 843 for (timeout = 1000; timeout > 0; timeout--) { 844 if ((HREAD4(sc, SDMMC_BMOD) & 845 SDMMC_BMOD_SWR) == 0) 846 break; 847 delay(100); 848 } 849 850 dwmmc_pio_mode(sc); 851 852 /* Clear descriptors that were in use, */ 853 memset(sc->sc_desc, 0, PAGE_SIZE); 854 dwmmc_init_descriptors(sc); 855 } 856 857 void 858 dwmmc_fifo_setup(struct dwmmc_softc *sc, int blklen) 859 { 860 int blkdepth = blklen / sc->sc_fifo_width; 861 int txwm = sc->sc_fifo_depth / 2; 862 int rxwm, msize = 0; 863 864 /* 865 * Bursting is only possible of the block size is a multiple of 866 * the FIFO width. 867 */ 868 if (blklen % sc->sc_fifo_width == 0) 869 msize = 7; 870 871 /* Magic to calculate the maximum burst size. */ 872 while (msize > 0) { 873 if (blkdepth % (2 << msize) == 0 && 874 (sc->sc_fifo_depth - txwm) % (2 << msize) == 0) 875 break; 876 msize--; 877 } 878 rxwm = (2 << msize) - 1; 879 880 HWRITE4(sc, SDMMC_FIFOTH, 881 msize << SDMMC_FIFOTH_MSIZE_SHIFT | 882 rxwm << SDMMC_FIFOTH_RXWM_SHIFT | 883 txwm << SDMMC_FIFOTH_TXWM_SHIFT); 884 885 sc->sc_blklen = blklen; 886 } 887 888 void 889 dwmmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 890 { 891 struct dwmmc_softc *sc = sch; 892 uint32_t cmdval = SDMMC_CMD_START_CMD | SDMMC_CMD_USE_HOLD_REG; 893 uint32_t status; 894 int error, timeout; 895 int s; 896 897 #if 0 898 printf("%s: cmd %d arg 0x%x flags 0x%x data %p datalen %d blklen %d\n", 899 sc->sc_dev.dv_xname, cmd->c_opcode, cmd->c_arg, cmd->c_flags, 900 cmd->c_data, cmd->c_datalen, cmd->c_blklen); 901 #endif 902 903 s = splbio(); 904 905 for (timeout = 10000; timeout > 0; timeout--) { 906 status = HREAD4(sc, SDMMC_STATUS); 907 if ((status & SDMMC_STATUS_DATA_BUSY) == 0) 908 break; 909 delay(100); 910 } 911 if (timeout == 0) { 912 printf("%s: timeout on data busy\n", sc->sc_dev.dv_xname); 913 goto done; 914 } 915 916 if (cmd->c_opcode == MMC_STOP_TRANSMISSION) 917 cmdval |= SDMMC_CMD_STOP_ABORT_CMD; 918 else if (cmd->c_opcode != MMC_SEND_STATUS) 919 cmdval |= SDMMC_CMD_WAIT_PRVDATA_COMPLETE; 920 921 if (cmd->c_opcode == 0) 922 cmdval |= SDMMC_CMD_SEND_INITIALIZATION; 923 if (cmd->c_flags & SCF_RSP_PRESENT) 924 cmdval |= SDMMC_CMD_RESPONSE_EXPECT; 925 if (cmd->c_flags & SCF_RSP_136) 926 cmdval |= SDMMC_CMD_RESPONSE_LENGTH; 927 if (cmd->c_flags & SCF_RSP_CRC) 928 cmdval |= SDMMC_CMD_CHECK_REPONSE_CRC; 929 930 if (cmd->c_datalen > 0) { 931 HWRITE4(sc, SDMMC_TMOUT, 0xffffffff); 932 HWRITE4(sc, SDMMC_BYTCNT, cmd->c_datalen); 933 HWRITE4(sc, SDMMC_BLKSIZ, cmd->c_blklen); 934 935 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 936 /* Set card read threshold to the size of a block. */ 937 HWRITE4(sc, SDMMC_CARDTHRCTL, 938 cmd->c_blklen << SDMMC_CARDTHRCTL_RDTHR_SHIFT | 939 SDMMC_CARDTHRCTL_RDTHREN); 940 } 941 942 cmdval |= SDMMC_CMD_DATA_EXPECTED; 943 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) 944 cmdval |= SDMMC_CMD_WR; 945 if (cmd->c_datalen > cmd->c_blklen && 946 cmd->c_opcode != SD_IO_RW_EXTENDED) 947 cmdval |= SDMMC_CMD_SEND_AUTO_STOP; 948 } 949 950 if (cmd->c_datalen > 0 && !cmd->c_dmamap) { 951 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_FIFO_RESET); 952 for (timeout = 1000; timeout > 0; timeout--) { 953 if ((HREAD4(sc, SDMMC_CTRL) & 954 SDMMC_CTRL_FIFO_RESET) == 0) 955 break; 956 delay(100); 957 } 958 if (timeout == 0) 959 printf("%s: FIFO reset failed\n", sc->sc_dev.dv_xname); 960 961 /* Disable DMA if we are switching back to PIO. */ 962 if (sc->sc_dmamode) 963 dwmmc_pio_mode(sc); 964 } 965 966 if (cmd->c_datalen > 0 && cmd->c_dmamap) { 967 dwmmc_dma_setup(sc, cmd); 968 HWRITE4(sc, SDMMC_PLDMND, 1); 969 970 /* Enable DMA if we did PIO before. */ 971 if (!sc->sc_dmamode) 972 dwmmc_dma_mode(sc); 973 974 /* Reconfigure FIFO thresholds if block size changed. */ 975 if (cmd->c_blklen != sc->sc_blklen) 976 dwmmc_fifo_setup(sc, cmd->c_blklen); 977 } 978 979 HWRITE4(sc, SDMMC_RINTSTS, ~SDMMC_RINTSTS_SDIO); 980 981 HWRITE4(sc, SDMMC_CMDARG, cmd->c_arg); 982 HWRITE4(sc, SDMMC_CMD, cmdval | cmd->c_opcode); 983 984 for (timeout = 1000; timeout > 0; timeout--) { 985 status = HREAD4(sc, SDMMC_RINTSTS); 986 if (status & SDMMC_RINTSTS_CD) 987 break; 988 delay(100); 989 } 990 if (timeout == 0 || status & SDMMC_RINTSTS_RTO) { 991 cmd->c_error = ETIMEDOUT; 992 dwmmc_dma_reset(sc, cmd); 993 goto done; 994 } 995 996 if (cmd->c_flags & SCF_RSP_PRESENT) { 997 if (cmd->c_flags & SCF_RSP_136) { 998 cmd->c_resp[0] = HREAD4(sc, SDMMC_RESP0); 999 cmd->c_resp[1] = HREAD4(sc, SDMMC_RESP1); 1000 cmd->c_resp[2] = HREAD4(sc, SDMMC_RESP2); 1001 cmd->c_resp[3] = HREAD4(sc, SDMMC_RESP3); 1002 if (cmd->c_flags & SCF_RSP_CRC) { 1003 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 1004 (cmd->c_resp[1] << 24); 1005 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 1006 (cmd->c_resp[2] << 24); 1007 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 1008 (cmd->c_resp[3] << 24); 1009 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 1010 } 1011 } else { 1012 cmd->c_resp[0] = HREAD4(sc, SDMMC_RESP0); 1013 } 1014 } 1015 1016 if (cmd->c_datalen > 0 && !cmd->c_dmamap) 1017 dwmmc_transfer_data(sc, cmd); 1018 1019 if (cmd->c_datalen > 0 && cmd->c_dmamap) { 1020 while (sc->sc_idsts == 0) { 1021 error = tsleep_nsec(&sc->sc_idsts, PWAIT, "idsts", 1022 SEC_TO_NSEC(1)); 1023 if (error) { 1024 cmd->c_error = error; 1025 dwmmc_dma_reset(sc, cmd); 1026 goto done; 1027 } 1028 } 1029 1030 for (timeout = 10000; timeout > 0; timeout--) { 1031 status = HREAD4(sc, SDMMC_RINTSTS); 1032 if (status & SDMMC_RINTSTS_DTO) 1033 break; 1034 delay(100); 1035 } 1036 if (timeout == 0) { 1037 cmd->c_error = ETIMEDOUT; 1038 dwmmc_dma_reset(sc, cmd); 1039 goto done; 1040 } 1041 } 1042 1043 if (cmdval & SDMMC_CMD_SEND_AUTO_STOP) { 1044 for (timeout = 10000; timeout > 0; timeout--) { 1045 status = HREAD4(sc, SDMMC_RINTSTS); 1046 if (status & SDMMC_RINTSTS_ACD) 1047 break; 1048 delay(10); 1049 } 1050 if (timeout == 0) { 1051 cmd->c_error = ETIMEDOUT; 1052 dwmmc_dma_reset(sc, cmd); 1053 goto done; 1054 } 1055 } 1056 1057 done: 1058 cmd->c_flags |= SCF_ITSDONE; 1059 #if 0 1060 printf("%s: err %d rintsts 0x%x\n", sc->sc_dev.dv_xname, cmd->c_error, 1061 HREAD4(sc, SDMMC_RINTSTS)); 1062 #endif 1063 splx(s); 1064 } 1065 1066 void 1067 dwmmc_transfer_data(struct dwmmc_softc *sc, struct sdmmc_command *cmd) 1068 { 1069 int datalen = cmd->c_datalen; 1070 u_char *datap = cmd->c_data; 1071 uint32_t status; 1072 int count, timeout; 1073 int fifodr = SDMMC_RINTSTS_DTO | SDMMC_RINTSTS_HTO; 1074 1075 if (ISSET(cmd->c_flags, SCF_CMD_READ)) 1076 fifodr |= SDMMC_RINTSTS_RXDR; 1077 else 1078 fifodr |= SDMMC_RINTSTS_TXDR; 1079 1080 while (datalen > 0) { 1081 status = HREAD4(sc, SDMMC_RINTSTS); 1082 if (status & SDMMC_RINTSTS_DATA_ERR) { 1083 cmd->c_error = EIO; 1084 return; 1085 } 1086 if (status & SDMMC_RINTSTS_DRTO) { 1087 cmd->c_error = ETIMEDOUT; 1088 return; 1089 } 1090 1091 for (timeout = 10000; timeout > 0; timeout--) { 1092 status = HREAD4(sc, SDMMC_RINTSTS); 1093 if (status & fifodr) 1094 break; 1095 delay(100); 1096 } 1097 if (timeout == 0) { 1098 cmd->c_error = ETIMEDOUT; 1099 return; 1100 } 1101 1102 count = SDMMC_STATUS_FIFO_COUNT(HREAD4(sc, SDMMC_STATUS)); 1103 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) 1104 count = sc->sc_fifo_depth - count; 1105 1106 count = MIN(datalen, count * sc->sc_fifo_width); 1107 if (ISSET(cmd->c_flags, SCF_CMD_READ)) 1108 sc->sc_read_data(sc, datap, count); 1109 else 1110 sc->sc_write_data(sc, datap, count); 1111 1112 datap += count; 1113 datalen -= count; 1114 } 1115 1116 for (timeout = 10000; timeout > 0; timeout--) { 1117 status = HREAD4(sc, SDMMC_RINTSTS); 1118 if (status & SDMMC_RINTSTS_DTO) 1119 break; 1120 delay(100); 1121 } 1122 if (timeout == 0) 1123 cmd->c_error = ETIMEDOUT; 1124 } 1125 1126 void 1127 dwmmc_read_data32(struct dwmmc_softc *sc, u_char *datap, int datalen) 1128 { 1129 while (datalen > 3) { 1130 *(uint32_t *)datap = HREAD4(sc, SDMMC_FIFO_BASE); 1131 datap += 4; 1132 datalen -= 4; 1133 } 1134 if (datalen > 0) { 1135 uint32_t rv = HREAD4(sc, SDMMC_FIFO_BASE); 1136 do { 1137 *datap++ = rv & 0xff; 1138 rv = rv >> 8; 1139 } while (--datalen > 0); 1140 } 1141 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_RXDR); 1142 } 1143 1144 void 1145 dwmmc_write_data32(struct dwmmc_softc *sc, u_char *datap, int datalen) 1146 { 1147 while (datalen > 3) { 1148 HWRITE4(sc, SDMMC_FIFO_BASE, *((uint32_t *)datap)); 1149 datap += 4; 1150 datalen -= 4; 1151 } 1152 if (datalen > 0) { 1153 uint32_t rv = *datap++; 1154 if (datalen > 1) 1155 rv |= *datap++ << 8; 1156 if (datalen > 2) 1157 rv |= *datap++ << 16; 1158 HWRITE4(sc, SDMMC_FIFO_BASE, rv); 1159 } 1160 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_TXDR); 1161 } 1162 1163 void 1164 dwmmc_read_data64(struct dwmmc_softc *sc, u_char *datap, int datalen) 1165 { 1166 while (datalen > 7) { 1167 *(uint32_t *)datap = HREAD4(sc, SDMMC_FIFO_BASE); 1168 datap += 4; 1169 datalen -= 4; 1170 *(uint32_t *)datap = HREAD4(sc, SDMMC_FIFO_BASE + 4); 1171 datap += 4; 1172 datalen -= 4; 1173 } 1174 if (datalen > 0) { 1175 uint64_t rv = HREAD4(sc, SDMMC_FIFO_BASE) | 1176 ((uint64_t)HREAD4(sc, SDMMC_FIFO_BASE + 4) << 32); 1177 do { 1178 *datap++ = rv & 0xff; 1179 rv = rv >> 8; 1180 } while (--datalen > 0); 1181 } 1182 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_RXDR); 1183 } 1184 1185 void 1186 dwmmc_write_data64(struct dwmmc_softc *sc, u_char *datap, int datalen) 1187 { 1188 while (datalen > 7) { 1189 HWRITE4(sc, SDMMC_FIFO_BASE, *((uint32_t *)datap)); 1190 datap += 4; 1191 datalen -= 4; 1192 HWRITE4(sc, SDMMC_FIFO_BASE + 4, *((uint32_t *)datap)); 1193 datap += 4; 1194 datalen -= 4; 1195 } 1196 if (datalen > 0) { 1197 uint32_t rv = *datap++; 1198 if (datalen > 1) 1199 rv |= *datap++ << 8; 1200 if (datalen > 2) 1201 rv |= *datap++ << 16; 1202 if (datalen > 3) 1203 rv |= *datap++ << 24; 1204 HWRITE4(sc, SDMMC_FIFO_BASE, rv); 1205 if (datalen > 4) 1206 rv = *datap++; 1207 if (datalen > 5) 1208 rv |= *datap++ << 8; 1209 if (datalen > 6) 1210 rv |= *datap++ << 16; 1211 HWRITE4(sc, SDMMC_FIFO_BASE + 4, rv); 1212 } 1213 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_TXDR); 1214 } 1215 1216 void 1217 dwmmc_pwrseq_pre(uint32_t phandle) 1218 { 1219 uint32_t *gpios, *gpio; 1220 int node; 1221 int len; 1222 1223 node = OF_getnodebyphandle(phandle); 1224 if (node == 0) 1225 return; 1226 1227 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1228 return; 1229 1230 pinctrl_byname(node, "default"); 1231 1232 clock_enable(node, "ext_clock"); 1233 1234 len = OF_getproplen(node, "reset-gpios"); 1235 if (len <= 0) 1236 return; 1237 1238 gpios = malloc(len, M_TEMP, M_WAITOK); 1239 OF_getpropintarray(node, "reset-gpios", gpios, len); 1240 1241 gpio = gpios; 1242 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1243 gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT); 1244 gpio_controller_set_pin(gpio, 1); 1245 gpio = gpio_controller_next_pin(gpio); 1246 } 1247 1248 free(gpios, M_TEMP, len); 1249 } 1250 1251 void 1252 dwmmc_pwrseq_post(uint32_t phandle) 1253 { 1254 uint32_t *gpios, *gpio; 1255 int node; 1256 int len; 1257 1258 node = OF_getnodebyphandle(phandle); 1259 if (node == 0) 1260 return; 1261 1262 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1263 return; 1264 1265 len = OF_getproplen(node, "reset-gpios"); 1266 if (len <= 0) 1267 return; 1268 1269 gpios = malloc(len, M_TEMP, M_WAITOK); 1270 OF_getpropintarray(node, "reset-gpios", gpios, len); 1271 1272 gpio = gpios; 1273 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1274 gpio_controller_set_pin(gpio, 0); 1275 gpio = gpio_controller_next_pin(gpio); 1276 } 1277 1278 free(gpios, M_TEMP, len); 1279 } 1280