dwc_mmc.c revision 1.19
1/* $NetBSD: dwc_mmc.c,v 1.19 2020/01/01 11:21:15 jmcneill Exp $ */ 2 3/*- 4 * Copyright (c) 2014-2017 Jared McNeill <jmcneill@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 <sys/cdefs.h> 30__KERNEL_RCSID(0, "$NetBSD: dwc_mmc.c,v 1.19 2020/01/01 11:21:15 jmcneill Exp $"); 31 32#include <sys/param.h> 33#include <sys/bus.h> 34#include <sys/device.h> 35#include <sys/intr.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38 39#include <dev/sdmmc/sdmmcvar.h> 40#include <dev/sdmmc/sdmmcchip.h> 41#include <dev/sdmmc/sdmmc_ioreg.h> 42 43#include <dev/ic/dwc_mmc_reg.h> 44#include <dev/ic/dwc_mmc_var.h> 45 46#define DWC_MMC_NDESC 64 47 48static int dwc_mmc_host_reset(sdmmc_chipset_handle_t); 49static uint32_t dwc_mmc_host_ocr(sdmmc_chipset_handle_t); 50static int dwc_mmc_host_maxblklen(sdmmc_chipset_handle_t); 51static int dwc_mmc_card_detect(sdmmc_chipset_handle_t); 52static int dwc_mmc_write_protect(sdmmc_chipset_handle_t); 53static int dwc_mmc_bus_power(sdmmc_chipset_handle_t, uint32_t); 54static int dwc_mmc_bus_clock(sdmmc_chipset_handle_t, int); 55static int dwc_mmc_bus_width(sdmmc_chipset_handle_t, int); 56static int dwc_mmc_bus_rod(sdmmc_chipset_handle_t, int); 57static int dwc_mmc_signal_voltage(sdmmc_chipset_handle_t, int); 58static void dwc_mmc_exec_command(sdmmc_chipset_handle_t, 59 struct sdmmc_command *); 60static void dwc_mmc_card_enable_intr(sdmmc_chipset_handle_t, int); 61static void dwc_mmc_card_intr_ack(sdmmc_chipset_handle_t); 62 63static struct sdmmc_chip_functions dwc_mmc_chip_functions = { 64 .host_reset = dwc_mmc_host_reset, 65 .host_ocr = dwc_mmc_host_ocr, 66 .host_maxblklen = dwc_mmc_host_maxblklen, 67 .card_detect = dwc_mmc_card_detect, 68 .write_protect = dwc_mmc_write_protect, 69 .bus_power = dwc_mmc_bus_power, 70 .bus_clock = dwc_mmc_bus_clock, 71 .bus_width = dwc_mmc_bus_width, 72 .bus_rod = dwc_mmc_bus_rod, 73 .signal_voltage = dwc_mmc_signal_voltage, 74 .exec_command = dwc_mmc_exec_command, 75 .card_enable_intr = dwc_mmc_card_enable_intr, 76 .card_intr_ack = dwc_mmc_card_intr_ack, 77}; 78 79#define MMC_WRITE(sc, reg, val) \ 80 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 81#define MMC_READ(sc, reg) \ 82 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 83 84static int 85dwc_mmc_dmabounce_setup(struct dwc_mmc_softc *sc) 86{ 87 bus_dma_segment_t ds[1]; 88 int error, rseg; 89 90 sc->sc_dmabounce_buflen = dwc_mmc_host_maxblklen(sc); 91 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_dmabounce_buflen, 0, 92 sc->sc_dmabounce_buflen, ds, 1, &rseg, BUS_DMA_WAITOK); 93 if (error) 94 return error; 95 error = bus_dmamem_map(sc->sc_dmat, ds, 1, sc->sc_dmabounce_buflen, 96 &sc->sc_dmabounce_buf, BUS_DMA_WAITOK); 97 if (error) 98 goto free; 99 error = bus_dmamap_create(sc->sc_dmat, sc->sc_dmabounce_buflen, 1, 100 sc->sc_dmabounce_buflen, 0, BUS_DMA_WAITOK, &sc->sc_dmabounce_map); 101 if (error) 102 goto unmap; 103 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmabounce_map, 104 sc->sc_dmabounce_buf, sc->sc_dmabounce_buflen, NULL, 105 BUS_DMA_WAITOK); 106 if (error) 107 goto destroy; 108 return 0; 109 110destroy: 111 bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmabounce_map); 112unmap: 113 bus_dmamem_unmap(sc->sc_dmat, sc->sc_dmabounce_buf, 114 sc->sc_dmabounce_buflen); 115free: 116 bus_dmamem_free(sc->sc_dmat, ds, rseg); 117 return error; 118} 119 120static int 121dwc_mmc_idma_setup(struct dwc_mmc_softc *sc) 122{ 123 int error; 124 125 sc->sc_idma_xferlen = 0x1000; 126 127 sc->sc_idma_ndesc = DWC_MMC_NDESC; 128 sc->sc_idma_size = sizeof(struct dwc_mmc_idma_desc) * 129 sc->sc_idma_ndesc; 130 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_idma_size, 8, 131 sc->sc_idma_size, sc->sc_idma_segs, 1, 132 &sc->sc_idma_nsegs, BUS_DMA_WAITOK); 133 if (error) 134 return error; 135 error = bus_dmamem_map(sc->sc_dmat, sc->sc_idma_segs, 136 sc->sc_idma_nsegs, sc->sc_idma_size, 137 &sc->sc_idma_desc, BUS_DMA_WAITOK); 138 if (error) 139 goto free; 140 error = bus_dmamap_create(sc->sc_dmat, sc->sc_idma_size, 1, 141 sc->sc_idma_size, 0, BUS_DMA_WAITOK, &sc->sc_idma_map); 142 if (error) 143 goto unmap; 144 error = bus_dmamap_load(sc->sc_dmat, sc->sc_idma_map, 145 sc->sc_idma_desc, sc->sc_idma_size, NULL, BUS_DMA_WAITOK); 146 if (error) 147 goto destroy; 148 return 0; 149 150destroy: 151 bus_dmamap_destroy(sc->sc_dmat, sc->sc_idma_map); 152unmap: 153 bus_dmamem_unmap(sc->sc_dmat, sc->sc_idma_desc, sc->sc_idma_size); 154free: 155 bus_dmamem_free(sc->sc_dmat, sc->sc_idma_segs, sc->sc_idma_nsegs); 156 return error; 157} 158 159static void 160dwc_mmc_attach_i(device_t self) 161{ 162 struct dwc_mmc_softc *sc = device_private(self); 163 struct sdmmcbus_attach_args saa; 164 165 if (sc->sc_pre_power_on) 166 sc->sc_pre_power_on(sc); 167 168 dwc_mmc_signal_voltage(sc, SDMMC_SIGNAL_VOLTAGE_330); 169 dwc_mmc_host_reset(sc); 170 dwc_mmc_bus_width(sc, 1); 171 172 if (sc->sc_post_power_on) 173 sc->sc_post_power_on(sc); 174 175 memset(&saa, 0, sizeof(saa)); 176 saa.saa_busname = "sdmmc"; 177 saa.saa_sct = &dwc_mmc_chip_functions; 178 saa.saa_sch = sc; 179 saa.saa_clkmin = 400; 180 saa.saa_clkmax = sc->sc_clock_freq / 1000; 181 saa.saa_dmat = sc->sc_dmat; 182 saa.saa_caps = SMC_CAPS_SD_HIGHSPEED | 183 SMC_CAPS_MMC_HIGHSPEED | 184 SMC_CAPS_AUTO_STOP | 185 SMC_CAPS_DMA | 186 SMC_CAPS_MULTI_SEG_DMA; 187 if (sc->sc_bus_width == 8) 188 saa.saa_caps |= SMC_CAPS_8BIT_MODE; 189 else 190 saa.saa_caps |= SMC_CAPS_4BIT_MODE; 191 if (sc->sc_card_detect) 192 saa.saa_caps |= SMC_CAPS_POLL_CARD_DET; 193 194 sc->sc_sdmmc_dev = config_found(self, &saa, NULL); 195} 196 197static void 198dwc_mmc_led(struct dwc_mmc_softc *sc, int on) 199{ 200 if (sc->sc_set_led) 201 sc->sc_set_led(sc, on); 202} 203 204static int 205dwc_mmc_host_reset(sdmmc_chipset_handle_t sch) 206{ 207 struct dwc_mmc_softc *sc = sch; 208 uint32_t fifoth, ctrl; 209 int retry = 1000; 210 211#ifdef DWC_MMC_DEBUG 212 aprint_normal_dev(sc->sc_dev, "host reset\n"); 213#endif 214 215 if (ISSET(sc->sc_flags, DWC_MMC_F_PWREN_INV)) 216 MMC_WRITE(sc, DWC_MMC_PWREN, 0); 217 else 218 MMC_WRITE(sc, DWC_MMC_PWREN, 1); 219 220 ctrl = MMC_READ(sc, DWC_MMC_GCTRL); 221 ctrl &= ~DWC_MMC_GCTRL_USE_INTERNAL_DMAC; 222 MMC_WRITE(sc, DWC_MMC_GCTRL, ctrl); 223 224 MMC_WRITE(sc, DWC_MMC_DMAC, DWC_MMC_DMAC_SOFTRESET); 225 226 MMC_WRITE(sc, DWC_MMC_GCTRL, 227 MMC_READ(sc, DWC_MMC_GCTRL) | DWC_MMC_GCTRL_RESET); 228 while (--retry > 0) { 229 if (!(MMC_READ(sc, DWC_MMC_GCTRL) & DWC_MMC_GCTRL_RESET)) 230 break; 231 delay(100); 232 } 233 234 MMC_WRITE(sc, DWC_MMC_CLKSRC, 0); 235 236 MMC_WRITE(sc, DWC_MMC_TIMEOUT, 0xffffffff); 237 238 MMC_WRITE(sc, DWC_MMC_IMASK, 0); 239 240 MMC_WRITE(sc, DWC_MMC_RINT, 0xffffffff); 241 242 const uint32_t rx_wmark = (sc->sc_fifo_depth / 2) - 1; 243 const uint32_t tx_wmark = sc->sc_fifo_depth / 2; 244 fifoth = __SHIFTIN(DWC_MMC_FIFOTH_DMA_MULTIPLE_TXN_SIZE_16, 245 DWC_MMC_FIFOTH_DMA_MULTIPLE_TXN_SIZE); 246 fifoth |= __SHIFTIN(rx_wmark, DWC_MMC_FIFOTH_RX_WMARK); 247 fifoth |= __SHIFTIN(tx_wmark, DWC_MMC_FIFOTH_TX_WMARK); 248 MMC_WRITE(sc, DWC_MMC_FIFOTH, fifoth); 249 250 MMC_WRITE(sc, DWC_MMC_UHS, 0); 251 252 ctrl = MMC_READ(sc, DWC_MMC_GCTRL); 253 ctrl |= DWC_MMC_GCTRL_INTEN; 254 ctrl |= DWC_MMC_GCTRL_DMAEN; 255 ctrl |= DWC_MMC_GCTRL_SEND_AUTO_STOP_CCSD; 256 ctrl |= DWC_MMC_GCTRL_USE_INTERNAL_DMAC; 257 MMC_WRITE(sc, DWC_MMC_GCTRL, ctrl); 258 259 return 0; 260} 261 262static uint32_t 263dwc_mmc_host_ocr(sdmmc_chipset_handle_t sch) 264{ 265 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS; 266} 267 268static int 269dwc_mmc_host_maxblklen(sdmmc_chipset_handle_t sch) 270{ 271 return 32768; 272} 273 274static int 275dwc_mmc_card_detect(sdmmc_chipset_handle_t sch) 276{ 277 struct dwc_mmc_softc *sc = sch; 278 279 if (!sc->sc_card_detect) 280 return 1; /* no card detect pin, assume present */ 281 282 return sc->sc_card_detect(sc); 283} 284 285static int 286dwc_mmc_write_protect(sdmmc_chipset_handle_t sch) 287{ 288 struct dwc_mmc_softc *sc = sch; 289 290 if (!sc->sc_write_protect) 291 return 0; /* no write protect pin, assume rw */ 292 293 return sc->sc_write_protect(sc); 294} 295 296static int 297dwc_mmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 298{ 299 return 0; 300} 301 302static int 303dwc_mmc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage) 304{ 305 struct dwc_mmc_softc *sc = sch; 306 307 if (sc->sc_signal_voltage == NULL) 308 return 0; 309 310 return sc->sc_signal_voltage(sc, signal_voltage); 311} 312 313static int 314dwc_mmc_update_clock(struct dwc_mmc_softc *sc) 315{ 316 uint32_t cmd; 317 int retry; 318 319#ifdef DWC_MMC_DEBUG 320 aprint_normal_dev(sc->sc_dev, "update clock\n"); 321#endif 322 323 cmd = DWC_MMC_CMD_START | 324 DWC_MMC_CMD_UPCLK_ONLY | 325 DWC_MMC_CMD_WAIT_PRE_OVER; 326 if (ISSET(sc->sc_flags, DWC_MMC_F_USE_HOLD_REG)) 327 cmd |= DWC_MMC_CMD_USE_HOLD_REG; 328 MMC_WRITE(sc, DWC_MMC_ARG, 0); 329 MMC_WRITE(sc, DWC_MMC_CMD, cmd); 330 retry = 200000; 331 while (--retry > 0) { 332 if (!(MMC_READ(sc, DWC_MMC_CMD) & DWC_MMC_CMD_START)) 333 break; 334 delay(10); 335 } 336 337 if (retry == 0) { 338 aprint_error_dev(sc->sc_dev, "timeout updating clock\n"); 339#ifdef DWC_MMC_DEBUG 340 device_printf(sc->sc_dev, "GCTRL: 0x%08x\n", 341 MMC_READ(sc, DWC_MMC_GCTRL)); 342 device_printf(sc->sc_dev, "CLKENA: 0x%08x\n", 343 MMC_READ(sc, DWC_MMC_CLKENA)); 344 device_printf(sc->sc_dev, "CLKDIV: 0x%08x\n", 345 MMC_READ(sc, DWC_MMC_CLKDIV)); 346 device_printf(sc->sc_dev, "TIMEOUT: 0x%08x\n", 347 MMC_READ(sc, DWC_MMC_TIMEOUT)); 348 device_printf(sc->sc_dev, "WIDTH: 0x%08x\n", 349 MMC_READ(sc, DWC_MMC_WIDTH)); 350 device_printf(sc->sc_dev, "CMD: 0x%08x\n", 351 MMC_READ(sc, DWC_MMC_CMD)); 352 device_printf(sc->sc_dev, "MINT: 0x%08x\n", 353 MMC_READ(sc, DWC_MMC_MINT)); 354 device_printf(sc->sc_dev, "RINT: 0x%08x\n", 355 MMC_READ(sc, DWC_MMC_RINT)); 356 device_printf(sc->sc_dev, "STATUS: 0x%08x\n", 357 MMC_READ(sc, DWC_MMC_STATUS)); 358#endif 359 return ETIMEDOUT; 360 } 361 362 return 0; 363} 364 365static int 366dwc_mmc_set_clock(struct dwc_mmc_softc *sc, u_int freq) 367{ 368 const u_int pll_freq = sc->sc_clock_freq / 1000; 369 u_int clk_div; 370 371 if (freq != pll_freq) 372 clk_div = howmany(pll_freq, freq); 373 else 374 clk_div = 0; 375 376 MMC_WRITE(sc, DWC_MMC_CLKDIV, clk_div); 377 378 return dwc_mmc_update_clock(sc); 379} 380 381static int 382dwc_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq) 383{ 384 struct dwc_mmc_softc *sc = sch; 385 uint32_t clkena; 386 387 MMC_WRITE(sc, DWC_MMC_CLKSRC, 0); 388 MMC_WRITE(sc, DWC_MMC_CLKENA, 0); 389 if (dwc_mmc_update_clock(sc) != 0) 390 return 1; 391 392 if (freq) { 393 if (sc->sc_bus_clock && sc->sc_bus_clock(sc, freq) != 0) 394 return 1; 395 396 if (dwc_mmc_set_clock(sc, freq) != 0) 397 return 1; 398 399 clkena = DWC_MMC_CLKENA_CARDCLKON; 400 MMC_WRITE(sc, DWC_MMC_CLKENA, clkena); 401 if (dwc_mmc_update_clock(sc) != 0) 402 return 1; 403 } 404 405 delay(1000); 406 407 return 0; 408} 409 410static int 411dwc_mmc_bus_width(sdmmc_chipset_handle_t sch, int width) 412{ 413 struct dwc_mmc_softc *sc = sch; 414 415#ifdef DWC_MMC_DEBUG 416 aprint_normal_dev(sc->sc_dev, "width = %d\n", width); 417#endif 418 419 switch (width) { 420 case 1: 421 MMC_WRITE(sc, DWC_MMC_WIDTH, DWC_MMC_WIDTH_1); 422 break; 423 case 4: 424 MMC_WRITE(sc, DWC_MMC_WIDTH, DWC_MMC_WIDTH_4); 425 break; 426 case 8: 427 MMC_WRITE(sc, DWC_MMC_WIDTH, DWC_MMC_WIDTH_8); 428 break; 429 default: 430 return 1; 431 } 432 433 sc->sc_mmc_width = width; 434 435 return 0; 436} 437 438static int 439dwc_mmc_bus_rod(sdmmc_chipset_handle_t sch, int on) 440{ 441 return -1; 442} 443 444static int 445dwc_mmc_dma_prepare(struct dwc_mmc_softc *sc, struct sdmmc_command *cmd) 446{ 447 struct dwc_mmc_idma_desc *dma = sc->sc_idma_desc; 448 bus_addr_t desc_paddr = sc->sc_idma_map->dm_segs[0].ds_addr; 449 bus_dmamap_t map; 450 bus_size_t off; 451 int desc, resid, seg; 452 uint32_t val; 453 454 /* 455 * If the command includs a dma map use it, otherwise we need to 456 * bounce. This can happen for SDIO IO_RW_EXTENDED (CMD53) commands. 457 */ 458 if (cmd->c_dmamap) { 459 map = cmd->c_dmamap; 460 } else { 461 if (cmd->c_datalen > sc->sc_dmabounce_buflen) 462 return E2BIG; 463 map = sc->sc_dmabounce_map; 464 465 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 466 memset(sc->sc_dmabounce_buf, 0, cmd->c_datalen); 467 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 468 0, cmd->c_datalen, BUS_DMASYNC_PREREAD); 469 } else { 470 memcpy(sc->sc_dmabounce_buf, cmd->c_data, 471 cmd->c_datalen); 472 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 473 0, cmd->c_datalen, BUS_DMASYNC_PREWRITE); 474 } 475 } 476 477 desc = 0; 478 for (seg = 0; seg < map->dm_nsegs; seg++) { 479 bus_addr_t paddr = map->dm_segs[seg].ds_addr; 480 bus_size_t len = map->dm_segs[seg].ds_len; 481 resid = uimin(len, cmd->c_resid); 482 off = 0; 483 while (resid > 0) { 484 if (desc == sc->sc_idma_ndesc) 485 break; 486 len = uimin(sc->sc_idma_xferlen, resid); 487 dma[desc].dma_buf_size = htole32(len); 488 dma[desc].dma_buf_addr = htole32(paddr + off); 489 dma[desc].dma_config = htole32( 490 DWC_MMC_IDMA_CONFIG_CH | 491 DWC_MMC_IDMA_CONFIG_OWN); 492 cmd->c_resid -= len; 493 resid -= len; 494 off += len; 495 if (desc == 0) { 496 dma[desc].dma_config |= htole32( 497 DWC_MMC_IDMA_CONFIG_FD); 498 } 499 if (cmd->c_resid == 0) { 500 dma[desc].dma_config |= htole32( 501 DWC_MMC_IDMA_CONFIG_LD); 502 dma[desc].dma_config |= htole32( 503 DWC_MMC_IDMA_CONFIG_ER); 504 dma[desc].dma_next = 0; 505 } else { 506 dma[desc].dma_config |= 507 htole32(DWC_MMC_IDMA_CONFIG_DIC); 508 dma[desc].dma_next = htole32( 509 desc_paddr + ((desc+1) * 510 sizeof(struct dwc_mmc_idma_desc))); 511 } 512 ++desc; 513 } 514 } 515 if (desc == sc->sc_idma_ndesc) { 516 aprint_error_dev(sc->sc_dev, 517 "not enough descriptors for %d byte transfer!\n", 518 cmd->c_datalen); 519 return EIO; 520 } 521 522 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 523 sc->sc_idma_size, BUS_DMASYNC_PREWRITE); 524 525 MMC_WRITE(sc, DWC_MMC_DLBA, desc_paddr); 526 527 val = MMC_READ(sc, DWC_MMC_GCTRL); 528 val |= DWC_MMC_GCTRL_DMAEN; 529 MMC_WRITE(sc, DWC_MMC_GCTRL, val); 530 val |= DWC_MMC_GCTRL_DMARESET; 531 MMC_WRITE(sc, DWC_MMC_GCTRL, val); 532 533 MMC_WRITE(sc, DWC_MMC_DMAC, DWC_MMC_DMAC_SOFTRESET); 534 if (cmd->c_flags & SCF_CMD_READ) 535 val = DWC_MMC_IDST_RECEIVE_INT; 536 else 537 val = 0; 538 MMC_WRITE(sc, DWC_MMC_IDIE, val); 539 MMC_WRITE(sc, DWC_MMC_DMAC, 540 DWC_MMC_DMAC_IDMA_ON|DWC_MMC_DMAC_FIX_BURST); 541 542 return 0; 543} 544 545static void 546dwc_mmc_dma_complete(struct dwc_mmc_softc *sc, struct sdmmc_command *cmd) 547{ 548 MMC_WRITE(sc, DWC_MMC_DMAC, 0); 549 MMC_WRITE(sc, DWC_MMC_IDIE, 0); 550 551 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 552 sc->sc_idma_size, BUS_DMASYNC_POSTWRITE); 553 554 if (cmd->c_dmamap == NULL) { 555 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 556 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 557 0, cmd->c_datalen, BUS_DMASYNC_POSTREAD); 558 memcpy(cmd->c_data, sc->sc_dmabounce_buf, 559 cmd->c_datalen); 560 } else { 561 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map, 562 0, cmd->c_datalen, BUS_DMASYNC_POSTWRITE); 563 } 564 } 565} 566 567static void 568dwc_mmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 569{ 570 struct dwc_mmc_softc *sc = sch; 571 uint32_t cmdval = DWC_MMC_CMD_START; 572 int retry, error; 573 uint32_t imask; 574 575#ifdef DWC_MMC_DEBUG 576 aprint_normal_dev(sc->sc_dev, 577 "opcode %d flags 0x%x data %p datalen %d blklen %d\n", 578 cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen, 579 cmd->c_blklen); 580#endif 581 582 mutex_enter(&sc->sc_intr_lock); 583 if (sc->sc_curcmd != NULL) { 584 device_printf(sc->sc_dev, 585 "WARNING: driver submitted a command while the controller was busy\n"); 586 cmd->c_error = EBUSY; 587 SET(cmd->c_flags, SCF_ITSDONE); 588 mutex_exit(&sc->sc_intr_lock); 589 return; 590 } 591 sc->sc_curcmd = cmd; 592 593 MMC_WRITE(sc, DWC_MMC_IDST, 0xffffffff); 594 595 if (ISSET(sc->sc_flags, DWC_MMC_F_USE_HOLD_REG)) 596 cmdval |= DWC_MMC_CMD_USE_HOLD_REG; 597 598 if (cmd->c_opcode == 0) 599 cmdval |= DWC_MMC_CMD_SEND_INIT_SEQ; 600 if (cmd->c_flags & SCF_RSP_PRESENT) 601 cmdval |= DWC_MMC_CMD_RSP_EXP; 602 if (cmd->c_flags & SCF_RSP_136) 603 cmdval |= DWC_MMC_CMD_LONG_RSP; 604 if (cmd->c_flags & SCF_RSP_CRC) 605 cmdval |= DWC_MMC_CMD_CHECK_RSP_CRC; 606 607 imask = DWC_MMC_INT_ERROR | DWC_MMC_INT_CMD_DONE; 608 609 if (cmd->c_datalen > 0) { 610 unsigned int nblks; 611 612 cmdval |= DWC_MMC_CMD_DATA_EXP | DWC_MMC_CMD_WAIT_PRE_OVER; 613 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) { 614 cmdval |= DWC_MMC_CMD_WRITE; 615 } 616 617 nblks = cmd->c_datalen / cmd->c_blklen; 618 if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0) 619 ++nblks; 620 621 if (nblks > 1) { 622 cmdval |= DWC_MMC_CMD_SEND_AUTO_STOP; 623 imask |= DWC_MMC_INT_AUTO_CMD_DONE; 624 } else { 625 imask |= DWC_MMC_INT_DATA_OVER; 626 } 627 628 MMC_WRITE(sc, DWC_MMC_BLKSZ, cmd->c_blklen); 629 MMC_WRITE(sc, DWC_MMC_BYTECNT, nblks * cmd->c_blklen); 630 } 631 632 MMC_WRITE(sc, DWC_MMC_IMASK, imask | sc->sc_intr_card); 633 MMC_WRITE(sc, DWC_MMC_RINT, 0x7fff); 634 635 MMC_WRITE(sc, DWC_MMC_ARG, cmd->c_arg); 636 637#ifdef DWC_MMC_DEBUG 638 aprint_normal_dev(sc->sc_dev, "cmdval = %08x\n", cmdval); 639#endif 640 641 cmd->c_resid = cmd->c_datalen; 642 if (cmd->c_datalen > 0) { 643 dwc_mmc_led(sc, 0); 644 cmd->c_error = dwc_mmc_dma_prepare(sc, cmd); 645 if (cmd->c_error != 0) { 646 SET(cmd->c_flags, SCF_ITSDONE); 647 goto done; 648 } 649 sc->sc_wait_dma = ISSET(cmd->c_flags, SCF_CMD_READ); 650 sc->sc_wait_data = true; 651 } else { 652 sc->sc_wait_dma = false; 653 sc->sc_wait_data = false; 654 } 655 sc->sc_wait_cmd = true; 656 657 MMC_WRITE(sc, DWC_MMC_CMD, cmdval | cmd->c_opcode); 658 659 if (sc->sc_wait_dma) 660 MMC_WRITE(sc, DWC_MMC_PLDMND, 1); 661 662 struct bintime timeout = { .sec = 15, .frac = 0 }; 663 const struct bintime epsilon = { .sec = 1, .frac = 0 }; 664 while (!ISSET(cmd->c_flags, SCF_ITSDONE)) { 665 error = cv_timedwaitbt(&sc->sc_intr_cv, 666 &sc->sc_intr_lock, &timeout, &epsilon); 667 if (error != 0) { 668 cmd->c_error = error; 669 SET(cmd->c_flags, SCF_ITSDONE); 670 goto done; 671 } 672 } 673 674 if (cmd->c_error == 0 && cmd->c_datalen > 0) 675 dwc_mmc_dma_complete(sc, cmd); 676 677 if (cmd->c_datalen > 0) 678 dwc_mmc_led(sc, 1); 679 680 if (cmd->c_flags & SCF_RSP_PRESENT) { 681 if (cmd->c_flags & SCF_RSP_136) { 682 cmd->c_resp[0] = MMC_READ(sc, DWC_MMC_RESP0); 683 cmd->c_resp[1] = MMC_READ(sc, DWC_MMC_RESP1); 684 cmd->c_resp[2] = MMC_READ(sc, DWC_MMC_RESP2); 685 cmd->c_resp[3] = MMC_READ(sc, DWC_MMC_RESP3); 686 if (cmd->c_flags & SCF_RSP_CRC) { 687 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 688 (cmd->c_resp[1] << 24); 689 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 690 (cmd->c_resp[2] << 24); 691 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 692 (cmd->c_resp[3] << 24); 693 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 694 } 695 } else { 696 cmd->c_resp[0] = MMC_READ(sc, DWC_MMC_RESP0); 697 } 698 } 699 700done: 701 KASSERT(ISSET(cmd->c_flags, SCF_ITSDONE)); 702 MMC_WRITE(sc, DWC_MMC_IMASK, sc->sc_intr_card); 703 MMC_WRITE(sc, DWC_MMC_IDIE, 0); 704 MMC_WRITE(sc, DWC_MMC_RINT, 0x7fff); 705 MMC_WRITE(sc, DWC_MMC_IDST, 0xffffffff); 706 sc->sc_curcmd = NULL; 707 mutex_exit(&sc->sc_intr_lock); 708 709 if (cmd->c_error) { 710#ifdef DWC_MMC_DEBUG 711 aprint_error_dev(sc->sc_dev, "i/o error %d\n", cmd->c_error); 712#endif 713 MMC_WRITE(sc, DWC_MMC_GCTRL, 714 MMC_READ(sc, DWC_MMC_GCTRL) | 715 DWC_MMC_GCTRL_DMARESET | DWC_MMC_GCTRL_FIFORESET); 716 for (retry = 0; retry < 1000; retry++) { 717 if (!(MMC_READ(sc, DWC_MMC_GCTRL) & DWC_MMC_GCTRL_RESET)) 718 break; 719 delay(10); 720 } 721 dwc_mmc_update_clock(sc); 722 } 723 724 MMC_WRITE(sc, DWC_MMC_GCTRL, 725 MMC_READ(sc, DWC_MMC_GCTRL) | DWC_MMC_GCTRL_FIFORESET); 726} 727 728static void 729dwc_mmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 730{ 731 struct dwc_mmc_softc *sc = sch; 732 uint32_t imask; 733 734 mutex_enter(&sc->sc_intr_lock); 735 imask = MMC_READ(sc, DWC_MMC_IMASK); 736 if (enable) 737 imask |= DWC_MMC_INT_SDIO_INT; 738 else 739 imask &= ~DWC_MMC_INT_SDIO_INT; 740 sc->sc_intr_card = imask & DWC_MMC_INT_SDIO_INT; 741 MMC_WRITE(sc, DWC_MMC_IMASK, imask); 742 mutex_exit(&sc->sc_intr_lock); 743} 744 745static void 746dwc_mmc_card_intr_ack(sdmmc_chipset_handle_t sch) 747{ 748 struct dwc_mmc_softc *sc = sch; 749 uint32_t imask; 750 751 mutex_enter(&sc->sc_intr_lock); 752 imask = MMC_READ(sc, DWC_MMC_IMASK); 753 MMC_WRITE(sc, DWC_MMC_IMASK, imask | sc->sc_intr_card); 754 mutex_exit(&sc->sc_intr_lock); 755} 756 757int 758dwc_mmc_init(struct dwc_mmc_softc *sc) 759{ 760 uint32_t val; 761 762 if (sc->sc_fifo_reg == 0) { 763 val = MMC_READ(sc, DWC_MMC_VERID); 764 const u_int id = __SHIFTOUT(val, DWC_MMC_VERID_ID); 765 766 if (id < DWC_MMC_VERID_240A) 767 sc->sc_fifo_reg = 0x100; 768 else 769 sc->sc_fifo_reg = 0x200; 770 } 771 772 if (sc->sc_fifo_depth == 0) { 773 val = MMC_READ(sc, DWC_MMC_FIFOTH); 774 sc->sc_fifo_depth = __SHIFTOUT(val, DWC_MMC_FIFOTH_RX_WMARK) + 1; 775 } 776 777 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO); 778 cv_init(&sc->sc_intr_cv, "dwcmmcirq"); 779 780 if (dwc_mmc_dmabounce_setup(sc) != 0 || 781 dwc_mmc_idma_setup(sc) != 0) { 782 aprint_error_dev(sc->sc_dev, "failed to setup DMA\n"); 783 return ENOMEM; 784 } 785 786 config_interrupts(sc->sc_dev, dwc_mmc_attach_i); 787 788 return 0; 789} 790 791int 792dwc_mmc_intr(void *priv) 793{ 794 struct dwc_mmc_softc *sc = priv; 795 struct sdmmc_command *cmd; 796 uint32_t idst, mint, imask; 797 798 mutex_enter(&sc->sc_intr_lock); 799 idst = MMC_READ(sc, DWC_MMC_IDST); 800 mint = MMC_READ(sc, DWC_MMC_MINT); 801 if (!idst && !mint) { 802 mutex_exit(&sc->sc_intr_lock); 803 return 0; 804 } 805 MMC_WRITE(sc, DWC_MMC_IDST, idst); 806 MMC_WRITE(sc, DWC_MMC_RINT, mint); 807 808 cmd = sc->sc_curcmd; 809 810#ifdef DWC_MMC_DEBUG 811 device_printf(sc->sc_dev, "mmc intr idst=%08X mint=%08X\n", 812 idst, mint); 813#endif 814 815 /* Handle SDIO card interrupt */ 816 if ((mint & DWC_MMC_INT_SDIO_INT) != 0) { 817 imask = MMC_READ(sc, DWC_MMC_IMASK); 818 MMC_WRITE(sc, DWC_MMC_IMASK, imask & ~DWC_MMC_INT_SDIO_INT); 819 sdmmc_card_intr(sc->sc_sdmmc_dev); 820 } 821 822 /* Error interrupts take priority over command and transfer interrupts */ 823 if (cmd != NULL && (mint & DWC_MMC_INT_ERROR) != 0) { 824 imask = MMC_READ(sc, DWC_MMC_IMASK); 825 MMC_WRITE(sc, DWC_MMC_IMASK, imask & ~DWC_MMC_INT_ERROR); 826 if ((mint & DWC_MMC_INT_RESP_TIMEOUT) != 0) { 827 cmd->c_error = ETIMEDOUT; 828 /* Wait for command to complete */ 829 sc->sc_wait_data = sc->sc_wait_dma = false; 830 if (cmd->c_opcode != SD_IO_SEND_OP_COND && 831 cmd->c_opcode != SD_IO_RW_DIRECT && 832 !ISSET(cmd->c_flags, SCF_TOUT_OK)) 833 device_printf(sc->sc_dev, "host controller timeout, mint=0x%08x\n", mint); 834 } else { 835 device_printf(sc->sc_dev, "host controller error, mint=0x%08x\n", mint); 836 cmd->c_error = EIO; 837 SET(cmd->c_flags, SCF_ITSDONE); 838 goto done; 839 } 840 } 841 842 if (cmd != NULL && (idst & DWC_MMC_IDST_RECEIVE_INT) != 0) { 843 MMC_WRITE(sc, DWC_MMC_IDIE, 0); 844 if (sc->sc_wait_dma == false) 845 device_printf(sc->sc_dev, "unexpected DMA receive interrupt\n"); 846 sc->sc_wait_dma = false; 847 } 848 849 if (cmd != NULL && (mint & DWC_MMC_INT_CMD_DONE) != 0) { 850 imask = MMC_READ(sc, DWC_MMC_IMASK); 851 MMC_WRITE(sc, DWC_MMC_IMASK, imask & ~DWC_MMC_INT_CMD_DONE); 852 if (sc->sc_wait_cmd == false) 853 device_printf(sc->sc_dev, "unexpected command complete interrupt\n"); 854 sc->sc_wait_cmd = false; 855 } 856 857 const uint32_t dmadone_mask = DWC_MMC_INT_AUTO_CMD_DONE|DWC_MMC_INT_DATA_OVER; 858 if (cmd != NULL && (mint & dmadone_mask) != 0) { 859 imask = MMC_READ(sc, DWC_MMC_IMASK); 860 MMC_WRITE(sc, DWC_MMC_IMASK, imask & ~dmadone_mask); 861 if (sc->sc_wait_data == false) 862 device_printf(sc->sc_dev, "unexpected data complete interrupt\n"); 863 sc->sc_wait_data = false; 864 } 865 866 if (cmd != NULL && 867 sc->sc_wait_dma == false && 868 sc->sc_wait_cmd == false && 869 sc->sc_wait_data == false) { 870 SET(cmd->c_flags, SCF_ITSDONE); 871 } 872 873done: 874 if (cmd != NULL && ISSET(cmd->c_flags, SCF_ITSDONE)) { 875 cv_broadcast(&sc->sc_intr_cv); 876 } 877 878 mutex_exit(&sc->sc_intr_lock); 879 880 return 1; 881} 882