aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 76bb621e9aa9..1d8409fcf155 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -534,39 +534,57 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
534 */ 534 */
535 if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && 535 if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
536 (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { 536 (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
537 unsigned ext_csd_bit, bus_width; 537 static unsigned ext_csd_bits[][2] = {
538 538 { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
539 if (host->caps & MMC_CAP_8_BIT_DATA) { 539 { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 },
540 if (ddr) 540 { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 },
541 ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; 541 };
542 else 542 static unsigned bus_widths[] = {
543 ext_csd_bit = EXT_CSD_BUS_WIDTH_8; 543 MMC_BUS_WIDTH_8,
544 bus_width = MMC_BUS_WIDTH_8; 544 MMC_BUS_WIDTH_4,
545 } else { 545 MMC_BUS_WIDTH_1
546 if (ddr) 546 };
547 ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; 547 unsigned idx, bus_width = 0;
548 else 548
549 ext_csd_bit = EXT_CSD_BUS_WIDTH_4; 549 if (host->caps & MMC_CAP_8_BIT_DATA)
550 bus_width = MMC_BUS_WIDTH_4; 550 idx = 0;
551 else
552 idx = 1;
553 for (; idx < ARRAY_SIZE(bus_widths); idx++) {
554 bus_width = bus_widths[idx];
555 if (bus_width == MMC_BUS_WIDTH_1)
556 ddr = 0; /* no DDR for 1-bit width */
557 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
558 EXT_CSD_BUS_WIDTH,
559 ext_csd_bits[idx][0]);
560 if (!err) {
561 /*
562 * If controller can't handle bus width test,
563 * use the highest bus width to maintain
564 * compatibility with previous MMC behavior.
565 */
566 if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
567 break;
568 mmc_set_bus_width_ddr(card->host,
569 bus_width, MMC_SDR_MODE);
570 err = mmc_bus_test(card, bus_width);
571 if (!err)
572 break;
573 }
551 } 574 }
552 575
553 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 576 if (!err && ddr) {
554 EXT_CSD_BUS_WIDTH, ext_csd_bit); 577 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
555 578 EXT_CSD_BUS_WIDTH,
556 if (err && err != -EBADMSG) 579 ext_csd_bits[idx][1]);
557 goto free_card; 580 }
558
559 if (err) { 581 if (err) {
560 printk(KERN_WARNING "%s: switch to bus width %d ddr %d " 582 printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
561 "failed\n", mmc_hostname(card->host), 583 "failed\n", mmc_hostname(card->host),
562 1 << bus_width, ddr); 584 1 << bus_width, ddr);
563 err = 0; 585 goto free_card;
564 } else { 586 } else if (ddr) {
565 if (ddr) 587 mmc_card_set_ddr_mode(card);
566 mmc_card_set_ddr_mode(card);
567 else
568 ddr = MMC_SDR_MODE;
569
570 mmc_set_bus_width_ddr(card->host, bus_width, ddr); 588 mmc_set_bus_width_ddr(card->host, bus_width, ddr);
571 } 589 }
572 } 590 }