Commit 0f823401 authored by Ye Li's avatar Ye Li Committed by Jason Liu

MLK-16499-1 mmc: Add support for HS400

The HS400 ES (Enhanced Strobe) has been added. This patch addes support
for HS400 for eMMC 5.0 devices. It needs tuning at HS200 to synchronize
command response.
Signed-off-by: 's avatarYe Li <ye.li@nxp.com>
Reviewed-by: 's avatarPeng Fan <peng.fan@nxp.com>
parent a0fc9891
......@@ -779,6 +779,12 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
case MMC_HS_200:
speed_bits = EXT_CSD_TIMING_HS200;
break;
case MMC_HS_400:
speed_bits = EXT_CSD_TIMING_HS400;
break;
case MMC_HS_400_ES:
speed_bits = EXT_CSD_TIMING_HS400;
break;
case MMC_LEGACY:
speed_bits = EXT_CSD_TIMING_LEGACY;
break;
......@@ -1658,6 +1664,11 @@ static const struct mode_width_tuning mmc_modes_by_pref[] = {
.mode = MMC_HS_400_ES,
.widths = MMC_MODE_8BIT,
},
{
.mode = MMC_HS_400,
.widths = MMC_MODE_8BIT,
.tuning = MMC_SEND_TUNING_BLOCK_HS200
},
{
.mode = MMC_HS_200,
.widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
......@@ -1737,6 +1748,45 @@ static int mmc_select_hs400es(struct mmc *mmc)
return 0;
}
static int mmc_select_hs400(struct mmc *mmc)
{
int err;
/* Set timing to HS200 for tuning */
err = mmc_set_card_speed(mmc, MMC_HS_200);
if (err)
return err;
/* configure the bus mode (host) */
mmc_select_mode(mmc, MMC_HS_200);
mmc_set_clock(mmc, mmc->tran_speed, false);
/* execute tuning if needed */
err = mmc_execute_tuning(mmc, MMC_SEND_TUNING_BLOCK_HS200);
if (err) {
debug("tuning failed\n");
return err;
}
/* Set back to HS */
mmc_set_card_speed(mmc, MMC_HS);
mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR);
if (err)
return err;
err = mmc_set_card_speed(mmc, MMC_HS_400);
if (err)
return err;
mmc_select_mode(mmc, MMC_HS_400);
mmc_set_clock(mmc, mmc->tran_speed, false);
return 0;
}
static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
{
int err;
......@@ -1775,7 +1825,11 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
goto error;
mmc_set_bus_width(mmc, bus_width(ecbw->cap));
if (mwt->mode == MMC_HS_400_ES) {
if (mwt->mode == MMC_HS_400) {
err = mmc_select_hs400(mmc);
if (err)
goto error;
} else if (mwt->mode == MMC_HS_400_ES) {
err = mmc_select_hs400es(mmc);
if (err)
goto error;
......
......@@ -248,7 +248,6 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7)
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment