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