aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/core/sd.c
diff options
context:
space:
mode:
authorJohan Rudholm <johan.rudholm@stericsson.com>2013-01-28 15:08:28 +0100
committerChris Ball <cjb@laptop.org>2013-02-24 14:37:08 -0500
commit0797e5f1453b2bedc08bbcbea0ea4fbe20350823 (patch)
tree999bbb3435f9c38f18506738834d13a9ea4a8f4e /drivers/mmc/core/sd.c
parent567c89032cfdda8047562abe450947ac01f2d3c7 (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/core/sd.c')
-rw-r--r--drivers/mmc/core/sd.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 9a59fcd55a7..03134b1e563 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)
{
int err;
u32 max_current;
+ int retries = 10;
+
+try_again:
+ if (!retries) {
+ ocr &= ~SD_OCR_S18R;
+ pr_warning("%s: Skipping voltage switch\n",
+ mmc_hostname(host));
+ }
/*
* 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)
/*
* If the host supports one of UHS-I modes, request the card
- * to switch to 1.8V signaling level.
+ * to switch to 1.8V signaling level. If the card has failed
+ * repeatedly to switch however, skip this.
*/
- if (mmc_host_uhs(host))
+ if (retries && mmc_host_uhs(host))
ocr |= SD_OCR_S18R;
/*
@@ -746,7 +755,6 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
if (max_current > 150)
ocr |= SD_OCR_XPC;
-try_again:
err = mmc_send_app_op_cond(host, ocr, rocr);
if (err)
return err;
@@ -758,8 +766,11 @@ try_again:
if (!mmc_host_is_spi(host) && rocr &&
((*rocr & 0x41000000) == 0x41000000)) {
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
- if (err) {
- ocr &= ~SD_OCR_S18R;
+ if (err == -EAGAIN) {
+ retries--;
+ goto try_again;
+ } else if (err) {
+ retries = 0;
goto try_again;
}
}