Skip to content

Commit 0797e5f

Browse files
Johan Rudholmcjb
authored andcommitted
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 <[email protected]> Signed-off-by: Kevin Liu <[email protected]> Acked-by: Ulf Hansson <[email protected]> Tested-by: Wei WANG <[email protected]> Signed-off-by: Chris Ball <[email protected]>
1 parent 567c890 commit 0797e5f

File tree

3 files changed

+107
-17
lines changed

3 files changed

+107
-17
lines changed

drivers/mmc/core/core.c

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,27 +1340,90 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
13401340
{
13411341
struct mmc_command cmd = {0};
13421342
int err = 0;
1343+
u32 clock;
13431344

13441345
BUG_ON(!host);
13451346

13461347
/*
13471348
* Send CMD11 only if the request is to switch the card to
13481349
* 1.8V signalling.
13491350
*/
1350-
if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) {
1351-
cmd.opcode = SD_SWITCH_VOLTAGE;
1352-
cmd.arg = 0;
1353-
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
1351+
if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
1352+
return __mmc_set_signal_voltage(host, signal_voltage);
13541353

1355-
err = mmc_wait_for_cmd(host, &cmd, 0);
1356-
if (err)
1357-
return err;
1354+
/*
1355+
* If we cannot switch voltages, return failure so the caller
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;
13581371

1359-
if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
1360-
return -EIO;
1372+
if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
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;
13611384
}
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);
13621392

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;
13641427
}
13651428

13661429
/*

drivers/mmc/core/sd.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,14 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
712712
{
713713
int err;
714714
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+
}
715723

716724
/*
717725
* 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)
733741

734742
/*
735743
* 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.
737746
*/
738-
if (mmc_host_uhs(host))
747+
if (retries && mmc_host_uhs(host))
739748
ocr |= SD_OCR_S18R;
740749

741750
/*
@@ -746,7 +755,6 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
746755
if (max_current > 150)
747756
ocr |= SD_OCR_XPC;
748757

749-
try_again:
750758
err = mmc_send_app_op_cond(host, ocr, rocr);
751759
if (err)
752760
return err;
@@ -758,8 +766,11 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
758766
if (!mmc_host_is_spi(host) && rocr &&
759767
((*rocr & 0x41000000) == 0x41000000)) {
760768
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
761-
if (err) {
762-
ocr &= ~SD_OCR_S18R;
769+
if (err == -EAGAIN) {
770+
retries--;
771+
goto try_again;
772+
} else if (err) {
773+
retries = 0;
763774
goto try_again;
764775
}
765776
}

drivers/mmc/core/sdio.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,10 +584,19 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
584584
{
585585
struct mmc_card *card;
586586
int err;
587+
int retries = 10;
587588

588589
BUG_ON(!host);
589590
WARN_ON(!host->claimed);
590591

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+
591600
/*
592601
* Inform the card of the voltage
593602
*/
@@ -646,9 +655,16 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
646655
* systems that claim 1.8v signalling in fact do not support
647656
* it.
648657
*/
649-
if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
658+
if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
650659
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) {
652668
ocr &= ~R4_18V_PRESENT;
653669
host->ocr &= ~R4_18V_PRESENT;
654670
}

0 commit comments

Comments
 (0)