Message ID | 20190710095006.15801-1-peng.fan@nxp.com |
---|---|
State | Accepted |
Delegated to: | Peng Fan |
Headers | show |
Series | [U-Boot,V2,1/7] mmc: support hs400 enhanced strobe mode | expand |
> Subject: [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode > > eMMC 5.1+ supports HS400 Enhances Strobe mode without the need for > tuning procedure. > The flow is as following: > - set HS_TIMIMG (Highspeed) > - Host change freq to <= 52Mhz > - set the bus width to Enhanced strobe and DDR8Bit(CMD6), > EXT_CSD[183] = 0x86 instead of 0x80 > - set HS_TIMING to 0x3 (HS400) > - Host change freq to <= 200Mhz > - Host select HS400 enhanced strobe complete > > Signed-off-by: Peng Fan <peng.fan@nxp.com> > Cc: Jean-Jacques Hiblot <jjhiblot@ti.com> > Cc: Baruch Siach <baruch@tkos.co.il> > Cc: Michal Simek <michal.simek@xilinx.com> > Cc: T Karthik Reddy <t.karthik.reddy@xilinx.com> > Cc: Simon Glass <sjg@chromium.org> > Cc: Marek Vasut <marek.vasut+renesas@gmail.com> > Cc: Jon Nettleton <jon@solid-run.com> > --- > > V2: > Add return value for mmc strobe functions Use mmc_set_card_speed to > replace mmc_switch > > drivers/mmc/Kconfig | 12 ++++++++ > drivers/mmc/mmc-uclass.c | 17 ++++++++++++ > drivers/mmc/mmc.c | 72 > +++++++++++++++++++++++++++++++++++++++++++++++- > include/mmc.h | 15 ++++++++++ > 4 files changed, 115 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index > 93588725f2..f22c0a0589 100644 > --- a/drivers/mmc/Kconfig > +++ b/drivers/mmc/Kconfig > @@ -117,6 +117,18 @@ config SPL_MMC_UHS_SUPPORT > cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus > frequency can go up to 208MHz (SDR104) > > +config MMC_HS400_ES_SUPPORT > + bool "enable HS400 Enhanced Strobe support" > + help > + The HS400 Enhanced Strobe mode is support by some eMMC. The bus > + frequency is up to 200MHz. This mode does not tune the IO. > + > +config SPL_MMC_HS400_ES_SUPPORT > + bool "enable HS400 Enhanced Strobe support in SPL" > + help > + The HS400 Enhanced Strobe mode is support by some eMMC. The bus > + frequency is up to 200MHz. This mode does not tune the IO. > + > config MMC_HS400_SUPPORT > bool "enable HS400 support" > select MMC_HS200_SUPPORT > diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index > fa4d1af55d..890b380f1f 100644 > --- a/drivers/mmc/mmc-uclass.c > +++ b/drivers/mmc/mmc-uclass.c > @@ -120,6 +120,23 @@ int mmc_execute_tuning(struct mmc *mmc, uint > opcode) } #endif > > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > +int dm_mmc_set_enhanced_strobe(struct udevice *dev) { > + struct dm_mmc_ops *ops = mmc_get_ops(dev); > + > + if (ops->set_enhanced_strobe) > + return ops->set_enhanced_strobe(dev); > + > + return -ENOTSUPP; > +} > + > +int mmc_set_enhanced_strobe(struct mmc *mmc) { > + return dm_mmc_set_enhanced_strobe(mmc->dev); > +} > +#endif > + > int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) { > int val; > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index > 71b52c6cf2..c6b5488352 100644 > --- a/drivers/mmc/mmc.c > +++ b/drivers/mmc/mmc.c > @@ -148,6 +148,7 @@ const char *mmc_mode_name(enum bus_mode > mode) > [MMC_DDR_52] = "MMC DDR52 (52MHz)", > [MMC_HS_200] = "HS200 (200MHz)", > [MMC_HS_400] = "HS400 (200MHz)", > + [MMC_HS_400_ES] = "HS400ES (200MHz)", > }; > > if (mode >= MMC_MODES_END) > @@ -173,6 +174,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum > bus_mode mode) > [UHS_SDR104] = 208000000, > [MMC_HS_200] = 200000000, > [MMC_HS_400] = 200000000, > + [MMC_HS_400_ES] = 200000000, > }; > > if (mode == MMC_LEGACY) > @@ -788,6 +790,11 @@ static int mmc_set_card_speed(struct mmc *mmc, > enum bus_mode mode, > case MMC_HS_400: > speed_bits = EXT_CSD_TIMING_HS400; > break; > +#endif > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > + case MMC_HS_400_ES: > + speed_bits = EXT_CSD_TIMING_HS400; > + break; > #endif > case MMC_LEGACY: > speed_bits = EXT_CSD_TIMING_LEGACY; > @@ -859,7 +866,8 @@ static int mmc_get_capabilities(struct mmc *mmc) > mmc->card_caps |= MMC_MODE_HS200; > } > #endif > -#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) || \ > + CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V | > EXT_CSD_CARD_TYPE_HS400_1_8V)) { > mmc->card_caps |= MMC_MODE_HS400; > @@ -873,6 +881,13 @@ static int mmc_get_capabilities(struct mmc *mmc) > if (cardtype & EXT_CSD_CARD_TYPE_26) > mmc->card_caps |= MMC_MODE_HS; > > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > + if (ext_csd[EXT_CSD_STROBE_SUPPORT] && > + (mmc->card_caps & MMC_MODE_HS400)) { > + mmc->card_caps |= MMC_MODE_HS400_ES; > + } > +#endif > + > return 0; > } > #endif > @@ -1778,6 +1793,7 @@ static int mmc_set_lowest_voltage(struct mmc > *mmc, enum bus_mode mode, > u32 card_mask = 0; > > switch (mode) { > + case MMC_HS_400_ES: > case MMC_HS_400: > case MMC_HS_200: > if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V | @@ > -1820,6 +1836,12 @@ static inline int mmc_set_lowest_voltage(struct mmc > *mmc, enum bus_mode mode, #endif > > static const struct mode_width_tuning mmc_modes_by_pref[] = { > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > + { > + .mode = MMC_HS_400_ES, > + .widths = MMC_MODE_8BIT, > + }, > +#endif > #if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) > { > .mode = MMC_HS_400, > @@ -1917,6 +1939,47 @@ static int mmc_select_hs400(struct mmc > *mmc) } #endif > > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > +#if !CONFIG_IS_ENABLED(DM_MMC) > +static int mmc_set_enhanced_strobe(struct mmc *mmc) { > + return -ENOTSUPP; > +} > +#endif > +static int mmc_select_hs400es(struct mmc *mmc) { > + int err; > + > + err = mmc_set_card_speed(mmc, MMC_HS, true); > + if (err) > + return err; > + > + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, > EXT_CSD_BUS_WIDTH, > + EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG | > + EXT_CSD_BUS_WIDTH_STROBE); > + if (err) { > + printf("switch to bus width for hs400 failed\n"); > + return err; > + } > + /* TODO: driver strength */ > + err = mmc_set_card_speed(mmc, MMC_HS_400_ES, false); > + if (err) > + return err; > + > + mmc_select_mode(mmc, MMC_HS_400_ES); > + err = mmc_set_clock(mmc, mmc->tran_speed, false); > + if (err) > + return err; > + > + return mmc_set_enhanced_strobe(mmc); > +} > +#else > +static int mmc_select_hs400es(struct mmc *mmc) { > + return -ENOTSUPP; > +} > +#endif > + > #define for_each_supported_width(caps, ddr, ecbv) \ > for (ecbv = ext_csd_bus_width;\ > ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\ > @@ -1988,6 +2051,13 @@ static int mmc_select_mode_and_width(struct > mmc *mmc, uint card_caps) > printf("Select HS400 failed %d\n", err); > goto error; > } > + } else if (mwt->mode == MMC_HS_400_ES) { > + err = mmc_select_hs400es(mmc); > + if (err) { > + printf("Select HS400ES failed %d\n", > + err); > + goto error; > + } > } else { > /* configure the bus speed (card) */ > err = mmc_set_card_speed(mmc, mwt->mode, false); diff > --git a/include/mmc.h b/include/mmc.h index 2be3e91fcb..b42687395c > 100644 > --- a/include/mmc.h > +++ b/include/mmc.h > @@ -65,6 +65,7 @@ > #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52) > #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_CAP_NONREMOVABLE BIT(14) > #define MMC_CAP_NEEDS_POLL BIT(15) > @@ -223,6 +224,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) > #define EXT_CSD_BOOT_BUS_WIDTH 177 > #define EXT_CSD_PART_CONF 179 /* 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_REV 192 /* RO */ > #define EXT_CSD_CARD_TYPE 196 /* RO */ > @@ -264,11 +266,13 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) > #define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode > */ > #define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode > */ > #define EXT_CSD_DDR_FLAG BIT(2) /* Flag for DDR mode */ > +#define EXT_CSD_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */ > > #define EXT_CSD_TIMING_LEGACY 0 /* no high speed */ > #define EXT_CSD_TIMING_HS 1 /* HS */ > #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_PARTITION_ENABLE (1 << 3) > @@ -465,6 +469,11 @@ struct dm_mmc_ops { > */ > int (*wait_dat0)(struct udevice *dev, int state, int timeout); #endif > + > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > + /* set_enhanced_strobe() - set HS400 enhanced strobe */ > + int (*set_enhanced_strobe)(struct udevice *dev); #endif > }; > > #define mmc_get_ops(dev) ((struct dm_mmc_ops > *)(dev)->driver->ops) > @@ -485,6 +494,7 @@ int mmc_getcd(struct mmc *mmc); int > mmc_getwp(struct mmc *mmc); int mmc_execute_tuning(struct mmc > *mmc, uint opcode); int mmc_wait_dat0(struct mmc *mmc, int state, int > timeout); > +int mmc_set_enhanced_strobe(struct mmc *mmc); > > #else > struct mmc_ops { > @@ -530,6 +540,7 @@ enum bus_mode { > UHS_SDR104, > MMC_HS_200, > MMC_HS_400, > + MMC_HS_400_ES, > MMC_MODES_END > }; > > @@ -547,6 +558,10 @@ static inline bool mmc_is_mode_ddr(enum > bus_mode mode) #if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) > else if (mode == MMC_HS_400) > return true; > +#endif > +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) > + else if (mode == MMC_HS_400_ES) > + return true; > #endif > else > return false; Patchset applied to mmc/master after rebasing minor conflicts fixed in 1/7. Thanks, Peng. > -- > 2.16.4
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 93588725f2..f22c0a0589 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -117,6 +117,18 @@ config SPL_MMC_UHS_SUPPORT cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus frequency can go up to 208MHz (SDR104) +config MMC_HS400_ES_SUPPORT + bool "enable HS400 Enhanced Strobe support" + help + The HS400 Enhanced Strobe mode is support by some eMMC. The bus + frequency is up to 200MHz. This mode does not tune the IO. + +config SPL_MMC_HS400_ES_SUPPORT + bool "enable HS400 Enhanced Strobe support in SPL" + help + The HS400 Enhanced Strobe mode is support by some eMMC. The bus + frequency is up to 200MHz. This mode does not tune the IO. + config MMC_HS400_SUPPORT bool "enable HS400 support" select MMC_HS200_SUPPORT diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index fa4d1af55d..890b380f1f 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -120,6 +120,23 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode) } #endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) +int dm_mmc_set_enhanced_strobe(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->set_enhanced_strobe) + return ops->set_enhanced_strobe(dev); + + return -ENOTSUPP; +} + +int mmc_set_enhanced_strobe(struct mmc *mmc) +{ + return dm_mmc_set_enhanced_strobe(mmc->dev); +} +#endif + int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) { int val; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 71b52c6cf2..c6b5488352 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -148,6 +148,7 @@ const char *mmc_mode_name(enum bus_mode mode) [MMC_DDR_52] = "MMC DDR52 (52MHz)", [MMC_HS_200] = "HS200 (200MHz)", [MMC_HS_400] = "HS400 (200MHz)", + [MMC_HS_400_ES] = "HS400ES (200MHz)", }; if (mode >= MMC_MODES_END) @@ -173,6 +174,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode) [UHS_SDR104] = 208000000, [MMC_HS_200] = 200000000, [MMC_HS_400] = 200000000, + [MMC_HS_400_ES] = 200000000, }; if (mode == MMC_LEGACY) @@ -788,6 +790,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode, case MMC_HS_400: speed_bits = EXT_CSD_TIMING_HS400; break; +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + case MMC_HS_400_ES: + speed_bits = EXT_CSD_TIMING_HS400; + break; #endif case MMC_LEGACY: speed_bits = EXT_CSD_TIMING_LEGACY; @@ -859,7 +866,8 @@ static int mmc_get_capabilities(struct mmc *mmc) mmc->card_caps |= MMC_MODE_HS200; } #endif -#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V | EXT_CSD_CARD_TYPE_HS400_1_8V)) { mmc->card_caps |= MMC_MODE_HS400; @@ -873,6 +881,13 @@ static int mmc_get_capabilities(struct mmc *mmc) if (cardtype & EXT_CSD_CARD_TYPE_26) mmc->card_caps |= MMC_MODE_HS; +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + if (ext_csd[EXT_CSD_STROBE_SUPPORT] && + (mmc->card_caps & MMC_MODE_HS400)) { + mmc->card_caps |= MMC_MODE_HS400_ES; + } +#endif + return 0; } #endif @@ -1778,6 +1793,7 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode, u32 card_mask = 0; switch (mode) { + case MMC_HS_400_ES: case MMC_HS_400: case MMC_HS_200: if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V | @@ -1820,6 +1836,12 @@ static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode, #endif static const struct mode_width_tuning mmc_modes_by_pref[] = { +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + { + .mode = MMC_HS_400_ES, + .widths = MMC_MODE_8BIT, + }, +#endif #if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) { .mode = MMC_HS_400, @@ -1917,6 +1939,47 @@ static int mmc_select_hs400(struct mmc *mmc) } #endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) +#if !CONFIG_IS_ENABLED(DM_MMC) +static int mmc_set_enhanced_strobe(struct mmc *mmc) +{ + return -ENOTSUPP; +} +#endif +static int mmc_select_hs400es(struct mmc *mmc) +{ + int err; + + err = mmc_set_card_speed(mmc, MMC_HS, true); + if (err) + return err; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, + EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG | + EXT_CSD_BUS_WIDTH_STROBE); + if (err) { + printf("switch to bus width for hs400 failed\n"); + return err; + } + /* TODO: driver strength */ + err = mmc_set_card_speed(mmc, MMC_HS_400_ES, false); + if (err) + return err; + + mmc_select_mode(mmc, MMC_HS_400_ES); + err = mmc_set_clock(mmc, mmc->tran_speed, false); + if (err) + return err; + + return mmc_set_enhanced_strobe(mmc); +} +#else +static int mmc_select_hs400es(struct mmc *mmc) +{ + return -ENOTSUPP; +} +#endif + #define for_each_supported_width(caps, ddr, ecbv) \ for (ecbv = ext_csd_bus_width;\ ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\ @@ -1988,6 +2051,13 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps) printf("Select HS400 failed %d\n", err); goto error; } + } else if (mwt->mode == MMC_HS_400_ES) { + err = mmc_select_hs400es(mmc); + if (err) { + printf("Select HS400ES failed %d\n", + err); + goto error; + } } else { /* configure the bus speed (card) */ err = mmc_set_card_speed(mmc, mwt->mode, false); diff --git a/include/mmc.h b/include/mmc.h index 2be3e91fcb..b42687395c 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -65,6 +65,7 @@ #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52) #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_CAP_NONREMOVABLE BIT(14) #define MMC_CAP_NEEDS_POLL BIT(15) @@ -223,6 +224,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) #define EXT_CSD_BOOT_BUS_WIDTH 177 #define EXT_CSD_PART_CONF 179 /* 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_REV 192 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */ @@ -264,11 +266,13 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) #define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ #define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ #define EXT_CSD_DDR_FLAG BIT(2) /* Flag for DDR mode */ +#define EXT_CSD_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */ #define EXT_CSD_TIMING_LEGACY 0 /* no high speed */ #define EXT_CSD_TIMING_HS 1 /* HS */ #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_PARTITION_ENABLE (1 << 3) @@ -465,6 +469,11 @@ struct dm_mmc_ops { */ int (*wait_dat0)(struct udevice *dev, int state, int timeout); #endif + +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + /* set_enhanced_strobe() - set HS400 enhanced strobe */ + int (*set_enhanced_strobe)(struct udevice *dev); +#endif }; #define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) @@ -485,6 +494,7 @@ int mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); int mmc_execute_tuning(struct mmc *mmc, uint opcode); int mmc_wait_dat0(struct mmc *mmc, int state, int timeout); +int mmc_set_enhanced_strobe(struct mmc *mmc); #else struct mmc_ops { @@ -530,6 +540,7 @@ enum bus_mode { UHS_SDR104, MMC_HS_200, MMC_HS_400, + MMC_HS_400_ES, MMC_MODES_END }; @@ -547,6 +558,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode) #if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) else if (mode == MMC_HS_400) return true; +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + else if (mode == MMC_HS_400_ES) + return true; #endif else return false;
eMMC 5.1+ supports HS400 Enhances Strobe mode without the need for tuning procedure. The flow is as following: - set HS_TIMIMG (Highspeed) - Host change freq to <= 52Mhz - set the bus width to Enhanced strobe and DDR8Bit(CMD6), EXT_CSD[183] = 0x86 instead of 0x80 - set HS_TIMING to 0x3 (HS400) - Host change freq to <= 200Mhz - Host select HS400 enhanced strobe complete Signed-off-by: Peng Fan <peng.fan@nxp.com> Cc: Jean-Jacques Hiblot <jjhiblot@ti.com> Cc: Baruch Siach <baruch@tkos.co.il> Cc: Michal Simek <michal.simek@xilinx.com> Cc: T Karthik Reddy <t.karthik.reddy@xilinx.com> Cc: Simon Glass <sjg@chromium.org> Cc: Marek Vasut <marek.vasut+renesas@gmail.com> Cc: Jon Nettleton <jon@solid-run.com> --- V2: Add return value for mmc strobe functions Use mmc_set_card_speed to replace mmc_switch drivers/mmc/Kconfig | 12 ++++++++ drivers/mmc/mmc-uclass.c | 17 ++++++++++++ drivers/mmc/mmc.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++- include/mmc.h | 15 ++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-)