1 /* $NetBSD: sunxi_mmc.c,v 1.50 2026/03/18 06:42:35 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2014-2017 Jared McNeill <jmcneill (at) invisible.ca> 5 * All rights reserved. 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "opt_sunximmc.h" 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: sunxi_mmc.c,v 1.50 2026/03/18 06:42:35 skrll Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/device.h> 37 #include <sys/intr.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/gpio.h> 41 42 #include <dev/sdmmc/sdmmcvar.h> 43 #include <dev/sdmmc/sdmmcchip.h> 44 #include <dev/sdmmc/sdmmc_ioreg.h> 45 46 #include <dev/fdt/fdtvar.h> 47 48 #include <arm/sunxi/sunxi_mmc.h> 49 50 #ifdef SUNXI_MMC_DEBUG 51 static int sunxi_mmc_debug = SUNXI_MMC_DEBUG; 52 #define DPRINTF(dev, fmt, ...) \ 53 do { \ 54 if (sunxi_mmc_debug & __BIT(device_unit(dev))) \ 55 device_printf((dev), fmt, ##__VA_ARGS__); \ 56 } while (0) 57 #else 58 #define DPRINTF(dev, fmt, ...) ((void)0) 59 #endif 60 61 enum sunxi_mmc_timing { 62 SUNXI_MMC_TIMING_400K, 63 SUNXI_MMC_TIMING_25M, 64 SUNXI_MMC_TIMING_50M, 65 SUNXI_MMC_TIMING_50M_DDR, 66 SUNXI_MMC_TIMING_50M_DDR_8BIT, 67 }; 68 69 struct sunxi_mmc_delay { 70 u_int output_phase; 71 u_int sample_phase; 72 }; 73 74 static const struct sunxi_mmc_delay sun7i_mmc_delays[] = { 75 [SUNXI_MMC_TIMING_400K] = { 180, 180 }, 76 [SUNXI_MMC_TIMING_25M] = { 180, 75 }, 77 [SUNXI_MMC_TIMING_50M] = { 90, 120 }, 78 [SUNXI_MMC_TIMING_50M_DDR] = { 60, 120 }, 79 [SUNXI_MMC_TIMING_50M_DDR_8BIT] = { 90, 180 }, 80 }; 81 82 static const struct sunxi_mmc_delay sun9i_mmc_delays[] = { 83 [SUNXI_MMC_TIMING_400K] = { 180, 180 }, 84 [SUNXI_MMC_TIMING_25M] = { 180, 75 }, 85 [SUNXI_MMC_TIMING_50M] = { 150, 120 }, 86 [SUNXI_MMC_TIMING_50M_DDR] = { 54, 36 }, 87 [SUNXI_MMC_TIMING_50M_DDR_8BIT] = { 72, 72 }, 88 }; 89 90 #define SUNXI_MMC_NDESC 64 91 92 struct sunxi_mmc_softc; 93 94 static int sunxi_mmc_match(device_t, cfdata_t, void *); 95 static void sunxi_mmc_attach(device_t, device_t, void *); 96 static void sunxi_mmc_attach_i(device_t); 97 98 static int sunxi_mmc_intr(void *); 99 static int sunxi_mmc_dmabounce_setup(struct sunxi_mmc_softc *); 100 static int sunxi_mmc_idma_setup(struct sunxi_mmc_softc *); 101 static void sunxi_mmc_dma_complete(struct sunxi_mmc_softc *, struct sdmmc_command *); 102 103 static int sunxi_mmc_host_reset(sdmmc_chipset_handle_t); 104 static uint32_t sunxi_mmc_host_ocr(sdmmc_chipset_handle_t); 105 static int sunxi_mmc_host_maxblklen(sdmmc_chipset_handle_t); 106 static int sunxi_mmc_card_detect(sdmmc_chipset_handle_t); 107 static int sunxi_mmc_write_protect(sdmmc_chipset_handle_t); 108 static int sunxi_mmc_bus_power(sdmmc_chipset_handle_t, uint32_t); 109 static int sunxi_mmc_bus_clock(sdmmc_chipset_handle_t, int, bool); 110 static int sunxi_mmc_bus_width(sdmmc_chipset_handle_t, int); 111 static int sunxi_mmc_bus_rod(sdmmc_chipset_handle_t, int); 112 static int sunxi_mmc_signal_voltage(sdmmc_chipset_handle_t, int); 113 static int sunxi_mmc_execute_tuning(sdmmc_chipset_handle_t, int); 114 static void sunxi_mmc_exec_command(sdmmc_chipset_handle_t, 115 struct sdmmc_command *); 116 static void sunxi_mmc_card_enable_intr(sdmmc_chipset_handle_t, int); 117 static void sunxi_mmc_card_intr_ack(sdmmc_chipset_handle_t); 118 119 static struct sdmmc_chip_functions sunxi_mmc_chip_functions = { 120 .host_reset = sunxi_mmc_host_reset, 121 .host_ocr = sunxi_mmc_host_ocr, 122 .host_maxblklen = sunxi_mmc_host_maxblklen, 123 .card_detect = sunxi_mmc_card_detect, 124 .write_protect = sunxi_mmc_write_protect, 125 .bus_power = sunxi_mmc_bus_power, 126 .bus_clock_ddr = sunxi_mmc_bus_clock, 127 .bus_width = sunxi_mmc_bus_width, 128 .bus_rod = sunxi_mmc_bus_rod, 129 .signal_voltage = sunxi_mmc_signal_voltage, 130 .execute_tuning = sunxi_mmc_execute_tuning, 131 .exec_command = sunxi_mmc_exec_command, 132 .card_enable_intr = sunxi_mmc_card_enable_intr, 133 .card_intr_ack = sunxi_mmc_card_intr_ack, 134 }; 135 136 struct sunxi_mmc_config { 137 u_int idma_xferlen; 138 u_int idma_shift; 139 u_int flags; 140 #define SUNXI_MMC_FLAG_CALIB_REG 0x01 141 #define SUNXI_MMC_FLAG_NEW_TIMINGS 0x02 142 #define SUNXI_MMC_FLAG_MASK_DATA0 0x04 143 #define SUNXI_MMC_FLAG_HS200 0x08 144 const struct sunxi_mmc_delay *delays; 145 uint32_t dma_ftrglevel; 146 }; 147 148 struct sunxi_mmc_softc { 149 device_t sc_dev; 150 bus_space_tag_t sc_bst; 151 bus_space_handle_t sc_bsh; 152 bus_dma_tag_t sc_dmat; 153 int sc_phandle; 154 155 void *sc_ih; 156 kmutex_t sc_intr_lock; 157 kcondvar_t sc_intr_cv; 158 159 int sc_mmc_width; 160 int sc_mmc_present; 161 162 u_int sc_max_frequency; 163 164 device_t sc_sdmmc_dev; 165 166 const struct sunxi_mmc_config *sc_config; 167 168 bus_dma_segment_t sc_idma_segs[1]; 169 int sc_idma_nsegs; 170 bus_size_t sc_idma_size; 171 bus_dmamap_t sc_idma_map; 172 int sc_idma_ndesc; 173 void *sc_idma_desc; 174 175 bus_dmamap_t sc_dmabounce_map; 176 void *sc_dmabounce_buf; 177 size_t sc_dmabounce_buflen; 178 179 struct clk *sc_clk_ahb; 180 struct clk *sc_clk_mmc; 181 struct clk *sc_clk_output; 182 struct clk *sc_clk_sample; 183 184 struct fdtbus_reset *sc_rst_ahb; 185 186 struct fdtbus_gpio_pin *sc_gpio_cd; 187 int sc_gpio_cd_inverted; 188 struct fdtbus_gpio_pin *sc_gpio_wp; 189 int sc_gpio_wp_inverted; 190 191 struct fdtbus_regulator *sc_reg_vmmc; 192 struct fdtbus_regulator *sc_reg_vqmmc; 193 194 struct fdtbus_mmc_pwrseq *sc_pwrseq; 195 196 bool sc_non_removable; 197 bool sc_broken_cd; 198 199 uint32_t sc_intr_card; 200 struct sdmmc_command *sc_curcmd; 201 bool sc_wait_dma; 202 bool sc_wait_cmd; 203 bool sc_wait_data; 204 }; 205 206 CFATTACH_DECL_NEW(sunxi_mmc, sizeof(struct sunxi_mmc_softc), 207 sunxi_mmc_match, sunxi_mmc_attach, NULL, NULL); 208 209 #define MMC_WRITE(sc, reg, val) \ 210 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 211 #define MMC_READ(sc, reg) \ 212 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 213 214 static const struct sunxi_mmc_config sun4i_a10_mmc_config = { 215 .idma_xferlen = 0x2000, 216 .dma_ftrglevel = 0x20070008, 217 .delays = NULL, 218 .flags = 0, 219 }; 220 221 static const struct sunxi_mmc_config sun5i_a13_mmc_config = { 222 .idma_xferlen = 0x10000, 223 .dma_ftrglevel = 0x20070008, 224 .delays = NULL, 225 .flags = 0, 226 }; 227 228 static const struct sunxi_mmc_config sun7i_a20_mmc_config = { 229 .idma_xferlen = 0x2000, 230 .dma_ftrglevel = 0x20070008, 231 .delays = sun7i_mmc_delays, 232 .flags = 0, 233 }; 234 235 static const struct sunxi_mmc_config sun8i_a83t_emmc_config = { 236 .idma_xferlen = 0x10000, 237 .dma_ftrglevel = 0x20070008, 238 .delays = NULL, 239 .flags = SUNXI_MMC_FLAG_NEW_TIMINGS, 240 }; 241 242 static const struct sunxi_mmc_config sun9i_a80_mmc_config = { 243 .idma_xferlen = 0x10000, 244 .dma_ftrglevel = 0x200f0010, 245 .delays = sun9i_mmc_delays, 246 .flags = 0, 247 }; 248 249 static const struct sunxi_mmc_config sun20i_d1_mmc_config = { 250 .idma_xferlen = 0x2000, 251 .idma_shift = 2, 252 .dma_ftrglevel = 0x20070008, 253 .delays = NULL, 254 .flags = SUNXI_MMC_FLAG_CALIB_REG | 255 SUNXI_MMC_FLAG_NEW_TIMINGS | 256 SUNXI_MMC_FLAG_MASK_DATA0, 257 }; 258 259 static const struct sunxi_mmc_config sun50i_a64_mmc_config = { 260 .idma_xferlen = 0x10000, 261 .dma_ftrglevel = 0x20070008, 262 .delays = NULL, 263 .flags = SUNXI_MMC_FLAG_CALIB_REG | 264 SUNXI_MMC_FLAG_NEW_TIMINGS | 265 SUNXI_MMC_FLAG_MASK_DATA0, 266 }; 267 268 static const struct sunxi_mmc_config sun50i_a64_emmc_config = { 269 .idma_xferlen = 0x2000, 270 .dma_ftrglevel = 0x20070008, 271 .delays = NULL, 272 .flags = SUNXI_MMC_FLAG_CALIB_REG | 273 SUNXI_MMC_FLAG_NEW_TIMINGS | 274 SUNXI_MMC_FLAG_HS200, 275 }; 276 277 static const struct sunxi_mmc_config sun50i_h6_mmc_config = { 278 .idma_xferlen = 0x10000, 279 .dma_ftrglevel = 0x20070008, 280 .delays = NULL, 281 .flags = SUNXI_MMC_FLAG_CALIB_REG | 282 SUNXI_MMC_FLAG_NEW_TIMINGS | 283 SUNXI_MMC_FLAG_MASK_DATA0, 284 }; 285 286 static const struct sunxi_mmc_config sun50i_h6_emmc_config = { 287 .idma_xferlen = 0x2000, 288 .dma_ftrglevel = 0x20070008, 289 .delays = NULL, 290 .flags = SUNXI_MMC_FLAG_CALIB_REG, 291 }; 292 293 static const struct device_compatible_entry compat_data[] = { 294 { .compat = "allwinner,sun4i-a10-mmc", 295 .data = &sun4i_a10_mmc_config }, 296 { .compat = "allwinner,sun5i-a13-mmc", 297 .data = &sun5i_a13_mmc_config }, 298 { .compat = "allwinner,sun7i-a20-mmc", 299 .data = &sun7i_a20_mmc_config }, 300 { .compat = "allwinner,sun8i-a83t-emmc", 301 .data = &sun8i_a83t_emmc_config }, 302 { .compat = "allwinner,sun9i-a80-mmc", 303 .data = &sun9i_a80_mmc_config }, 304 { .compat = "allwinner,sun20i-d1-mmc", 305 .data = &sun20i_d1_mmc_config }, 306 { .compat = "allwinner,sun50i-a64-mmc", 307 .data = &sun50i_a64_mmc_config }, 308 { .compat = "allwinner,sun50i-a64-emmc", 309 .data = &sun50i_a64_emmc_config }, 310 { .compat = "allwinner,sun50i-h6-mmc", 311 .data = &sun50i_h6_mmc_config }, 312 { .compat = "allwinner,sun50i-h6-emmc", 313 .data = &sun50i_h6_emmc_config }, 314 315 DEVICE_COMPAT_EOL 316 }; 317 318 static int 319 sunxi_mmc_match(device_t parent, cfdata_t cf, void *aux) 320 { 321 struct fdt_attach_args * const faa = aux; 322 323 return of_compatible_match(faa->faa_phandle, compat_data); 324 } 325 326 static void 327 sunxi_mmc_attach(device_t parent, device_t self, void *aux) 328 { 329 struct sunxi_mmc_softc * const sc = device_private(self); 330 struct fdt_attach_args * const faa = aux; 331 const int phandle = faa->faa_phandle; 332 char intrstr[128]; 333 bus_addr_t addr; 334 bus_size_t size; 335 336 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 337 aprint_error(": couldn't get registers\n"); 338 return; 339 } 340 341 sc->sc_clk_ahb = fdtbus_clock_get(phandle, "ahb"); 342 sc->sc_clk_mmc = fdtbus_clock_get(phandle, "mmc"); 343 sc->sc_clk_output = fdtbus_clock_get(phandle, "output"); 344 sc->sc_clk_sample = fdtbus_clock_get(phandle, "sample"); 345 346 #if notyet 347 if (sc->sc_clk_ahb == NULL || sc->sc_clk_mmc == NULL || 348 sc->sc_clk_output == NULL || sc->sc_clk_sample == NULL) { 349 #else 350 if (sc->sc_clk_ahb == NULL || sc->sc_clk_mmc == NULL) { 351 #endif 352 aprint_error(": couldn't get clocks\n"); 353 return; 354 } 355 356 sc->sc_rst_ahb = fdtbus_reset_get(phandle, "ahb"); 357 358 sc->sc_pwrseq = fdtbus_mmc_pwrseq_get(phandle); 359 360 if (clk_enable(sc->sc_clk_ahb) != 0 || 361 clk_enable(sc->sc_clk_mmc) != 0) { 362 aprint_error(": couldn't enable clocks\n"); 363 return; 364 } 365 366 if (sc->sc_rst_ahb != NULL) { 367 if (fdtbus_reset_deassert(sc->sc_rst_ahb) != 0) { 368 aprint_error(": couldn't de-assert resets\n"); 369 return; 370 } 371 } 372 373 sc->sc_dev = self; 374 sc->sc_phandle = phandle; 375 sc->sc_config = of_compatible_lookup(phandle, compat_data)->data; 376 sc->sc_bst = faa->faa_bst; 377 sc->sc_dmat = faa->faa_dmat; 378 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO); 379 cv_init(&sc->sc_intr_cv, "sunximmcirq"); 380 381 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 382 aprint_error(": couldn't map registers\n"); 383 return; 384 } 385 386 sc->sc_reg_vmmc = fdtbus_regulator_acquire(phandle, "vmmc-supply"); 387 if (sc->sc_reg_vmmc != NULL && fdtbus_regulator_enable(sc->sc_reg_vmmc)) { 388 aprint_error(": couldn't enable vmmc-supply\n"); 389 return; 390 } 391 392 aprint_naive("\n"); 393 aprint_normal(": SD/MMC controller\n"); 394 395 sc->sc_reg_vqmmc = fdtbus_regulator_acquire(phandle, "vqmmc-supply"); 396 397 sc->sc_gpio_cd = fdtbus_gpio_acquire(phandle, "cd-gpios", 398 GPIO_PIN_INPUT); 399 sc->sc_gpio_wp = fdtbus_gpio_acquire(phandle, "wp-gpios", 400 GPIO_PIN_INPUT); 401 402 sc->sc_gpio_cd_inverted = of_hasprop(phandle, "cd-inverted") ? 0 : 1; 403 sc->sc_gpio_wp_inverted = of_hasprop(phandle, "wp-inverted") ? 0 : 1; 404 405 sc->sc_non_removable = of_hasprop(phandle, "non-removable"); 406 sc->sc_broken_cd = of_hasprop(phandle, "broken-cd"); 407 408 if (of_getprop_uint32(phandle, "max-frequency", &sc->sc_max_frequency)) 409 sc->sc_max_frequency = 52000000; 410 411 if (sunxi_mmc_dmabounce_setup(sc) != 0 || 412 sunxi_mmc_idma_setup(sc) != 0) { 413 aprint_error_dev(self, "failed to setup DMA\n"); 414 return; 415 } 416 417 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 418 aprint_error_dev(self, "failed to decode interrupt\n"); 419 return; 420 } 421 422 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 423 FDT_INTR_MPSAFE, sunxi_mmc_intr, sc, device_xname(self)); 424 if (sc->sc_ih == NULL) { 425 aprint_error_dev(self, "failed to establish interrupt on %s\n", 426 intrstr); 427 return; 428 } 429 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 430 431 config_interrupts(self, sunxi_mmc_attach_i); 432 } 433 434 static int 435 sunxi_mmc_dmabounce_setup(struct sunxi_mmc_softc *sc) 436 { 437 bus_dma_segment_t ds[1]; 438 int error, rseg; 439 440 sc->sc_dmabounce_buflen = sunxi_mmc_host_maxblklen(sc); 441 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_dmabounce_buflen, 0, 442 sc->sc_dmabounce_buflen, ds, 1, &rseg, BUS_DMA_WAITOK); 443 if (error) 444 return error; 445 error = bus_dmamem_map(sc->sc_dmat, ds, 1, sc->sc_dmabounce_buflen, 446 &sc->sc_dmabounce_buf, BUS_DMA_WAITOK); 447 if (error) 448 goto free; 449 error = bus_dmamap_create(sc->sc_dmat, sc->sc_dmabounce_buflen, 1, 450 sc->sc_dmabounce_buflen, 0, BUS_DMA_WAITOK, &sc->sc_dmabounce_map); 451 if (error) 452 goto unmap; 453 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmabounce_map, 454 sc->sc_dmabounce_buf, sc->sc_dmabounce_buflen, NULL, 455 BUS_DMA_WAITOK); 456 if (error) 457 goto destroy; 458 return 0; 459 460 destroy: 461 bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmabounce_map); 462 unmap: 463 bus_dmamem_unmap(sc->sc_dmat, sc->sc_dmabounce_buf, 464 sc->sc_dmabounce_buflen); 465 free: 466 bus_dmamem_free(sc->sc_dmat, ds, rseg); 467 return error; 468 } 469 470 static int 471 sunxi_mmc_idma_setup(struct sunxi_mmc_softc *sc) 472 { 473 int error; 474 475 sc->sc_idma_ndesc = SUNXI_MMC_NDESC; 476 sc->sc_idma_size = sizeof(struct sunxi_mmc_idma_descriptor) * 477 sc->sc_idma_ndesc; 478 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_idma_size, 0, 479 sc->sc_idma_size, sc->sc_idma_segs, 1, 480 &sc->sc_idma_nsegs, BUS_DMA_WAITOK); 481 if (error) 482 return error; 483 error = bus_dmamem_map(sc->sc_dmat, sc->sc_idma_segs, 484 sc->sc_idma_nsegs, sc->sc_idma_size, 485 &sc->sc_idma_desc, BUS_DMA_WAITOK); 486 if (error) 487 goto free; 488 error = bus_dmamap_create(sc->sc_dmat, sc->sc_idma_size, 1, 489 sc->sc_idma_size, 0, BUS_DMA_WAITOK, &sc->sc_idma_map); 490 if (error) 491 goto unmap; 492 error = bus_dmamap_load(sc->sc_dmat, sc->sc_idma_map, 493 sc->sc_idma_desc, sc->sc_idma_size, NULL, BUS_DMA_WAITOK); 494 if (error) 495 goto destroy; 496 return 0; 497 498 destroy: 499 bus_dmamap_destroy(sc->sc_dmat, sc->sc_idma_map); 500 unmap: 501 bus_dmamem_unmap(sc->sc_dmat, sc->sc_idma_desc, sc->sc_idma_size); 502 free: 503 bus_dmamem_free(sc->sc_dmat, sc->sc_idma_segs, sc->sc_idma_nsegs); 504 return error; 505 } 506 507 static int 508 sunxi_mmc_set_clock(struct sunxi_mmc_softc *sc, u_int freq, bool ddr, bool dbl) 509 { 510 const struct sunxi_mmc_delay *delays; 511 int error, timing = SUNXI_MMC_TIMING_400K; 512 513 if (sc->sc_config->delays) { 514 if (freq <= 400) { 515 timing = SUNXI_MMC_TIMING_400K; 516 } else if (freq <= 25000) { 517 timing = SUNXI_MMC_TIMING_25M; 518 } else if (freq <= 52000) { 519 if (ddr) { 520 timing = sc->sc_mmc_width == 8 ? 521 SUNXI_MMC_TIMING_50M_DDR_8BIT : 522 SUNXI_MMC_TIMING_50M_DDR; 523 } else { 524 timing = SUNXI_MMC_TIMING_50M; 525 } 526 } else 527 return EINVAL; 528 } 529 if (sc->sc_max_frequency) { 530 if (freq * 1000 > sc->sc_max_frequency) 531 return EINVAL; 532 } 533 534 error = clk_set_rate(sc->sc_clk_mmc, (freq * 1000) << dbl); 535 if (error != 0) 536 return error; 537 538 if (sc->sc_config->delays == NULL) 539 return 0; 540 541 delays = &sc->sc_config->delays[timing]; 542 543 if (sc->sc_clk_sample) { 544 error = clk_set_rate(sc->sc_clk_sample, delays->sample_phase); 545 if (error != 0) 546 return error; 547 } 548 if (sc->sc_clk_output) { 549 error = clk_set_rate(sc->sc_clk_output, delays->output_phase); 550 if (error != 0) 551 return error; 552 } 553 554 return 0; 555 } 556 557 static void 558 sunxi_mmc_hw_reset(struct sunxi_mmc_softc *sc) 559 { 560 MMC_WRITE(sc, SUNXI_MMC_HWRST, 0); 561 delay(1000); 562 MMC_WRITE(sc, SUNXI_MMC_HWRST, 1); 563 delay(1000); 564 } 565 566 static void 567 sunxi_mmc_attach_i(device_t self) 568 { 569 struct sunxi_mmc_softc *sc = device_private(self); 570 const u_int flags = sc->sc_config->flags; 571 struct sdmmcbus_attach_args saa; 572 uint32_t width; 573 const bool supports_hs200 = 574 of_hasprop(sc->sc_phandle, "mmc-hs200-1_2v") | 575 of_hasprop(sc->sc_phandle, "mmc-hs200-1_8v"); 576 577 const bool supports_ddr = 578 of_hasprop(sc->sc_phandle, "mmc-ddr-1_2v") | 579 of_hasprop(sc->sc_phandle, "mmc-ddr-1_8v") | 580 of_hasprop(sc->sc_phandle, "mmc-ddr-3_3v"); 581 582 if (sc->sc_pwrseq) 583 fdtbus_mmc_pwrseq_pre_power_on(sc->sc_pwrseq); 584 585 if (of_hasprop(sc->sc_phandle, "cap-mmc-hw-reset")) 586 sunxi_mmc_hw_reset(sc); 587 588 sunxi_mmc_host_reset(sc); 589 sunxi_mmc_bus_width(sc, 1); 590 sunxi_mmc_set_clock(sc, 400, false, false); 591 592 if (sc->sc_pwrseq) 593 fdtbus_mmc_pwrseq_post_power_on(sc->sc_pwrseq); 594 595 if (of_getprop_uint32(sc->sc_phandle, "bus-width", &width) != 0) 596 width = 4; 597 598 memset(&saa, 0, sizeof(saa)); 599 saa.saa_busname = "sdmmc"; 600 saa.saa_sct = &sunxi_mmc_chip_functions; 601 saa.saa_sch = sc; 602 saa.saa_dmat = sc->sc_dmat; 603 saa.saa_clkmin = 400; 604 saa.saa_clkmax = sc->sc_max_frequency / 1000; 605 saa.saa_caps = SMC_CAPS_DMA | 606 SMC_CAPS_MULTI_SEG_DMA | 607 SMC_CAPS_AUTO_STOP | 608 SMC_CAPS_SD_HIGHSPEED | 609 SMC_CAPS_MMC_HIGHSPEED; 610 611 if ((sc->sc_config->delays || (flags & SUNXI_MMC_FLAG_NEW_TIMINGS)) && 612 supports_ddr) 613 saa.saa_caps |= SMC_CAPS_MMC_DDR52; 614 615 if ((flags & SUNXI_MMC_FLAG_HS200) != 0 && supports_hs200) 616 saa.saa_caps |= SMC_CAPS_MMC_HS200; 617 618 if (width == 4) 619 saa.saa_caps |= SMC_CAPS_4BIT_MODE; 620 if (width == 8) 621 saa.saa_caps |= SMC_CAPS_8BIT_MODE; 622 623 if (sc->sc_gpio_cd) 624 saa.saa_caps |= SMC_CAPS_POLL_CARD_DET; 625 626 sc->sc_sdmmc_dev = config_found(self, &saa, NULL, CFARGS_NONE); 627 } 628 629 static int 630 sunxi_mmc_intr(void *priv) 631 { 632 struct sunxi_mmc_softc *sc = priv; 633 struct sdmmc_command *cmd; 634 uint32_t idst, mint, imask; 635 636 mutex_enter(&sc->sc_intr_lock); 637 idst = MMC_READ(sc, SUNXI_MMC_IDST); 638 mint = MMC_READ(sc, SUNXI_MMC_MINT); 639 if (!idst && !mint) { 640 mutex_exit(&sc->sc_intr_lock); 641 return 0; 642 } 643 MMC_WRITE(sc, SUNXI_MMC_IDST, idst); 644 MMC_WRITE(sc, SUNXI_MMC_RINT, mint); 645 646 cmd = sc->sc_curcmd; 647 648 DPRINTF(sc->sc_dev, "mmc intr idst=%08X mint=%08X\n", 649 idst, mint); 650 651 /* Handle SDIO card interrupt */ 652 if ((mint & SUNXI_MMC_INT_SDIO_INT) != 0) { 653 imask = MMC_READ(sc, SUNXI_MMC_IMASK); 654 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask & ~SUNXI_MMC_INT_SDIO_INT); 655 sdmmc_card_intr(sc->sc_sdmmc_dev); 656 } 657 658 /* Error interrupts take priority over command and transfer interrupts */ 659 if (cmd != NULL && (mint & SUNXI_MMC_INT_ERROR) != 0) { 660 imask = MMC_READ(sc, SUNXI_MMC_IMASK); 661 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask & ~SUNXI_MMC_INT_ERROR); 662 if ((mint & SUNXI_MMC_INT_RESP_TIMEOUT) != 0) { 663 cmd->c_error = ETIMEDOUT; 664 /* Wait for command to complete */ 665 sc->sc_wait_data = sc->sc_wait_dma = false; 666 if (cmd->c_opcode != SD_IO_SEND_OP_COND && 667 cmd->c_opcode != SD_IO_RW_DIRECT && 668 !ISSET(cmd->c_flags, SCF_TOUT_OK)) 669 device_printf(sc->sc_dev, "host controller timeout, mint=0x%08x\n", mint); 670 } else { 671 device_printf(sc->sc_dev, "host controller error, mint=0x%08x\n", mint); 672 cmd->c_error = EIO; 673 SET(cmd->c_flags, SCF_ITSDONE); 674 goto done; 675 } 676 } 677 678 if (cmd != NULL && (idst & SUNXI_MMC_IDST_RECEIVE_INT) != 0) { 679 MMC_WRITE(sc, SUNXI_MMC_IDIE, 0); 680 if (sc->sc_wait_dma == false) 681 device_printf(sc->sc_dev, "unexpected DMA receive interrupt\n"); 682 sc->sc_wait_dma = false; 683 } 684 685 if (cmd != NULL && (mint & SUNXI_MMC_INT_CMD_DONE) != 0) { 686 imask = MMC_READ(sc, SUNXI_MMC_IMASK); 687 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask & ~SUNXI_MMC_INT_CMD_DONE); 688 if (sc->sc_wait_cmd == false) 689 device_printf(sc->sc_dev, "unexpected command complete interrupt\n"); 690 sc->sc_wait_cmd = false; 691 } 692 693 const uint32_t dmadone_mask = SUNXI_MMC_INT_AUTO_CMD_DONE|SUNXI_MMC_INT_DATA_OVER; 694 if (cmd != NULL && (mint & dmadone_mask) != 0) { 695 imask = MMC_READ(sc, SUNXI_MMC_IMASK); 696 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask & ~dmadone_mask); 697 if (sc->sc_wait_data == false) 698 device_printf(sc->sc_dev, "unexpected data complete interrupt\n"); 699 sc->sc_wait_data = false; 700 } 701 702 if (cmd != NULL && 703 sc->sc_wait_dma == false && 704 sc->sc_wait_cmd == false && 705 sc->sc_wait_data == false) { 706 SET(cmd->c_flags, SCF_ITSDONE); 707 } 708 709 done: 710 if (cmd != NULL && ISSET(cmd->c_flags, SCF_ITSDONE)) { 711 cv_broadcast(&sc->sc_intr_cv); 712 } 713 714 mutex_exit(&sc->sc_intr_lock); 715 716 return 1; 717 } 718 719 static int 720 sunxi_mmc_host_reset(sdmmc_chipset_handle_t sch) 721 { 722 struct sunxi_mmc_softc *sc = sch; 723 uint32_t gctrl; 724 int retry = 1000; 725 726 DPRINTF(sc->sc_dev, "host reset\n"); 727 728 gctrl = MMC_READ(sc, SUNXI_MMC_GCTRL); 729 gctrl |= SUNXI_MMC_GCTRL_RESET; 730 MMC_WRITE(sc, SUNXI_MMC_GCTRL, gctrl); 731 while (--retry > 0) { 732 if (!(MMC_READ(sc, SUNXI_MMC_GCTRL) & SUNXI_MMC_GCTRL_RESET)) 733 break; 734 delay(100); 735 } 736 737 MMC_WRITE(sc, SUNXI_MMC_TIMEOUT, 0xffffffff); 738 739 MMC_WRITE(sc, SUNXI_MMC_IMASK, 0); 740 741 MMC_WRITE(sc, SUNXI_MMC_RINT, 0xffffffff); 742 743 gctrl = MMC_READ(sc, SUNXI_MMC_GCTRL); 744 gctrl |= SUNXI_MMC_GCTRL_INTEN; 745 gctrl &= ~SUNXI_MMC_GCTRL_WAIT_MEM_ACCESS_DONE; 746 gctrl &= ~SUNXI_MMC_GCTRL_ACCESS_BY_AHB; 747 MMC_WRITE(sc, SUNXI_MMC_GCTRL, gctrl); 748 749 return 0; 750 } 751 752 static uint32_t 753 sunxi_mmc_host_ocr(sdmmc_chipset_handle_t sch) 754 { 755 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS; 756 } 757 758 static int 759 sunxi_mmc_host_maxblklen(sdmmc_chipset_handle_t sch) 760 { 761 return 8192; 762 } 763 764 static int 765 sunxi_mmc_card_detect(sdmmc_chipset_handle_t sch) 766 { 767 struct sunxi_mmc_softc *sc = sch; 768 769 if (sc->sc_non_removable || sc->sc_broken_cd) { 770 /* 771 * Non-removable or broken card detect flag set in 772 * DT, assume always present 773 */ 774 return 1; 775 } else if (sc->sc_gpio_cd != NULL) { 776 /* Use card detect GPIO */ 777 int v = 0, i; 778 for (i = 0; i < 5; i++) { 779 v += (fdtbus_gpio_read(sc->sc_gpio_cd) ^ 780 sc->sc_gpio_cd_inverted); 781 delay(1000); 782 } 783 if (v == 5) 784 sc->sc_mmc_present = 0; 785 else if (v == 0) 786 sc->sc_mmc_present = 1; 787 return sc->sc_mmc_present; 788 } else { 789 /* Use CARD_PRESENT field of SD_STATUS register */ 790 const uint32_t present = MMC_READ(sc, SUNXI_MMC_STATUS) & 791 SUNXI_MMC_STATUS_CARD_PRESENT; 792 return present != 0; 793 } 794 } 795 796 static int 797 sunxi_mmc_write_protect(sdmmc_chipset_handle_t sch) 798 { 799 struct sunxi_mmc_softc *sc = sch; 800 801 if (sc->sc_gpio_wp == NULL) { 802 return 0; /* no write protect pin, assume rw */ 803 } else { 804 return fdtbus_gpio_read(sc->sc_gpio_wp) ^ 805 sc->sc_gpio_wp_inverted; 806 } 807 } 808 809 static int 810 sunxi_mmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 811 { 812 return 0; 813 } 814 815 static int 816 sunxi_mmc_update_clock(struct sunxi_mmc_softc *sc) 817 { 818 uint32_t cmd; 819 int retry; 820 821 DPRINTF(sc->sc_dev, "update clock\n"); 822 823 cmd = SUNXI_MMC_CMD_START | 824 SUNXI_MMC_CMD_UPCLK_ONLY | 825 SUNXI_MMC_CMD_WAIT_PRE_OVER; 826 MMC_WRITE(sc, SUNXI_MMC_CMD, cmd); 827 retry = 100000; 828 while (--retry > 0) { 829 if (!(MMC_READ(sc, SUNXI_MMC_CMD) & SUNXI_MMC_CMD_START)) 830 break; 831 delay(10); 832 } 833 834 if (retry == 0) { 835 aprint_error_dev(sc->sc_dev, "timeout updating clock\n"); 836 DPRINTF(sc->sc_dev, "GCTRL: 0x%08x\n", 837 MMC_READ(sc, SUNXI_MMC_GCTRL)); 838 DPRINTF(sc->sc_dev, "CLKCR: 0x%08x\n", 839 MMC_READ(sc, SUNXI_MMC_CLKCR)); 840 DPRINTF(sc->sc_dev, "TIMEOUT: 0x%08x\n", 841 MMC_READ(sc, SUNXI_MMC_TIMEOUT)); 842 DPRINTF(sc->sc_dev, "WIDTH: 0x%08x\n", 843 MMC_READ(sc, SUNXI_MMC_WIDTH)); 844 DPRINTF(sc->sc_dev, "CMD: 0x%08x\n", 845 MMC_READ(sc, SUNXI_MMC_CMD)); 846 DPRINTF(sc->sc_dev, "MINT: 0x%08x\n", 847 MMC_READ(sc, SUNXI_MMC_MINT)); 848 DPRINTF(sc->sc_dev, "RINT: 0x%08x\n", 849 MMC_READ(sc, SUNXI_MMC_RINT)); 850 DPRINTF(sc->sc_dev, "STATUS: 0x%08x\n", 851 MMC_READ(sc, SUNXI_MMC_STATUS)); 852 return ETIMEDOUT; 853 } 854 855 return 0; 856 } 857 858 static int 859 sunxi_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, bool ddr) 860 { 861 struct sunxi_mmc_softc *sc = sch; 862 uint32_t clkcr, gctrl, ntsr; 863 const u_int flags = sc->sc_config->flags; 864 bool dbl = 0; 865 866 clkcr = MMC_READ(sc, SUNXI_MMC_CLKCR); 867 if (clkcr & SUNXI_MMC_CLKCR_CARDCLKON) { 868 clkcr &= ~SUNXI_MMC_CLKCR_CARDCLKON; 869 if (flags & SUNXI_MMC_CLKCR_MASK_DATA0) 870 clkcr |= SUNXI_MMC_CLKCR_MASK_DATA0; 871 MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr); 872 if (sunxi_mmc_update_clock(sc) != 0) 873 return 1; 874 if (flags & SUNXI_MMC_CLKCR_MASK_DATA0) { 875 clkcr = MMC_READ(sc, SUNXI_MMC_CLKCR); 876 clkcr &= ~SUNXI_MMC_CLKCR_MASK_DATA0; 877 MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr); 878 } 879 } 880 881 if (freq) { 882 /* For 8bits ddr in old timing modes, and all ddr in new 883 * timing modes, the module clock has to be 2x the card clock. 884 */ 885 if (ddr && ((flags & SUNXI_MMC_FLAG_NEW_TIMINGS) || 886 sc->sc_mmc_width == 8)) 887 dbl = 1; 888 889 clkcr &= ~SUNXI_MMC_CLKCR_DIV; 890 clkcr |= __SHIFTIN(dbl, SUNXI_MMC_CLKCR_DIV); 891 MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr); 892 893 if (flags & SUNXI_MMC_FLAG_NEW_TIMINGS) { 894 ntsr = MMC_READ(sc, SUNXI_MMC_NTSR); 895 ntsr |= SUNXI_MMC_NTSR_MODE_SELECT; 896 MMC_WRITE(sc, SUNXI_MMC_NTSR, ntsr); 897 } 898 899 if (flags & SUNXI_MMC_FLAG_CALIB_REG) 900 MMC_WRITE(sc, SUNXI_MMC_SAMP_DL, SUNXI_MMC_SAMP_DL_SW_EN); 901 902 if (sunxi_mmc_update_clock(sc) != 0) 903 return 1; 904 905 gctrl = MMC_READ(sc, SUNXI_MMC_GCTRL); 906 if (ddr) 907 gctrl |= SUNXI_MMC_GCTRL_DDR_MODE; 908 else 909 gctrl &= ~SUNXI_MMC_GCTRL_DDR_MODE; 910 MMC_WRITE(sc, SUNXI_MMC_GCTRL, gctrl); 911 912 if (sunxi_mmc_set_clock(sc, freq, ddr, dbl) != 0) 913 return 1; 914 915 clkcr |= SUNXI_MMC_CLKCR_CARDCLKON; 916 if (flags & SUNXI_MMC_CLKCR_MASK_DATA0) 917 clkcr |= SUNXI_MMC_CLKCR_MASK_DATA0; 918 MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr); 919 if (sunxi_mmc_update_clock(sc) != 0) 920 return 1; 921 if (flags & SUNXI_MMC_CLKCR_MASK_DATA0) { 922 clkcr = MMC_READ(sc, SUNXI_MMC_CLKCR); 923 clkcr &= ~SUNXI_MMC_CLKCR_MASK_DATA0; 924 MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr); 925 } 926 } 927 928 return 0; 929 } 930 931 static int 932 sunxi_mmc_bus_width(sdmmc_chipset_handle_t sch, int width) 933 { 934 struct sunxi_mmc_softc *sc = sch; 935 936 DPRINTF(sc->sc_dev, "width = %d\n", width); 937 938 switch (width) { 939 case 1: 940 MMC_WRITE(sc, SUNXI_MMC_WIDTH, SUNXI_MMC_WIDTH_1); 941 break; 942 case 4: 943 MMC_WRITE(sc, SUNXI_MMC_WIDTH, SUNXI_MMC_WIDTH_4); 944 break; 945 case 8: 946 MMC_WRITE(sc, SUNXI_MMC_WIDTH, SUNXI_MMC_WIDTH_8); 947 break; 948 default: 949 return 1; 950 } 951 952 sc->sc_mmc_width = width; 953 954 return 0; 955 } 956 957 static int 958 sunxi_mmc_bus_rod(sdmmc_chipset_handle_t sch, int on) 959 { 960 return -1; 961 } 962 963 static int 964 sunxi_mmc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage) 965 { 966 struct sunxi_mmc_softc *sc = sch; 967 u_int uvol; 968 int error; 969 970 if (sc->sc_reg_vqmmc == NULL) 971 return 0; 972 973 switch (signal_voltage) { 974 case SDMMC_SIGNAL_VOLTAGE_330: 975 uvol = 3300000; 976 break; 977 case SDMMC_SIGNAL_VOLTAGE_180: 978 uvol = 1800000; 979 break; 980 default: 981 return EINVAL; 982 } 983 984 error = fdtbus_regulator_supports_voltage(sc->sc_reg_vqmmc, uvol, uvol); 985 if (error != 0) 986 return 0; 987 988 error = fdtbus_regulator_set_voltage(sc->sc_reg_vqmmc, uvol, uvol); 989 if (error != 0) 990 return error; 991 992 return fdtbus_regulator_enable(sc->sc_reg_vqmmc); 993 } 994 995 static int 996 sunxi_mmc_execute_tuning(sdmmc_chipset_handle_t sch, int timing) 997 { 998 switch (timing) { 999 case SDMMC_TIMING_MMC_HS200: 1000 break; 1001 default: 1002 return EINVAL; 1003 } 1004 1005 return 0; 1006 } 1007 1008 static int 1009 sunxi_mmc_dma_prepare(struct sunxi_mmc_softc *sc, struct sdmmc_command *cmd) 1010 { 1011 struct sunxi_mmc_idma_descriptor *dma = sc->sc_idma_desc; 1012 bus_addr_t desc_paddr = sc->sc_idma_map->dm_segs[0].ds_addr; 1013 bus_dmamap_t map; 1014 bus_size_t off; 1015 int desc, resid, seg; 1016 uint32_t val; 1017 1018 /* 1019 * If the command includes a dma map use it, otherwise we need to 1020 * bounce. This can happen for SDIO IO_RW_EXTENDED (CMD53) commands. 1021 */ 1022 if (cmd->c_dmamap) { 1023 map = cmd->c_dmamap; 1024 } else { 1025 if (cmd->c_datalen > sc->sc_dmabounce_buflen) 1026 return E2BIG; 1027 map = sc->sc_dmabounce_map; 1028 1029 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 1030 memset(sc->sc_dmabounce_buf, 0, cmd->c_datalen); 1031 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 1032 0, cmd->c_datalen, BUS_DMASYNC_PREREAD); 1033 } else { 1034 memcpy(sc->sc_dmabounce_buf, cmd->c_data, 1035 cmd->c_datalen); 1036 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 1037 0, cmd->c_datalen, BUS_DMASYNC_PREWRITE); 1038 } 1039 } 1040 1041 desc = 0; 1042 for (seg = 0; seg < map->dm_nsegs; seg++) { 1043 bus_addr_t paddr = map->dm_segs[seg].ds_addr; 1044 bus_size_t len = map->dm_segs[seg].ds_len; 1045 resid = uimin(len, cmd->c_resid); 1046 off = 0; 1047 while (resid > 0) { 1048 if (desc == sc->sc_idma_ndesc) 1049 break; 1050 len = uimin(sc->sc_config->idma_xferlen, resid); 1051 dma[desc].dma_buf_size = htole32(len); 1052 dma[desc].dma_buf_addr = htole32((paddr + off) >> sc->sc_config->idma_shift); 1053 dma[desc].dma_config = htole32(SUNXI_MMC_IDMA_CONFIG_CH | 1054 SUNXI_MMC_IDMA_CONFIG_OWN); 1055 cmd->c_resid -= len; 1056 resid -= len; 1057 off += len; 1058 if (desc == 0) { 1059 dma[desc].dma_config |= htole32(SUNXI_MMC_IDMA_CONFIG_FD); 1060 } 1061 if (cmd->c_resid == 0) { 1062 dma[desc].dma_config |= htole32(SUNXI_MMC_IDMA_CONFIG_LD); 1063 dma[desc].dma_config |= htole32(SUNXI_MMC_IDMA_CONFIG_ER); 1064 dma[desc].dma_next = 0; 1065 } else { 1066 dma[desc].dma_config |= 1067 htole32(SUNXI_MMC_IDMA_CONFIG_DIC); 1068 dma[desc].dma_next = htole32(( 1069 desc_paddr + ((desc+1) * 1070 sizeof(struct sunxi_mmc_idma_descriptor))) >> sc->sc_config->idma_shift); 1071 } 1072 ++desc; 1073 } 1074 } 1075 if (desc == sc->sc_idma_ndesc) { 1076 aprint_error_dev(sc->sc_dev, 1077 "not enough descriptors for %d byte transfer! " 1078 "there are %u segments with a max xfer length of %u\n", 1079 cmd->c_datalen, map->dm_nsegs, sc->sc_config->idma_xferlen); 1080 return EIO; 1081 } 1082 1083 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 1084 sc->sc_idma_size, BUS_DMASYNC_PREWRITE); 1085 1086 MMC_WRITE(sc, SUNXI_MMC_DLBA, desc_paddr >> sc->sc_config->idma_shift); 1087 MMC_WRITE(sc, SUNXI_MMC_FTRGLEVEL, sc->sc_config->dma_ftrglevel); 1088 1089 val = MMC_READ(sc, SUNXI_MMC_GCTRL); 1090 val |= SUNXI_MMC_GCTRL_DMAEN; 1091 MMC_WRITE(sc, SUNXI_MMC_GCTRL, val); 1092 val |= SUNXI_MMC_GCTRL_DMARESET; 1093 MMC_WRITE(sc, SUNXI_MMC_GCTRL, val); 1094 1095 MMC_WRITE(sc, SUNXI_MMC_DMAC, SUNXI_MMC_DMAC_SOFTRESET); 1096 if (ISSET(cmd->c_flags, SCF_CMD_READ)) 1097 val = SUNXI_MMC_IDST_RECEIVE_INT; 1098 else 1099 val = 0; 1100 MMC_WRITE(sc, SUNXI_MMC_IDIE, val); 1101 MMC_WRITE(sc, SUNXI_MMC_DMAC, 1102 SUNXI_MMC_DMAC_IDMA_ON|SUNXI_MMC_DMAC_FIX_BURST); 1103 1104 return 0; 1105 } 1106 1107 static void 1108 sunxi_mmc_dma_complete(struct sunxi_mmc_softc *sc, struct sdmmc_command *cmd) 1109 { 1110 MMC_WRITE(sc, SUNXI_MMC_DMAC, 0); 1111 MMC_WRITE(sc, SUNXI_MMC_IDIE, 0); 1112 1113 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 1114 sc->sc_idma_size, BUS_DMASYNC_POSTWRITE); 1115 1116 if (cmd->c_dmamap == NULL) { 1117 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 1118 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 1119 0, cmd->c_datalen, BUS_DMASYNC_POSTREAD); 1120 memcpy(cmd->c_data, sc->sc_dmabounce_buf, 1121 cmd->c_datalen); 1122 } else { 1123 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 1124 0, cmd->c_datalen, BUS_DMASYNC_POSTWRITE); 1125 } 1126 } 1127 } 1128 1129 static void 1130 sunxi_mmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 1131 { 1132 struct sunxi_mmc_softc *sc = sch; 1133 uint32_t cmdval = SUNXI_MMC_CMD_START; 1134 uint32_t imask; 1135 int retry, error; 1136 1137 DPRINTF(sc->sc_dev, 1138 "opcode %d flags 0x%x data %p datalen %d blklen %d\n", 1139 cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen, 1140 cmd->c_blklen); 1141 1142 mutex_enter(&sc->sc_intr_lock); 1143 if (sc->sc_curcmd != NULL) { 1144 device_printf(sc->sc_dev, 1145 "WARNING: driver submitted a command while the controller was busy\n"); 1146 cmd->c_error = EBUSY; 1147 SET(cmd->c_flags, SCF_ITSDONE); 1148 mutex_exit(&sc->sc_intr_lock); 1149 return; 1150 } 1151 sc->sc_curcmd = cmd; 1152 1153 if (cmd->c_opcode == 0) 1154 cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ; 1155 if (cmd->c_flags & SCF_RSP_PRESENT) 1156 cmdval |= SUNXI_MMC_CMD_RSP_EXP; 1157 if (cmd->c_flags & SCF_RSP_136) 1158 cmdval |= SUNXI_MMC_CMD_LONG_RSP; 1159 if (cmd->c_flags & SCF_RSP_CRC) 1160 cmdval |= SUNXI_MMC_CMD_CHECK_RSP_CRC; 1161 1162 imask = SUNXI_MMC_INT_ERROR | SUNXI_MMC_INT_CMD_DONE; 1163 1164 if (cmd->c_datalen > 0) { 1165 unsigned int nblks; 1166 1167 cmdval |= SUNXI_MMC_CMD_DATA_EXP | SUNXI_MMC_CMD_WAIT_PRE_OVER; 1168 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) { 1169 cmdval |= SUNXI_MMC_CMD_WRITE; 1170 } 1171 1172 nblks = cmd->c_datalen / cmd->c_blklen; 1173 if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0) 1174 ++nblks; 1175 1176 if (nblks > 1 && !ISSET(cmd->c_flags, SCF_NO_STOP)) { 1177 cmdval |= SUNXI_MMC_CMD_SEND_AUTO_STOP; 1178 imask |= SUNXI_MMC_INT_AUTO_CMD_DONE; 1179 } else { 1180 imask |= SUNXI_MMC_INT_DATA_OVER; 1181 } 1182 1183 MMC_WRITE(sc, SUNXI_MMC_BLKSZ, cmd->c_blklen); 1184 MMC_WRITE(sc, SUNXI_MMC_BYTECNT, nblks * cmd->c_blklen); 1185 } 1186 1187 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask | sc->sc_intr_card); 1188 MMC_WRITE(sc, SUNXI_MMC_RINT, 0x7fff); 1189 1190 MMC_WRITE(sc, SUNXI_MMC_A12A, 1191 (cmdval & SUNXI_MMC_CMD_SEND_AUTO_STOP) ? 0 : 0xffff); 1192 1193 MMC_WRITE(sc, SUNXI_MMC_ARG, cmd->c_arg); 1194 1195 cmd->c_resid = cmd->c_datalen; 1196 if (cmd->c_resid > 0) { 1197 cmd->c_error = sunxi_mmc_dma_prepare(sc, cmd); 1198 if (cmd->c_error != 0) { 1199 SET(cmd->c_flags, SCF_ITSDONE); 1200 goto done; 1201 } 1202 sc->sc_wait_dma = ISSET(cmd->c_flags, SCF_CMD_READ); 1203 sc->sc_wait_data = true; 1204 } else { 1205 sc->sc_wait_dma = false; 1206 sc->sc_wait_data = false; 1207 } 1208 sc->sc_wait_cmd = true; 1209 1210 DPRINTF(sc->sc_dev, "cmdval = %08x\n", cmdval); 1211 1212 MMC_WRITE(sc, SUNXI_MMC_CMD, cmdval | cmd->c_opcode); 1213 1214 struct bintime timeout = { .sec = 15, .frac = 0 }; 1215 const struct bintime epsilon = { .sec = 1, .frac = 0 }; 1216 while (!ISSET(cmd->c_flags, SCF_ITSDONE)) { 1217 error = cv_timedwaitbt(&sc->sc_intr_cv, 1218 &sc->sc_intr_lock, &timeout, &epsilon); 1219 if (error != 0) { 1220 cmd->c_error = error; 1221 SET(cmd->c_flags, SCF_ITSDONE); 1222 goto done; 1223 } 1224 } 1225 1226 if (cmd->c_error == 0 && cmd->c_datalen > 0) 1227 sunxi_mmc_dma_complete(sc, cmd); 1228 1229 if (cmd->c_flags & SCF_RSP_PRESENT) { 1230 if (cmd->c_flags & SCF_RSP_136) { 1231 cmd->c_resp[0] = MMC_READ(sc, SUNXI_MMC_RESP0); 1232 cmd->c_resp[1] = MMC_READ(sc, SUNXI_MMC_RESP1); 1233 cmd->c_resp[2] = MMC_READ(sc, SUNXI_MMC_RESP2); 1234 cmd->c_resp[3] = MMC_READ(sc, SUNXI_MMC_RESP3); 1235 if (cmd->c_flags & SCF_RSP_CRC) { 1236 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 1237 (cmd->c_resp[1] << 24); 1238 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 1239 (cmd->c_resp[2] << 24); 1240 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 1241 (cmd->c_resp[3] << 24); 1242 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 1243 } 1244 } else { 1245 cmd->c_resp[0] = MMC_READ(sc, SUNXI_MMC_RESP0); 1246 } 1247 } 1248 1249 done: 1250 KASSERT(ISSET(cmd->c_flags, SCF_ITSDONE)); 1251 MMC_WRITE(sc, SUNXI_MMC_IMASK, sc->sc_intr_card); 1252 MMC_WRITE(sc, SUNXI_MMC_RINT, 0x7fff); 1253 MMC_WRITE(sc, SUNXI_MMC_IDST, 0x337); 1254 sc->sc_curcmd = NULL; 1255 mutex_exit(&sc->sc_intr_lock); 1256 1257 if (cmd->c_error) { 1258 DPRINTF(sc->sc_dev, "i/o error %d\n", cmd->c_error); 1259 MMC_WRITE(sc, SUNXI_MMC_GCTRL, 1260 MMC_READ(sc, SUNXI_MMC_GCTRL) | 1261 SUNXI_MMC_GCTRL_DMARESET | SUNXI_MMC_GCTRL_FIFORESET); 1262 for (retry = 0; retry < 1000; retry++) { 1263 if (!(MMC_READ(sc, SUNXI_MMC_GCTRL) & SUNXI_MMC_GCTRL_RESET)) 1264 break; 1265 delay(10); 1266 } 1267 sunxi_mmc_update_clock(sc); 1268 } 1269 1270 MMC_WRITE(sc, SUNXI_MMC_GCTRL, 1271 MMC_READ(sc, SUNXI_MMC_GCTRL) | SUNXI_MMC_GCTRL_FIFORESET); 1272 } 1273 1274 static void 1275 sunxi_mmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 1276 { 1277 struct sunxi_mmc_softc *sc = sch; 1278 uint32_t imask; 1279 1280 mutex_enter(&sc->sc_intr_lock); 1281 imask = MMC_READ(sc, SUNXI_MMC_IMASK); 1282 if (enable) 1283 imask |= SUNXI_MMC_INT_SDIO_INT; 1284 else 1285 imask &= ~SUNXI_MMC_INT_SDIO_INT; 1286 sc->sc_intr_card = imask & SUNXI_MMC_INT_SDIO_INT; 1287 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask); 1288 mutex_exit(&sc->sc_intr_lock); 1289 } 1290 1291 static void 1292 sunxi_mmc_card_intr_ack(sdmmc_chipset_handle_t sch) 1293 { 1294 struct sunxi_mmc_softc *sc = sch; 1295 uint32_t imask; 1296 1297 mutex_enter(&sc->sc_intr_lock); 1298 imask = MMC_READ(sc, SUNXI_MMC_IMASK); 1299 MMC_WRITE(sc, SUNXI_MMC_IMASK, imask | sc->sc_intr_card); 1300 mutex_exit(&sc->sc_intr_lock); 1301 } 1302