1 /* $NetBSD: mvsdio.c,v 1.5 2014/03/15 13:33:48 kiyohara Exp $ */ 2 /* 3 * Copyright (c) 2010 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: mvsdio.c,v 1.5 2014/03/15 13:33:48 kiyohara Exp $"); 29 30 #include "opt_mvsdio.h" 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/condvar.h> 35 #include <sys/device.h> 36 #include <sys/errno.h> 37 #include <sys/mutex.h> 38 39 #include <dev/marvell/marvellreg.h> 40 #include <dev/marvell/marvellvar.h> 41 #include <dev/marvell/mvsdioreg.h> 42 43 #include <dev/sdmmc/sdmmcvar.h> 44 #include <dev/sdmmc/sdmmcchip.h> 45 46 //#define MVSDIO_DEBUG 1 47 #ifdef MVSDIO_DEBUG 48 #define DPRINTF(n, x) if (mvsdio_debug >= (n)) printf x 49 int mvsdio_debug = MVSDIO_DEBUG; 50 #else 51 #define DPRINTF(n, x) 52 #endif 53 54 struct mvsdio_softc { 55 device_t sc_dev; 56 device_t sc_sdmmc; 57 58 bus_space_tag_t sc_iot; 59 bus_space_handle_t sc_ioh; 60 bus_dma_tag_t sc_dmat; 61 62 struct kmutex sc_mtx; 63 kcondvar_t sc_cv; 64 65 struct sdmmc_command *sc_exec_cmd; 66 uint32_t sc_waitintr; 67 }; 68 69 static int mvsdio_match(device_t, struct cfdata *, void *); 70 static void mvsdio_attach(device_t, device_t, void *); 71 72 static int mvsdio_intr(void *); 73 74 static int mvsdio_host_reset(sdmmc_chipset_handle_t); 75 static uint32_t mvsdio_host_ocr(sdmmc_chipset_handle_t); 76 static int mvsdio_host_maxblklen(sdmmc_chipset_handle_t); 77 #ifdef MVSDIO_CARD_DETECT 78 int MVSDIO_CARD_DETECT(sdmmc_chipset_handle_t); 79 #else 80 static int mvsdio_card_detect(sdmmc_chipset_handle_t); 81 #endif 82 #ifdef MVSDIO_WRITE_PROTECT 83 int MVSDIO_WRITE_PROTECT(sdmmc_chipset_handle_t); 84 #else 85 static int mvsdio_write_protect(sdmmc_chipset_handle_t); 86 #endif 87 static int mvsdio_bus_power(sdmmc_chipset_handle_t, uint32_t); 88 static int mvsdio_bus_clock(sdmmc_chipset_handle_t, int); 89 static int mvsdio_bus_width(sdmmc_chipset_handle_t, int); 90 static int mvsdio_bus_rod(sdmmc_chipset_handle_t, int); 91 static void mvsdio_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *); 92 static void mvsdio_card_enable_intr(sdmmc_chipset_handle_t, int); 93 static void mvsdio_card_intr_ack(sdmmc_chipset_handle_t); 94 95 static void mvsdio_wininit(struct mvsdio_softc *, enum marvell_tags *); 96 97 static struct sdmmc_chip_functions mvsdio_chip_functions = { 98 /* host controller reset */ 99 .host_reset = mvsdio_host_reset, 100 101 /* host controller capabilities */ 102 .host_ocr = mvsdio_host_ocr, 103 .host_maxblklen = mvsdio_host_maxblklen, 104 105 /* card detection */ 106 #ifdef MVSDIO_CARD_DETECT 107 .card_detect = MVSDIO_CARD_DETECT, 108 #else 109 .card_detect = mvsdio_card_detect, 110 #endif 111 112 /* write protect */ 113 #ifdef MVSDIO_WRITE_PROTECT 114 .write_protect = MVSDIO_WRITE_PROTECT, 115 #else 116 .write_protect = mvsdio_write_protect, 117 #endif 118 119 /* bus power, clock frequency, width, rod */ 120 .bus_power = mvsdio_bus_power, 121 .bus_clock = mvsdio_bus_clock, 122 .bus_width = mvsdio_bus_width, 123 .bus_rod = mvsdio_bus_rod, 124 125 /* command execution */ 126 .exec_command = mvsdio_exec_command, 127 128 /* card interrupt */ 129 .card_enable_intr = mvsdio_card_enable_intr, 130 .card_intr_ack = mvsdio_card_intr_ack, 131 }; 132 133 CFATTACH_DECL_NEW(mvsdio_mbus, sizeof(struct mvsdio_softc), 134 mvsdio_match, mvsdio_attach, NULL, NULL); 135 136 137 /* ARGSUSED */ 138 static int 139 mvsdio_match(device_t parent, struct cfdata *match, void *aux) 140 { 141 struct marvell_attach_args *mva = aux; 142 143 if (strcmp(mva->mva_name, match->cf_name) != 0) 144 return 0; 145 if (mva->mva_offset == MVA_OFFSET_DEFAULT) 146 return 0; 147 148 mva->mva_size = MVSDIO_SIZE; 149 return 1; 150 } 151 152 /* ARGSUSED */ 153 static void 154 mvsdio_attach(device_t parent, device_t self, void *aux) 155 { 156 struct mvsdio_softc *sc = device_private(self); 157 struct marvell_attach_args *mva = aux; 158 struct sdmmcbus_attach_args saa; 159 uint32_t nis, eis; 160 161 aprint_naive("\n"); 162 aprint_normal(": Marvell Secure Digital Input/Output Interface\n"); 163 164 sc->sc_dev = self; 165 sc->sc_iot = mva->mva_iot; 166 if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, mva->mva_offset, 167 mva->mva_size, &sc->sc_ioh)) { 168 aprint_error_dev(self, "Cannot map registers\n"); 169 return; 170 } 171 sc->sc_dmat = mva->mva_dmat; 172 173 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_SDMMC); 174 cv_init(&sc->sc_cv, "mvsdio_intr"); 175 176 sc->sc_exec_cmd = NULL; 177 sc->sc_waitintr = 0; 178 179 marvell_intr_establish(mva->mva_irq, IPL_SDMMC, mvsdio_intr, sc); 180 181 mvsdio_wininit(sc, mva->mva_tags); 182 183 #if BYTE_ORDER == LITTLE_ENDIAN 184 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, HC_BIGENDIAN); 185 #else 186 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, HC_LSBFIRST); 187 #endif 188 nis = 189 NIS_CMDCOMPLETE /* Command Complete */ | 190 NIS_XFERCOMPLETE /* Transfer Complete */ | 191 NIS_BLOCKGAPEV /* Block gap event */ | 192 NIS_DMAINT /* DMA interrupt */ | 193 NIS_CARDINT /* Card interrupt */ | 194 NIS_READWAITON /* Read Wait state is on */ | 195 NIS_SUSPENSEON | 196 NIS_AUTOCMD12COMPLETE /* Auto_cmd12 is comp */| 197 NIS_UNEXPECTEDRESPDET | 198 NIS_ERRINT; /* Error interrupt */ 199 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NIS, nis); 200 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISE, nis); 201 202 #define NIC_DYNAMIC_CONFIG_INTRS (NIS_CMDCOMPLETE | \ 203 NIS_XFERCOMPLETE | \ 204 NIS_DMAINT | \ 205 NIS_CARDINT | \ 206 NIS_AUTOCMD12COMPLETE) 207 208 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE, 209 nis & ~NIC_DYNAMIC_CONFIG_INTRS); 210 211 eis = 212 EIS_CMDTIMEOUTERR /*Command timeout err*/ | 213 EIS_CMDCRCERR /* Command CRC Error */ | 214 EIS_CMDENDBITERR /*Command end bit err*/ | 215 EIS_CMDINDEXERR /*Command Index Error*/ | 216 EIS_DATATIMEOUTERR /* Data timeout error */ | 217 EIS_RDDATACRCERR /* Read data CRC err */ | 218 EIS_RDDATAENDBITERR /*Rd data end bit err*/ | 219 EIS_AUTOCMD12ERR /* Auto CMD12 error */ | 220 EIS_CMDSTARTBITERR /*Cmd start bit error*/ | 221 EIS_XFERSIZEERR /*Tx size mismatched err*/ | 222 EIS_RESPTBITERR /* Response T bit err */ | 223 EIS_CRCENDBITERR /* CRC end bit error */ | 224 EIS_CRCSTARTBITERR /* CRC start bit err */ | 225 EIS_CRCSTATERR; /* CRC status error */ 226 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EIS, eis); 227 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EISE, eis); 228 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EISIE, eis); 229 230 /* 231 * Attach the generic SD/MMC bus driver. (The bus driver must 232 * not invoke any chipset functions before it is attached.) 233 */ 234 memset(&saa, 0, sizeof(saa)); 235 saa.saa_busname = "sdmmc"; 236 saa.saa_sct = &mvsdio_chip_functions; 237 saa.saa_sch = sc; 238 saa.saa_dmat = sc->sc_dmat; 239 saa.saa_clkmin = 100; /* XXXX: 100 kHz from SheevaPlug LSP */ 240 saa.saa_clkmax = MVSDIO_MAX_CLOCK; 241 saa.saa_caps = SMC_CAPS_AUTO_STOP | SMC_CAPS_4BIT_MODE | SMC_CAPS_DMA | 242 SMC_CAPS_SD_HIGHSPEED | SMC_CAPS_MMC_HIGHSPEED; 243 #ifndef MVSDIO_CARD_DETECT 244 saa.saa_caps |= SMC_CAPS_POLL_CARD_DET; 245 #endif 246 sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL); 247 } 248 249 static int 250 mvsdio_intr(void *arg) 251 { 252 struct mvsdio_softc *sc = (struct mvsdio_softc *)arg; 253 struct sdmmc_command *cmd = sc->sc_exec_cmd; 254 uint32_t nis, eis; 255 int handled = 0, error; 256 257 nis = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NIS); 258 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NIS, nis); 259 260 DPRINTF(3, ("%s: intr: NIS=0x%x, NISE=0x%x, NISIE=0x%x\n", 261 __func__, nis, 262 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISE), 263 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE))); 264 265 if (__predict_false(nis & NIS_ERRINT)) { 266 sc->sc_exec_cmd = NULL; 267 eis = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EIS); 268 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EIS, eis); 269 270 DPRINTF(3, (" EIS=0x%x, EISE=0x%x, EISIE=0x%x\n", 271 eis, 272 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EISE), 273 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EISIE))); 274 275 if (eis & (EIS_CMDTIMEOUTERR | EIS_DATATIMEOUTERR)) { 276 error = ETIMEDOUT; /* Timeouts */ 277 DPRINTF(2, (" Command/Data Timeout (0x%x)\n", 278 eis & (EIS_CMDTIMEOUTERR | EIS_DATATIMEOUTERR))); 279 } else { 280 281 #define CRC_ERROR (EIS_CMDCRCERR | \ 282 EIS_RDDATACRCERR | \ 283 EIS_CRCENDBITERR | \ 284 EIS_CRCSTARTBITERR | \ 285 EIS_CRCSTATERR) 286 if (eis & CRC_ERROR) { 287 error = EIO; /* CRC errors */ 288 aprint_error_dev(sc->sc_dev, 289 "CRC Error (0x%x)\n", eis & CRC_ERROR); 290 } 291 292 #define COMMAND_ERROR (EIS_CMDENDBITERR | \ 293 EIS_CMDINDEXERR | \ 294 EIS_CMDSTARTBITERR) 295 if (eis & COMMAND_ERROR) { 296 error = EIO; /*Other command errors*/ 297 aprint_error_dev(sc->sc_dev, 298 "Command Error (0x%x)\n", 299 eis & COMMAND_ERROR); 300 } 301 302 #define MISC_ERROR (EIS_RDDATAENDBITERR | \ 303 EIS_AUTOCMD12ERR | \ 304 EIS_XFERSIZEERR | \ 305 EIS_RESPTBITERR) 306 if (eis & MISC_ERROR) { 307 error = EIO; /* Misc error */ 308 aprint_error_dev(sc->sc_dev, 309 "Misc Error (0x%x)\n", eis & MISC_ERROR); 310 } 311 } 312 313 if (cmd != NULL) { 314 cmd->c_error = error; 315 cv_signal(&sc->sc_cv); 316 } 317 handled = 1; 318 } else if (cmd != NULL && 319 ((nis & sc->sc_waitintr) || (nis & NIS_UNEXPECTEDRESPDET))) { 320 sc->sc_exec_cmd = NULL; 321 sc->sc_waitintr = 0; 322 if (cmd->c_flags & SCF_RSP_PRESENT) { 323 uint16_t rh[MVSDIO_NRH + 1]; 324 int i, j; 325 326 if (cmd->c_flags & SCF_RSP_136) { 327 for (i = 0; i < MVSDIO_NRH; i++) 328 rh[i + 1] = bus_space_read_4(sc->sc_iot, 329 sc->sc_ioh, MVSDIO_RH(i)); 330 rh[0] = 0; 331 for (j = 3, i = 1; j >= 0; j--, i += 2) { 332 cmd->c_resp[j] = 333 rh[i - 1] << 30 | 334 rh[i + 0] << 14 | 335 rh[i + 1] >> 2; 336 } 337 cmd->c_resp[3] &= 0x00ffffff; 338 } else { 339 for (i = 0; i < 3; i++) 340 rh[i] = bus_space_read_4(sc->sc_iot, 341 sc->sc_ioh, MVSDIO_RH(i)); 342 cmd->c_resp[0] = 343 ((rh[0] & 0x03ff) << 22) | 344 ((rh[1] ) << 6) | 345 ((rh[2] & 0x003f) << 0); 346 cmd->c_resp[1] = (rh[0] & 0xfc00) >> 10; 347 cmd->c_resp[2] = 0; 348 cmd->c_resp[3] = 0; 349 } 350 } 351 if (nis & NIS_UNEXPECTEDRESPDET) 352 cmd->c_error = EIO; 353 cv_signal(&sc->sc_cv); 354 } 355 356 if (nis & NIS_CARDINT) 357 if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE) & 358 NIS_CARDINT) { 359 sdmmc_card_intr(sc->sc_sdmmc); 360 handled = 1; 361 } 362 363 return handled; 364 } 365 366 static int 367 mvsdio_host_reset(sdmmc_chipset_handle_t sch) 368 { 369 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 370 371 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_SR, SR_SWRESET); 372 return 0; 373 } 374 375 static uint32_t 376 mvsdio_host_ocr(sdmmc_chipset_handle_t sch) 377 { 378 379 return MMC_OCR_3_3V_3_4V | MMC_OCR_3_2V_3_3V; 380 } 381 382 static int 383 mvsdio_host_maxblklen(sdmmc_chipset_handle_t sch) 384 { 385 386 return DBS_BLOCKSIZE_MAX; 387 } 388 389 #ifndef MVSDIO_CARD_DETECT 390 static int 391 mvsdio_card_detect(sdmmc_chipset_handle_t sch) 392 { 393 struct mvsdio_softc *sc __unused = (struct mvsdio_softc *)sch; 394 395 DPRINTF(2, ("%s: driver lacks card_detect() function.\n", 396 device_xname(sc->sc_dev))); 397 return 1; /* always detect */ 398 } 399 #endif 400 401 #ifndef MVSDIO_WRITE_PROTECT 402 static int 403 mvsdio_write_protect(sdmmc_chipset_handle_t sch) 404 { 405 406 /* Nothing */ 407 408 return 0; 409 } 410 #endif 411 412 static int 413 mvsdio_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 414 { 415 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 416 uint32_t reg; 417 418 /* Initial state is Open Drain on CMD line. */ 419 mutex_enter(&sc->sc_mtx); 420 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 421 reg &= ~HC_PUSHPULLEN; 422 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 423 mutex_exit(&sc->sc_mtx); 424 425 return 0; 426 } 427 428 static int 429 mvsdio_bus_clock(sdmmc_chipset_handle_t sch, int freq) 430 { 431 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 432 uint32_t reg; 433 int m; 434 435 mutex_enter(&sc->sc_mtx); 436 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM); 437 438 /* Just stop the clock. */ 439 if (freq == 0) { 440 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM, 441 reg | TM_STOPCLKEN); 442 goto out; 443 } 444 445 #define FREQ_TO_M(f) (100000 / (f) - 1) 446 447 m = FREQ_TO_M(freq); 448 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_CDV, 449 m & CDV_CLKDVDRMVALUE_MASK); 450 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM, 451 reg & ~TM_STOPCLKEN); 452 453 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 454 if (freq > 25000) 455 reg |= HC_HISPEEDEN; 456 else 457 reg &= ~HC_HISPEEDEN; /* up to 25 MHz */ 458 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 459 460 out: 461 mutex_exit(&sc->sc_mtx); 462 463 return 0; 464 } 465 466 static int 467 mvsdio_bus_width(sdmmc_chipset_handle_t sch, int width) 468 { 469 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 470 uint32_t reg, v; 471 472 switch (width) { 473 case 1: 474 v = 0; 475 break; 476 477 case 4: 478 v = HC_DATAWIDTH; 479 break; 480 481 default: 482 DPRINTF(0, ("%s: unsupported bus width (%d)\n", 483 device_xname(sc->sc_dev), width)); 484 return EINVAL; 485 } 486 487 mutex_enter(&sc->sc_mtx); 488 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 489 reg &= ~HC_DATAWIDTH; 490 reg |= v; 491 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 492 mutex_exit(&sc->sc_mtx); 493 494 return 0; 495 } 496 497 static int 498 mvsdio_bus_rod(sdmmc_chipset_handle_t sch, int on) 499 { 500 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 501 uint32_t reg; 502 503 /* Change Open-drain/Push-pull. */ 504 mutex_enter(&sc->sc_mtx); 505 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 506 if (on) 507 reg &= ~HC_PUSHPULLEN; 508 else 509 reg |= HC_PUSHPULLEN; 510 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 511 mutex_exit(&sc->sc_mtx); 512 513 return 0; 514 } 515 516 static void 517 mvsdio_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 518 { 519 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 520 uint32_t tm, c, hc, aacc, nisie, wait; 521 int blklen; 522 523 DPRINTF(1, ("%s: start cmd %d arg=%#x data=%p dlen=%d flags=%#x\n", 524 device_xname(sc->sc_dev), cmd->c_opcode, cmd->c_arg, cmd->c_data, 525 cmd->c_datalen, cmd->c_flags)); 526 527 mutex_enter(&sc->sc_mtx); 528 529 tm = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM); 530 531 if (cmd->c_datalen > 0) { 532 bus_dma_segment_t *dm_seg = 533 &cmd->c_dmamap->dm_segs[cmd->c_dmaseg]; 534 bus_addr_t ds_addr = dm_seg->ds_addr + cmd->c_dmaoff; 535 536 blklen = MIN(cmd->c_datalen, cmd->c_blklen); 537 538 if (cmd->c_datalen % blklen > 0) { 539 aprint_error_dev(sc->sc_dev, 540 "data not a multiple of %u bytes\n", blklen); 541 cmd->c_error = EINVAL; 542 goto out; 543 } 544 if ((uint32_t)cmd->c_data & 0x3) { 545 aprint_error_dev(sc->sc_dev, 546 "data not 4byte aligned\n"); 547 cmd->c_error = EINVAL; 548 goto out; 549 } 550 551 /* Set DMA Buffer Address */ 552 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DMABA16LSB, 553 ds_addr & 0xffff); 554 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DMABA16MSB, 555 (ds_addr >> 16) & 0xffff); 556 557 /* Set Data Block Size and Count */ 558 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DBS, 559 DBS_BLOCKSIZE(blklen)); 560 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DBC, 561 DBC_BLOCKCOUNT(cmd->c_datalen / blklen)); 562 563 tm &= ~TM_HOSTXFERMODE; /* Always DMA */ 564 if (cmd->c_flags & SCF_CMD_READ) 565 tm |= TM_DATAXFERTOWARDHOST; 566 else 567 tm &= ~TM_DATAXFERTOWARDHOST; 568 tm |= TM_HWWRDATAEN; 569 wait = NIS_XFERCOMPLETE; 570 } else { 571 tm &= ~TM_HWWRDATAEN; 572 wait = NIS_CMDCOMPLETE; 573 } 574 575 /* Set Argument in Command */ 576 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AC16LSB, 577 cmd->c_arg & 0xffff); 578 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AC16MSB, 579 (cmd->c_arg >> 16) & 0xffff); 580 581 /* Set Host Control, exclude PushPullEn, DataWidth, HiSpeedEn. */ 582 hc = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 583 hc |= (HC_TIMEOUTVALUE_MAX | HC_TIMEOUTEN); 584 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, hc); 585 586 /* Data Block Gap Control: Resume */ 587 588 /* Clock Control: SclkMasterEn */ 589 590 if (cmd->c_opcode == MMC_READ_BLOCK_MULTIPLE || 591 cmd->c_opcode == MMC_WRITE_BLOCK_MULTIPLE) { 592 aacc = 0; 593 #if 1 /* XXXX: need? */ 594 if (cmd->c_opcode == MMC_READ_BLOCK_MULTIPLE) { 595 struct sdmmc_softc *sdmmc = 596 device_private(sc->sc_sdmmc); 597 struct sdmmc_function *sf = sdmmc->sc_card; 598 599 aacc = MMC_ARG_RCA(sf->rca); 600 } 601 #endif 602 603 /* Set Argument in Auto Cmd12 Command */ 604 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AACC16LSBT, 605 aacc & 0xffff); 606 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AACC16MSBT, 607 (aacc >> 16) & 0xffff); 608 609 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_IACCT, 610 IACCT_AUTOCMD12BUSYCHKEN | 611 IACCT_AUTOCMD12INDEXCHKEN | 612 IACCT_AUTOCMD12INDEX); 613 614 tm |= TM_AUTOCMD12EN; 615 wait = NIS_AUTOCMD12COMPLETE; 616 } else 617 tm &= ~TM_AUTOCMD12EN; 618 619 tm |= TM_INTCHKEN; 620 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM, tm); 621 622 c = C_CMDINDEX(cmd->c_opcode); 623 if (cmd->c_flags & SCF_RSP_PRESENT) { 624 if (cmd->c_flags & SCF_RSP_136) 625 c |= C_RESPTYPE_136BR; 626 else if (!(cmd->c_flags & SCF_RSP_BSY)) 627 c |= C_RESPTYPE_48BR; 628 else 629 c |= C_RESPTYPE_48BRCB; 630 c |= C_UNEXPECTEDRESPEN; 631 } else 632 c |= C_RESPTYPE_NR; 633 if (cmd->c_flags & SCF_RSP_CRC) 634 c |= C_CMDCRCCHKEN; 635 if (cmd->c_flags & SCF_RSP_IDX) 636 c |= C_CMDINDEXCHKEN; 637 if (cmd->c_datalen > 0) 638 c |= (C_DATAPRESENT | C_DATACRC16CHKEN); 639 640 DPRINTF(2, ("%s: TM=0x%x, C=0x%x, HC=0x%x\n", __func__, tm, c, hc)); 641 642 nisie = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE); 643 nisie &= ~(NIS_CMDCOMPLETE | NIS_XFERCOMPLETE | NIS_AUTOCMD12COMPLETE); 644 nisie |= wait; 645 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE, nisie); 646 647 /* Execute command */ 648 sc->sc_exec_cmd = cmd; 649 sc->sc_waitintr = wait; 650 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_C, c); 651 652 /* Wait interrupt for complete or error or timeout */ 653 while (sc->sc_exec_cmd == cmd) 654 cv_wait(&sc->sc_cv, &sc->sc_mtx); 655 656 out: 657 mutex_exit(&sc->sc_mtx); 658 659 DPRINTF(1, ("%s: cmd %d done (flags=%08x error=%d)\n", 660 device_xname(sc->sc_dev), 661 cmd->c_opcode, cmd->c_flags, cmd->c_error)); 662 } 663 664 static void 665 mvsdio_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 666 { 667 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 668 uint32_t reg; 669 670 mutex_enter(&sc->sc_mtx); 671 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE); 672 reg |= NIS_CARDINT; 673 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE, reg); 674 mutex_exit(&sc->sc_mtx); 675 } 676 677 static void 678 mvsdio_card_intr_ack(sdmmc_chipset_handle_t sch) 679 { 680 681 /* Nothing */ 682 } 683 684 685 static void 686 mvsdio_wininit(struct mvsdio_softc *sc, enum marvell_tags *tags) 687 { 688 uint64_t base; 689 uint32_t size; 690 int window, target, attr, rv, i; 691 692 for (window = 0, i = 0; 693 tags[i] != MARVELL_TAG_UNDEFINED && window < MVSDIO_NWINDOW; i++) { 694 rv = marvell_winparams_by_tag(sc->sc_dev, tags[i], 695 &target, &attr, &base, &size); 696 if (rv != 0 || size == 0) 697 continue; 698 699 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_WC(window), 700 WC_WINEN | 701 WC_TARGET(target) | 702 WC_ATTR(attr) | 703 WC_SIZE(size)); 704 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_WB(window), 705 WB_BASE(base)); 706 window++; 707 } 708 for (; window < MVSDIO_NWINDOW; window++) 709 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_WC(window), 0); 710 } 711