diff options
author | Johan Rudholm <johan.rudholm@stericsson.com> | 2013-01-28 15:08:28 +0100 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-02-24 14:37:08 -0500 |
commit | 0797e5f1453b2bedc08bbcbea0ea4fbe20350823 (patch) | |
tree | 999bbb3435f9c38f18506738834d13a9ea4a8f4e /drivers/mmc/core/sd.c | |
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/core/sd.c')
-rw-r--r-- | drivers/mmc/core/sd.c | 21 |
1 files changed, 16 insertions, 5 deletions
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) { 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; } } |