[U-Boot] [PATCH 31/33] mmc: add support for HS400 mode of eMMC5.0

Ziyuan Xu xzy.xu at rock-chips.com
Mon May 15 06:07:25 UTC 2017


This patch adds HS400 mode support for eMMC5.0 device. HS400 mode is
high speed DDR interface timing from HS200. Clock frequency is up to
200MHz and only 8-bit bus width is supported. In addition, tuning
process of HS200 is required to synchronize the command response on the
CMD line because CMD input timing for HS400 mode is the same as HS200
mode.

Signed-off-by: Ziyuan Xu <xzy.xu at rock-chips.com>
---

 drivers/mmc/mmc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index c1f54c3..71c9cfa 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -855,6 +855,45 @@ static int mmc_select_hs200(struct mmc *mmc)
 }
 #endif
 
+static int mmc_select_hs400(struct mmc *mmc)
+{
+	int ret;
+
+	/* Switch card to HS mode */
+	ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, false);
+	if (ret)
+		return ret;
+
+	/* Set host controller to HS timing */
+	mmc_set_timing(mmc, MMC_TIMING_MMC_HS);
+
+	/* Reduce frequency to HS frequency */
+	mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
+
+	ret = mmc_send_status(mmc, 1000);
+	if (ret)
+		return ret;
+
+	/* Switch card to DDR */
+	ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+			 EXT_CSD_BUS_WIDTH,
+			 EXT_CSD_DDR_BUS_WIDTH_8);
+	if (ret)
+		return ret;
+
+	/* Switch card to HS400 */
+	ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, false);
+	if (ret)
+		return ret;
+
+	/* Set host controller to HS400 timing and frequency */
+	mmc_set_timing(mmc, MMC_TIMING_MMC_HS400);
+
+	return ret;
+}
+
 static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
 {
 	u8 card_type;
@@ -960,9 +999,14 @@ static int mmc_change_freq(struct mmc *mmc)
 
 	mmc_set_bus_speed(mmc, avail_type);
 
-	if (mmc_card_hs200(mmc))
+	if (mmc_card_hs200(mmc)) {
 		err = mmc_hs200_tuning(mmc);
-	else if (!mmc_card_hs400es(mmc)) {
+		if (avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+		    mmc->bus_width == MMC_BUS_WIDTH_8BIT) {
+			err = mmc_select_hs400(mmc);
+			mmc_set_bus_speed(mmc, avail_type);
+		}
+	} else if (!mmc_card_hs400es(mmc)) {
 		err = mmc_select_bus_width(mmc) > 0 ? 0 : err;
 		if (!err && avail_type & EXT_CSD_CARD_TYPE_DDR_52)
 			err = mmc_select_hs_ddr(mmc);
-- 
2.7.4




More information about the U-Boot mailing list