diff options
author | Johan Rudholm <johan.rudholm@stericsson.com> | 2013-01-28 09:08:28 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-02-24 14:37:08 -0500 |
commit | 0797e5f1453b2bedc08bbcbea0ea4fbe20350823 (patch) | |
tree | 999bbb3435f9c38f18506738834d13a9ea4a8f4e /drivers/mmc | |
parent | 567c89032cfdda8047562abe450947ac01f2d3c7 (diff) |
mmc: core: Fixup signal voltage switch
When switching SD and SDIO cards from 3.3V to 1.8V signal levels, the
clock should be gated for 5 ms during the step. After enabling the
clock, the host should wait for at least 1 ms before checking for
failure. Failure by the card to switch is indicated by dat[0:3] being
pulled low. The host should check for this condition and power-cycle
the card if failure is indicated.
Add a retry mechanism for the SDIO case.
If the voltage switch fails repeatedly, give up and continue the
initialization using the original voltage.
This patch places a couple of requirements on the host driver:
1) mmc_set_ios with ios.clock = 0 must gate the clock
2) mmc_power_off must actually cut the power to the card
3) The card_busy host_ops member must be implemented
if these requirements are not fulfilled, the 1.8V signal voltage switch
will still be attempted but may not be successful.
Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com>
Signed-off-by: Kevin Liu <kliu5@marvell.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Wei WANG <wei_wang@realsil.com.cn>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/core.c | 83 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 21 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 20 |
3 files changed, 107 insertions, 17 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index bb794c784597..e41badbf9b50 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1340,6 +1340,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | |||
1340 | { | 1340 | { |
1341 | struct mmc_command cmd = {0}; | 1341 | struct mmc_command cmd = {0}; |
1342 | int err = 0; | 1342 | int err = 0; |
1343 | u32 clock; | ||
1343 | 1344 | ||
1344 | BUG_ON(!host); | 1345 | BUG_ON(!host); |
1345 | 1346 | ||
@@ -1347,20 +1348,82 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | |||
1347 | * Send CMD11 only if the request is to switch the card to | 1348 | * Send CMD11 only if the request is to switch the card to |
1348 | * 1.8V signalling. | 1349 | * 1.8V signalling. |
1349 | */ | 1350 | */ |
1350 | if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) { | 1351 | if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) |
1351 | cmd.opcode = SD_SWITCH_VOLTAGE; | 1352 | return __mmc_set_signal_voltage(host, signal_voltage); |
1352 | cmd.arg = 0; | ||
1353 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
1354 | 1353 | ||
1355 | err = mmc_wait_for_cmd(host, &cmd, 0); | 1354 | /* |
1356 | if (err) | 1355 | * If we cannot switch voltages, return failure so the caller |
1357 | return err; | 1356 | * can continue without UHS mode |
1357 | */ | ||
1358 | if (!host->ops->start_signal_voltage_switch) | ||
1359 | return -EPERM; | ||
1360 | if (!host->ops->card_busy) | ||
1361 | pr_warning("%s: cannot verify signal voltage switch\n", | ||
1362 | mmc_hostname(host)); | ||
1363 | |||
1364 | cmd.opcode = SD_SWITCH_VOLTAGE; | ||
1365 | cmd.arg = 0; | ||
1366 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
1367 | |||
1368 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
1369 | if (err) | ||
1370 | return err; | ||
1358 | 1371 | ||
1359 | if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) | 1372 | if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) |
1360 | return -EIO; | 1373 | return -EIO; |
1374 | |||
1375 | mmc_host_clk_hold(host); | ||
1376 | /* | ||
1377 | * The card should drive cmd and dat[0:3] low immediately | ||
1378 | * after the response of cmd11, but wait 1 ms to be sure | ||
1379 | */ | ||
1380 | mmc_delay(1); | ||
1381 | if (host->ops->card_busy && !host->ops->card_busy(host)) { | ||
1382 | err = -EAGAIN; | ||
1383 | goto power_cycle; | ||
1361 | } | 1384 | } |
1385 | /* | ||
1386 | * During a signal voltage level switch, the clock must be gated | ||
1387 | * for 5 ms according to the SD spec | ||
1388 | */ | ||
1389 | clock = host->ios.clock; | ||
1390 | host->ios.clock = 0; | ||
1391 | mmc_set_ios(host); | ||
1362 | 1392 | ||
1363 | return __mmc_set_signal_voltage(host, signal_voltage); | 1393 | if (__mmc_set_signal_voltage(host, signal_voltage)) { |
1394 | /* | ||
1395 | * Voltages may not have been switched, but we've already | ||
1396 | * sent CMD11, so a power cycle is required anyway | ||
1397 | */ | ||
1398 | err = -EAGAIN; | ||
1399 | goto power_cycle; | ||
1400 | } | ||
1401 | |||
1402 | /* Keep clock gated for at least 5 ms */ | ||
1403 | mmc_delay(5); | ||
1404 | host->ios.clock = clock; | ||
1405 | mmc_set_ios(host); | ||
1406 | |||
1407 | /* Wait for at least 1 ms according to spec */ | ||
1408 | mmc_delay(1); | ||
1409 | |||
1410 | /* | ||
1411 | * Failure to switch is indicated by the card holding | ||
1412 | * dat[0:3] low | ||
1413 | */ | ||
1414 | if (host->ops->card_busy && host->ops->card_busy(host)) | ||
1415 | err = -EAGAIN; | ||
1416 | |||
1417 | power_cycle: | ||
1418 | if (err) { | ||
1419 | pr_debug("%s: Signal voltage switch failed, " | ||
1420 | "power cycling card\n", mmc_hostname(host)); | ||
1421 | mmc_power_cycle(host); | ||
1422 | } | ||
1423 | |||
1424 | mmc_host_clk_release(host); | ||
1425 | |||
1426 | return err; | ||
1364 | } | 1427 | } |
1365 | 1428 | ||
1366 | /* | 1429 | /* |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 9a59fcd55a75..03134b1e563c 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -712,6 +712,14 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) | |||
712 | { | 712 | { |
713 | int err; | 713 | int err; |
714 | u32 max_current; | 714 | u32 max_current; |
715 | int retries = 10; | ||
716 | |||
717 | try_again: | ||
718 | if (!retries) { | ||
719 | ocr &= ~SD_OCR_S18R; | ||
720 | pr_warning("%s: Skipping voltage switch\n", | ||
721 | mmc_hostname(host)); | ||
722 | } | ||
715 | 723 | ||
716 | /* | 724 | /* |
717 | * Since we're changing the OCR value, we seem to | 725 | * Since we're changing the OCR value, we seem to |
@@ -733,9 +741,10 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) | |||
733 | 741 | ||
734 | /* | 742 | /* |
735 | * If the host supports one of UHS-I modes, request the card | 743 | * If the host supports one of UHS-I modes, request the card |
736 | * to switch to 1.8V signaling level. | 744 | * to switch to 1.8V signaling level. If the card has failed |
745 | * repeatedly to switch however, skip this. | ||
737 | */ | 746 | */ |
738 | if (mmc_host_uhs(host)) | 747 | if (retries && mmc_host_uhs(host)) |
739 | ocr |= SD_OCR_S18R; | 748 | ocr |= SD_OCR_S18R; |
740 | 749 | ||
741 | /* | 750 | /* |
@@ -746,7 +755,6 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) | |||
746 | if (max_current > 150) | 755 | if (max_current > 150) |
747 | ocr |= SD_OCR_XPC; | 756 | ocr |= SD_OCR_XPC; |
748 | 757 | ||
749 | try_again: | ||
750 | err = mmc_send_app_op_cond(host, ocr, rocr); | 758 | err = mmc_send_app_op_cond(host, ocr, rocr); |
751 | if (err) | 759 | if (err) |
752 | return err; | 760 | return err; |
@@ -758,8 +766,11 @@ try_again: | |||
758 | if (!mmc_host_is_spi(host) && rocr && | 766 | if (!mmc_host_is_spi(host) && rocr && |
759 | ((*rocr & 0x41000000) == 0x41000000)) { | 767 | ((*rocr & 0x41000000) == 0x41000000)) { |
760 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); | 768 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); |
761 | if (err) { | 769 | if (err == -EAGAIN) { |
762 | ocr &= ~SD_OCR_S18R; | 770 | retries--; |
771 | goto try_again; | ||
772 | } else if (err) { | ||
773 | retries = 0; | ||
763 | goto try_again; | 774 | goto try_again; |
764 | } | 775 | } |
765 | } | 776 | } |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 1a726aef211d..aa0719a4dfd1 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -584,10 +584,19 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
584 | { | 584 | { |
585 | struct mmc_card *card; | 585 | struct mmc_card *card; |
586 | int err; | 586 | int err; |
587 | int retries = 10; | ||
587 | 588 | ||
588 | BUG_ON(!host); | 589 | BUG_ON(!host); |
589 | WARN_ON(!host->claimed); | 590 | WARN_ON(!host->claimed); |
590 | 591 | ||
592 | try_again: | ||
593 | if (!retries) { | ||
594 | pr_warning("%s: Skipping voltage switch\n", | ||
595 | mmc_hostname(host)); | ||
596 | ocr &= ~R4_18V_PRESENT; | ||
597 | host->ocr &= ~R4_18V_PRESENT; | ||
598 | } | ||
599 | |||
591 | /* | 600 | /* |
592 | * Inform the card of the voltage | 601 | * Inform the card of the voltage |
593 | */ | 602 | */ |
@@ -646,9 +655,16 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
646 | * systems that claim 1.8v signalling in fact do not support | 655 | * systems that claim 1.8v signalling in fact do not support |
647 | * it. | 656 | * it. |
648 | */ | 657 | */ |
649 | if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { | 658 | if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { |
650 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); | 659 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); |
651 | if (err) { | 660 | if (err == -EAGAIN) { |
661 | sdio_reset(host); | ||
662 | mmc_go_idle(host); | ||
663 | mmc_send_if_cond(host, host->ocr_avail); | ||
664 | mmc_remove_card(card); | ||
665 | retries--; | ||
666 | goto try_again; | ||
667 | } else if (err) { | ||
652 | ocr &= ~R4_18V_PRESENT; | 668 | ocr &= ~R4_18V_PRESENT; |
653 | host->ocr &= ~R4_18V_PRESENT; | 669 | host->ocr &= ~R4_18V_PRESENT; |
654 | } | 670 | } |