Commit a0fc9891 authored by Peng Fan's avatar Peng Fan Committed by Jason Liu

MLK-16496-2 mmc: fsl_esdhc: add hs400 es mode support

Add HS400 ES mode support.

The flow is same as mmc_select_hs400es in kernel drivers/mmc/core/mmc.c.
With HS400 ES, there is no tuning needed.

With Toshiba 32GB Automotive eMMC5.1 on 8QXP ARM2 board, speed test:
'time mmc read 0x90000000 0 0x200000' shows that speed is 282MB/s.
Signed-off-by: 's avatarPeng Fan <peng.fan@nxp.com>
Reviewed-by: 's avatarYe Li <ye.li@nxp.com>
parent f168228e
...@@ -79,7 +79,10 @@ struct fsl_esdhc { ...@@ -79,7 +79,10 @@ struct fsl_esdhc {
uint dllctrl; uint dllctrl;
uint dllstat; uint dllstat;
uint clktunectrlstatus; uint clktunectrlstatus;
char reserved3[84]; char reserved[4];
uint strobe_dllctrl;
uint strobe_dllstat;
char reserved3[72];
uint vendorspec; uint vendorspec;
uint mmcboot; uint mmcboot;
uint vendorspec2; uint vendorspec2;
...@@ -137,6 +140,7 @@ struct fsl_esdhc_priv { ...@@ -137,6 +140,7 @@ struct fsl_esdhc_priv {
int is_ddr; int is_ddr;
u32 tuning_step; u32 tuning_step;
u32 tuning_start_tap; u32 tuning_start_tap;
u32 strobe_dll_delay_target;
u32 delay_line; u32 delay_line;
uint signal_voltage; uint signal_voltage;
#if CONFIG_IS_ENABLED(DM_REGULATOR) #if CONFIG_IS_ENABLED(DM_REGULATOR)
...@@ -698,6 +702,8 @@ static int esdhc_change_pinstate(struct mmc *mmc) ...@@ -698,6 +702,8 @@ static int esdhc_change_pinstate(struct mmc *mmc)
break; break;
case UHS_SDR104: case UHS_SDR104:
case MMC_HS_200: case MMC_HS_200:
case MMC_HS_400:
case MMC_HS_400_ES:
ret = pinctrl_select_state(dev, "state_200mhz"); ret = pinctrl_select_state(dev, "state_200mhz");
break; break;
default: default:
...@@ -726,6 +732,32 @@ static void esdhc_reset_tuning(struct mmc *mmc) ...@@ -726,6 +732,32 @@ static void esdhc_reset_tuning(struct mmc *mmc)
} }
} }
static void esdhc_set_strobe_dll(struct mmc *mmc)
{
struct fsl_esdhc_priv *priv = mmc->priv;
struct fsl_esdhc *regs = priv->esdhc_regs;
u32 v;
if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) {
writel(ESDHC_STROBE_DLL_CTRL_RESET, &regs->strobe_dllctrl);
/*
* enable strobe dll ctrl and adjust the delay target
* for the uSDHC loopback read clock
*/
v = ESDHC_STROBE_DLL_CTRL_ENABLE |
(priv->strobe_dll_delay_target << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
writel(v, &regs->strobe_dllctrl);
/* wait 1us to make sure strobe dll status register stable */
udelay(1);
v = readl(&regs->strobe_dllstat);
if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
printf("warning! HS400 strobe DLL status REF not lock!\n");
if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
printf("warning! HS400 strobe DLL status SLV not lock!\n");
}
}
static int esdhc_set_timing(struct mmc *mmc) static int esdhc_set_timing(struct mmc *mmc)
{ {
struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc_priv *priv = mmc->priv;
...@@ -741,6 +773,14 @@ static int esdhc_set_timing(struct mmc *mmc) ...@@ -741,6 +773,14 @@ static int esdhc_set_timing(struct mmc *mmc)
case SD_LEGACY: case SD_LEGACY:
esdhc_reset_tuning(mmc); esdhc_reset_tuning(mmc);
break; break;
case MMC_HS_400:
case MMC_HS_400_ES:
m |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
writel(m, &regs->mixctrl);
priv->is_ddr = 1;
set_sysctl(mmc, mmc->clock);
esdhc_set_strobe_dll(mmc);
break;
case MMC_HS: case MMC_HS:
case MMC_HS_52: case MMC_HS_52:
case MMC_HS_200: case MMC_HS_200:
...@@ -898,6 +938,17 @@ static int esdhc_execute_tuning(struct mmc *mmc, uint32_t opcode) ...@@ -898,6 +938,17 @@ static int esdhc_execute_tuning(struct mmc *mmc, uint32_t opcode)
return ret; return ret;
} }
static void esdhc_hs400_enhanced_strobe(struct mmc *mmc)
{
struct fsl_esdhc_priv *priv = mmc->priv;
struct fsl_esdhc *regs = priv->esdhc_regs;
u32 m;
m = readl(&regs->mixctrl);
m |= MIX_CTRL_HS400_ES;
writel(m, &regs->mixctrl);
}
static int esdhc_set_vdd(struct mmc *mmc, bool enable) static int esdhc_set_vdd(struct mmc *mmc, bool enable)
{ {
#if CONFIG_IS_ENABLED(DM_REGULATOR) #if CONFIG_IS_ENABLED(DM_REGULATOR)
...@@ -1073,6 +1124,7 @@ static const struct mmc_ops esdhc_ops = { ...@@ -1073,6 +1124,7 @@ static const struct mmc_ops esdhc_ops = {
#if CONFIG_IS_ENABLED(DM_MMC) #if CONFIG_IS_ENABLED(DM_MMC)
.execute_tuning = esdhc_execute_tuning, .execute_tuning = esdhc_execute_tuning,
.set_vdd = esdhc_set_vdd, .set_vdd = esdhc_set_vdd,
.hs400_enhanced_strobe = esdhc_hs400_enhanced_strobe,
#endif #endif
}; };
...@@ -1382,6 +1434,8 @@ static int fsl_esdhc_probe(struct udevice *dev) ...@@ -1382,6 +1434,8 @@ static int fsl_esdhc_probe(struct udevice *dev)
priv->tuning_step = val; priv->tuning_step = val;
val = fdtdec_get_int(fdt, node, "fsl,tuning-start-tap", ESDHC_TUNING_START_TAP_DEFAULT); val = fdtdec_get_int(fdt, node, "fsl,tuning-start-tap", ESDHC_TUNING_START_TAP_DEFAULT);
priv->tuning_start_tap = val; priv->tuning_start_tap = val;
val = fdtdec_get_int(fdt, node, "fsl,strobe-dll-delay-target", ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
priv->strobe_dll_delay_target = val;
if (fdt_get_property(fdt, node, "non-removable", NULL)) { if (fdt_get_property(fdt, node, "non-removable", NULL)) {
priv->non_removable = 1; priv->non_removable = 1;
...@@ -1421,8 +1475,10 @@ static int fsl_esdhc_probe(struct udevice *dev) ...@@ -1421,8 +1475,10 @@ static int fsl_esdhc_probe(struct udevice *dev)
dev_dbg(dev, "no vmmc supply\n"); dev_dbg(dev, "no vmmc supply\n");
#endif #endif
if (fdt_get_property(fdt, node, "no-1-8-v", NULL)) if (fdt_get_property(fdt, node, "no-1-8-v", NULL)) {
priv->caps &= ~UHS_CAPS; priv->caps &= ~(UHS_CAPS | MMC_MODE_HS400 | MMC_MODE_HS400_ES |
MMC_MODE_HS200);
}
/* /*
* TODO: * TODO:
...@@ -1468,8 +1524,9 @@ static struct esdhc_soc_data usdhc_imx8qm_data = { ...@@ -1468,8 +1524,9 @@ static struct esdhc_soc_data usdhc_imx8qm_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
| ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES, | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES,
.caps = UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_DDR_52MHz .caps = UHS_CAPS | MMC_MODE_HS400 | MMC_MODE_HS400_ES |
| MMC_MODE_HS_52MHz | MMC_MODE_HS, MMC_MODE_HS200 | MMC_MODE_DDR_52MHz | MMC_MODE_HS_52MHz |
MMC_MODE_HS,
}; };
static const struct udevice_id fsl_esdhc_ids[] = { static const struct udevice_id fsl_esdhc_ids[] = {
......
...@@ -169,6 +169,8 @@ const char *mmc_mode_name(enum bus_mode mode) ...@@ -169,6 +169,8 @@ const char *mmc_mode_name(enum bus_mode mode)
[MMC_HS_52] = "MMC High Speed (52MHz)", [MMC_HS_52] = "MMC High Speed (52MHz)",
[MMC_DDR_52] = "MMC DDR52 (52MHz)", [MMC_DDR_52] = "MMC DDR52 (52MHz)",
[MMC_HS_200] = "HS200 (200MHz)", [MMC_HS_200] = "HS200 (200MHz)",
[MMC_HS_400] = "HS400 (200MHz)",
[MMC_HS_400_ES] = "HS400ES (200MHz)",
}; };
if (mode >= MMC_MODES_END) if (mode >= MMC_MODES_END)
...@@ -191,6 +193,8 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode) ...@@ -191,6 +193,8 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
[MMC_HS_52] = 52000000, [MMC_HS_52] = 52000000,
[MMC_DDR_52] = 52000000, [MMC_DDR_52] = 52000000,
[MMC_HS_200] = 200000000, [MMC_HS_200] = 200000000,
[MMC_HS_400] = 200000000,
[MMC_HS_400_ES] = 200000000,
}; };
if (mode == MMC_LEGACY) if (mode == MMC_LEGACY)
...@@ -804,6 +808,7 @@ static int mmc_get_capabilities(struct mmc *mmc) ...@@ -804,6 +808,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
{ {
u8 *ext_csd = mmc->ext_csd; u8 *ext_csd = mmc->ext_csd;
char cardtype; char cardtype;
char strobe_support;
mmc->card_caps = MMC_MODE_1BIT; mmc->card_caps = MMC_MODE_1BIT;
...@@ -821,12 +826,17 @@ static int mmc_get_capabilities(struct mmc *mmc) ...@@ -821,12 +826,17 @@ static int mmc_get_capabilities(struct mmc *mmc)
mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f; cardtype = ext_csd[EXT_CSD_CARD_TYPE];
strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V | if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
EXT_CSD_CARD_TYPE_HS200_1_8V)) { EXT_CSD_CARD_TYPE_HS200_1_8V)) {
mmc->card_caps |= MMC_MODE_HS200; mmc->card_caps |= MMC_MODE_HS200;
} }
if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
EXT_CSD_CARD_TYPE_HS400_1_8V)) {
mmc->card_caps |= MMC_MODE_HS400;
}
if (cardtype & EXT_CSD_CARD_TYPE_52) { if (cardtype & EXT_CSD_CARD_TYPE_52) {
if (cardtype & EXT_CSD_CARD_TYPE_DDR_52) if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
mmc->card_caps |= MMC_MODE_DDR_52MHz; mmc->card_caps |= MMC_MODE_DDR_52MHz;
...@@ -835,6 +845,9 @@ static int mmc_get_capabilities(struct mmc *mmc) ...@@ -835,6 +845,9 @@ static int mmc_get_capabilities(struct mmc *mmc)
if (cardtype & EXT_CSD_CARD_TYPE_26) if (cardtype & EXT_CSD_CARD_TYPE_26)
mmc->card_caps |= MMC_MODE_HS; mmc->card_caps |= MMC_MODE_HS;
if (strobe_support && (mmc->card_caps & MMC_MODE_HS400))
mmc->card_caps |= MMC_MODE_HS400_ES;
return 0; return 0;
} }
...@@ -1641,6 +1654,10 @@ static int mmc_read_and_compare_ext_csd(struct mmc *mmc) ...@@ -1641,6 +1654,10 @@ static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
static const struct mode_width_tuning mmc_modes_by_pref[] = { static const struct mode_width_tuning mmc_modes_by_pref[] = {
{
.mode = MMC_HS_400_ES,
.widths = MMC_MODE_8BIT,
},
{ {
.mode = MMC_HS_200, .mode = MMC_HS_200,
.widths = MMC_MODE_8BIT | MMC_MODE_4BIT, .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
...@@ -1686,6 +1703,40 @@ static const struct ext_csd_bus_width { ...@@ -1686,6 +1703,40 @@ static const struct ext_csd_bus_width {
ecbv++) \ ecbv++) \
if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap)) if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
static int mmc_select_hs400es(struct mmc *mmc)
{
int err;
err = mmc_set_card_speed(mmc, MMC_HS);
if (err)
return err;
/* configure the bus mode (host) */
mmc_select_mode(mmc, MMC_HS);
mmc_set_clock(mmc, mmc->tran_speed, false);
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8 |
EXT_CSD_DDR | EXT_CSD_BUS_WIDTH_STROBE);
if (err) {
printf("switch to bus width for hs400 failed\n");
return err;
}
/* TODO: driver strength */
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400 | (0 << EXT_CSD_DRV_STR_SHIFT));
if (err) {
printf("switch to hs400 failed\n");
return err;
}
mmc_select_mode(mmc, MMC_HS_400_ES);
mmc_set_clock(mmc, mmc->tran_speed, false);
mmc->cfg->ops->hs400_enhanced_strobe(mmc);
return 0;
}
static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps) static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
{ {
int err; int err;
...@@ -1724,32 +1775,38 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps) ...@@ -1724,32 +1775,38 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
goto error; goto error;
mmc_set_bus_width(mmc, bus_width(ecbw->cap)); mmc_set_bus_width(mmc, bus_width(ecbw->cap));
/* configure the bus speed (card) */ if (mwt->mode == MMC_HS_400_ES) {
err = mmc_set_card_speed(mmc, mwt->mode); err = mmc_select_hs400es(mmc);
if (err) if (err)
goto error; goto error;
} else {
/* /* configure the bus speed (card) */
* configure the bus width AND the ddr mode (card) err = mmc_set_card_speed(mmc, mwt->mode);
* The host side will be taken care of in the next step
*/
if (ecbw->ext_csd_bits & EXT_CSD_DDR) {
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH, ecbw->ext_csd_bits);
if (err) if (err)
goto error; goto error;
}
/* configure the bus mode (host) */ /*
mmc_select_mode(mmc, mwt->mode); * configure the bus width AND the ddr mode (card)
mmc_set_clock(mmc, mmc->tran_speed, false); * The host side will be taken care of in the next step
*/
if (ecbw->ext_csd_bits & EXT_CSD_DDR) {
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH, ecbw->ext_csd_bits);
if (err)
goto error;
}
/* execute tuning if needed */ /* configure the bus mode (host) */
if (mwt->tuning) { mmc_select_mode(mmc, mwt->mode);
err = mmc_execute_tuning(mmc, mwt->tuning); mmc_set_clock(mmc, mmc->tran_speed, false);
if (err) {
debug("tuning failed\n"); /* execute tuning if needed */
goto error; if (mwt->tuning) {
err = mmc_execute_tuning(mmc, mwt->tuning);
if (err) {
debug("tuning failed\n");
goto error;
}
} }
} }
......
...@@ -55,6 +55,18 @@ ...@@ -55,6 +55,18 @@
/* Tuning bits */ /* Tuning bits */
#define MIX_CTRL_TUNING_MASK 0x03c00000 #define MIX_CTRL_TUNING_MASK 0x03c00000
/* strobe dll register */
#define ESDHC_STROBE_DLL_CTRL 0x70
#define ESDHC_STROBE_DLL_CTRL_ENABLE (1 << 0)
#define ESDHC_STROBE_DLL_CTRL_RESET (1 << 1)
#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT 0x7
#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3
#define ESDHC_STROBE_DLL_STATUS 0x74
#define ESDHC_STROBE_DLL_STS_REF_LOCK (1 << 1)
#define ESDHC_STROBE_DLL_STS_SLV_LOCK 0x1
#define ESDHC_STROBE_DLL_CLK_FREQ 100000000
#define ESDHC_STD_TUNING_EN (1 << 24) #define ESDHC_STD_TUNING_EN (1 << 24)
/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
#define ESDHC_TUNING_START_TAP_DEFAULT 0x1 #define ESDHC_TUNING_START_TAP_DEFAULT 0x1
......
...@@ -57,6 +57,8 @@ ...@@ -57,6 +57,8 @@
#define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52) #define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52)
#define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52) #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
#define MMC_MODE_HS200 MMC_CAP(MMC_HS_200) #define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
#define MMC_MODE_HS400 MMC_CAP(MMC_HS_400)
#define MMC_MODE_HS400_ES MMC_CAP(MMC_HS_400_ES)
#define MMC_MODE_8BIT (1 << 30) #define MMC_MODE_8BIT (1 << 30)
#define MMC_MODE_4BIT (1 << 29) #define MMC_MODE_4BIT (1 << 29)
...@@ -211,6 +213,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) ...@@ -211,6 +213,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
#define EXT_CSD_BOOT_BUS_WIDTH 177 #define EXT_CSD_BOOT_BUS_WIDTH 177
#define EXT_CSD_PART_CONF 179 /* R/W */ #define EXT_CSD_PART_CONF 179 /* R/W */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */
...@@ -241,14 +244,23 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) ...@@ -241,14 +244,23 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \ #define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V) EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6)
#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_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR 4 /* Card is in DDR mode */ #define EXT_CSD_DDR 4 /* Card is in DDR mode */
#define EXT_CSD_BUS_WIDTH_STROBE (1 << 7) /* Enhanced strobe mode */
#define EXT_CSD_TIMING_LEGACY 0 /* no high speed */ #define EXT_CSD_TIMING_LEGACY 0 /* no high speed */
#define EXT_CSD_TIMING_HS 1 /* HS */ #define EXT_CSD_TIMING_HS 1 /* HS */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */ #define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
...@@ -425,6 +437,9 @@ struct dm_mmc_ops { ...@@ -425,6 +437,9 @@ struct dm_mmc_ops {
* @return 1 if busy, O if not busy * @return 1 if busy, O if not busy
*/ */
int (*card_busy)(struct udevice *dev); int (*card_busy)(struct udevice *dev);
/* hs400_enhanced_strobe() - set enhanced strobe */
void (*hs400_enhanced_strobe)(struct udevice *dev);
}; };
#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) #define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops)
...@@ -457,6 +472,7 @@ struct mmc_ops { ...@@ -457,6 +472,7 @@ struct mmc_ops {
int (*getwp)(struct mmc *mmc); int (*getwp)(struct mmc *mmc);
int (*execute_tuning)(struct mmc *mmc, uint opcode); int (*execute_tuning)(struct mmc *mmc, uint opcode);
int (*card_busy)(struct mmc *mmc); int (*card_busy)(struct mmc *mmc);
void (*hs400_enhanced_strobe)(struct mmc *mmc);
}; };
#endif #endif
...@@ -492,6 +508,8 @@ enum bus_mode { ...@@ -492,6 +508,8 @@ enum bus_mode {
MMC_HS_52 = 9, MMC_HS_52 = 9,
MMC_DDR_52 = 10, MMC_DDR_52 = 10,
MMC_HS_200 = 11, MMC_HS_200 = 11,
MMC_HS_400 = 12,
MMC_HS_400_ES = 13,
MMC_MODES_END MMC_MODES_END
}; };
...@@ -500,7 +518,8 @@ void mmc_dump_capabilities(const char *text, uint caps); ...@@ -500,7 +518,8 @@ void mmc_dump_capabilities(const char *text, uint caps);
static inline bool mmc_is_mode_ddr(enum bus_mode mode) static inline bool mmc_is_mode_ddr(enum bus_mode mode)
{ {
if ((mode == MMC_DDR_52) || (mode == UHS_DDR50)) if ((mode == MMC_HS_400) || (mode == MMC_HS_400_ES) || \
(mode == MMC_DDR_52) || (mode == UHS_DDR50))
return true; return true;
else else
return false; return false;
......
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