1 /* $NetBSD: mvsdio.c,v 1.2 2010/10/08 11:20:22 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.2 2010/10/08 11:20:22 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 *); 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); 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 #ifndef MVSDIO_CARD_DETECT 243 saa.saa_caps |= SMC_CAPS_POLL_CARD_DET; 244 #endif 245 sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL); 246 } 247 248 static int 249 mvsdio_intr(void *arg) 250 { 251 struct mvsdio_softc *sc = (struct mvsdio_softc *)arg; 252 struct sdmmc_command *cmd = sc->sc_exec_cmd; 253 uint32_t nis, eis; 254 int handled = 0, error; 255 256 nis = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NIS); 257 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NIS, nis); 258 259 DPRINTF(3, ("%s: intr: NIS=0x%x, NISE=0x%x, NISIE=0x%x\n", 260 __func__, nis, 261 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISE), 262 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE))); 263 264 if (__predict_false(nis & NIS_ERRINT)) { 265 sc->sc_exec_cmd = NULL; 266 eis = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EIS); 267 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EIS, eis); 268 269 DPRINTF(3, (" EIS=0x%x, EISE=0x%x, EISIE=0x%x\n", 270 eis, 271 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EISE), 272 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_EISIE))); 273 274 if (eis & (EIS_CMDTIMEOUTERR | EIS_DATATIMEOUTERR)) { 275 error = ETIMEDOUT; /* Timeouts */ 276 DPRINTF(2, (" Command/Data Timeout (0x%x)\n", 277 eis & (EIS_CMDTIMEOUTERR | EIS_DATATIMEOUTERR))); 278 } else { 279 280 #define CRC_ERROR (EIS_CMDCRCERR | \ 281 EIS_RDDATACRCERR | \ 282 EIS_CRCENDBITERR | \ 283 EIS_CRCSTARTBITERR | \ 284 EIS_CRCSTATERR) 285 if (eis & CRC_ERROR) { 286 error = EIO; /* CRC errors */ 287 aprint_error_dev(sc->sc_dev, 288 "CRC Error (0x%x)\n", eis & CRC_ERROR); 289 } 290 291 #define COMMAND_ERROR (EIS_CMDENDBITERR | \ 292 EIS_CMDINDEXERR | \ 293 EIS_CMDSTARTBITERR) 294 if (eis & COMMAND_ERROR) { 295 error = EIO; /*Other command errors*/ 296 aprint_error_dev(sc->sc_dev, 297 "Command Error (0x%x)\n", 298 eis & COMMAND_ERROR); 299 } 300 301 #define MISC_ERROR (EIS_RDDATAENDBITERR | \ 302 EIS_AUTOCMD12ERR | \ 303 EIS_XFERSIZEERR | \ 304 EIS_RESPTBITERR) 305 if (eis & MISC_ERROR) { 306 error = EIO; /* Misc error */ 307 aprint_error_dev(sc->sc_dev, 308 "Misc Error (0x%x)\n", eis & MISC_ERROR); 309 } 310 } 311 312 if (cmd != NULL) { 313 cmd->c_error = error; 314 cv_signal(&sc->sc_cv); 315 } 316 handled = 1; 317 } else if (cmd != NULL && 318 ((nis & sc->sc_waitintr) || (nis & NIS_UNEXPECTEDRESPDET))) { 319 sc->sc_exec_cmd = NULL; 320 sc->sc_waitintr = 0; 321 if (cmd->c_flags & SCF_RSP_PRESENT) { 322 uint16_t rh[MVSDIO_NRH + 1]; 323 int i, j; 324 325 if (cmd->c_flags & SCF_RSP_136) { 326 for (i = 0; i < MVSDIO_NRH; i++) 327 rh[i + 1] = bus_space_read_4(sc->sc_iot, 328 sc->sc_ioh, MVSDIO_RH(i)); 329 rh[0] = 0; 330 for (j = 3, i = 1; j >= 0; j--, i += 2) { 331 cmd->c_resp[j] = 332 rh[i - 1] << 30 | 333 rh[i + 0] << 14 | 334 rh[i + 1] >> 2; 335 } 336 cmd->c_resp[3] &= 0x00ffffff; 337 } else { 338 for (i = 0; i < 3; i++) 339 rh[i] = bus_space_read_4(sc->sc_iot, 340 sc->sc_ioh, MVSDIO_RH(i)); 341 cmd->c_resp[0] = 342 ((rh[0] & 0x03ff) << 22) | 343 ((rh[1] ) << 6) | 344 ((rh[2] & 0x003f) << 0); 345 cmd->c_resp[1] = (rh[0] & 0xfc00) >> 10; 346 cmd->c_resp[2] = 0; 347 cmd->c_resp[3] = 0; 348 } 349 } 350 if (nis & NIS_UNEXPECTEDRESPDET) 351 cmd->c_error = EIO; 352 cv_signal(&sc->sc_cv); 353 } 354 355 if (nis & NIS_CARDINT) 356 if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE) & 357 NIS_CARDINT) { 358 sdmmc_card_intr(sc->sc_sdmmc); 359 handled = 1; 360 } 361 362 return handled; 363 } 364 365 static int 366 mvsdio_host_reset(sdmmc_chipset_handle_t sch) 367 { 368 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 369 370 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_SR, SR_SWRESET); 371 return 0; 372 } 373 374 static uint32_t 375 mvsdio_host_ocr(sdmmc_chipset_handle_t sch) 376 { 377 378 return MMC_OCR_3_3V_3_4V | MMC_OCR_3_2V_3_3V; 379 } 380 381 static int 382 mvsdio_host_maxblklen(sdmmc_chipset_handle_t sch) 383 { 384 385 return DBS_BLOCKSIZE_MAX; 386 } 387 388 #ifndef MVSDIO_CARD_DETECT 389 static int 390 mvsdio_card_detect(sdmmc_chipset_handle_t sch) 391 { 392 struct mvsdio_softc *sc __unused = (struct mvsdio_softc *)sch; 393 394 DPRINTF(2, ("%s: driver lacks card_detect() function.\n", 395 device_xname(sc->sc_dev))); 396 return 1; /* always detect */ 397 } 398 #endif 399 400 #ifndef MVSDIO_WRITE_PROTECT 401 static int 402 mvsdio_write_protect(sdmmc_chipset_handle_t sch) 403 { 404 405 /* Nothing */ 406 407 return 0; 408 } 409 #endif 410 411 static int 412 mvsdio_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 413 { 414 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 415 uint32_t reg; 416 417 /* Initial state is Open Drain on CMD line. */ 418 mutex_enter(&sc->sc_mtx); 419 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 420 reg &= ~HC_PUSHPULLEN; 421 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 422 mutex_exit(&sc->sc_mtx); 423 424 return 0; 425 } 426 427 static int 428 mvsdio_bus_clock(sdmmc_chipset_handle_t sch, int freq) 429 { 430 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 431 uint32_t reg; 432 int m; 433 434 mutex_enter(&sc->sc_mtx); 435 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM); 436 437 /* Just stop the clock. */ 438 if (freq == 0) { 439 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM, 440 reg | TM_STOPCLKEN); 441 goto out; 442 } 443 444 #define FREQ_TO_M(f) (100000 / (f) - 1) 445 446 m = FREQ_TO_M(freq); 447 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_CDV, 448 m & CDV_CLKDVDRMVALUE_MASK); 449 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM, 450 reg & ~TM_STOPCLKEN); 451 452 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 453 if (freq > 25000) 454 reg |= HC_HISPEEDEN; 455 else 456 reg &= ~HC_HISPEEDEN; /* up to 25 MHz */ 457 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 458 459 out: 460 mutex_exit(&sc->sc_mtx); 461 462 return 0; 463 } 464 465 static int 466 mvsdio_bus_width(sdmmc_chipset_handle_t sch, int width) 467 { 468 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 469 uint32_t reg, v; 470 471 switch (width) { 472 case 1: 473 v = 0; 474 break; 475 476 case 4: 477 v = HC_DATAWIDTH; 478 break; 479 480 default: 481 DPRINTF(0, ("%s: unsupported bus width (%d)\n", 482 device_xname(sc->sc_dev), width)); 483 return EINVAL; 484 } 485 486 mutex_enter(&sc->sc_mtx); 487 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 488 reg &= ~HC_DATAWIDTH; 489 reg |= v; 490 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 491 mutex_exit(&sc->sc_mtx); 492 493 return 0; 494 } 495 496 static int 497 mvsdio_bus_rod(sdmmc_chipset_handle_t sch, int on) 498 { 499 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 500 uint32_t reg; 501 502 /* Change Open-drain/Push-pull. */ 503 mutex_enter(&sc->sc_mtx); 504 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 505 if (on) 506 reg &= ~HC_PUSHPULLEN; 507 else 508 reg |= HC_PUSHPULLEN; 509 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, reg); 510 mutex_exit(&sc->sc_mtx); 511 512 return 0; 513 } 514 515 static void 516 mvsdio_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 517 { 518 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 519 uint32_t tm, c, hc, aacc, nisie, wait; 520 int blklen; 521 522 DPRINTF(1, ("%s: start cmd %d arg=%#x data=%p dlen=%d flags=%#x\n", 523 device_xname(sc->sc_dev), cmd->c_opcode, cmd->c_arg, cmd->c_data, 524 cmd->c_datalen, cmd->c_flags)); 525 526 mutex_enter(&sc->sc_mtx); 527 528 tm = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM); 529 530 if (cmd->c_datalen > 0) { 531 bus_dma_segment_t *dm_seg = 532 &cmd->c_dmamap->dm_segs[cmd->c_dmaseg]; 533 bus_addr_t ds_addr = dm_seg->ds_addr + cmd->c_dmaoff; 534 535 blklen = MIN(cmd->c_datalen, cmd->c_blklen); 536 537 if (cmd->c_datalen % blklen > 0) { 538 aprint_error_dev(sc->sc_dev, 539 "data not a multiple of %u bytes\n", blklen); 540 cmd->c_error = EINVAL; 541 goto out; 542 } 543 if ((uint32_t)cmd->c_data & 0x3) { 544 aprint_error_dev(sc->sc_dev, 545 "data not 4byte aligned\n"); 546 cmd->c_error = EINVAL; 547 goto out; 548 } 549 550 /* Set DMA Buffer Address */ 551 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DMABA16LSB, 552 ds_addr & 0xffff); 553 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DMABA16MSB, 554 (ds_addr >> 16) & 0xffff); 555 556 /* Set Data Block Size and Count */ 557 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DBS, 558 DBS_BLOCKSIZE(blklen)); 559 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_DBC, 560 DBC_BLOCKCOUNT(cmd->c_datalen / blklen)); 561 562 tm &= ~TM_HOSTXFERMODE; /* Always DMA */ 563 if (cmd->c_flags & SCF_CMD_READ) 564 tm |= TM_DATAXFERTOWARDHOST; 565 else 566 tm &= ~TM_DATAXFERTOWARDHOST; 567 tm |= TM_HWWRDATAEN; 568 wait = NIS_XFERCOMPLETE; 569 } else { 570 tm &= ~TM_HWWRDATAEN; 571 wait = NIS_CMDCOMPLETE; 572 } 573 574 /* Set Argument in Command */ 575 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AC16LSB, 576 cmd->c_arg & 0xffff); 577 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AC16MSB, 578 (cmd->c_arg >> 16) & 0xffff); 579 580 /* Set Host Control, exclude PushPullEn, DataWidth, HiSpeedEn. */ 581 hc = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC); 582 hc |= (HC_TIMEOUTVALUE_MAX | HC_TIMEOUTEN); 583 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_HC, hc); 584 585 /* Data Block Gap Control: Resume */ 586 587 /* Clock Control: SclkMasterEn */ 588 589 if (cmd->c_opcode == MMC_READ_BLOCK_MULTIPLE || 590 cmd->c_opcode == MMC_WRITE_BLOCK_MULTIPLE) { 591 aacc = 0; 592 #if 1 /* XXXX: need? */ 593 if (cmd->c_opcode == MMC_READ_BLOCK_MULTIPLE) { 594 struct sdmmc_softc *sdmmc = 595 device_private(sc->sc_sdmmc); 596 struct sdmmc_function *sf = sdmmc->sc_card; 597 598 aacc = MMC_ARG_RCA(sf->rca); 599 } 600 #endif 601 602 /* Set Argument in Auto Cmd12 Command */ 603 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AACC16LSBT, 604 aacc & 0xffff); 605 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_AACC16MSBT, 606 (aacc >> 16) & 0xffff); 607 608 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_IACCT, 609 IACCT_AUTOCMD12BUSYCHKEN | 610 IACCT_AUTOCMD12INDEXCHKEN | 611 IACCT_AUTOCMD12INDEX); 612 613 tm |= TM_AUTOCMD12EN; 614 wait = NIS_AUTOCMD12COMPLETE; 615 } else 616 tm &= ~TM_AUTOCMD12EN; 617 618 tm |= TM_INTCHKEN; 619 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_TM, tm); 620 621 c = C_CMDINDEX(cmd->c_opcode); 622 if (cmd->c_flags & SCF_RSP_PRESENT) { 623 if (cmd->c_flags & SCF_RSP_136) 624 c |= C_RESPTYPE_136BR; 625 else if (!(cmd->c_flags & SCF_RSP_BSY)) 626 c |= C_RESPTYPE_48BR; 627 else 628 c |= C_RESPTYPE_48BRCB; 629 c |= C_UNEXPECTEDRESPEN; 630 } else 631 c |= C_RESPTYPE_NR; 632 if (cmd->c_flags & SCF_RSP_CRC) 633 c |= C_CMDCRCCHKEN; 634 if (cmd->c_flags & SCF_RSP_IDX) 635 c |= C_CMDINDEXCHKEN; 636 if (cmd->c_datalen > 0) 637 c |= (C_DATAPRESENT | C_DATACRC16CHKEN); 638 639 DPRINTF(2, ("%s: TM=0x%x, C=0x%x, HC=0x%x\n", __func__, tm, c, hc)); 640 641 nisie = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE); 642 nisie &= ~(NIS_CMDCOMPLETE | NIS_XFERCOMPLETE | NIS_AUTOCMD12COMPLETE); 643 nisie |= wait; 644 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE, nisie); 645 646 /* Execute command */ 647 sc->sc_exec_cmd = cmd; 648 sc->sc_waitintr = wait; 649 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_C, c); 650 651 /* Wait interrupt for complete or error or timeout */ 652 while (sc->sc_exec_cmd == cmd) 653 cv_wait(&sc->sc_cv, &sc->sc_mtx); 654 655 out: 656 mutex_exit(&sc->sc_mtx); 657 658 DPRINTF(1, ("%s: cmd %d done (flags=%08x error=%d)\n", 659 device_xname(sc->sc_dev), 660 cmd->c_opcode, cmd->c_flags, cmd->c_error)); 661 } 662 663 static void 664 mvsdio_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 665 { 666 struct mvsdio_softc *sc = (struct mvsdio_softc *)sch; 667 uint32_t reg; 668 669 mutex_enter(&sc->sc_mtx); 670 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE); 671 reg |= NIS_CARDINT; 672 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_NISIE, reg); 673 mutex_exit(&sc->sc_mtx); 674 } 675 676 static void 677 mvsdio_card_intr_ack(sdmmc_chipset_handle_t sch) 678 { 679 680 /* Nothing */ 681 } 682 683 684 static void 685 mvsdio_wininit(struct mvsdio_softc *sc) 686 { 687 uint64_t base; 688 uint32_t size; 689 int window, target, attr, rv, i; 690 static int tags[] = { 691 MARVELL_TAG_SDRAM_CS0, 692 MARVELL_TAG_SDRAM_CS1, 693 MARVELL_TAG_SDRAM_CS2, 694 MARVELL_TAG_SDRAM_CS3, 695 696 MARVELL_TAG_UNDEFINED, 697 }; 698 699 for (window = 0, i = 0; 700 tags[i] != MARVELL_TAG_UNDEFINED && window < MVSDIO_NWINDOW; i++) { 701 rv = marvell_winparams_by_tag(sc->sc_dev, tags[i], 702 &target, &attr, &base, &size); 703 if (rv != 0 || size == 0) 704 continue; 705 706 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_WC(window), 707 WC_WINEN | 708 WC_TARGET(target) | 709 WC_ATTR(attr) | 710 WC_SIZE(size)); 711 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_WB(window), 712 WB_BASE(base)); 713 window++; 714 } 715 for (; window < MVSDIO_NWINDOW; window++) 716 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSDIO_WC(window), 0); 717 } 718