1 /* $NetBSD: ti_sdhc.c,v 1.5 2019/11/28 23:57:09 jmcneill Exp $ */ 2 /*- 3 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Matt Thomas of 3am Software Foundry. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: ti_sdhc.c,v 1.5 2019/11/28 23:57:09 jmcneill Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/device.h> 37 #include <sys/errno.h> 38 #include <sys/kernel.h> 39 #include <sys/proc.h> 40 #include <sys/queue.h> 41 #include <sys/mutex.h> 42 #include <sys/condvar.h> 43 #include <sys/bus.h> 44 45 #include <arm/ti/ti_prcm.h> 46 #include <arm/ti/ti_edma.h> 47 #include <arm/ti/ti_sdhcreg.h> 48 49 #include <dev/sdmmc/sdhcreg.h> 50 #include <dev/sdmmc/sdhcvar.h> 51 #include <dev/sdmmc/sdmmcvar.h> 52 53 #include <dev/fdt/fdtvar.h> 54 55 #define EDMA_MAX_PARAMS 32 56 57 #ifdef TISDHC_DEBUG 58 int tisdhcdebug = 1; 59 #define DPRINTF(n,s) do { if ((n) <= tisdhcdebug) device_printf s; } while (0) 60 #else 61 #define DPRINTF(n,s) do {} while (0) 62 #endif 63 64 65 #define CLKD(kz) (sc->sc.sc_clkbase / (kz)) 66 67 #define SDHC_READ(sc, reg) \ 68 bus_space_read_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg)) 69 #define SDHC_WRITE(sc, reg, val) \ 70 bus_space_write_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg), (val)) 71 72 struct ti_sdhc_config { 73 bus_size_t regoff; 74 uint32_t flags; 75 }; 76 77 static const struct ti_sdhc_config omap2_hsmmc_config = { 78 }; 79 80 static const struct ti_sdhc_config omap3_pre_es3_hsmmc_config = { 81 .flags = SDHC_FLAG_SINGLE_ONLY 82 }; 83 84 static const struct ti_sdhc_config omap4_hsmmc_config = { 85 .regoff = 0x100 86 }; 87 88 static const struct of_compat_data compat_data[] = { 89 { "ti,omap2-hsmmc", (uintptr_t)&omap2_hsmmc_config }, 90 { "ti,omap3-hsmmc", (uintptr_t)&omap2_hsmmc_config }, 91 { "ti,omap3-pre-es3-hsmmc", (uintptr_t)&omap3_pre_es3_hsmmc_config }, 92 { "ti,omap4-hsmmc", (uintptr_t)&omap4_hsmmc_config }, 93 { NULL } 94 }; 95 96 enum { 97 EDMA_CHAN_TX, 98 EDMA_CHAN_RX, 99 EDMA_NCHAN 100 }; 101 102 struct ti_sdhc_softc { 103 struct sdhc_softc sc; 104 int sc_phandle; 105 bus_addr_t sc_addr; 106 bus_space_tag_t sc_bst; 107 bus_space_handle_t sc_bsh; 108 bus_space_handle_t sc_hl_bsh; 109 bus_space_handle_t sc_sdhc_bsh; 110 struct sdhc_host *sc_hosts[1]; 111 void *sc_ih; /* interrupt vectoring */ 112 113 int sc_edma_chan[EDMA_NCHAN]; 114 struct edma_channel *sc_edma_tx; 115 struct edma_channel *sc_edma_rx; 116 uint16_t sc_edma_param_tx[EDMA_MAX_PARAMS]; 117 uint16_t sc_edma_param_rx[EDMA_MAX_PARAMS]; 118 kcondvar_t sc_edma_cv; 119 bus_addr_t sc_edma_fifo; 120 bool sc_edma_pending; 121 bus_dmamap_t sc_edma_dmamap; 122 bus_dma_segment_t sc_edma_segs[1]; 123 void *sc_edma_bbuf; 124 }; 125 126 static int ti_sdhc_match(device_t, cfdata_t, void *); 127 static void ti_sdhc_attach(device_t, device_t, void *); 128 129 static void ti_sdhc_init(struct ti_sdhc_softc *, const struct ti_sdhc_config *); 130 131 static int ti_sdhc_bus_width(struct sdhc_softc *, int); 132 static int ti_sdhc_rod(struct sdhc_softc *, int); 133 static int ti_sdhc_write_protect(struct sdhc_softc *); 134 static int ti_sdhc_card_detect(struct sdhc_softc *); 135 136 static int ti_sdhc_edma_init(struct ti_sdhc_softc *, u_int, u_int); 137 static int ti_sdhc_edma_xfer_data(struct sdhc_softc *, struct sdmmc_command *); 138 static void ti_sdhc_edma_done(void *); 139 static int ti_sdhc_edma_transfer(struct sdhc_softc *, struct sdmmc_command *); 140 141 CFATTACH_DECL_NEW(ti_sdhc, sizeof(struct ti_sdhc_softc), 142 ti_sdhc_match, ti_sdhc_attach, NULL, NULL); 143 144 static int 145 ti_sdhc_match(device_t parent, cfdata_t cf, void *aux) 146 { 147 struct fdt_attach_args * const faa = aux; 148 149 return of_match_compat_data(faa->faa_phandle, compat_data); 150 } 151 152 static void 153 ti_sdhc_attach(device_t parent, device_t self, void *aux) 154 { 155 struct ti_sdhc_softc * const sc = device_private(self); 156 struct fdt_attach_args * const faa = aux; 157 const int phandle = faa->faa_phandle; 158 const struct ti_sdhc_config *conf; 159 bus_addr_t addr; 160 bus_size_t size; 161 u_int bus_width; 162 163 conf = (const void *)of_search_compatible(phandle, compat_data)->data; 164 165 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 166 aprint_error(": couldn't enable module\n"); 167 return; 168 } 169 170 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0 || size <= conf->regoff) { 171 aprint_error(": couldn't get registers\n"); 172 return; 173 } 174 addr += conf->regoff; 175 size -= conf->regoff; 176 177 sc->sc.sc_dmat = faa->faa_dmat; 178 sc->sc.sc_dev = self; 179 sc->sc_phandle = phandle; 180 sc->sc_addr = addr; 181 sc->sc_bst = faa->faa_bst; 182 183 /* XXX use fdtbus_dma API */ 184 int len; 185 const u_int *dmas = fdtbus_get_prop(phandle, "dmas", &len); 186 switch (len) { 187 case 24: 188 sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]); 189 sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[4]); 190 break; 191 case 32: 192 sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]); 193 sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[5]); 194 break; 195 default: 196 sc->sc_edma_chan[EDMA_CHAN_TX] = -1; 197 sc->sc_edma_chan[EDMA_CHAN_RX] = -1; 198 break; 199 } 200 201 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 202 aprint_error(": couldn't map registers\n"); 203 return; 204 } 205 206 if (of_getprop_uint32(phandle, "bus-width", &bus_width) != 0) 207 bus_width = 4; 208 209 sc->sc.sc_flags |= conf->flags; 210 sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS; 211 sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON; 212 sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC; 213 if (bus_width == 8) 214 sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE; 215 if (of_hasprop(phandle, "ti,needs-special-reset")) 216 sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET; 217 if (!of_hasprop(phandle, "ti,needs-special-hs-handling")) 218 sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT; 219 if (of_hasprop(phandle, "ti,dual-volt")) 220 sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_0V; 221 222 sc->sc.sc_host = sc->sc_hosts; 223 sc->sc.sc_clkbase = 96000; /* 96MHZ */ 224 sc->sc.sc_clkmsk = 0x0000ffc0; 225 sc->sc.sc_vendor_rod = ti_sdhc_rod; 226 sc->sc.sc_vendor_write_protect = ti_sdhc_write_protect; 227 sc->sc.sc_vendor_card_detect = ti_sdhc_card_detect; 228 sc->sc.sc_vendor_bus_width = ti_sdhc_bus_width; 229 230 if (bus_space_subregion(sc->sc_bst, sc->sc_bsh, 0x100, 0x100, 231 &sc->sc_sdhc_bsh) != 0) { 232 aprint_error(": couldn't map subregion\n"); 233 return; 234 } 235 236 aprint_naive("\n"); 237 aprint_normal(": MMCHS\n"); 238 239 ti_sdhc_init(sc, conf); 240 } 241 242 static void 243 ti_sdhc_init(struct ti_sdhc_softc *sc, const struct ti_sdhc_config *conf) 244 { 245 device_t dev = sc->sc.sc_dev; 246 uint32_t clkd, stat; 247 int error, timo, clksft, n; 248 char intrstr[128]; 249 250 const int tx_chan = sc->sc_edma_chan[EDMA_CHAN_TX]; 251 const int rx_chan = sc->sc_edma_chan[EDMA_CHAN_RX]; 252 253 if (tx_chan != -1 && rx_chan != -1) { 254 aprint_normal_dev(dev, 255 "EDMA tx channel %d, rx channel %d\n", 256 tx_chan, rx_chan); 257 258 if (ti_sdhc_edma_init(sc, tx_chan, rx_chan) != 0) { 259 aprint_error_dev(dev, "EDMA disabled\n"); 260 goto no_dma; 261 } 262 263 cv_init(&sc->sc_edma_cv, "sdhcedma"); 264 sc->sc_edma_fifo = sc->sc_addr + 0x100 + SDHC_DATA; 265 sc->sc.sc_flags |= SDHC_FLAG_USE_DMA; 266 sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA; 267 sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN; 268 sc->sc.sc_vendor_transfer_data_dma = ti_sdhc_edma_xfer_data; 269 } 270 no_dma: 271 272 /* XXXXXX: Turn-on regulator via I2C. */ 273 /* XXXXXX: And enable ICLOCK/FCLOCK. */ 274 275 SDHC_WRITE(sc, SDHC_CAPABILITIES, 276 SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_1_8V); 277 if (sc->sc.sc_caps & SDHC_VOLTAGE_SUPP_3_0V) 278 SDHC_WRITE(sc, SDHC_CAPABILITIES, 279 SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_3_0V); 280 281 /* MMCHS Soft reset */ 282 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG, 283 SYSCONFIG_SOFTRESET); 284 timo = 3000000; /* XXXX 3 sec. */ 285 while (timo--) { 286 if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) & 287 SYSSTATUS_RESETDONE) 288 break; 289 delay(1); 290 } 291 if (timo == 0) 292 aprint_error_dev(dev, "Soft reset timeout\n"); 293 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG, 294 SYSCONFIG_ENAWAKEUP | 295 #if notyet 296 SYSCONFIG_AUTOIDLE | 297 SYSCONFIG_SIDLEMODE_AUTO | 298 #else 299 SYSCONFIG_SIDLEMODE_IGNORE | 300 #endif 301 SYSCONFIG_CLOCKACTIVITY_FCLK | 302 SYSCONFIG_CLOCKACTIVITY_ICLK); 303 304 if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) { 305 aprint_error_dev(dev, "couldn't decode interrupt\n"); 306 return; 307 } 308 sc->sc_ih = fdtbus_intr_establish(sc->sc_phandle, 0, IPL_VM, 309 0, sdhc_intr, &sc->sc); 310 if (sc->sc_ih == NULL) { 311 aprint_error_dev(dev, "couldn't establish interrupt\n"); 312 return; 313 } 314 aprint_normal_dev(dev, "interrupting on %s\n", intrstr); 315 316 error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh, 0x100); 317 if (error != 0) { 318 aprint_error_dev(dev, "couldn't initialize host, error=%d\n", 319 error); 320 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); 321 return; 322 } 323 324 clksft = ffs(sc->sc.sc_clkmsk) - 1; 325 326 /* Set SDVS 1.8v and DTW 1bit mode */ 327 SDHC_WRITE(sc, SDHC_HOST_CTL, 328 SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8)); 329 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 330 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE | 331 SDHC_SDCLK_ENABLE); 332 SDHC_WRITE(sc, SDHC_HOST_CTL, 333 SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8); 334 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 335 SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft); 336 337 /* 338 * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start 339 * from 'OMAP35x Applications Processor Technical Reference Manual'. 340 * 341 * During the INIT procedure, the MMCHS controller generates 80 clock 342 * periods. In order to keep the 1ms gap, the MMCHS controller should 343 * be configured to generate a clock whose frequency is smaller or 344 * equal to 80 KHz. 345 */ 346 347 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 348 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE); 349 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 350 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk); 351 clkd = CLKD(80); 352 n = 1; 353 while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) { 354 clkd >>= 1; 355 n <<= 1; 356 } 357 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 358 SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft)); 359 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 360 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE); 361 362 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, 363 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT); 364 SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000); 365 delay(1000); 366 stat = SDHC_READ(sc, SDHC_NINTR_STATUS); 367 SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat | SDHC_COMMAND_COMPLETE); 368 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, 369 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT); 370 SDHC_WRITE(sc, SDHC_NINTR_STATUS, 0xffffffff); 371 372 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 373 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE); 374 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 375 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk); 376 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 377 SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft); 378 timo = 3000000; /* XXXX 3 sec. */ 379 while (--timo) { 380 if (SDHC_READ(sc, SDHC_CLOCK_CTL) & SDHC_INTCLK_STABLE) 381 break; 382 delay(1); 383 } 384 if (timo == 0) 385 aprint_error_dev(dev, "ICS timeout\n"); 386 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 387 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE); 388 389 if (sc->sc.sc_flags & SDHC_FLAG_USE_ADMA2) 390 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, 391 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | 392 CON_MNS); 393 } 394 395 static int 396 ti_sdhc_rod(struct sdhc_softc *sc, int on) 397 { 398 struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc; 399 uint32_t con; 400 401 con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON); 402 if (on) 403 con |= CON_OD; 404 else 405 con &= ~CON_OD; 406 bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con); 407 408 return 0; 409 } 410 411 static int 412 ti_sdhc_write_protect(struct sdhc_softc *sc) 413 { 414 415 /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */ 416 return 0; /* XXXXXXX */ 417 } 418 419 static int 420 ti_sdhc_card_detect(struct sdhc_softc *sc) 421 { 422 423 /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */ 424 return 1; /* XXXXXXXX */ 425 } 426 427 static int 428 ti_sdhc_bus_width(struct sdhc_softc *sc, int width) 429 { 430 struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc; 431 uint32_t con, hctl; 432 433 con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON); 434 hctl = SDHC_READ(hmsc, SDHC_HOST_CTL); 435 if (width == 8) { 436 con |= CON_DW8; 437 } else if (width == 4) { 438 con &= ~CON_DW8; 439 hctl |= SDHC_4BIT_MODE; 440 } else { 441 con &= ~CON_DW8; 442 hctl &= ~SDHC_4BIT_MODE; 443 } 444 bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con); 445 SDHC_WRITE(hmsc, SDHC_HOST_CTL, hctl); 446 447 return 0; 448 } 449 450 static int 451 ti_sdhc_edma_init(struct ti_sdhc_softc *sc, u_int tx_chan, u_int rx_chan) 452 { 453 int i, error, rseg; 454 455 /* Request tx and rx DMA channels */ 456 sc->sc_edma_tx = edma_channel_alloc(EDMA_TYPE_DMA, tx_chan, 457 ti_sdhc_edma_done, sc); 458 KASSERT(sc->sc_edma_tx != NULL); 459 sc->sc_edma_rx = edma_channel_alloc(EDMA_TYPE_DMA, rx_chan, 460 ti_sdhc_edma_done, sc); 461 KASSERT(sc->sc_edma_rx != NULL); 462 463 /* Allocate some PaRAM pages */ 464 for (i = 0; i < __arraycount(sc->sc_edma_param_tx); i++) { 465 sc->sc_edma_param_tx[i] = edma_param_alloc(sc->sc_edma_tx); 466 KASSERT(sc->sc_edma_param_tx[i] != 0xffff); 467 } 468 for (i = 0; i < __arraycount(sc->sc_edma_param_rx); i++) { 469 sc->sc_edma_param_rx[i] = edma_param_alloc(sc->sc_edma_rx); 470 KASSERT(sc->sc_edma_param_rx[i] != 0xffff); 471 } 472 473 /* Setup bounce buffer */ 474 error = bus_dmamem_alloc(sc->sc.sc_dmat, MAXPHYS, 32, MAXPHYS, 475 sc->sc_edma_segs, 1, &rseg, BUS_DMA_WAITOK); 476 if (error) { 477 aprint_error_dev(sc->sc.sc_dev, 478 "couldn't allocate dmamem: %d\n", error); 479 return error; 480 } 481 KASSERT(rseg == 1); 482 error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_edma_segs, rseg, MAXPHYS, 483 &sc->sc_edma_bbuf, BUS_DMA_WAITOK); 484 if (error) { 485 aprint_error_dev(sc->sc.sc_dev, "couldn't map dmamem: %d\n", 486 error); 487 return error; 488 } 489 error = bus_dmamap_create(sc->sc.sc_dmat, MAXPHYS, 1, MAXPHYS, 0, 490 BUS_DMA_WAITOK, &sc->sc_edma_dmamap); 491 if (error) { 492 aprint_error_dev(sc->sc.sc_dev, "couldn't create dmamap: %d\n", 493 error); 494 return error; 495 } 496 error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_edma_dmamap, 497 sc->sc_edma_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK); 498 if (error) { 499 device_printf(sc->sc.sc_dev, "couldn't load dmamap: %d\n", 500 error); 501 return error; 502 } 503 504 return error; 505 } 506 507 static int 508 ti_sdhc_edma_xfer_data(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd) 509 { 510 struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev); 511 const bus_dmamap_t map = cmd->c_dmamap; 512 bool bounce; 513 int error; 514 515 #if notyet 516 bounce = false; 517 for (int seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 518 if ((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) != 0 || 519 (cmd->c_dmamap->dm_segs[seg].ds_len & 3) != 0) { 520 bounce = true; 521 break; 522 } 523 } 524 #else 525 bounce = true; 526 #endif 527 528 if (bounce) { 529 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 530 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 531 MAXPHYS, BUS_DMASYNC_PREREAD); 532 } else { 533 memcpy(sc->sc_edma_bbuf, cmd->c_data, cmd->c_datalen); 534 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 535 MAXPHYS, BUS_DMASYNC_PREWRITE); 536 } 537 538 cmd->c_dmamap = sc->sc_edma_dmamap; 539 } 540 541 error = ti_sdhc_edma_transfer(sdhc_sc, cmd); 542 543 if (bounce) { 544 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 545 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 546 MAXPHYS, BUS_DMASYNC_POSTREAD); 547 } else { 548 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 549 MAXPHYS, BUS_DMASYNC_POSTWRITE); 550 } 551 if (ISSET(cmd->c_flags, SCF_CMD_READ) && error == 0) { 552 memcpy(cmd->c_data, sc->sc_edma_bbuf, cmd->c_datalen); 553 } 554 555 cmd->c_dmamap = map; 556 } 557 558 return error; 559 } 560 561 static int 562 ti_sdhc_edma_transfer(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd) 563 { 564 struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev); 565 kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]); 566 struct edma_channel *edma; 567 uint16_t *edma_param; 568 struct edma_param ep; 569 size_t seg; 570 int error, resid = cmd->c_datalen; 571 int blksize = MIN(cmd->c_datalen, cmd->c_blklen); 572 573 KASSERT(mutex_owned(plock)); 574 575 edma = ISSET(cmd->c_flags, SCF_CMD_READ) ? 576 sc->sc_edma_rx : sc->sc_edma_tx; 577 edma_param = ISSET(cmd->c_flags, SCF_CMD_READ) ? 578 sc->sc_edma_param_rx : sc->sc_edma_param_tx; 579 580 DPRINTF(1, (sc->sc.sc_dev, "edma xfer: nsegs=%d ch# %d\n", 581 cmd->c_dmamap->dm_nsegs, edma_channel_index(edma))); 582 583 if (cmd->c_dmamap->dm_nsegs > EDMA_MAX_PARAMS) { 584 return ENOMEM; 585 } 586 587 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 588 KASSERT(resid > 0); 589 const int xferlen = uimin(resid, 590 cmd->c_dmamap->dm_segs[seg].ds_len); 591 KASSERT(xferlen == cmd->c_dmamap->dm_segs[seg].ds_len || 592 seg == cmd->c_dmamap->dm_nsegs - 1); 593 resid -= xferlen; 594 KASSERT((xferlen & 0x3) == 0); 595 ep.ep_opt = __SHIFTIN(2, EDMA_PARAM_OPT_FWID) /* 32-bit */; 596 ep.ep_opt |= __SHIFTIN(edma_channel_index(edma), 597 EDMA_PARAM_OPT_TCC); 598 if (seg == cmd->c_dmamap->dm_nsegs - 1) { 599 ep.ep_opt |= EDMA_PARAM_OPT_TCINTEN; 600 ep.ep_link = 0xffff; 601 } else { 602 ep.ep_link = EDMA_PARAM_BASE(edma_param[seg+1]); 603 } 604 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 605 ep.ep_opt |= EDMA_PARAM_OPT_SAM; 606 ep.ep_src = sc->sc_edma_fifo; 607 ep.ep_dst = cmd->c_dmamap->dm_segs[seg].ds_addr; 608 } else { 609 ep.ep_opt |= EDMA_PARAM_OPT_DAM; 610 ep.ep_src = cmd->c_dmamap->dm_segs[seg].ds_addr; 611 ep.ep_dst = sc->sc_edma_fifo; 612 } 613 614 KASSERT(xferlen <= 65536 * 4); 615 616 /* 617 * In constant addressing mode, the address must be aligned 618 * to 256-bits. 619 */ 620 KASSERT((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) == 0); 621 622 /* 623 * For unknown reason, the A-DMA transfers never completes for 624 * transfers larger than 64 butes. So use a AB transfer, 625 * with a 64 bytes A len 626 */ 627 ep.ep_bcntrld = 0; /* not used for AB-synchronous mode */ 628 ep.ep_opt |= EDMA_PARAM_OPT_SYNCDIM; 629 ep.ep_acnt = uimin(xferlen, 64); 630 ep.ep_bcnt = uimin(xferlen, blksize) / ep.ep_acnt; 631 ep.ep_ccnt = xferlen / (ep.ep_acnt * ep.ep_bcnt); 632 ep.ep_srcbidx = ep.ep_dstbidx = 0; 633 ep.ep_srccidx = ep.ep_dstcidx = 0; 634 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 635 ep.ep_dstbidx = ep.ep_acnt; 636 ep.ep_dstcidx = ep.ep_acnt * ep.ep_bcnt; 637 } else { 638 ep.ep_srcbidx = ep.ep_acnt; 639 ep.ep_srccidx = ep.ep_acnt * ep.ep_bcnt; 640 } 641 642 edma_set_param(edma, edma_param[seg], &ep); 643 #ifdef TISDHC_DEBUG 644 if (tisdhcdebug >= 1) { 645 printf("target OPT: %08x\n", ep.ep_opt); 646 edma_dump_param(edma, edma_param[seg]); 647 } 648 #endif 649 } 650 651 error = 0; 652 sc->sc_edma_pending = true; 653 edma_transfer_enable(edma, edma_param[0]); 654 while (sc->sc_edma_pending) { 655 error = cv_timedwait(&sc->sc_edma_cv, plock, hz*10); 656 if (error == EWOULDBLOCK) { 657 device_printf(sc->sc.sc_dev, "transfer timeout!\n"); 658 edma_dump(edma); 659 edma_dump_param(edma, edma_param[0]); 660 edma_halt(edma); 661 sc->sc_edma_pending = false; 662 error = ETIMEDOUT; 663 break; 664 } 665 } 666 edma_halt(edma); 667 668 return error; 669 } 670 671 static void 672 ti_sdhc_edma_done(void *priv) 673 { 674 struct ti_sdhc_softc *sc = priv; 675 kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]); 676 677 mutex_enter(plock); 678 KASSERT(sc->sc_edma_pending == true); 679 sc->sc_edma_pending = false; 680 cv_broadcast(&sc->sc_edma_cv); 681 mutex_exit(plock); 682 } 683