summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorChuanxiao.Dong <chuanxiao.dong@intel.com>2014-08-15 11:28:07 +0800
committerUlf Hansson <ulf.hansson@linaro.org>2014-09-09 13:59:24 +0200
commit312449efd16bb06a1e4fda94793d3eb8b8bb16f6 (patch)
tree7030e3616f7b928a78db1ea32895dc8607e3798f /drivers/mmc
parente73708190557911893ce4fb7a551ff5285e62ca2 (diff)
downloadblackbird-op-linux-312449efd16bb06a1e4fda94793d3eb8b8bb16f6.tar.gz
blackbird-op-linux-312449efd16bb06a1e4fda94793d3eb8b8bb16f6.zip
mmc: core: Fix sequence for I/O voltage in DDR mode for eMMC
Even (e)MMC card can support 3.3v to 1.2v vccq in DDR, but not all host controller can support this, like some of the SDHCI host which connect to an eMMC device. Some of these host controller still needs to use 1.8v vccq for supporting DDR mode. So the sequence will be: if (host and device can both support 1.2v IO) use 1.2v IO; else if (host and device can both support 1.8v IO) use 1.8v IO; so if host and device can only support 3.3v IO, this is the last choice. Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.com> Signed-off-by: Yunpeng Gao <yunpeng.gao@intel.com> Tested-by: Jean-Michel Hautbois <jhautbois@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/mmc.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 31c43165f8bc..69e6273ed228 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -988,19 +988,35 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
* 1.8V vccq at 3.3V core voltage (vcc) is not required
* in the JEDEC spec for DDR.
*
- * Do not force change in vccq since we are obviously
- * working and no change to vccq is needed.
+ * Even (e)MMC card can support 3.3v to 1.2v vccq, but not all
+ * host controller can support this, like some of the SDHCI
+ * controller which connect to an eMMC device. Some of these
+ * host controller still needs to use 1.8v vccq for supporting
+ * DDR mode.
+ *
+ * So the sequence will be:
+ * if (host and device can both support 1.2v IO)
+ * use 1.2v IO;
+ * else if (host and device can both support 1.8v IO)
+ * use 1.8v IO;
+ * so if host and device can only support 3.3v IO, this is the
+ * last choice.
*
* WARNING: eMMC rules are NOT the same as SD DDR
*/
- if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) {
- err = __mmc_set_signal_voltage(host,
- MMC_SIGNAL_VOLTAGE_120);
- if (err)
- return err;
- }
+ err = -EINVAL;
+ if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
+ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
- mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
+ if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V))
+ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
+
+ /* make sure vccq is 3.3v after switching disaster */
+ if (err)
+ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
+
+ if (!err)
+ mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
return err;
}
OpenPOWER on IntegriCloud