fsl_sdhc.c revision 318198
1/*- 2 * Copyright (c) 2011-2012 Semihalf 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Driver for Freescale integrated eSDHC controller. 29 * Limitations: 30 * - No support for multi-block transfers. 31 */ 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: stable/10/sys/powerpc/mpc85xx/fsl_sdhc.c 318198 2017-05-11 21:01:02Z marius $"); 35 36#include <sys/param.h> 37#include <sys/bus.h> 38#include <sys/kernel.h> 39#include <sys/lock.h> 40#include <sys/module.h> 41#include <sys/mutex.h> 42#include <sys/rman.h> 43#include <sys/sysctl.h> 44#include <sys/systm.h> 45#include <sys/taskqueue.h> 46 47#include <machine/bus.h> 48#include <machine/vmparam.h> 49 50#include <dev/fdt/fdt_common.h> 51#include <dev/ofw/ofw_bus.h> 52#include <dev/ofw/ofw_bus_subr.h> 53 54#include <dev/mmc/bridge.h> 55#include <dev/mmc/mmcreg.h> 56#include <dev/mmc/mmcvar.h> 57#include <dev/mmc/mmcbrvar.h> 58 59#include <powerpc/mpc85xx/mpc85xx.h> 60 61#include "opt_platform.h" 62 63#include "mmcbr_if.h" 64 65#include "fsl_sdhc.h" 66 67#ifdef DEBUG 68#define DPRINTF(fmt, arg...) printf("DEBUG %s(): " fmt, __FUNCTION__, ##arg) 69#else 70#define DPRINTF(fmt, arg...) 71#endif 72 73 74/***************************************************************************** 75 * Register the driver 76 *****************************************************************************/ 77/* Forward declarations */ 78static int fsl_sdhc_probe(device_t); 79static int fsl_sdhc_attach(device_t); 80static int fsl_sdhc_detach(device_t); 81 82static int fsl_sdhc_read_ivar(device_t, device_t, int, uintptr_t *); 83static int fsl_sdhc_write_ivar(device_t, device_t, int, uintptr_t); 84 85static int fsl_sdhc_update_ios(device_t, device_t); 86static int fsl_sdhc_request(device_t, device_t, struct mmc_request *); 87static int fsl_sdhc_get_ro(device_t, device_t); 88static int fsl_sdhc_acquire_host(device_t, device_t); 89static int fsl_sdhc_release_host(device_t, device_t); 90 91static device_method_t fsl_sdhc_methods[] = { 92 /* device_if */ 93 DEVMETHOD(device_probe, fsl_sdhc_probe), 94 DEVMETHOD(device_attach, fsl_sdhc_attach), 95 DEVMETHOD(device_detach, fsl_sdhc_detach), 96 97 /* Bus interface */ 98 DEVMETHOD(bus_read_ivar, fsl_sdhc_read_ivar), 99 DEVMETHOD(bus_write_ivar, fsl_sdhc_write_ivar), 100 101 /* OFW bus interface */ 102 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 103 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 104 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 105 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 106 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 107 108 /* mmcbr_if */ 109 DEVMETHOD(mmcbr_update_ios, fsl_sdhc_update_ios), 110 DEVMETHOD(mmcbr_request, fsl_sdhc_request), 111 DEVMETHOD(mmcbr_get_ro, fsl_sdhc_get_ro), 112 DEVMETHOD(mmcbr_acquire_host, fsl_sdhc_acquire_host), 113 DEVMETHOD(mmcbr_release_host, fsl_sdhc_release_host), 114 115 {0, 0}, 116}; 117 118/* kobj_class definition */ 119static driver_t fsl_sdhc_driver = { 120 "sdhci", 121 fsl_sdhc_methods, 122 sizeof(struct fsl_sdhc_softc) 123}; 124 125static devclass_t fsl_sdhc_devclass; 126 127DRIVER_MODULE(sdhci, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0); 128DRIVER_MODULE(mmc, sdhci_fsl, mmc_driver, mmc_devclass, NULL, NULL); 129MODULE_DEPEND(sdhci_fsl, mmc, 1, 1, 1); 130 131/***************************************************************************** 132 * Private methods 133 *****************************************************************************/ 134static inline int 135read4(struct fsl_sdhc_softc *sc, unsigned int offset) 136{ 137 138 return bus_space_read_4(sc->bst, sc->bsh, offset); 139} 140 141static inline void 142write4(struct fsl_sdhc_softc *sc, unsigned int offset, int value) 143{ 144 145 bus_space_write_4(sc->bst, sc->bsh, offset, value); 146} 147 148static inline void 149set_bit(struct fsl_sdhc_softc *sc, uint32_t offset, uint32_t mask) 150{ 151 uint32_t x = read4(sc, offset); 152 153 write4(sc, offset, x | mask); 154} 155 156static inline void 157clear_bit(struct fsl_sdhc_softc *sc, uint32_t offset, uint32_t mask) 158{ 159 uint32_t x = read4(sc, offset); 160 161 write4(sc, offset, x & ~mask); 162} 163 164static int 165wait_for_bit_clear(struct fsl_sdhc_softc *sc, enum sdhc_reg_off reg, 166 uint32_t bit) 167{ 168 uint32_t timeout = 10; 169 uint32_t stat; 170 171 stat = read4(sc, reg); 172 while (stat & bit) { 173 if (timeout == 0) { 174 return (-1); 175 } 176 --timeout; 177 DELAY(1000); 178 stat = read4(sc, reg); 179 } 180 181 return (0); 182} 183 184static int 185wait_for_free_line(struct fsl_sdhc_softc *sc, enum sdhc_line line) 186{ 187 uint32_t timeout = 100; 188 uint32_t stat; 189 190 stat = read4(sc, SDHC_PRSSTAT); 191 while (stat & line) { 192 if (timeout == 0) { 193 return (-1); 194 } 195 --timeout; 196 DELAY(1000); 197 stat = read4(sc, SDHC_PRSSTAT); 198 } 199 200 return (0); 201} 202 203static uint32_t 204get_platform_clock(struct fsl_sdhc_softc *sc) 205{ 206 device_t self, parent; 207 phandle_t node; 208 uint32_t clock; 209 210 self = sc->self; 211 node = ofw_bus_get_node(self); 212 213 /* Get sdhci node properties */ 214 if((OF_getprop(node, "clock-frequency", (void *)&clock, 215 sizeof(clock)) <= 0) || (clock == 0)) { 216 217 /* 218 * Trying to get clock from parent device (soc) if correct 219 * clock cannot be acquired from sdhci node. 220 */ 221 parent = device_get_parent(self); 222 node = ofw_bus_get_node(parent); 223 224 /* Get soc properties */ 225 if ((OF_getprop(node, "bus-frequency", (void *)&clock, 226 sizeof(clock)) <= 0) || (clock == 0)) { 227 device_printf(self,"Cannot acquire correct sdhci " 228 "frequency from DTS.\n"); 229 230 return (0); 231 } 232 } 233 234 DPRINTF("Acquired clock: %d from DTS\n", clock); 235 236 return (clock); 237} 238 239/** 240 * Set clock driving card. 241 * @param sc 242 * @param clock Desired clock frequency in Hz 243 */ 244static void 245set_clock(struct fsl_sdhc_softc *sc, uint32_t clock) 246{ 247 uint32_t base_clock; 248 uint32_t divisor, prescaler = 1; 249 uint32_t round = 0; 250 251 if (clock == sc->slot.clock) 252 return; 253 254 if (clock == 0) { 255 clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL | SYSCTL_PEREN | 256 SYSCTL_HCKEN | SYSCTL_IPGEN); 257 return; 258 } 259 260 base_clock = sc->platform_clock; 261 round = base_clock & 0x2; 262 base_clock >>= 2; 263 base_clock += round; 264 round = 0; 265 266 /* SD specification 1.1 doesn't allow frequences above 50 MHz */ 267 if (clock > FSL_SDHC_MAX_CLOCK) 268 clock = FSL_SDHC_MAX_CLOCK; 269 270 /* 271 * divisor = ceil(base_clock / clock) 272 * TODO: Reconsider symmetric rounding here instead of ceiling. 273 */ 274 divisor = (base_clock + clock - 1) / clock; 275 276 while (divisor > 16) { 277 round = divisor & 0x1; 278 divisor >>= 1; 279 280 prescaler <<= 1; 281 } 282 divisor += round - 1; 283 284 /* Turn off the clock. */ 285 clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL); 286 287 /* Write clock settings. */ 288 set_bit(sc, SDHC_SYSCTL, (prescaler << SHIFT_SDCLKFS) | 289 (divisor << SHIFT_DVS)); 290 291 /* 292 * Turn on clocks. 293 * TODO: This actually disables clock automatic gating off feature of 294 * the controller which eventually should be enabled but as for now 295 * it prevents controller from generating card insertion/removal 296 * interrupts correctly. 297 */ 298 set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN); 299 300 sc->slot.clock = clock; 301 302 DPRINTF("given clock = %d, computed clock = %d\n", clock, 303 (base_clock / prescaler) / (divisor + 1)); 304} 305 306static inline void 307send_80_clock_ticks(struct fsl_sdhc_softc *sc) 308{ 309 int err; 310 311 err = wait_for_free_line(sc, SDHC_CMD_LINE | SDHC_DAT_LINE); 312 if (err != 0) { 313 device_printf(sc->self, "Can't acquire data/cmd lines\n"); 314 return; 315 } 316 317 set_bit(sc, SDHC_SYSCTL, SYSCTL_INITA); 318 err = wait_for_bit_clear(sc, SDHC_SYSCTL, SYSCTL_INITA); 319 if (err != 0) { 320 device_printf(sc->self, "Can't send 80 clocks to the card.\n"); 321 } 322} 323 324static void 325set_bus_width(struct fsl_sdhc_softc *sc, enum mmc_bus_width width) 326{ 327 328 DPRINTF("setting bus width to %d\n", width); 329 switch (width) { 330 case bus_width_1: 331 set_bit(sc, SDHC_PROCTL, DTW_1); 332 break; 333 case bus_width_4: 334 set_bit(sc, SDHC_PROCTL, DTW_4); 335 break; 336 case bus_width_8: 337 set_bit(sc, SDHC_PROCTL, DTW_8); 338 break; 339 default: 340 device_printf(sc->self, "Unsupported bus width\n"); 341 } 342} 343 344static void 345reset_controller_all(struct fsl_sdhc_softc *sc) 346{ 347 uint32_t count = 5; 348 349 set_bit(sc, SDHC_SYSCTL, SYSCTL_RSTA); 350 while (read4(sc, SDHC_SYSCTL) & SYSCTL_RSTA) { 351 DELAY(FSL_SDHC_RESET_DELAY); 352 --count; 353 if (count == 0) { 354 device_printf(sc->self, 355 "Can't reset the controller\n"); 356 return; 357 } 358 } 359} 360 361static void 362reset_controller_dat_cmd(struct fsl_sdhc_softc *sc) 363{ 364 int err; 365 366 set_bit(sc, SDHC_SYSCTL, SYSCTL_RSTD | SYSCTL_RSTC); 367 err = wait_for_bit_clear(sc, SDHC_SYSCTL, SYSCTL_RSTD | SYSCTL_RSTC); 368 if (err != 0) { 369 device_printf(sc->self, "Can't reset data & command part!\n"); 370 return; 371 } 372} 373 374static void 375init_controller(struct fsl_sdhc_softc *sc) 376{ 377 378 /* Enable interrupts. */ 379#ifdef FSL_SDHC_NO_DMA 380 write4(sc, SDHC_IRQSTATEN, MASK_IRQ_ALL & ~IRQ_DINT & ~IRQ_DMAE); 381 write4(sc, SDHC_IRQSIGEN, MASK_IRQ_ALL & ~IRQ_DINT & ~IRQ_DMAE); 382#else 383 write4(sc, SDHC_IRQSTATEN, MASK_IRQ_ALL & ~IRQ_BRR & ~IRQ_BWR); 384 write4(sc, SDHC_IRQSIGEN, MASK_IRQ_ALL & ~IRQ_BRR & ~IRQ_BWR); 385 386 /* Write DMA address */ 387 write4(sc, SDHC_DSADDR, sc->dma_phys); 388 389 /* Enable snooping and fix for AHB2MAG bypass. */ 390 write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS); 391#endif 392 /* Set data timeout. */ 393 set_bit(sc, SDHC_SYSCTL, 0xe << SHIFT_DTOCV); 394 395 /* Set water-mark levels (FIFO buffer size). */ 396 write4(sc, SDHC_WML, (FSL_SDHC_FIFO_BUF_WORDS << 16) | 397 FSL_SDHC_FIFO_BUF_WORDS); 398} 399 400static void 401init_mmc_host_struct(struct fsl_sdhc_softc *sc) 402{ 403 struct mmc_host *host = &sc->mmc_host; 404 405 /* Clear host structure. */ 406 bzero(host, sizeof(struct mmc_host)); 407 408 /* Calculate minimum and maximum operating frequencies. */ 409 host->f_min = sc->platform_clock / FSL_SDHC_MAX_DIV; 410 host->f_max = FSL_SDHC_MAX_CLOCK; 411 412 /* Set operation conditions (voltage). */ 413 host->host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340; 414 415 /* Set additional host controller capabilities. */ 416 host->caps = MMC_CAP_4_BIT_DATA; 417 418 /* Set mode. */ 419 host->mode = mode_sd; 420} 421 422static void 423card_detect_task(void *arg, int pending) 424{ 425 struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg; 426 int err; 427 int insert; 428 429 insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS; 430 431 mtx_lock(&sc->mtx); 432 433 if (insert) { 434 if (sc->child != NULL) { 435 mtx_unlock(&sc->mtx); 436 return; 437 } 438 439 sc->child = device_add_child(sc->self, "mmc", -1); 440 if (sc->child == NULL) { 441 device_printf(sc->self, "Couldn't add MMC bus!\n"); 442 mtx_unlock(&sc->mtx); 443 return; 444 } 445 446 /* Initialize MMC bus host structure. */ 447 init_mmc_host_struct(sc); 448 device_set_ivars(sc->child, &sc->mmc_host); 449 450 } else { 451 if (sc->child == NULL) { 452 mtx_unlock(&sc->mtx); 453 return; 454 } 455 } 456 457 mtx_unlock(&sc->mtx); 458 459 if (insert) { 460 if ((err = device_probe_and_attach(sc->child)) != 0) { 461 device_printf(sc->self, "MMC bus failed on probe " 462 "and attach! error %d\n", err); 463 device_delete_child(sc->self, sc->child); 464 sc->child = NULL; 465 } 466 } else { 467 if (device_delete_child(sc->self, sc->child) != 0) 468 device_printf(sc->self, "Could not delete MMC bus!\n"); 469 sc->child = NULL; 470 } 471} 472 473static void 474card_detect_delay(void *arg) 475{ 476 struct fsl_sdhc_softc *sc = arg; 477 478 taskqueue_enqueue(taskqueue_swi_giant, &sc->card_detect_task); 479} 480 481static void 482finalize_request(struct fsl_sdhc_softc *sc) 483{ 484 485 DPRINTF("finishing request %x\n", sc->request); 486 487 sc->request->done(sc->request); 488 sc->request = NULL; 489} 490 491/** 492 * Read response from card. 493 * @todo Implement Auto-CMD responses being held in R3 for multi-block xfers. 494 * @param sc 495 */ 496static void 497get_response(struct fsl_sdhc_softc *sc) 498{ 499 struct mmc_command *cmd = sc->request->cmd; 500 int i; 501 uint32_t val; 502 uint8_t ext = 0; 503 504 if (cmd->flags & MMC_RSP_136) { 505 /* CRC is stripped, need to shift one byte left. */ 506 for (i = 0; i < 4; i++) { 507 val = read4(sc, SDHC_CMDRSP0 + i * 4); 508 cmd->resp[3 - i] = (val << 8) + ext; 509 ext = val >> 24; 510 } 511 } else { 512 cmd->resp[0] = read4(sc, SDHC_CMDRSP0); 513 } 514} 515 516#ifdef FSL_SDHC_NO_DMA 517/** 518 * Read all content of a fifo buffer. 519 * @warning Assumes data buffer is 32-bit aligned. 520 * @param sc 521 */ 522static void 523read_block_pio(struct fsl_sdhc_softc *sc) 524{ 525 struct mmc_data *data = sc->request->cmd->data; 526 size_t left = min(FSL_SDHC_FIFO_BUF_SIZE, data->len); 527 uint8_t *buf = data->data; 528 uint32_t word; 529 530 buf += sc->data_offset; 531 bus_space_read_multi_4(sc->bst, sc->bsh, SDHC_DATPORT, (uint32_t *)buf, 532 left >> 2); 533 534 sc->data_offset += left; 535 536 /* Handle 32-bit unaligned size case. */ 537 left &= 0x3; 538 if (left > 0) { 539 buf = (uint8_t *)data->data + (sc->data_offset & ~0x3); 540 word = read4(sc, SDHC_DATPORT); 541 while (left > 0) { 542 *(buf++) = word; 543 word >>= 8; 544 --left; 545 } 546 } 547} 548 549/** 550 * Write a fifo buffer. 551 * @warning Assumes data buffer size is 32-bit aligned. 552 * @param sc 553 */ 554static void 555write_block_pio(struct fsl_sdhc_softc *sc) 556{ 557 struct mmc_data *data = sc->request->cmd->data; 558 size_t left = min(FSL_SDHC_FIFO_BUF_SIZE, data->len); 559 uint8_t *buf = data->data; 560 uint32_t word = 0; 561 562 DPRINTF("sc->data_offset %d\n", sc->data_offset); 563 564 buf += sc->data_offset; 565 bus_space_write_multi_4(sc->bst, sc->bsh, SDHC_DATPORT, (uint32_t *)buf, 566 left >> 2); 567 568 sc->data_offset += left; 569 570 /* Handle 32-bit unaligned size case. */ 571 left &= 0x3; 572 if (left > 0) { 573 buf = (uint8_t *)data->data + (sc->data_offset & ~0x3); 574 while (left > 0) { 575 word += *(buf++); 576 word <<= 8; 577 --left; 578 } 579 write4(sc, SDHC_DATPORT, word); 580 } 581} 582 583static void 584pio_read_transfer(struct fsl_sdhc_softc *sc) 585{ 586 587 while (read4(sc, SDHC_PRSSTAT) & PRSSTAT_BREN) { 588 read_block_pio(sc); 589 590 /* 591 * TODO: should we check here whether data_offset >= data->len? 592 */ 593 } 594} 595 596static void 597pio_write_transfer(struct fsl_sdhc_softc *sc) 598{ 599 600 while (read4(sc, SDHC_PRSSTAT) & PRSSTAT_BWEN) { 601 write_block_pio(sc); 602 603 /* 604 * TODO: should we check here whether data_offset >= data->len? 605 */ 606 } 607} 608#endif /* FSL_SDHC_USE_DMA */ 609 610static inline void 611handle_command_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat) 612{ 613 struct mmc_command *cmd = sc->request->cmd; 614 615 /* Handle errors. */ 616 if (irq_stat & IRQ_CTOE) { 617 cmd->error = MMC_ERR_TIMEOUT; 618 } else if (irq_stat & IRQ_CCE) { 619 cmd->error = MMC_ERR_BADCRC; 620 } else if (irq_stat & (IRQ_CEBE | IRQ_CIE)) { 621 cmd->error = MMC_ERR_FIFO; 622 } 623 624 if (cmd->error) { 625 device_printf(sc->self, "Error interrupt occured\n"); 626 reset_controller_dat_cmd(sc); 627 return; 628 } 629 630 if (sc->command_done) 631 return; 632 633 if (irq_stat & IRQ_CC) { 634 sc->command_done = 1; 635 636 if (cmd->flags & MMC_RSP_PRESENT) 637 get_response(sc); 638 } 639} 640 641static inline void 642handle_data_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat) 643{ 644 struct mmc_command *cmd = sc->request->cmd; 645 646 /* Handle errors. */ 647 if (irq_stat & IRQ_DTOE) { 648 cmd->error = MMC_ERR_TIMEOUT; 649 } else if (irq_stat & (IRQ_DCE | IRQ_DEBE)) { 650 cmd->error = MMC_ERR_BADCRC; 651 } else if (irq_stat & IRQ_ERROR_DATA_MASK) { 652 cmd->error = MMC_ERR_FAILED; 653 } 654 655 if (cmd->error) { 656 device_printf(sc->self, "Error interrupt occured\n"); 657 sc->data_done = 1; 658 reset_controller_dat_cmd(sc); 659 return; 660 } 661 662 if (sc->data_done) 663 return; 664 665#ifdef FSL_SDHC_NO_DMA 666 if (irq_stat & IRQ_BRR) { 667 pio_read_transfer(sc); 668 } 669 670 if (irq_stat & IRQ_BWR) { 671 pio_write_transfer(sc); 672 } 673#else 674 if (irq_stat & IRQ_DINT) { 675 struct mmc_data *data = sc->request->cmd->data; 676 677 /* Synchronize DMA. */ 678 if (data->flags & MMC_DATA_READ) { 679 bus_dmamap_sync(sc->dma_tag, sc->dma_map, 680 BUS_DMASYNC_POSTREAD); 681 memcpy(data->data, sc->dma_mem, data->len); 682 } else { 683 bus_dmamap_sync(sc->dma_tag, sc->dma_map, 684 BUS_DMASYNC_POSTWRITE); 685 } 686 687 /* 688 * TODO: For multiple block transfers, address of dma memory 689 * in DSADDR register should be set to the beginning of the 690 * segment here. Also offset to data pointer should be handled. 691 */ 692 } 693#endif 694 695 if (irq_stat & IRQ_TC) 696 sc->data_done = 1; 697} 698 699static void 700interrupt_handler(void *arg) 701{ 702 struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg; 703 uint32_t irq_stat; 704 705 mtx_lock(&sc->mtx); 706 707 irq_stat = read4(sc, SDHC_IRQSTAT); 708 709 /* Card interrupt. */ 710 if (irq_stat & IRQ_CINT) { 711 DPRINTF("Card interrupt recievied\n"); 712 713 } 714 715 /* Card insertion interrupt. */ 716 if (irq_stat & IRQ_CINS) { 717 clear_bit(sc, SDHC_IRQSIGEN, IRQ_CINS); 718 clear_bit(sc, SDHC_IRQSTATEN, IRQ_CINS); 719 set_bit(sc, SDHC_IRQSIGEN, IRQ_CRM); 720 set_bit(sc, SDHC_IRQSTATEN, IRQ_CRM); 721 722 callout_reset(&sc->card_detect_callout, hz / 2, 723 card_detect_delay, sc); 724 } 725 726 /* Card removal interrupt. */ 727 if (irq_stat & IRQ_CRM) { 728 clear_bit(sc, SDHC_IRQSIGEN, IRQ_CRM); 729 clear_bit(sc, SDHC_IRQSTATEN, IRQ_CRM); 730 set_bit(sc, SDHC_IRQSIGEN, IRQ_CINS); 731 set_bit(sc, SDHC_IRQSTATEN, IRQ_CINS); 732 733 callout_stop(&sc->card_detect_callout); 734 taskqueue_enqueue(taskqueue_swi_giant, &sc->card_detect_task); 735 } 736 737 /* Handle request interrupts. */ 738 if (sc->request) { 739 handle_command_intr(sc, irq_stat); 740 handle_data_intr(sc, irq_stat); 741 742 /* 743 * Finalize request when transfer is done successfully 744 * or was interrupted due to error. 745 */ 746 if ((sc->data_done && sc->command_done) || 747 (sc->request->cmd->error)) 748 finalize_request(sc); 749 } 750 751 /* Clear status register. */ 752 write4(sc, SDHC_IRQSTAT, irq_stat); 753 754 mtx_unlock(&sc->mtx); 755} 756 757#ifndef FSL_SDHC_NO_DMA 758static void 759dma_get_phys_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 760{ 761 762 if (error != 0) 763 return; 764 765 /* Get first segment's physical address. */ 766 *(bus_addr_t *)arg = segs->ds_addr; 767} 768 769static int 770init_dma(struct fsl_sdhc_softc *sc) 771{ 772 device_t self = sc->self; 773 int err; 774 775 err = bus_dma_tag_create(bus_get_dma_tag(self), 776 FSL_SDHC_DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT, 777 BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE, 1, 778 FSL_SDHC_DMA_BLOCK_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL, 779 &sc->dma_tag); 780 781 if (err) { 782 device_printf(self, "Could not create DMA tag!\n"); 783 return (-1); 784 } 785 786 err = bus_dmamem_alloc(sc->dma_tag, (void **)&(sc->dma_mem), 787 BUS_DMA_NOWAIT | BUS_DMA_NOCACHE, &sc->dma_map); 788 if (err) { 789 device_printf(self, "Could not allocate DMA memory!\n"); 790 goto fail1; 791 } 792 793 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, (void *)sc->dma_mem, 794 FSL_SDHC_DMA_BLOCK_SIZE, dma_get_phys_addr, &sc->dma_phys, 0); 795 if (err) { 796 device_printf(self, "Could not load DMA map!\n"); 797 goto fail2; 798 } 799 800 return (0); 801 802fail2: 803 bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map); 804fail1: 805 bus_dma_tag_destroy(sc->dma_tag); 806 807 return (-1); 808} 809#endif /* FSL_SDHC_NO_DMA */ 810 811static uint32_t 812set_xfertyp_register(const struct mmc_command *cmd) 813{ 814 uint32_t xfertyp = 0; 815 816 /* Set command index. */ 817 xfertyp |= cmd->opcode << CMDINX_SHIFT; 818 819 /* Set command type. */ 820 if (cmd->opcode == MMC_STOP_TRANSMISSION) 821 xfertyp |= CMDTYP_ABORT; 822 823 /* Set data preset select. */ 824 if (cmd->data) { 825 xfertyp |= XFERTYP_DPSEL; 826 827 /* Set transfer direction. */ 828 if (cmd->data->flags & MMC_DATA_READ) 829 xfertyp |= XFERTYP_DTDSEL; 830 } 831 832 /* Set command index check. */ 833 if (cmd->flags & MMC_RSP_OPCODE) 834 xfertyp |= XFERTYP_CICEN; 835 836 /* Set command CRC check. */ 837 if (cmd->flags & MMC_RSP_CRC) 838 xfertyp |= XFERTYP_CCCEN; 839 840 /* Set response type */ 841 if (!(cmd->flags & MMC_RSP_PRESENT)) 842 xfertyp |= RSPTYP_NONE; 843 else if (cmd->flags & MMC_RSP_136) 844 xfertyp |= RSPTYP_136; 845 else if (cmd->flags & MMC_RSP_BUSY) 846 xfertyp |= RSPTYP_48_BUSY; 847 else 848 xfertyp |= RSPTYP_48; 849 850#ifndef FSL_SDHC_NO_DMA 851 /* Enable DMA */ 852 xfertyp |= XFERTYP_DMAEN; 853#endif 854 855 return (xfertyp); 856} 857 858static uint32_t 859set_blkattr_register(const struct mmc_data *data) 860{ 861 862 if (data->len <= FSL_SDHC_MAX_BLOCK_SIZE) { 863 /* One block transfer. */ 864 return (BLKATTR_BLOCK_COUNT(1) | ((data->len) & 865 BLKATTR_BLKSZE)); 866 } 867 868 /* TODO: Write code here for multi-block transfers. */ 869 return (0); 870} 871 872/** 873 * Initiate data transfer. Interrupt handler will finalize it. 874 * @todo Implement multi-block transfers. 875 * @param sc 876 * @param cmd 877 */ 878static int 879start_data(struct fsl_sdhc_softc *sc, struct mmc_data *data) 880{ 881 uint32_t reg; 882 883 if ((uint32_t)data->data & 0x3) { 884 device_printf(sc->self, "32-bit unaligned data pointer in " 885 "request\n"); 886 return (-1); 887 } 888 889 sc->data_done = 0; 890 891#ifdef FSL_SDHC_NO_DMA 892 sc->data_ptr = data->data; 893 sc->data_offset = 0; 894#else 895 /* Write DMA address register. */ 896 write4(sc, SDHC_DSADDR, sc->dma_phys); 897 898 /* Synchronize DMA. */ 899 if (data->flags & MMC_DATA_READ) { 900 bus_dmamap_sync(sc->dma_tag, sc->dma_map, 901 BUS_DMASYNC_PREREAD); 902 } else { 903 memcpy(sc->dma_mem, data->data, data->len); 904 bus_dmamap_sync(sc->dma_tag, sc->dma_map, 905 BUS_DMASYNC_PREWRITE); 906 } 907#endif 908 /* Set block size and count. */ 909 reg = set_blkattr_register(data); 910 if (reg == 0) { 911 device_printf(sc->self, "Requested unsupported multi-block " 912 "transfer.\n"); 913 return (-1); 914 } 915 write4(sc, SDHC_BLKATTR, reg); 916 917 return (0); 918} 919 920static int 921start_command(struct fsl_sdhc_softc *sc, struct mmc_command *cmd) 922{ 923 struct mmc_request *req = sc->request; 924 uint32_t mask; 925 uint32_t xfertyp; 926 int err; 927 928 DPRINTF("opcode %d, flags 0x%08x\n", cmd->opcode, cmd->flags); 929 DPRINTF("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT)); 930 931 sc->command_done = 0; 932 933 cmd->error = MMC_ERR_NONE; 934 935 /* TODO: should we check here for card presence and clock settings? */ 936 937 /* Always wait for free CMD line. */ 938 mask = SDHC_CMD_LINE; 939 /* Wait for free DAT if we have data or busy signal. */ 940 if (cmd->data || (cmd->flags & MMC_RSP_BUSY)) 941 mask |= SDHC_DAT_LINE; 942 /* We shouldn't wait for DAT for stop commands. */ 943 if (cmd == req->stop) 944 mask &= ~SDHC_DAT_LINE; 945 err = wait_for_free_line(sc, mask); 946 if (err != 0) { 947 device_printf(sc->self, "Controller never released inhibit " 948 "bit(s).\n"); 949 reset_controller_dat_cmd(sc); 950 cmd->error = MMC_ERR_FAILED; 951 sc->request = NULL; 952 req->done(req); 953 return (-1); 954 } 955 956 xfertyp = set_xfertyp_register(cmd); 957 958 if (cmd->data != NULL) { 959 err = start_data(sc, cmd->data); 960 if (err != 0) { 961 device_printf(sc->self, 962 "Data transfer request failed\n"); 963 reset_controller_dat_cmd(sc); 964 cmd->error = MMC_ERR_FAILED; 965 sc->request = NULL; 966 req->done(req); 967 return (-1); 968 } 969 } 970 971 write4(sc, SDHC_CMDARG, cmd->arg); 972 write4(sc, SDHC_XFERTYP, xfertyp); 973 974 DPRINTF("XFERTYP = 0x%08x\n", xfertyp); 975 DPRINTF("CMDARG = 0x%08x\n", cmd->arg); 976 977 return (0); 978} 979 980#ifdef DEBUG 981static void 982dump_registers(struct fsl_sdhc_softc *sc) 983{ 984 printf("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT)); 985 printf("PROCTL = 0x%08x\n", read4(sc, SDHC_PROCTL)); 986 printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR)); 987 printf("HOSTCAPBLT = 0x%08x\n", read4(sc, SDHC_HOSTCAPBLT)); 988 printf("IRQSTAT = 0x%08x\n", read4(sc, SDHC_IRQSTAT)); 989 printf("IRQSTATEN = 0x%08x\n", read4(sc, SDHC_IRQSTATEN)); 990 printf("IRQSIGEN = 0x%08x\n", read4(sc, SDHC_IRQSIGEN)); 991 printf("WML = 0x%08x\n", read4(sc, SDHC_WML)); 992 printf("DSADDR = 0x%08x\n", read4(sc, SDHC_DSADDR)); 993 printf("XFERTYP = 0x%08x\n", read4(sc, SDHC_XFERTYP)); 994 printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR)); 995 printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR)); 996} 997#endif 998 999/***************************************************************************** 1000 * Public methods 1001 *****************************************************************************/ 1002/* 1003 * Device interface methods. 1004 */ 1005static int 1006fsl_sdhc_probe(device_t self) 1007{ 1008 static const char *desc = 1009 "Freescale Enhanced Secure Digital Host Controller"; 1010 1011 if (!ofw_bus_is_compatible(self, "fsl,p2020-esdhc") && 1012 !ofw_bus_is_compatible(self, "fsl,esdhc")) 1013 return (ENXIO); 1014 1015 device_set_desc(self, desc); 1016 1017 return (BUS_PROBE_VENDOR); 1018} 1019 1020static int 1021fsl_sdhc_attach(device_t self) 1022{ 1023 struct fsl_sdhc_softc *sc; 1024 1025 sc = device_get_softc(self); 1026 1027 sc->self = self; 1028 1029 mtx_init(&sc->mtx, device_get_nameunit(self), NULL, MTX_DEF); 1030 1031 /* Setup memory resource */ 1032 sc->mem_rid = 0; 1033 sc->mem_resource = bus_alloc_resource_any(self, SYS_RES_MEMORY, 1034 &sc->mem_rid, RF_ACTIVE); 1035 if (sc->mem_resource == NULL) { 1036 device_printf(self, "Could not allocate memory.\n"); 1037 goto fail; 1038 } 1039 sc->bst = rman_get_bustag(sc->mem_resource); 1040 sc->bsh = rman_get_bushandle(sc->mem_resource); 1041 1042 /* Setup interrupt resource. */ 1043 sc->irq_rid = 0; 1044 sc->irq_resource = bus_alloc_resource_any(self, SYS_RES_IRQ, 1045 &sc->irq_rid, RF_ACTIVE); 1046 if (sc->irq_resource == NULL) { 1047 device_printf(self, "Could not allocate interrupt.\n"); 1048 goto fail; 1049 } 1050 if (bus_setup_intr(self, sc->irq_resource, INTR_TYPE_MISC | 1051 INTR_MPSAFE, NULL, interrupt_handler, sc, &sc->ihl) != 0) { 1052 device_printf(self, "Could not setup interrupt.\n"); 1053 goto fail; 1054 } 1055 1056 /* Setup DMA. */ 1057#ifndef FSL_SDHC_NO_DMA 1058 if (init_dma(sc) != 0) { 1059 device_printf(self, "Could not setup DMA\n"); 1060 } 1061#endif 1062 sc->bus_busy = 0; 1063 sc->platform_clock = get_platform_clock(sc); 1064 if (sc->platform_clock == 0) { 1065 device_printf(self, "Could not get platform clock.\n"); 1066 goto fail; 1067 } 1068 sc->command_done = 1; 1069 sc->data_done = 1; 1070 1071 /* Init card detection task. */ 1072 TASK_INIT(&sc->card_detect_task, 0, card_detect_task, sc); 1073 callout_init(&sc->card_detect_callout, 1); 1074 1075 reset_controller_all(sc); 1076 init_controller(sc); 1077 set_clock(sc, 400000); 1078 send_80_clock_ticks(sc); 1079 1080#ifdef DEBUG 1081 dump_registers(sc); 1082#endif 1083 1084 return (0); 1085 1086fail: 1087 fsl_sdhc_detach(self); 1088 return (ENXIO); 1089} 1090 1091static int 1092fsl_sdhc_detach(device_t self) 1093{ 1094 struct fsl_sdhc_softc *sc = device_get_softc(self); 1095 int err; 1096 1097 if (sc->child) 1098 device_delete_child(self, sc->child); 1099 1100 taskqueue_drain(taskqueue_swi_giant, &sc->card_detect_task); 1101 1102#ifndef FSL_SDHC_NO_DMA 1103 bus_dmamap_unload(sc->dma_tag, sc->dma_map); 1104 bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map); 1105 bus_dma_tag_destroy(sc->dma_tag); 1106#endif 1107 1108 if (sc->ihl != NULL) { 1109 err = bus_teardown_intr(self, sc->irq_resource, sc->ihl); 1110 if (err) 1111 return (err); 1112 } 1113 if (sc->irq_resource != NULL) { 1114 err = bus_release_resource(self, SYS_RES_IRQ, sc->irq_rid, 1115 sc->irq_resource); 1116 if (err) 1117 return (err); 1118 1119 } 1120 if (sc->mem_resource != NULL) { 1121 err = bus_release_resource(self, SYS_RES_MEMORY, sc->mem_rid, 1122 sc->mem_resource); 1123 if (err) 1124 return (err); 1125 } 1126 1127 mtx_destroy(&sc->mtx); 1128 1129 return (0); 1130} 1131 1132 1133/* 1134 * Bus interface methods. 1135 */ 1136static int 1137fsl_sdhc_read_ivar(device_t self, device_t child, int index, 1138 uintptr_t *result) 1139{ 1140 struct mmc_host *host = device_get_ivars(child); 1141 1142 switch (index) { 1143 case MMCBR_IVAR_BUS_MODE: 1144 *(int *)result = host->ios.bus_mode; 1145 break; 1146 case MMCBR_IVAR_BUS_WIDTH: 1147 *(int *)result = host->ios.bus_width; 1148 break; 1149 case MMCBR_IVAR_CHIP_SELECT: 1150 *(int *)result = host->ios.chip_select; 1151 break; 1152 case MMCBR_IVAR_CLOCK: 1153 *(int *)result = host->ios.clock; 1154 break; 1155 case MMCBR_IVAR_F_MIN: 1156 *(int *)result = host->f_min; 1157 break; 1158 case MMCBR_IVAR_F_MAX: 1159 *(int *)result = host->f_max; 1160 break; 1161 case MMCBR_IVAR_HOST_OCR: 1162 *(int *)result = host->host_ocr; 1163 break; 1164 case MMCBR_IVAR_MODE: 1165 *(int *)result = host->mode; 1166 break; 1167 case MMCBR_IVAR_OCR: 1168 *(int *)result = host->ocr; 1169 break; 1170 case MMCBR_IVAR_POWER_MODE: 1171 *(int *)result = host->ios.power_mode; 1172 break; 1173 case MMCBR_IVAR_VDD: 1174 *(int *)result = host->ios.vdd; 1175 break; 1176 default: 1177 return (EINVAL); 1178 } 1179 1180 return (0); 1181} 1182 1183static int 1184fsl_sdhc_write_ivar(device_t self, device_t child, int index, 1185 uintptr_t value) 1186{ 1187 struct mmc_host *host = device_get_ivars(child); 1188 1189 switch (index) { 1190 case MMCBR_IVAR_BUS_MODE: 1191 host->ios.bus_mode = value; 1192 break; 1193 case MMCBR_IVAR_BUS_WIDTH: 1194 host->ios.bus_width = value; 1195 break; 1196 case MMCBR_IVAR_CHIP_SELECT: 1197 host->ios.chip_select = value; 1198 break; 1199 case MMCBR_IVAR_CLOCK: 1200 host->ios.clock = value; 1201 break; 1202 case MMCBR_IVAR_MODE: 1203 host->mode = value; 1204 break; 1205 case MMCBR_IVAR_OCR: 1206 host->ocr = value; 1207 break; 1208 case MMCBR_IVAR_POWER_MODE: 1209 host->ios.power_mode = value; 1210 break; 1211 case MMCBR_IVAR_VDD: 1212 host->ios.vdd = value; 1213 break; 1214 case MMCBR_IVAR_HOST_OCR: 1215 case MMCBR_IVAR_F_MIN: 1216 case MMCBR_IVAR_F_MAX: 1217 default: 1218 /* Instance variable not writable. */ 1219 return (EINVAL); 1220 } 1221 1222 return (0); 1223} 1224 1225 1226/* 1227 * MMC bridge methods. 1228 */ 1229static int 1230fsl_sdhc_update_ios(device_t self, device_t reqdev) 1231{ 1232 struct fsl_sdhc_softc *sc = device_get_softc(self); 1233 struct mmc_host *host = device_get_ivars(reqdev); 1234 struct mmc_ios *ios = &host->ios; 1235 1236 mtx_lock(&sc->mtx); 1237 1238 /* Full reset on bus power down to clear from any state. */ 1239 if (ios->power_mode == power_off) { 1240 reset_controller_all(sc); 1241 init_controller(sc); 1242 } 1243 1244 set_clock(sc, ios->clock); 1245 set_bus_width(sc, ios->bus_width); 1246 1247 mtx_unlock(&sc->mtx); 1248 1249 return (0); 1250} 1251 1252static int 1253fsl_sdhc_request(device_t self, device_t reqdev, struct mmc_request *req) 1254{ 1255 struct fsl_sdhc_softc *sc = device_get_softc(self); 1256 int err; 1257 1258 mtx_lock(&sc->mtx); 1259 1260 sc->request = req; 1261 err = start_command(sc, req->cmd); 1262 1263 mtx_unlock(&sc->mtx); 1264 1265 return (err); 1266} 1267 1268static int 1269fsl_sdhc_get_ro(device_t self, device_t reqdev) 1270{ 1271 struct fsl_sdhc_softc *sc = device_get_softc(self); 1272 1273 /* Wouldn't it be faster using branching (if {}) ?? */ 1274 return (((read4(sc, SDHC_PRSSTAT) & PRSSTAT_WPSPL) >> 19) ^ 0x1); 1275} 1276 1277static int 1278fsl_sdhc_acquire_host(device_t self, device_t reqdev) 1279{ 1280 struct fsl_sdhc_softc *sc = device_get_softc(self); 1281 int retval = 0; 1282 1283 mtx_lock(&sc->mtx); 1284 1285 while (sc->bus_busy) 1286 retval = mtx_sleep(sc, &sc->mtx, PZERO, "sdhcah", 0); 1287 ++(sc->bus_busy); 1288 1289 mtx_unlock(&sc->mtx); 1290 1291 return (retval); 1292} 1293 1294static int 1295fsl_sdhc_release_host(device_t self, device_t reqdev) 1296{ 1297 struct fsl_sdhc_softc *sc = device_get_softc(self); 1298 1299 mtx_lock(&sc->mtx); 1300 --(sc->bus_busy); 1301 mtx_unlock(&sc->mtx); 1302 wakeup(sc); 1303 1304 return (0); 1305} 1306