1 /* $NetBSD: s3c2440_sdi.c,v 1.4 2015/05/25 15:04:01 christos Exp $ */ 2 /*- 3 * Copyright (c) 2012 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Paul Fleischer <paul@xpg.dk> 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 #include <sys/cdefs.h> 31 __KERNEL_RCSID(0, "$NetBSD: s3c2440_sdi.c,v 1.4 2015/05/25 15:04:01 christos Exp $"); 32 33 #include <sys/param.h> 34 #include <sys/kernel.h> 35 #include <sys/systm.h> 36 #include <sys/conf.h> 37 #include <sys/malloc.h> /* For M_NOWAIT*/ 38 39 #include <sys/mutex.h> 40 #include <sys/condvar.h> 41 42 #include <sys/bus.h> 43 #include <machine/cpu.h> 44 45 #include <arm/s3c2xx0/s3c24x0var.h> 46 #include <arm/s3c2xx0/s3c2440var.h> 47 #include <arm/s3c2xx0/s3c24x0reg.h> 48 #include <arm/s3c2xx0/s3c2440reg.h> 49 #include <arm/s3c2xx0/s3c2440_dma.h> 50 51 //#include <arm/s3c2xx0/s3c2440_sdi.h> 52 53 #include <dev/sdmmc/sdmmcchip.h> 54 #include <dev/sdmmc/sdmmcvar.h> 55 56 #include <uvm/uvm_extern.h> 57 /*#define SSSDI_DEBUG*/ 58 #ifdef SSSDI_DEBUG 59 #define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 60 #else 61 #define DPRINTF(s) do {} while (/*CONSTCOND*/0) 62 #endif 63 64 struct sssdi_softc { 65 device_t dev; 66 67 bus_space_tag_t iot; 68 69 bus_space_handle_t ioh; 70 bus_space_handle_t card_ioh; /* Card detect I/O*/ 71 72 device_t sdmmc; 73 74 uint32_t caps; 75 76 int width; /* Transfer width */ 77 void *sc_ih; /* SSSDI Interrupt handler */ 78 79 struct kmutex intr_mtx; 80 struct kcondvar intr_cv; 81 uint32_t intr_status; /* Set by the interrupt handler */ 82 83 dmac_xfer_t sc_xfer; 84 85 bus_dma_segment_t sc_dr; 86 }; 87 88 /* Basic driver stuff */ 89 static int sssdi_match(device_t, cfdata_t, void *); 90 static void sssdi_attach(device_t, device_t, void *); 91 92 CFATTACH_DECL_NEW(sssdi, sizeof(struct sssdi_softc), sssdi_match, sssdi_attach, 93 NULL, NULL); 94 95 /* SD/MMC chip functions */ 96 static int sssdi_host_reset(sdmmc_chipset_handle_t); 97 static uint32_t sssdi_host_ocr(sdmmc_chipset_handle_t); 98 static int sssdi_maxblklen(sdmmc_chipset_handle_t); 99 static int sssdi_card_detect(sdmmc_chipset_handle_t); 100 static int sssdi_write_protect(sdmmc_chipset_handle_t); 101 static int sssdi_bus_power(sdmmc_chipset_handle_t, uint32_t); 102 static int sssdi_bus_clock(sdmmc_chipset_handle_t, int); 103 static int sssdi_bus_width(sdmmc_chipset_handle_t, int); 104 static int sssdi_bus_rod(sdmmc_chipset_handle_t, int); 105 static void sssdi_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *); 106 static void sssdi_card_enable_intr(sdmmc_chipset_handle_t, int); 107 static void sssdi_card_intr_ack(sdmmc_chipset_handle_t); 108 109 /* Interrupt Handlers */ 110 int sssdi_intr(void *arg); 111 int sssdi_intr_card(void *arg); 112 113 /* Interrupt helper functions */ 114 static void sssdi_enable_intr(struct sssdi_softc *, uint32_t ); 115 void sssdi_disable_intr(struct sssdi_softc *sc, uint32_t i); 116 void sssdi_clear_intr(struct sssdi_softc *sc); 117 static int sssdi_wait_intr(struct sssdi_softc *sc, uint32_t mask, int timeout); 118 119 /* Programmed I/O transfer helpers */ 120 void sssdi_perform_pio_read(struct sssdi_softc *sc, struct sdmmc_command *cmd); 121 void sssdi_perform_pio_write(struct sssdi_softc *sc, struct sdmmc_command *cmd); 122 123 /* Interrupt helper defines */ 124 #define SDI_CMD_SENT SDIINTMASK_CMD_SENT 125 #define SDI_CMD_TIMEOUT SDIINTMASK_CMD_TIMEOUT 126 #define SDI_RESP_FIN SDIINTMASK_RESP 127 #define SDI_FIFO_RX_FULL SDIINTMASK_RF_FULL 128 #define SDI_FIFO_RX_LAST SDIINTMASK_RF_LAST 129 #define SDI_FIFO_TX_EMPTY SDIINTMASK_TF_EMPTY 130 #define SDI_DATA_FIN SDIINTMASK_DATA_FIN 131 #define SDI_DATA_TIMEOUT SDIINTMASK_DATA_TIMEOUT 132 133 /* Constants */ 134 #define SDI_DMA_WAIT_TIME 5000 /* ms */ 135 #define SDI_CMD_WAIT_TIME 5000 /* ms */ 136 137 /* SDMMC function structure */ 138 struct sdmmc_chip_functions sssdi_functions = { 139 /* host controller reset */ 140 .host_reset = sssdi_host_reset, 141 142 /* host capabilities */ 143 .host_ocr = sssdi_host_ocr, 144 .host_maxblklen = sssdi_maxblklen, 145 146 /* card detection */ 147 .card_detect = sssdi_card_detect, 148 149 /* write protect */ 150 .write_protect = sssdi_write_protect, 151 152 /* bus power, clock frequency and width */ 153 .bus_power = sssdi_bus_power, 154 .bus_clock = sssdi_bus_clock, 155 .bus_width = sssdi_bus_width, 156 .bus_rod = sssdi_bus_rod, 157 158 /* command execution */ 159 .exec_command = sssdi_exec_command, 160 161 /* card interrupt */ 162 .card_enable_intr = sssdi_card_enable_intr, 163 .card_intr_ack = sssdi_card_intr_ack, 164 }; 165 166 int 167 sssdi_match(device_t parent, cfdata_t match, void *aux) 168 { 169 /* struct s3c2xx0_attach_args *sa = aux;*/ 170 171 /* Not sure how to match here, maybe CPU type? */ 172 return 1; 173 } 174 175 void 176 sssdi_attach(device_t parent, device_t self, void *aux) 177 { 178 struct sssdi_softc *sc = device_private(self); 179 struct s3c2xx0_attach_args *sa = (struct s3c2xx0_attach_args *)aux; 180 struct sdmmcbus_attach_args saa; 181 bus_space_tag_t iot = sa->sa_iot; 182 uint32_t data; 183 184 sc->dev = self; 185 sc->iot = iot; 186 187 if (bus_space_map(iot, S3C2440_SDI_BASE, S3C2440_SDI_SIZE, 0, &sc->ioh) ) { 188 printf(": failed to map registers"); 189 return; 190 } 191 192 if (bus_space_map(iot, S3C2440_GPIO_BASE, S3C2440_GPIO_SIZE, 0, &sc->card_ioh) ) { 193 printf(": failed to map GPIO memory for card detection"); 194 return; 195 } 196 197 /* Set GPG8 to EINT[16], as it is the card detect line. */ 198 data = bus_space_read_4(sc->iot, sc->card_ioh, GPIO_PGCON); 199 data = GPIO_SET_FUNC(data, 8, 0x2); 200 bus_space_write_4(sc->iot, sc->card_ioh, GPIO_PGCON, data); 201 202 /* Set GPH8 to input, as it is used to detect write protection. */ 203 data = bus_space_read_4(sc->iot, sc->card_ioh, GPIO_PHCON); 204 data = GPIO_SET_FUNC(data, 8, 0x00); 205 bus_space_write_4(sc->iot, sc->card_ioh, GPIO_PHCON, data); 206 207 mutex_init(&sc->intr_mtx, MUTEX_DEFAULT, IPL_SDMMC); 208 209 cv_init(&sc->intr_cv, "s3c2440_sdiintr"); 210 sc->intr_status = 0; 211 sc->caps = SMC_CAPS_4BIT_MODE | SMC_CAPS_DMA | SMC_CAPS_MULTI_SEG_DMA; 212 213 memset(&saa, 0, sizeof(saa)); 214 saa.saa_busname = "sdmmc"; 215 saa.saa_sct = &sssdi_functions; 216 saa.saa_sch = sc; 217 saa.saa_dmat = sa->sa_dmat; 218 saa.saa_clkmin = s3c2xx0_softc->sc_pclk / 256; 219 saa.saa_clkmax = s3c2xx0_softc->sc_pclk / 1; /* PCLK/1 or PCLK/2 depending on how the spec is read */ 220 saa.saa_caps = sc->caps; 221 222 /* Attach our interrupt handler */ 223 sc->sc_ih = s3c24x0_intr_establish(S3C2410_INT_SDI, IPL_SDMMC, IST_EDGE_RISING, sssdi_intr, sc); 224 225 /* Attach interrupt handler to detect change in card status */ 226 s3c2440_extint_establish(16, IPL_SDMMC, IST_EDGE_BOTH, sssdi_intr_card, sc); 227 228 data = bus_space_read_4(s3c2xx0_softc->sc_iot, s3c2xx0_softc->sc_clkman_ioh, CLKMAN_CLKCON); 229 bus_space_write_4(s3c2xx0_softc->sc_iot, s3c2xx0_softc->sc_clkman_ioh, CLKMAN_CLKCON, data | CLKCON_SDI); 230 231 (void) sssdi_host_reset(sc); 232 233 printf("\n"); 234 235 /* Attach to the generic SD/MMC bus */ 236 /* Is it a good idea to get the private parts of sdmmc ? */ 237 sc->sdmmc = config_found(sc->dev, &saa, NULL); 238 239 sc->sc_xfer = s3c2440_dmac_allocate_xfer(M_NOWAIT); 240 sc->sc_dr.ds_addr = S3C2440_SDI_BASE+SDI_DAT_LI_W; 241 sc->sc_dr.ds_len = 4; 242 } 243 244 int 245 sssdi_host_reset(sdmmc_chipset_handle_t sch) 246 { 247 struct sssdi_softc *sc = (struct sssdi_softc*)sch; 248 249 /* Note that we do not enable the clock just yet. */ 250 bus_space_write_4(sc->iot, sc->ioh, SDI_CON, SDICON_SD_RESET | 251 SDICON_CTYP_SD | SDICON_RCV_IO_INT); 252 /* bus_space_write_4(sc->iot, sc->ioh, SDI_CMD_STA, SDICMDSTA_RSP_CRC | SDICMDSTA_CMD_SENT | 253 SDICMDSTA_CMD_TIMEOUT | SDICMDSTA_RSP_FIN);*/ 254 255 sssdi_clear_intr(sc); 256 sssdi_enable_intr(sc, SDI_CMD_SENT | SDI_CMD_TIMEOUT | SDI_DATA_TIMEOUT 257 | SDI_RESP_FIN); 258 259 return 0; 260 } 261 262 uint32_t 263 sssdi_host_ocr(sdmmc_chipset_handle_t sch) 264 { 265 /* This really ought to be made configurable, I guess... */ 266 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; 267 } 268 269 int 270 sssdi_maxblklen(sdmmc_chipset_handle_t sch) 271 { 272 /* The S3C2440 user's manual mentions 4095 as a maximum */ 273 return 4095; 274 } 275 276 int 277 sssdi_card_detect(sdmmc_chipset_handle_t sch) 278 { 279 struct sssdi_softc *sc = (struct sssdi_softc*)sch; 280 uint32_t data; 281 282 DPRINTF(("sssdi_card_detect\n")); 283 284 data = bus_space_read_4(sc->iot, sc->card_ioh, GPIO_PGDAT); 285 286 /* GPIO Port G, pin 8 is high when card is inserted. */ 287 if ( (data & (1<<8)) == 0) { 288 return 1; /* Card Present */ 289 } else { 290 return 0; /* No Card */ 291 } 292 } 293 294 int 295 sssdi_write_protect(sdmmc_chipset_handle_t sch) 296 { 297 struct sssdi_softc *sc = (struct sssdi_softc*)sch; 298 uint32_t data; 299 300 data = bus_space_read_4(sc->iot, sc->card_ioh, GPIO_PHDAT); 301 302 303 /* If GPIO Port H Pin 8 is high, the card is write protected. */ 304 if ( (data & (1<<8)) ) { 305 return 1; /* Write protected */ 306 } else { 307 return 0; /* Writable */ 308 } 309 } 310 311 int 312 sssdi_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 313 { 314 /* Do nothing, we can't adjust the bus power */ 315 return 0; 316 } 317 318 int 319 sssdi_bus_clock(sdmmc_chipset_handle_t sch, int freq) 320 { 321 struct sssdi_softc *sc = (struct sssdi_softc*)sch; 322 int div; 323 int clock_set = 0; 324 int control; 325 int pclk = s3c2xx0_softc->sc_pclk/1000; /*Peripheral bus clock in KHz*/ 326 327 /* Round peripheral bus clock down to nearest MHz */ 328 pclk = (pclk / 1000) * 1000; 329 330 control = bus_space_read_4(sc->iot, sc->ioh, SDI_CON); 331 bus_space_write_4(sc->iot, sc->ioh, SDI_CON, control & ~SDICON_ENCLK); 332 333 DPRINTF(("sssdi_bus_clock (freq: %d KHz)\n", freq)); 334 335 /* If the frequency is zero just keep the clock disabled */ 336 if (freq == 0) 337 return 0; 338 339 for (div = 1; div <= 256; div++) { 340 if ( pclk / div <= freq) { 341 DPRINTF(("Using divisor %d: %d/%d = %d\n", div, pclk, 342 div, pclk/div)); 343 clock_set = 1; 344 bus_space_write_1(sc->iot, sc->ioh, SDI_PRE, div-1); 345 break; 346 } 347 } 348 349 if (clock_set) { 350 bus_space_write_4(sc->iot, sc->ioh, 351 SDI_CON, control | SDICON_ENCLK); 352 if (div-1 == bus_space_read_4(sc->iot, sc->ioh, SDI_PRE)) { 353 /* Clock successfully set, TODO: how do we fail?! */ 354 } 355 356 /* We do not need to wait here, as the sdmmc code will do that 357 for us. */ 358 return 0; 359 } else { 360 return 1; 361 } 362 } 363 364 int 365 sssdi_bus_width(sdmmc_chipset_handle_t sch, int width) 366 { 367 struct sssdi_softc *sc = (struct sssdi_softc*)sch; 368 369 sc->width = width; 370 return 0; 371 } 372 373 int 374 sssdi_bus_rod(sdmmc_chipset_handle_t sch, int on) 375 { 376 return -1; 377 } 378 379 #define SSSDI_TRANSFER_NONE 0 380 #define SSSDI_TRANSFER_READ 1 381 #define SSSDI_TRANSFER_WRITE 2 382 383 void 384 sssdi_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 385 { 386 struct sssdi_softc *sc = (struct sssdi_softc*)sch; 387 uint32_t cmd_control; 388 int status = 0; 389 #ifdef SSSDI_DEBUG 390 uint32_t data_status; 391 #endif 392 int transfer = SSSDI_TRANSFER_NONE; 393 dmac_xfer_t xfer; 394 395 /* Reset all status registers prior to sending a command */ 396 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_FSTA, 0xFFFFFFFF); 397 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_STA, 0xFFFFFFFF); 398 bus_space_write_4(sc->iot, sc->ioh, SDI_CMD_STA, 0xFFFFFFFF); 399 400 /* Set the argument */ 401 bus_space_write_4(sc->iot, sc->ioh, SDI_CMD_ARG, cmd->c_arg); 402 403 /* Prepare the value for the command control register */ 404 cmd_control = (cmd->c_opcode & SDICMDCON_CMD_MASK) | 405 SDICMDCON_HOST_CMD | SDICMDCON_CMST; 406 if (cmd->c_flags & SCF_RSP_PRESENT) 407 cmd_control |= SDICMDCON_WAIT_RSP; 408 if (cmd->c_flags & SCF_RSP_136) 409 cmd_control |= SDICMDCON_LONG_RSP; 410 411 if (cmd->c_datalen > 0 && cmd->c_data != NULL) { 412 /* TODO: Ensure that the above condition matches the semantics 413 of SDICMDCON_WITH_DATA*/ 414 DPRINTF(("DATA, datalen: %d, blk_size: %d\n", cmd->c_datalen, 415 cmd->c_blklen)); 416 cmd_control |= SDICMDCON_WITH_DATA; 417 } 418 419 /* Unfortunately we have to set the ABORT_CMD bit when using CMD12 and 420 CMD52. 421 CMD12 is MMC_STOP_TRANSMISSION. I currently do not know what CMD52 422 is, but it is related to SDIO. 423 */ 424 if (cmd->c_opcode == MMC_STOP_TRANSMISSION) { 425 cmd_control |= SDICMDCON_ABORT_CMD; 426 } 427 428 /* Prepare SDI for data transfer */ 429 bus_space_write_4(sc->iot, sc->ioh, SDI_BSIZE, cmd->c_blklen); 430 431 /* Set maximum transfer timeout */ 432 bus_space_write_4(sc->iot, sc->ioh, SDI_DTIMER, 0x007FFFFF); 433 434 /* Set the timeout as low as possible to trigger timeouts for debugging purposes */ 435 /*bus_space_write_4(sc->iot, sc->ioh, SDI_DTIMER, 0x00005000);*/ 436 437 if ( (cmd->c_flags & SCF_CMD_READ) && 438 (cmd_control & SDICMDCON_WITH_DATA)) { 439 uint32_t data_control; 440 DPRINTF(("Reading %d bytes\n", cmd->c_datalen)); 441 transfer = SSSDI_TRANSFER_READ; 442 443 data_control = SDIDATCON_DATMODE_RECEIVE | SDIDATCON_RACMD | 444 SDIDATCON_DTST | SDIDATCON_BLKMODE | 445 ((cmd->c_datalen / cmd->c_blklen) & SDIDATCON_BLKNUM_MASK) | 446 SDIDATCON_DATA_WORD; 447 448 if (sc->caps & SMC_CAPS_DMA) { 449 data_control |= SDIDATCON_ENDMA; 450 xfer = sc->sc_xfer; 451 xfer->dx_desc[DMAC_DESC_SRC].xd_bus_type = DMAC_BUS_TYPE_PERIPHERAL; 452 xfer->dx_desc[DMAC_DESC_SRC].xd_increment = FALSE; 453 xfer->dx_desc[DMAC_DESC_SRC].xd_nsegs = 1; 454 xfer->dx_desc[DMAC_DESC_SRC].xd_dma_segs = &sc->sc_dr; 455 456 xfer->dx_desc[DMAC_DESC_DST].xd_bus_type = DMAC_BUS_TYPE_SYSTEM; 457 xfer->dx_desc[DMAC_DESC_DST].xd_increment = TRUE; 458 xfer->dx_desc[DMAC_DESC_DST].xd_nsegs = cmd->c_dmamap->dm_nsegs; 459 xfer->dx_desc[DMAC_DESC_DST].xd_dma_segs = cmd->c_dmamap->dm_segs; 460 461 /* Let the SD/MMC peripheral control the DMA transfer */ 462 xfer->dx_peripheral = DMAC_PERIPH_SDI; 463 xfer->dx_xfer_width = DMAC_XFER_WIDTH_32BIT; 464 } 465 if (sc->width == 4) { 466 data_control |= SDIDATCON_WIDEBUS; 467 } 468 469 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_CON, data_control); 470 } else if (cmd_control & SDICMDCON_WITH_DATA) { 471 /* Write data */ 472 473 uint32_t data_control; 474 DPRINTF(("Writing %d bytes\n", cmd->c_datalen)); 475 DPRINTF(("Requesting %d blocks\n", 476 cmd->c_datalen / cmd->c_blklen)); 477 transfer = SSSDI_TRANSFER_WRITE; 478 data_control = SDIDATCON_DATMODE_TRANSMIT | SDIDATCON_BLKMODE | 479 SDIDATCON_TARSP | SDIDATCON_DTST | 480 ((cmd->c_datalen / cmd->c_blklen) & SDIDATCON_BLKNUM_MASK) | 481 SDIDATCON_DATA_WORD; 482 483 if (sc->caps & SMC_CAPS_DMA) { 484 data_control |= SDIDATCON_ENDMA; 485 xfer = sc->sc_xfer; 486 487 xfer->dx_desc[DMAC_DESC_DST].xd_bus_type = DMAC_BUS_TYPE_PERIPHERAL; 488 xfer->dx_desc[DMAC_DESC_DST].xd_increment = FALSE; 489 xfer->dx_desc[DMAC_DESC_DST].xd_nsegs = 1; 490 xfer->dx_desc[DMAC_DESC_DST].xd_dma_segs = &sc->sc_dr; 491 492 xfer->dx_desc[DMAC_DESC_SRC].xd_bus_type = DMAC_BUS_TYPE_SYSTEM; 493 xfer->dx_desc[DMAC_DESC_SRC].xd_increment = TRUE; 494 xfer->dx_desc[DMAC_DESC_SRC].xd_nsegs = cmd->c_dmamap->dm_nsegs; 495 xfer->dx_desc[DMAC_DESC_SRC].xd_dma_segs = cmd->c_dmamap->dm_segs; 496 497 /* Let the SD/MMC peripheral control the DMA transfer */ 498 xfer->dx_peripheral = DMAC_PERIPH_SDI; 499 xfer->dx_xfer_width = DMAC_XFER_WIDTH_32BIT; 500 } 501 if (sc->width == 4) { 502 data_control |= SDIDATCON_WIDEBUS; 503 } 504 505 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_CON, data_control); 506 } 507 508 /* Send command to SDI */ 509 bus_space_write_4(sc->iot, sc->ioh, SDI_CMD_CON, cmd_control); 510 511 /* Wait for command sent acknowledgement, timeout set to 5000ms */ 512 status = sssdi_wait_intr(sc, SDI_CMD_SENT | SDI_CMD_TIMEOUT, mstohz(SDI_CMD_WAIT_TIME)); 513 514 if (status & SDI_CMD_TIMEOUT) { 515 DPRINTF(("Timeout waiting for command acknowledgement\n")); 516 cmd->c_error = ETIMEDOUT; 517 goto out; 518 } else if (status & SDICMDSTA_CMD_SENT) { 519 /* Interrupt handler has acknowledged already, we do not need 520 to do anything further here */ 521 } 522 523 if (!(cmd_control & SDICMDCON_WAIT_RSP)) { 524 cmd->c_flags |= SCF_ITSDONE; 525 goto out; 526 } 527 528 DPRINTF(("waiting for response\n")); 529 530 status = sssdi_wait_intr(sc, SDI_RESP_FIN | SDI_DATA_TIMEOUT, 100); 531 if (status & SDI_CMD_TIMEOUT || status & SDI_DATA_TIMEOUT) { 532 cmd->c_error = ETIMEDOUT; 533 DPRINTF(("Timeout waiting for response\n")); 534 goto out; 535 } 536 DPRINTF(("Got Response\n")); 537 538 539 if (cmd->c_flags & SCF_RSP_136 ) { 540 uint32_t w[4]; 541 542 /* We store the response least significant word first */ 543 w[0] = bus_space_read_4(sc->iot, sc->ioh, SDI_RSP3); 544 w[1] = bus_space_read_4(sc->iot, sc->ioh, SDI_RSP2); 545 w[2] = bus_space_read_4(sc->iot, sc->ioh, SDI_RSP1); 546 w[3] = bus_space_read_4(sc->iot, sc->ioh, SDI_RSP0); 547 548 /* The sdmmc subsystem expects that the response is delivered 549 without the lower 8 bits (CRC + '1' bit) */ 550 cmd->c_resp[0] = (w[0] >> 8) | ((w[1] & 0xFF) << 24); 551 cmd->c_resp[1] = (w[1] >> 8) | ((w[2] & 0XFF) << 24); 552 cmd->c_resp[2] = (w[2] >> 8) | ((w[3] & 0XFF) << 24); 553 cmd->c_resp[3] = (w[3] >> 8); 554 555 } else { 556 cmd->c_resp[0] = bus_space_read_4(sc->iot, sc->ioh, SDI_RSP0); 557 cmd->c_resp[1] = bus_space_read_4(sc->iot, sc->ioh, SDI_RSP1); 558 } 559 560 DPRINTF(("Response: %X %X %X %X\n", 561 cmd->c_resp[0], 562 cmd->c_resp[1], 563 cmd->c_resp[2], 564 cmd->c_resp[3])); 565 566 status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_CNT); 567 568 DPRINTF(("Remaining bytes of current block: %d\n", 569 SDIDATCNT_BLK_CNT(status))); 570 DPRINTF(("Remaining Block Number : %d\n", 571 SDIDATCNT_BLK_NUM_CNT(status))); 572 573 #ifdef SSSDI_DEBUG 574 data_status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_STA); 575 printf("SDI Data Status Register Before xfer: 0x%X\n", data_status); 576 #endif 577 if (transfer == SSSDI_TRANSFER_READ) { 578 DPRINTF(("Waiting for transfer to complete\n")); 579 580 if (sc->sc_xfer != NULL ) { 581 int dma_error = 0; 582 /* It might not be very efficient to delay the start of 583 the DMA transfer until now, but it works :-). 584 */ 585 s3c2440_dmac_start_xfer(sc->sc_xfer); 586 587 /* Wait until the transfer has completed, timeout is 588 500ms */ 589 dma_error = s3c2440_dmac_wait_xfer(sc->sc_xfer, mstohz(SDI_DMA_WAIT_TIME)); 590 if (dma_error != 0) { 591 //s3c2440_dma_xfer_abort(sc->dma_xfer, mstohz(100)); /* XXX: Handle timeout during abort */ 592 cmd->c_error = dma_error; 593 DPRINTF(("DMA xfer failed: %d\n", dma_error)); 594 goto out; 595 } 596 } else { 597 DPRINTF(("PIO READ\n")); 598 sssdi_perform_pio_read(sc, cmd); 599 } 600 } else if (transfer == SSSDI_TRANSFER_WRITE) { 601 DPRINTF(("Waiting for WRITE transfer to complete\n")); 602 603 if (sc->sc_xfer != NULL) { 604 int dma_error = 0; 605 s3c2440_dmac_start_xfer(sc->sc_xfer); 606 607 dma_error = s3c2440_dmac_wait_xfer(sc->sc_xfer, mstohz(SDI_DMA_WAIT_TIME)); 608 if (dma_error != 0) { 609 //s3c2440_dma_xfer_abort(sc->dma_xfer, mstohz(100)); /* XXX: Handle timeout during abort*/ 610 cmd->c_error = dma_error; 611 DPRINTF(("DMA xfer failed: %d\n", dma_error)); 612 goto out; 613 } 614 } else { 615 DPRINTF(("PIO WRITE\n")); 616 sssdi_perform_pio_write(sc, cmd); 617 } 618 619 if (cmd->c_error == ETIMEDOUT) 620 goto out; 621 622 DPRINTF(("Waiting for transfer to complete\n")); 623 status = sssdi_wait_intr(sc, SDI_DATA_FIN | SDI_DATA_TIMEOUT, 1000); 624 if (status & SDI_CMD_TIMEOUT || status & SDI_DATA_TIMEOUT) { 625 cmd->c_error = ETIMEDOUT; 626 DPRINTF(("Timeout waiting for data to complete\n")); 627 goto out; 628 } 629 DPRINTF(("Done\n")); 630 631 } 632 633 634 /* Response has been received, and any data transfer needed has been 635 performed */ 636 cmd->c_flags |= SCF_ITSDONE; 637 638 out: 639 640 #ifdef SSSDI_DEBUG 641 data_status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_STA); 642 printf("SDI Data Status Register after execute: 0x%X\n", data_status); 643 #endif 644 645 /* Clear status register. Their are cleared on the 646 next sssdi_exec_command */ 647 bus_space_write_4(sc->iot, sc->ioh, SDI_CMD_STA, 0xFFFFFFFF); 648 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_CON, 0x0); 649 } 650 651 void sssdi_perform_pio_read(struct sssdi_softc *sc, struct sdmmc_command *cmd) 652 { 653 uint32_t fifo_status; 654 int count; 655 uint32_t written; 656 uint32_t *dest = (uint32_t*)cmd->c_data; 657 658 written = 0; 659 660 while (written < cmd->c_datalen ) { 661 /* Wait until the FIFO is full or has the final data. 662 In the latter case it might not get filled. */ 663 sssdi_wait_intr(sc, SDI_FIFO_RX_FULL | SDI_FIFO_RX_LAST, 1000); 664 665 fifo_status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_FSTA); 666 count = SDIDATFSTA_FFCNT(fifo_status); 667 668 for(int i=0; i<count; i+=4) { 669 uint32_t buf; 670 671 buf = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_LI_W); 672 *dest = buf; 673 written += 4; 674 dest++; 675 } 676 } 677 } 678 679 void 680 sssdi_perform_pio_write(struct sssdi_softc *sc, struct sdmmc_command *cmd) 681 { 682 uint32_t status; 683 uint32_t fifo_status; 684 int count; 685 uint32_t written; 686 uint32_t *dest = (uint32_t*)cmd->c_data; 687 688 written = 0; 689 690 while (written < cmd->c_datalen ) { 691 /* Wait until the FIFO is full or has the final data. 692 In the latter case it might not get filled. */ 693 DPRINTF(("Waiting for FIFO to become empty\n")); 694 status = sssdi_wait_intr(sc, SDI_FIFO_TX_EMPTY, 1000); 695 696 fifo_status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_FSTA); 697 DPRINTF(("PIO Write FIFO Status: 0x%X\n", fifo_status)); 698 count = 64-SDIDATFSTA_FFCNT(fifo_status); 699 700 status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_CNT); 701 DPRINTF(("Remaining bytes of current block: %d\n", 702 SDIDATCNT_BLK_CNT(status))); 703 DPRINTF(("Remaining Block Number : %d\n", 704 SDIDATCNT_BLK_NUM_CNT(status))); 705 706 707 status = bus_space_read_4(sc->iot,sc->ioh, SDI_DAT_STA); 708 DPRINTF(("PIO Write Data Status: 0x%X\n", status)); 709 710 if (status & SDIDATSTA_DATA_TIMEOUT) { 711 cmd->c_error = ETIMEDOUT; 712 /* Acknowledge the timeout*/ 713 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_STA, 714 SDIDATSTA_DATA_TIMEOUT); 715 printf("%s: Data timeout\n", device_xname(sc->dev)); 716 break; 717 } 718 719 DPRINTF(("Filling FIFO with %d bytes\n", count)); 720 for(int i=0; i<count; i+=4) { 721 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_LI_W, *dest); 722 written += 4; 723 dest++; 724 } 725 } 726 } 727 728 729 void 730 sssdi_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 731 { 732 printf("sssdi_card_enable_intr not implemented\n"); 733 } 734 735 void 736 sssdi_card_intr_ack(sdmmc_chipset_handle_t sch) 737 { 738 printf("sssdi_card_intr_ack not implemented\n"); 739 } 740 741 int 742 sssdi_intr(void *arg) 743 { 744 struct sssdi_softc *sc = (struct sssdi_softc*)arg; 745 uint32_t status; 746 uint32_t ack_status; 747 748 /* Start by dealing with Command Status */ 749 ack_status = 0; 750 status = bus_space_read_4(sc->iot, sc->ioh, SDI_CMD_STA); 751 752 if (status & SDICMDSTA_CMD_TIMEOUT) { 753 ack_status |= SDICMDSTA_CMD_TIMEOUT; 754 sc->intr_status |= SDI_CMD_TIMEOUT; 755 /*sssdi_disable_intr(sc, SDI_CMD_TIMEOUT);*/ 756 } 757 if (status & SDICMDSTA_CMD_SENT) { 758 ack_status |= SDICMDSTA_CMD_SENT; 759 sc->intr_status |= SDI_CMD_SENT; 760 /* sssdi_disable_intr(sc, SDI_CMD_SENT);*/ 761 } 762 if (status & SDICMDSTA_RSP_FIN) { 763 ack_status |= SDICMDSTA_RSP_FIN; 764 sc->intr_status |= SDI_RESP_FIN; 765 /* sssdi_disable_intr(sc, SDI_RESP_FIN);*/ 766 } 767 bus_space_write_4(sc->iot, sc->ioh, SDI_CMD_STA, ack_status); 768 769 /* Next: FIFO Status */ 770 ack_status = 0; 771 status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_FSTA); 772 if (status & SDIDATFSTA_RF_FULL) { 773 ack_status |= SDIDATFSTA_RF_FULL; 774 sc->intr_status |= SDI_FIFO_RX_FULL; 775 sssdi_disable_intr(sc, SDI_FIFO_RX_FULL); 776 } 777 if (status & SDIDATFSTA_RF_LAST) { 778 ack_status |= SDIDATFSTA_RF_LAST | SDIDATFSTA_RESET; 779 sc->intr_status |= SDI_FIFO_RX_LAST; 780 sssdi_disable_intr(sc, SDI_FIFO_RX_LAST); 781 } 782 if (status & SDIDATFSTA_TF_EMPTY) { 783 ack_status |= SDIDATFSTA_TF_EMPTY; 784 sc->intr_status |= SDI_FIFO_TX_EMPTY; 785 sssdi_disable_intr(sc, SDI_FIFO_TX_EMPTY); 786 } 787 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_FSTA, ack_status); 788 789 ack_status = 0; 790 status = bus_space_read_4(sc->iot, sc->ioh, SDI_DAT_STA); 791 if (status & SDIDATSTA_DATA_FIN) { 792 DPRINTF(("sssdi_intr: DATA FINISHED\n")); 793 ack_status |= SDIDATSTA_DATA_FIN; 794 sc->intr_status |= SDI_DATA_FIN; 795 sssdi_disable_intr(sc, SDI_DATA_FIN); 796 } 797 if (status & SDIDATSTA_DATA_TIMEOUT) { 798 printf("sssdi_intr: DATA TIMEOUT\n"); 799 ack_status |= SDIDATSTA_DATA_TIMEOUT; 800 sc->intr_status |= SDI_DATA_TIMEOUT; 801 /* Data timeout interrupt is always enabled, thus 802 we do not disable it when we have received one. */ 803 /*sssdi_disable_intr(sc, SDI_DATA_TIMEOUT);*/ 804 805 if (sc->sc_xfer != NULL) { 806 s3c2440_dmac_abort_xfer(sc->sc_xfer); 807 } 808 } 809 bus_space_write_4(sc->iot, sc->ioh, SDI_DAT_STA, ack_status); 810 811 mutex_enter(&sc->intr_mtx); 812 cv_broadcast(&sc->intr_cv); 813 mutex_exit(&sc->intr_mtx); 814 815 return 1; 816 } 817 818 int 819 sssdi_intr_card(void *arg) 820 { 821 struct sssdi_softc *sc = (struct sssdi_softc*)arg; 822 823 /* TODO: If card was removed then abort any current command */ 824 825 sdmmc_needs_discover(sc->sdmmc); 826 827 return 1; /* handled */ 828 } 829 830 static void 831 sssdi_enable_intr(struct sssdi_softc *sc, uint32_t i) 832 { 833 uint32_t v = bus_space_read_4(sc->iot, sc->ioh, SDI_INT_MASK); 834 bus_space_write_4(sc->iot, sc->ioh, SDI_INT_MASK, v | i ); 835 } 836 837 void 838 sssdi_disable_intr(struct sssdi_softc *sc, uint32_t i) 839 { 840 uint32_t v = bus_space_read_4(sc->iot, sc->ioh, SDI_INT_MASK); 841 bus_space_write_4(sc->iot, sc->ioh, SDI_INT_MASK, v & ~i ); 842 } 843 844 void 845 sssdi_clear_intr(struct sssdi_softc *sc) 846 { 847 bus_space_write_4(sc->iot, sc->ioh, SDI_INT_MASK, 0x0); 848 } 849 850 static int 851 sssdi_wait_intr(struct sssdi_softc *sc, uint32_t mask, int timeout) 852 { 853 uint32_t status; 854 855 /* Wait until the command has been sent */ 856 mutex_enter(&sc->intr_mtx); 857 sssdi_enable_intr(sc, mask); 858 status = sc->intr_status & mask; 859 while(status == 0) { 860 861 if (cv_timedwait(&sc->intr_cv, &sc->intr_mtx, timeout) == 862 EWOULDBLOCK ) { 863 DPRINTF(("Timed out waiting for interrupt from SDI controller\n")); 864 status |= SDI_CMD_TIMEOUT; 865 break; 866 } 867 868 status = sc->intr_status & mask; 869 } 870 871 sc->intr_status &= ~status; 872 mutex_exit(&sc->intr_mtx); 873 874 return status; 875 } 876