1 /* 2 * (C) Copyright 2009 SAMSUNG Electronics 3 * Minkyu Kang <mk7.kang@samsung.com> 4 * Jaehoon Chung <jh80.chung@samsung.com> 5 * Portions Copyright 2011-2015 NVIDIA Corporation 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <bouncebuf.h> 11 #include <common.h> 12 #include <asm/gpio.h> 13 #include <asm/io.h> 14 #ifndef CONFIG_TEGRA186 15 #include <asm/arch/clock.h> 16 #include <asm/arch-tegra/clk_rst.h> 17 #endif 18 #include <asm/arch-tegra/mmc.h> 19 #include <asm/arch-tegra/tegra_mmc.h> 20 #include <mmc.h> 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 struct mmc_host mmc_host[CONFIG_SYS_MMC_MAX_DEVICE]; 25 26 #if !CONFIG_IS_ENABLED(OF_CONTROL) 27 #error "Please enable device tree support to use this driver" 28 #endif 29 30 static void mmc_set_power(struct mmc_host *host, unsigned short power) 31 { 32 u8 pwr = 0; 33 debug("%s: power = %x\n", __func__, power); 34 35 if (power != (unsigned short)-1) { 36 switch (1 << power) { 37 case MMC_VDD_165_195: 38 pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8; 39 break; 40 case MMC_VDD_29_30: 41 case MMC_VDD_30_31: 42 pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0; 43 break; 44 case MMC_VDD_32_33: 45 case MMC_VDD_33_34: 46 pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3; 47 break; 48 } 49 } 50 debug("%s: pwr = %X\n", __func__, pwr); 51 52 /* Set the bus voltage first (if any) */ 53 writeb(pwr, &host->reg->pwrcon); 54 if (pwr == 0) 55 return; 56 57 /* Now enable bus power */ 58 pwr |= TEGRA_MMC_PWRCTL_SD_BUS_POWER; 59 writeb(pwr, &host->reg->pwrcon); 60 } 61 62 static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data, 63 struct bounce_buffer *bbstate) 64 { 65 unsigned char ctrl; 66 67 68 debug("buf: %p (%p), data->blocks: %u, data->blocksize: %u\n", 69 bbstate->bounce_buffer, bbstate->user_buffer, data->blocks, 70 data->blocksize); 71 72 writel((u32)(unsigned long)bbstate->bounce_buffer, &host->reg->sysad); 73 /* 74 * DMASEL[4:3] 75 * 00 = Selects SDMA 76 * 01 = Reserved 77 * 10 = Selects 32-bit Address ADMA2 78 * 11 = Selects 64-bit Address ADMA2 79 */ 80 ctrl = readb(&host->reg->hostctl); 81 ctrl &= ~TEGRA_MMC_HOSTCTL_DMASEL_MASK; 82 ctrl |= TEGRA_MMC_HOSTCTL_DMASEL_SDMA; 83 writeb(ctrl, &host->reg->hostctl); 84 85 /* We do not handle DMA boundaries, so set it to max (512 KiB) */ 86 writew((7 << 12) | (data->blocksize & 0xFFF), &host->reg->blksize); 87 writew(data->blocks, &host->reg->blkcnt); 88 } 89 90 static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data) 91 { 92 unsigned short mode; 93 debug(" mmc_set_transfer_mode called\n"); 94 /* 95 * TRNMOD 96 * MUL1SIN0[5] : Multi/Single Block Select 97 * RD1WT0[4] : Data Transfer Direction Select 98 * 1 = read 99 * 0 = write 100 * ENACMD12[2] : Auto CMD12 Enable 101 * ENBLKCNT[1] : Block Count Enable 102 * ENDMA[0] : DMA Enable 103 */ 104 mode = (TEGRA_MMC_TRNMOD_DMA_ENABLE | 105 TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE); 106 107 if (data->blocks > 1) 108 mode |= TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT; 109 110 if (data->flags & MMC_DATA_READ) 111 mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ; 112 113 writew(mode, &host->reg->trnmod); 114 } 115 116 static int mmc_wait_inhibit(struct mmc_host *host, 117 struct mmc_cmd *cmd, 118 struct mmc_data *data, 119 unsigned int timeout) 120 { 121 /* 122 * PRNSTS 123 * CMDINHDAT[1] : Command Inhibit (DAT) 124 * CMDINHCMD[0] : Command Inhibit (CMD) 125 */ 126 unsigned int mask = TEGRA_MMC_PRNSTS_CMD_INHIBIT_CMD; 127 128 /* 129 * We shouldn't wait for data inhibit for stop commands, even 130 * though they might use busy signaling 131 */ 132 if ((data == NULL) && (cmd->resp_type & MMC_RSP_BUSY)) 133 mask |= TEGRA_MMC_PRNSTS_CMD_INHIBIT_DAT; 134 135 while (readl(&host->reg->prnsts) & mask) { 136 if (timeout == 0) { 137 printf("%s: timeout error\n", __func__); 138 return -1; 139 } 140 timeout--; 141 udelay(1000); 142 } 143 144 return 0; 145 } 146 147 static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd, 148 struct mmc_data *data, struct bounce_buffer *bbstate) 149 { 150 struct mmc_host *host = mmc->priv; 151 int flags, i; 152 int result; 153 unsigned int mask = 0; 154 unsigned int retry = 0x100000; 155 debug(" mmc_send_cmd called\n"); 156 157 result = mmc_wait_inhibit(host, cmd, data, 10 /* ms */); 158 159 if (result < 0) 160 return result; 161 162 if (data) 163 mmc_prepare_data(host, data, bbstate); 164 165 debug("cmd->arg: %08x\n", cmd->cmdarg); 166 writel(cmd->cmdarg, &host->reg->argument); 167 168 if (data) 169 mmc_set_transfer_mode(host, data); 170 171 if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) 172 return -1; 173 174 /* 175 * CMDREG 176 * CMDIDX[13:8] : Command index 177 * DATAPRNT[5] : Data Present Select 178 * ENCMDIDX[4] : Command Index Check Enable 179 * ENCMDCRC[3] : Command CRC Check Enable 180 * RSPTYP[1:0] 181 * 00 = No Response 182 * 01 = Length 136 183 * 10 = Length 48 184 * 11 = Length 48 Check busy after response 185 */ 186 if (!(cmd->resp_type & MMC_RSP_PRESENT)) 187 flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE; 188 else if (cmd->resp_type & MMC_RSP_136) 189 flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136; 190 else if (cmd->resp_type & MMC_RSP_BUSY) 191 flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY; 192 else 193 flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48; 194 195 if (cmd->resp_type & MMC_RSP_CRC) 196 flags |= TEGRA_MMC_TRNMOD_CMD_CRC_CHECK; 197 if (cmd->resp_type & MMC_RSP_OPCODE) 198 flags |= TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK; 199 if (data) 200 flags |= TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER; 201 202 debug("cmd: %d\n", cmd->cmdidx); 203 204 writew((cmd->cmdidx << 8) | flags, &host->reg->cmdreg); 205 206 for (i = 0; i < retry; i++) { 207 mask = readl(&host->reg->norintsts); 208 /* Command Complete */ 209 if (mask & TEGRA_MMC_NORINTSTS_CMD_COMPLETE) { 210 if (!data) 211 writel(mask, &host->reg->norintsts); 212 break; 213 } 214 } 215 216 if (i == retry) { 217 printf("%s: waiting for status update\n", __func__); 218 writel(mask, &host->reg->norintsts); 219 return TIMEOUT; 220 } 221 222 if (mask & TEGRA_MMC_NORINTSTS_CMD_TIMEOUT) { 223 /* Timeout Error */ 224 debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx); 225 writel(mask, &host->reg->norintsts); 226 return TIMEOUT; 227 } else if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { 228 /* Error Interrupt */ 229 debug("error: %08x cmd %d\n", mask, cmd->cmdidx); 230 writel(mask, &host->reg->norintsts); 231 return -1; 232 } 233 234 if (cmd->resp_type & MMC_RSP_PRESENT) { 235 if (cmd->resp_type & MMC_RSP_136) { 236 /* CRC is stripped so we need to do some shifting. */ 237 for (i = 0; i < 4; i++) { 238 unsigned long offset = 239 (unsigned long)(&host->reg->rspreg3 - i); 240 cmd->response[i] = readl(offset) << 8; 241 242 if (i != 3) { 243 cmd->response[i] |= 244 readb(offset - 1); 245 } 246 debug("cmd->resp[%d]: %08x\n", 247 i, cmd->response[i]); 248 } 249 } else if (cmd->resp_type & MMC_RSP_BUSY) { 250 for (i = 0; i < retry; i++) { 251 /* PRNTDATA[23:20] : DAT[3:0] Line Signal */ 252 if (readl(&host->reg->prnsts) 253 & (1 << 20)) /* DAT[0] */ 254 break; 255 } 256 257 if (i == retry) { 258 printf("%s: card is still busy\n", __func__); 259 writel(mask, &host->reg->norintsts); 260 return TIMEOUT; 261 } 262 263 cmd->response[0] = readl(&host->reg->rspreg0); 264 debug("cmd->resp[0]: %08x\n", cmd->response[0]); 265 } else { 266 cmd->response[0] = readl(&host->reg->rspreg0); 267 debug("cmd->resp[0]: %08x\n", cmd->response[0]); 268 } 269 } 270 271 if (data) { 272 unsigned long start = get_timer(0); 273 274 while (1) { 275 mask = readl(&host->reg->norintsts); 276 277 if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { 278 /* Error Interrupt */ 279 writel(mask, &host->reg->norintsts); 280 printf("%s: error during transfer: 0x%08x\n", 281 __func__, mask); 282 return -1; 283 } else if (mask & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT) { 284 /* 285 * DMA Interrupt, restart the transfer where 286 * it was interrupted. 287 */ 288 unsigned int address = readl(&host->reg->sysad); 289 290 debug("DMA end\n"); 291 writel(TEGRA_MMC_NORINTSTS_DMA_INTERRUPT, 292 &host->reg->norintsts); 293 writel(address, &host->reg->sysad); 294 } else if (mask & TEGRA_MMC_NORINTSTS_XFER_COMPLETE) { 295 /* Transfer Complete */ 296 debug("r/w is done\n"); 297 break; 298 } else if (get_timer(start) > 8000UL) { 299 writel(mask, &host->reg->norintsts); 300 printf("%s: MMC Timeout\n" 301 " Interrupt status 0x%08x\n" 302 " Interrupt status enable 0x%08x\n" 303 " Interrupt signal enable 0x%08x\n" 304 " Present status 0x%08x\n", 305 __func__, mask, 306 readl(&host->reg->norintstsen), 307 readl(&host->reg->norintsigen), 308 readl(&host->reg->prnsts)); 309 return -1; 310 } 311 } 312 writel(mask, &host->reg->norintsts); 313 } 314 315 udelay(1000); 316 return 0; 317 } 318 319 static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, 320 struct mmc_data *data) 321 { 322 void *buf; 323 unsigned int bbflags; 324 size_t len; 325 struct bounce_buffer bbstate; 326 int ret; 327 328 if (data) { 329 if (data->flags & MMC_DATA_READ) { 330 buf = data->dest; 331 bbflags = GEN_BB_WRITE; 332 } else { 333 buf = (void *)data->src; 334 bbflags = GEN_BB_READ; 335 } 336 len = data->blocks * data->blocksize; 337 338 bounce_buffer_start(&bbstate, buf, len, bbflags); 339 } 340 341 ret = mmc_send_cmd_bounced(mmc, cmd, data, &bbstate); 342 343 if (data) 344 bounce_buffer_stop(&bbstate); 345 346 return ret; 347 } 348 349 static void mmc_change_clock(struct mmc_host *host, uint clock) 350 { 351 int div; 352 unsigned short clk; 353 unsigned long timeout; 354 355 debug(" mmc_change_clock called\n"); 356 357 /* 358 * Change Tegra SDMMCx clock divisor here. Source is PLLP_OUT0 359 */ 360 if (clock == 0) 361 goto out; 362 #ifndef CONFIG_TEGRA186 363 clock_adjust_periph_pll_div(host->mmc_id, CLOCK_ID_PERIPH, clock, 364 &div); 365 #else 366 div = (20000000 + clock - 1) / clock; 367 #endif 368 debug("div = %d\n", div); 369 370 writew(0, &host->reg->clkcon); 371 372 /* 373 * CLKCON 374 * SELFREQ[15:8] : base clock divided by value 375 * ENSDCLK[2] : SD Clock Enable 376 * STBLINTCLK[1] : Internal Clock Stable 377 * ENINTCLK[0] : Internal Clock Enable 378 */ 379 div >>= 1; 380 clk = ((div << TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT) | 381 TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE); 382 writew(clk, &host->reg->clkcon); 383 384 /* Wait max 10 ms */ 385 timeout = 10; 386 while (!(readw(&host->reg->clkcon) & 387 TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE)) { 388 if (timeout == 0) { 389 printf("%s: timeout error\n", __func__); 390 return; 391 } 392 timeout--; 393 udelay(1000); 394 } 395 396 clk |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; 397 writew(clk, &host->reg->clkcon); 398 399 debug("mmc_change_clock: clkcon = %08X\n", clk); 400 401 out: 402 host->clock = clock; 403 } 404 405 static void tegra_mmc_set_ios(struct mmc *mmc) 406 { 407 struct mmc_host *host = mmc->priv; 408 unsigned char ctrl; 409 debug(" mmc_set_ios called\n"); 410 411 debug("bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock); 412 413 /* Change clock first */ 414 mmc_change_clock(host, mmc->clock); 415 416 ctrl = readb(&host->reg->hostctl); 417 418 /* 419 * WIDE8[5] 420 * 0 = Depend on WIDE4 421 * 1 = 8-bit mode 422 * WIDE4[1] 423 * 1 = 4-bit mode 424 * 0 = 1-bit mode 425 */ 426 if (mmc->bus_width == 8) 427 ctrl |= (1 << 5); 428 else if (mmc->bus_width == 4) 429 ctrl |= (1 << 1); 430 else 431 ctrl &= ~(1 << 1); 432 433 writeb(ctrl, &host->reg->hostctl); 434 debug("mmc_set_ios: hostctl = %08X\n", ctrl); 435 } 436 437 static void mmc_reset(struct mmc_host *host, struct mmc *mmc) 438 { 439 unsigned int timeout; 440 debug(" mmc_reset called\n"); 441 442 /* 443 * RSTALL[0] : Software reset for all 444 * 1 = reset 445 * 0 = work 446 */ 447 writeb(TEGRA_MMC_SWRST_SW_RESET_FOR_ALL, &host->reg->swrst); 448 449 host->clock = 0; 450 451 /* Wait max 100 ms */ 452 timeout = 100; 453 454 /* hw clears the bit when it's done */ 455 while (readb(&host->reg->swrst) & TEGRA_MMC_SWRST_SW_RESET_FOR_ALL) { 456 if (timeout == 0) { 457 printf("%s: timeout error\n", __func__); 458 return; 459 } 460 timeout--; 461 udelay(1000); 462 } 463 464 /* Set SD bus voltage & enable bus power */ 465 mmc_set_power(host, fls(mmc->cfg->voltages) - 1); 466 debug("%s: power control = %02X, host control = %02X\n", __func__, 467 readb(&host->reg->pwrcon), readb(&host->reg->hostctl)); 468 469 /* Make sure SDIO pads are set up */ 470 pad_init_mmc(host); 471 } 472 473 static int tegra_mmc_core_init(struct mmc *mmc) 474 { 475 struct mmc_host *host = mmc->priv; 476 unsigned int mask; 477 debug(" mmc_core_init called\n"); 478 479 mmc_reset(host, mmc); 480 481 host->version = readw(&host->reg->hcver); 482 debug("host version = %x\n", host->version); 483 484 /* mask all */ 485 writel(0xffffffff, &host->reg->norintstsen); 486 writel(0xffffffff, &host->reg->norintsigen); 487 488 writeb(0xe, &host->reg->timeoutcon); /* TMCLK * 2^27 */ 489 /* 490 * NORMAL Interrupt Status Enable Register init 491 * [5] ENSTABUFRDRDY : Buffer Read Ready Status Enable 492 * [4] ENSTABUFWTRDY : Buffer write Ready Status Enable 493 * [3] ENSTADMAINT : DMA boundary interrupt 494 * [1] ENSTASTANSCMPLT : Transfre Complete Status Enable 495 * [0] ENSTACMDCMPLT : Command Complete Status Enable 496 */ 497 mask = readl(&host->reg->norintstsen); 498 mask &= ~(0xffff); 499 mask |= (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | 500 TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | 501 TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT | 502 TEGRA_MMC_NORINTSTSEN_BUFFER_WRITE_READY | 503 TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY); 504 writel(mask, &host->reg->norintstsen); 505 506 /* 507 * NORMAL Interrupt Signal Enable Register init 508 * [1] ENSTACMDCMPLT : Transfer Complete Signal Enable 509 */ 510 mask = readl(&host->reg->norintsigen); 511 mask &= ~(0xffff); 512 mask |= TEGRA_MMC_NORINTSIGEN_XFER_COMPLETE; 513 writel(mask, &host->reg->norintsigen); 514 515 return 0; 516 } 517 518 static int tegra_mmc_getcd(struct mmc *mmc) 519 { 520 struct mmc_host *host = mmc->priv; 521 522 debug("tegra_mmc_getcd called\n"); 523 524 if (dm_gpio_is_valid(&host->cd_gpio)) 525 return dm_gpio_get_value(&host->cd_gpio); 526 527 return 1; 528 } 529 530 static const struct mmc_ops tegra_mmc_ops = { 531 .send_cmd = tegra_mmc_send_cmd, 532 .set_ios = tegra_mmc_set_ios, 533 .init = tegra_mmc_core_init, 534 .getcd = tegra_mmc_getcd, 535 }; 536 537 static int do_mmc_init(int dev_index, bool removable) 538 { 539 struct mmc_host *host; 540 struct mmc *mmc; 541 542 /* DT should have been read & host config filled in */ 543 host = &mmc_host[dev_index]; 544 if (!host->enabled) 545 return -1; 546 547 debug(" do_mmc_init: index %d, bus width %d pwr_gpio %d cd_gpio %d\n", 548 dev_index, host->width, gpio_get_number(&host->pwr_gpio), 549 gpio_get_number(&host->cd_gpio)); 550 551 host->clock = 0; 552 #ifndef CONFIG_TEGRA186 553 clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000); 554 #endif 555 556 if (dm_gpio_is_valid(&host->pwr_gpio)) 557 dm_gpio_set_value(&host->pwr_gpio, 1); 558 559 memset(&host->cfg, 0, sizeof(host->cfg)); 560 561 host->cfg.name = "Tegra SD/MMC"; 562 host->cfg.ops = &tegra_mmc_ops; 563 564 host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; 565 host->cfg.host_caps = 0; 566 if (host->width == 8) 567 host->cfg.host_caps |= MMC_MODE_8BIT; 568 if (host->width >= 4) 569 host->cfg.host_caps |= MMC_MODE_4BIT; 570 host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; 571 572 /* 573 * min freq is for card identification, and is the highest 574 * low-speed SDIO card frequency (actually 400KHz) 575 * max freq is highest HS eMMC clock as per the SD/MMC spec 576 * (actually 52MHz) 577 */ 578 host->cfg.f_min = 375000; 579 #ifndef CONFIG_TEGRA186 580 host->cfg.f_max = 48000000; 581 #else 582 host->cfg.f_max = 375000; 583 #endif 584 585 host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; 586 587 mmc = mmc_create(&host->cfg, host); 588 mmc->block_dev.removable = removable; 589 if (mmc == NULL) 590 return -1; 591 592 return 0; 593 } 594 595 /** 596 * Get the host address and peripheral ID for a node. 597 * 598 * @param blob fdt blob 599 * @param node Device index (0-3) 600 * @param host Structure to fill in (reg, width, mmc_id) 601 */ 602 static int mmc_get_config(const void *blob, int node, struct mmc_host *host, 603 bool *removablep) 604 { 605 debug("%s: node = %d\n", __func__, node); 606 607 host->enabled = fdtdec_get_is_enabled(blob, node); 608 609 host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg"); 610 if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) { 611 debug("%s: no sdmmc base reg info found\n", __func__); 612 return -FDT_ERR_NOTFOUND; 613 } 614 615 #ifndef CONFIG_TEGRA186 616 host->mmc_id = clock_decode_periph_id(blob, node); 617 if (host->mmc_id == PERIPH_ID_NONE) { 618 debug("%s: could not decode periph id\n", __func__); 619 return -FDT_ERR_NOTFOUND; 620 } 621 #endif 622 623 /* 624 * NOTE: mmc->bus_width is determined by mmc.c dynamically. 625 * TBD: Override it with this value? 626 */ 627 host->width = fdtdec_get_int(blob, node, "bus-width", 0); 628 if (!host->width) 629 debug("%s: no sdmmc width found\n", __func__); 630 631 /* These GPIOs are optional */ 632 gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio, 633 GPIOD_IS_IN); 634 gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio, 635 GPIOD_IS_IN); 636 gpio_request_by_name_nodev(blob, node, "power-gpios", 0, 637 &host->pwr_gpio, GPIOD_IS_OUT); 638 *removablep = !fdtdec_get_bool(blob, node, "non-removable"); 639 640 debug("%s: found controller at %p, width = %d, periph_id = %d\n", 641 __func__, host->reg, host->width, 642 #ifndef CONFIG_TEGRA186 643 host->mmc_id 644 #else 645 -1 646 #endif 647 ); 648 return 0; 649 } 650 651 /* 652 * Process a list of nodes, adding them to our list of SDMMC ports. 653 * 654 * @param blob fdt blob 655 * @param node_list list of nodes to process (any <=0 are ignored) 656 * @param count number of nodes to process 657 * @return 0 if ok, -1 on error 658 */ 659 static int process_nodes(const void *blob, int node_list[], int count) 660 { 661 struct mmc_host *host; 662 bool removable; 663 int i, node; 664 665 debug("%s: count = %d\n", __func__, count); 666 667 /* build mmc_host[] for each controller */ 668 for (i = 0; i < count; i++) { 669 node = node_list[i]; 670 if (node <= 0) 671 continue; 672 673 host = &mmc_host[i]; 674 host->id = i; 675 676 if (mmc_get_config(blob, node, host, &removable)) { 677 printf("%s: failed to decode dev %d\n", __func__, i); 678 return -1; 679 } 680 do_mmc_init(i, removable); 681 } 682 return 0; 683 } 684 685 void tegra_mmc_init(void) 686 { 687 int node_list[CONFIG_SYS_MMC_MAX_DEVICE], count; 688 const void *blob = gd->fdt_blob; 689 debug("%s entry\n", __func__); 690 691 /* See if any Tegra186 MMC controllers are present */ 692 count = fdtdec_find_aliases_for_id(blob, "sdhci", 693 COMPAT_NVIDIA_TEGRA186_SDMMC, node_list, 694 CONFIG_SYS_MMC_MAX_DEVICE); 695 debug("%s: count of Tegra186 sdhci nodes is %d\n", __func__, count); 696 if (process_nodes(blob, node_list, count)) { 697 printf("%s: Error processing T186 mmc node(s)!\n", __func__); 698 return; 699 } 700 701 /* See if any Tegra210 MMC controllers are present */ 702 count = fdtdec_find_aliases_for_id(blob, "sdhci", 703 COMPAT_NVIDIA_TEGRA210_SDMMC, node_list, 704 CONFIG_SYS_MMC_MAX_DEVICE); 705 debug("%s: count of Tegra210 sdhci nodes is %d\n", __func__, count); 706 if (process_nodes(blob, node_list, count)) { 707 printf("%s: Error processing T210 mmc node(s)!\n", __func__); 708 return; 709 } 710 711 /* See if any Tegra124 MMC controllers are present */ 712 count = fdtdec_find_aliases_for_id(blob, "sdhci", 713 COMPAT_NVIDIA_TEGRA124_SDMMC, node_list, 714 CONFIG_SYS_MMC_MAX_DEVICE); 715 debug("%s: count of Tegra124 sdhci nodes is %d\n", __func__, count); 716 if (process_nodes(blob, node_list, count)) { 717 printf("%s: Error processing T124 mmc node(s)!\n", __func__); 718 return; 719 } 720 721 /* See if any Tegra30 MMC controllers are present */ 722 count = fdtdec_find_aliases_for_id(blob, "sdhci", 723 COMPAT_NVIDIA_TEGRA30_SDMMC, node_list, 724 CONFIG_SYS_MMC_MAX_DEVICE); 725 debug("%s: count of T30 sdhci nodes is %d\n", __func__, count); 726 if (process_nodes(blob, node_list, count)) { 727 printf("%s: Error processing T30 mmc node(s)!\n", __func__); 728 return; 729 } 730 731 /* Now look for any Tegra20 MMC controllers */ 732 count = fdtdec_find_aliases_for_id(blob, "sdhci", 733 COMPAT_NVIDIA_TEGRA20_SDMMC, node_list, 734 CONFIG_SYS_MMC_MAX_DEVICE); 735 debug("%s: count of T20 sdhci nodes is %d\n", __func__, count); 736 if (process_nodes(blob, node_list, count)) { 737 printf("%s: Error processing T20 mmc node(s)!\n", __func__); 738 return; 739 } 740 } 741