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