[PATCH 0/9] mmc: fsl_esdhc: support eMMC HS200/HS400 modes

This patch-set is to support eMMC HS200 and HS400 speed modes for eSDHC, and enable them on LX2160ARDB board.
CI build link https://travis-ci.org/github/yangbolu1991/u-boot-test/builds/708215558
Yangbo Lu (9): mmc: add a reinit() API mmc: fsl_esdhc: add a reinit() callback mmc: fsl_esdhc: support tuning for eMMC HS200 mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init mmc: add a hs400_tuning flag mmc: add a mmc_hs400_prepare_ddr() interface mmc: fsl_esdhc: support eMMC HS400 mode arm: dts: lx2160ardb: support eMMC HS400 mode configs: lx2160ardb: enable eMMC HS400 mode support
arch/arm/dts/fsl-lx2160a-rdb.dts | 2 + configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 + configs/lx2160ardb_tfa_defconfig | 1 + configs/lx2160ardb_tfa_stmm_defconfig | 1 + drivers/mmc/fsl_esdhc.c | 148 ++++++++++++++++++++++++++- drivers/mmc/mmc-uclass.c | 30 ++++++ drivers/mmc/mmc.c | 12 ++- include/fsl_esdhc.h | 29 +++++- include/mmc.h | 26 ++++- 9 files changed, 240 insertions(+), 10 deletions(-)

For DM_MMC, the controller re-initialization is needed to clear old configuration for mmc rescan.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/mmc-uclass.c | 15 +++++++++++++++ drivers/mmc/mmc.c | 8 ++++++-- include/mmc.h | 10 ++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index c5b7872..b9f0880 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -170,6 +170,21 @@ int mmc_deferred_probe(struct mmc *mmc) return dm_mmc_deferred_probe(mmc->dev); }
+int dm_mmc_reinit(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->reinit) + return ops->reinit(dev); + + return 0; +} + +int mmc_reinit(struct mmc *mmc) +{ + return dm_mmc_reinit(mmc->dev); +} + 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 50f47d4..a53f93a 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -2813,13 +2813,17 @@ int mmc_get_op_cond(struct mmc *mmc) return err;
#if CONFIG_IS_ENABLED(DM_MMC) - /* The device has already been probed ready for use */ + /* + * Re-initialization is needed to clear old configuration for + * mmc rescan. + */ + err = mmc_reinit(mmc); #else /* made sure it's not NULL earlier */ err = mmc->cfg->ops->init(mmc); +#endif if (err) return err; -#endif mmc->ddr_mode = 0;
retry: diff --git a/include/mmc.h b/include/mmc.h index 8256219..161b8bc 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -422,6 +422,14 @@ struct dm_mmc_ops { */ int (*deferred_probe)(struct udevice *dev); /** + * reinit() - Re-initialization to clear old configuration for + * mmc rescan. + * + * @dev: Device to reinit + * @return 0 if Ok, -ve if error + */ + int (*reinit)(struct udevice *dev); + /** * send_cmd() - Send a command to the MMC device * * @dev: Device to receive the command @@ -518,6 +526,7 @@ int dm_mmc_execute_tuning(struct udevice *dev, uint opcode); int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us); int dm_mmc_host_power_cycle(struct udevice *dev); int dm_mmc_deferred_probe(struct udevice *dev); +int dm_mmc_reinit(struct udevice *dev); int dm_mmc_get_b_max(struct udevice *dev, void *dst, lbaint_t blkcnt);
/* Transition functions for compatibility */ @@ -529,6 +538,7 @@ int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us); int mmc_set_enhanced_strobe(struct mmc *mmc); int mmc_host_power_cycle(struct mmc *mmc); int mmc_deferred_probe(struct mmc *mmc); +int mmc_reinit(struct mmc *mmc); int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt);
#else

Add a reinit() callback for mmc rescan.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/fsl_esdhc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index a4b923a..d1f2e4a 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -946,6 +946,14 @@ static int fsl_esdhc_set_ios(struct udevice *dev) return esdhc_set_ios_common(priv, &plat->mmc); }
+static int fsl_esdhc_reinit(struct udevice *dev) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return esdhc_init_common(priv, &plat->mmc); +} + static const struct dm_mmc_ops fsl_esdhc_ops = { .get_cd = fsl_esdhc_get_cd, .send_cmd = fsl_esdhc_send_cmd, @@ -953,6 +961,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = { #ifdef MMC_SUPPORTS_TUNING .execute_tuning = fsl_esdhc_execute_tuning, #endif + .reinit = fsl_esdhc_reinit, };
static const struct udevice_id fsl_esdhc_ids[] = {

Support tuning process for eMMC HS200 for eSDHC.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/fsl_esdhc.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++-- include/fsl_esdhc.h | 17 ++++++-- 2 files changed, 116 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index d1f2e4a..5ad01ac 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -60,7 +60,9 @@ struct fsl_esdhc { uint dmaerrattr; /* DMA error attribute register */ char reserved5[4]; /* reserved */ uint hostcapblt2; /* Host controller capabilities register 2 */ - char reserved6[756]; /* reserved */ + char reserved6[8]; /* reserved */ + uint tbctl; /* Tuning block control register */ + char reserved7[744]; /* reserved */ uint esdhcctl; /* eSDHC control register */ };
@@ -101,7 +103,9 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) if (data) { xfertyp |= XFERTYP_DPSEL; #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - xfertyp |= XFERTYP_DMAEN; + if (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK && + cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200) + xfertyp |= XFERTYP_DMAEN; #endif if (data->blocks > 1) { xfertyp |= XFERTYP_MSBSEL; @@ -380,6 +384,10 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, esdhc_write32(®s->cmdarg, cmd->cmdarg); esdhc_write32(®s->xfertyp, xfertyp);
+ if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK || + cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) + flags = IRQSTAT_BRR; + /* Wait for the command to complete */ start = get_timer(0); while (!(esdhc_read32(®s->irqstat) & flags)) { @@ -439,6 +447,11 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO esdhc_pio_read_write(priv, data); #else + flags = DATA_COMPLETE; + if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK || + cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) + flags = IRQSTAT_BRR; + do { irqstat = esdhc_read32(®s->irqstat);
@@ -451,7 +464,7 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, err = -ECOMM; goto out; } - } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE); + } while ((irqstat & flags) != flags);
/* * Need invalidate the dcache here again to avoid any @@ -555,6 +568,19 @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) } }
+static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode) +{ + struct fsl_esdhc *regs = priv->esdhc_regs; + + esdhc_clock_control(priv, false); + + if (mode == MMC_HS_200) + esdhc_clrsetbits32(®s->autoc12err, UHSM_MASK, + UHSM_SDR104_HS200); + + esdhc_clock_control(priv, true); +} + static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { struct fsl_esdhc *regs = priv->esdhc_regs; @@ -570,6 +596,9 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) if (priv->clock != mmc->clock) set_sysctl(priv, mmc, mmc->clock);
+ /* Set timing */ + esdhc_set_timing(priv, mmc->selected_mode); + /* Set the bus width */ esdhc_clrbits32(®s->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
@@ -954,6 +983,77 @@ static int fsl_esdhc_reinit(struct udevice *dev) return esdhc_init_common(priv, &plat->mmc); }
+#ifdef MMC_SUPPORTS_TUNING +static void esdhc_flush_async_fifo(struct fsl_esdhc_priv *priv) +{ + struct fsl_esdhc *regs = priv->esdhc_regs; + u32 time_out; + + esdhc_setbits32(®s->esdhcctl, ESDHCCTL_FAF); + + time_out = 20; + while (esdhc_read32(®s->esdhcctl) & ESDHCCTL_FAF) { + if (time_out == 0) { + printf("fsl_esdhc: Flush asynchronous FIFO timeout.\n"); + break; + } + time_out--; + mdelay(1); + } +} + +static void esdhc_tuning_block_enable(struct fsl_esdhc_priv *priv, + bool en) +{ + struct fsl_esdhc *regs = priv->esdhc_regs; + + esdhc_clock_control(priv, false); + esdhc_flush_async_fifo(priv); + if (en) + esdhc_setbits32(®s->tbctl, TBCTL_TB_EN); + else + esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN); + esdhc_clock_control(priv, true); +} + +static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + struct fsl_esdhc *regs = priv->esdhc_regs; + u32 val, irqstaten; + int i; + + esdhc_tuning_block_enable(priv, true); + esdhc_setbits32(®s->autoc12err, EXECUTE_TUNING); + + irqstaten = esdhc_read32(®s->irqstaten); + esdhc_write32(®s->irqstaten, IRQSTATEN_BRR); + + for (i = 0; i < MAX_TUNING_LOOP; i++) { + mmc_send_tuning(&plat->mmc, opcode, NULL); + mdelay(1); + + val = esdhc_read32(®s->autoc12err); + if (!(val & EXECUTE_TUNING)) { + if (val & SMPCLKSEL) + break; + } + } + + esdhc_write32(®s->irqstaten, irqstaten); + + if (i != MAX_TUNING_LOOP) + return 0; + + printf("fsl_esdhc: tuning failed!\n"); + esdhc_clrbits32(®s->autoc12err, SMPCLKSEL); + esdhc_clrbits32(®s->autoc12err, EXECUTE_TUNING); + esdhc_tuning_block_enable(priv, false); + return -ETIMEDOUT; +} +#endif + static const struct dm_mmc_ops fsl_esdhc_ops = { .get_cd = fsl_esdhc_get_cd, .send_cmd = fsl_esdhc_send_cmd, diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index e148eaa..ada95bc 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -78,8 +78,10 @@ #define IRQSTATEN_TC (0x00000002) #define IRQSTATEN_CC (0x00000001)
+/* eSDHC control register */ #define ESDHCCTL 0x0002e40c #define ESDHCCTL_PCS (0x00080000) +#define ESDHCCTL_FAF (0x00040000)
#define PRSSTAT 0x0002e024 #define PRSSTAT_DAT0 (0x01000000) @@ -158,6 +160,12 @@ #define BLKATTR_SIZE(x) (x & 0x1fff) #define MAX_BLK_CNT 0x7fff /* so malloc will have enough room with 32M */
+/* Auto CMD error status register / system control 2 register */ +#define EXECUTE_TUNING 0x00400000 +#define SMPCLKSEL 0x00800000 +#define UHSM_MASK 0x00070000 +#define UHSM_SDR104_HS200 0x00030000 + /* Host controller capabilities register */ #define HOSTCAPBLT_VS18 0x04000000 #define HOSTCAPBLT_VS30 0x02000000 @@ -166,6 +174,11 @@ #define HOSTCAPBLT_DMAS 0x00400000 #define HOSTCAPBLT_HSS 0x00200000
+/* Tuning block control register */ +#define TBCTL_TB_EN 0x00000004 + +#define MAX_TUNING_LOOP 40 + struct fsl_esdhc_cfg { phys_addr_t esdhc_base; u32 sdhc_clk; @@ -207,10 +220,6 @@ struct fsl_esdhc_cfg { int fsl_esdhc_mmc_init(bd_t *bis); int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg); void fdt_fixup_esdhc(void *blob, bd_t *bd); -#ifdef MMC_SUPPORTS_TUNING -static inline int fsl_esdhc_execute_tuning(struct udevice *dev, - uint32_t opcode) {return 0; } -#endif #else static inline int fsl_esdhc_mmc_init(bd_t *bis) { return -ENOSYS; } static inline void fdt_fixup_esdhc(void *blob, bd_t *bd) {}

Clean TBCTL[TB_EN] manually during init since it is not able to be reset by reset all operation.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/fsl_esdhc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 5ad01ac..607b420 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -637,6 +637,9 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) return -ETIMEDOUT; }
+ /* Clean TBCTL[TB_EN] which is not able to be reset by reset all */ + esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN); + esdhc_enable_cache_snooping(regs);
esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);

Add a hs400_tuning flag to identify the tuning for HS400 mode.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/mmc.c | 2 ++ include/mmc.h | 1 + 2 files changed, 3 insertions(+)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index a53f93a..a18e75d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1976,7 +1976,9 @@ static int mmc_select_hs400(struct mmc *mmc) mmc_set_clock(mmc, mmc->tran_speed, false);
/* execute tuning if needed */ + mmc->hs400_tuning = 1; err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200); + mmc->hs400_tuning = 0; if (err) { debug("tuning failed\n"); return err; diff --git a/include/mmc.h b/include/mmc.h index 161b8bc..2399cc2 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -707,6 +707,7 @@ struct mmc { * accessing the boot partitions */ u32 quirks; + u8 hs400_tuning; };
struct mmc_hwpart_conf {

Add a mmc_hs400_prepare_ddr() interface for controllers which needs preparation before switching to DDR mode for HS400 mode.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/mmc-uclass.c | 15 +++++++++++++++ drivers/mmc/mmc.c | 2 ++ include/mmc.h | 15 ++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index b9f0880..240b205 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -141,6 +141,21 @@ int mmc_set_enhanced_strobe(struct mmc *mmc) } #endif
+int dm_mmc_hs400_prepare_ddr(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->hs400_prepare_ddr) + return ops->hs400_prepare_ddr(dev); + + return 0; +} + +int mmc_hs400_prepare_ddr(struct mmc *mmc) +{ + return dm_mmc_hs400_prepare_ddr(mmc->dev); +} + int dm_mmc_host_power_cycle(struct udevice *dev) { struct dm_mmc_ops *ops = mmc_get_ops(dev); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index a18e75d..e396207 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1987,6 +1987,8 @@ static int mmc_select_hs400(struct mmc *mmc) /* Set back to HS */ mmc_set_card_speed(mmc, MMC_HS, true);
+ mmc_hs400_prepare_ddr(mmc); + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG); if (err) diff --git a/include/mmc.h b/include/mmc.h index 2399cc2..659df75 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -513,6 +513,14 @@ struct dm_mmc_ops { * @return maximum number of blocks for this transfer */ int (*get_b_max)(struct udevice *dev, void *dst, lbaint_t blkcnt); + + /** + * hs400_prepare_ddr - prepare to switch to DDR mode + * + * @dev: Device to check + * @return 0 if success, -ve on error + */ + int (*hs400_prepare_ddr)(struct udevice *dev); };
#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) @@ -540,7 +548,7 @@ int mmc_host_power_cycle(struct mmc *mmc); int mmc_deferred_probe(struct mmc *mmc); int mmc_reinit(struct mmc *mmc); int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt); - +int mmc_hs400_prepare_ddr(struct mmc *mmc); #else struct mmc_ops { int (*send_cmd)(struct mmc *mmc, @@ -552,6 +560,11 @@ struct mmc_ops { int (*host_power_cycle)(struct mmc *mmc); int (*get_b_max)(struct mmc *mmc, void *dst, lbaint_t blkcnt); }; + +static inline int mmc_hs400_prepare_ddr(struct mmc *mmc) +{ + return 0; +} #endif
struct mmc_config {

The process for eMMC HS400 mode for eSDHC is,
1. Perform the Tuning Process at the HS400 target operating frequency. Latched the clock division value. 2. if read transaction, then set the SDTIMNGCTL[FLW_CTL_BG]. 3. Switch to High Speed mode and then set the card clock frequency to a value not greater than 52Mhz 4. Clear TBCTL[TB_EN],tuning block enable bit. 5. Change to 8 bit DDR Mode 6. Switch the card to HS400 mode. 7. Set TBCTL[TB_EN], tuning block enable bit. 8. Clear SYSCTL[SDCLKEN] 9. Wait for PRSSTAT[SDSTB] to be set 10. Change the clock division to latched value.Set TBCTL[HS 400 mode] and Set SDCLKCTL[CMD_CLK_CTRL] 11. Set SYSCTL[SDCLKEN] 12. Wait for PRSSTAT[SDSTB] to be set 13. Set DLLCFG0[DLL_ENABLE] and DLLCFG0[DLL_FREQ_SEL]. 14. Wait for delay chain to lock. 15. Set TBCTL[HS400_WNDW_ADJUST] 16. Again clear SYSCTL[SDCLKEN] 17. Wait for PRSSTAT[SDSTB] to be set 18. Set ESDHCCTL[FAF] 19. Wait for ESDHCCTL[FAF] to be cleared 20. Set SYSCTL[SDCLKEN] 21. Wait for PRSSTAT[SDSTB] to be set.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- drivers/mmc/fsl_esdhc.c | 98 ++++++++++++++++++++++++++++++++----------------- include/fsl_esdhc.h | 12 ++++++ 2 files changed, 76 insertions(+), 34 deletions(-)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 607b420..c1a127c 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -62,7 +62,12 @@ struct fsl_esdhc { uint hostcapblt2; /* Host controller capabilities register 2 */ char reserved6[8]; /* reserved */ uint tbctl; /* Tuning block control register */ - char reserved7[744]; /* reserved */ + char reserved7[32]; /* reserved */ + uint sdclkctl; /* SD clock control register */ + uint sdtimingctl; /* SD timing control register */ + char reserved8[20]; /* reserved */ + uint dllcfg0; /* DLL config 0 register */ + char reserved9[680]; /* reserved */ uint esdhcctl; /* eSDHC control register */ };
@@ -568,6 +573,38 @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) } }
+static void esdhc_flush_async_fifo(struct fsl_esdhc_priv *priv) +{ + struct fsl_esdhc *regs = priv->esdhc_regs; + u32 time_out; + + esdhc_setbits32(®s->esdhcctl, ESDHCCTL_FAF); + + time_out = 20; + while (esdhc_read32(®s->esdhcctl) & ESDHCCTL_FAF) { + if (time_out == 0) { + printf("fsl_esdhc: Flush asynchronous FIFO timeout.\n"); + break; + } + time_out--; + mdelay(1); + } +} + +static void esdhc_tuning_block_enable(struct fsl_esdhc_priv *priv, + bool en) +{ + struct fsl_esdhc *regs = priv->esdhc_regs; + + esdhc_clock_control(priv, false); + esdhc_flush_async_fifo(priv); + if (en) + esdhc_setbits32(®s->tbctl, TBCTL_TB_EN); + else + esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN); + esdhc_clock_control(priv, true); +} + static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode) { struct fsl_esdhc *regs = priv->esdhc_regs; @@ -577,7 +614,17 @@ static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode) if (mode == MMC_HS_200) esdhc_clrsetbits32(®s->autoc12err, UHSM_MASK, UHSM_SDR104_HS200); + if (mode == MMC_HS_400) { + esdhc_setbits32(®s->tbctl, HS400_MODE); + esdhc_setbits32(®s->sdclkctl, CMD_CLK_CTL); + esdhc_clock_control(priv, true);
+ esdhc_setbits32(®s->dllcfg0, DLL_ENABLE | DLL_FREQ_SEL); + esdhc_setbits32(®s->tbctl, HS400_WNDW_ADJUST); + + esdhc_clock_control(priv, false); + esdhc_flush_async_fifo(priv); + } esdhc_clock_control(priv, true); }
@@ -592,6 +639,9 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) esdhc_clock_control(priv, true); }
+ if (mmc->selected_mode == MMC_HS_400) + esdhc_tuning_block_enable(priv, true); + /* Set the clock speed */ if (priv->clock != mmc->clock) set_sysctl(priv, mmc, mmc->clock); @@ -987,38 +1037,6 @@ static int fsl_esdhc_reinit(struct udevice *dev) }
#ifdef MMC_SUPPORTS_TUNING -static void esdhc_flush_async_fifo(struct fsl_esdhc_priv *priv) -{ - struct fsl_esdhc *regs = priv->esdhc_regs; - u32 time_out; - - esdhc_setbits32(®s->esdhcctl, ESDHCCTL_FAF); - - time_out = 20; - while (esdhc_read32(®s->esdhcctl) & ESDHCCTL_FAF) { - if (time_out == 0) { - printf("fsl_esdhc: Flush asynchronous FIFO timeout.\n"); - break; - } - time_out--; - mdelay(1); - } -} - -static void esdhc_tuning_block_enable(struct fsl_esdhc_priv *priv, - bool en) -{ - struct fsl_esdhc *regs = priv->esdhc_regs; - - esdhc_clock_control(priv, false); - esdhc_flush_async_fifo(priv); - if (en) - esdhc_setbits32(®s->tbctl, TBCTL_TB_EN); - else - esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN); - esdhc_clock_control(priv, true); -} - static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) { struct fsl_esdhc_plat *plat = dev_get_platdata(dev); @@ -1046,8 +1064,11 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
esdhc_write32(®s->irqstaten, irqstaten);
- if (i != MAX_TUNING_LOOP) + if (i != MAX_TUNING_LOOP) { + if (plat->mmc.hs400_tuning) + esdhc_setbits32(®s->sdtimingctl, FLW_CTL_BG); return 0; + }
printf("fsl_esdhc: tuning failed!\n"); esdhc_clrbits32(®s->autoc12err, SMPCLKSEL); @@ -1057,6 +1078,14 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) } #endif
+int fsl_esdhc_hs400_prepare_ddr(struct udevice *dev) +{ + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + esdhc_tuning_block_enable(priv, false); + return 0; +} + static const struct dm_mmc_ops fsl_esdhc_ops = { .get_cd = fsl_esdhc_get_cd, .send_cmd = fsl_esdhc_send_cmd, @@ -1065,6 +1094,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = { .execute_tuning = fsl_esdhc_execute_tuning, #endif .reinit = fsl_esdhc_reinit, + .hs400_prepare_ddr = fsl_esdhc_hs400_prepare_ddr, };
static const struct udevice_id fsl_esdhc_ids[] = { diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index ada95bc..cbb2c34 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -176,6 +176,18 @@
/* Tuning block control register */ #define TBCTL_TB_EN 0x00000004 +#define HS400_MODE 0x00000010 +#define HS400_WNDW_ADJUST 0x00000040 + +/* SD clock control register */ +#define CMD_CLK_CTL 0x00008000 + +/* SD timing control register */ +#define FLW_CTL_BG 0x00008000 + +/* DLL config 0 register */ +#define DLL_ENABLE 0x80000000 +#define DLL_FREQ_SEL 0x08000000
#define MAX_TUNING_LOOP 40

Add properties related to eMMC HS400 mode.
mmc-hs400-1_8v; bus-width = <8>;
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- arch/arm/dts/fsl-lx2160a-rdb.dts | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/dts/fsl-lx2160a-rdb.dts b/arch/arm/dts/fsl-lx2160a-rdb.dts index d787778..5fbdd90 100644 --- a/arch/arm/dts/fsl-lx2160a-rdb.dts +++ b/arch/arm/dts/fsl-lx2160a-rdb.dts @@ -80,6 +80,8 @@ &esdhc1 { status = "okay"; mmc-hs200-1_8v; + mmc-hs400-1_8v; + bus-width = <8>; };
&fspi {

Enable eMMC HS400 mode support on LX2160ARDB.
Signed-off-by: Yangbo Lu yangbo.lu@nxp.com --- configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 + configs/lx2160ardb_tfa_defconfig | 1 + configs/lx2160ardb_tfa_stmm_defconfig | 1 + 3 files changed, 3 insertions(+)
diff --git a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig index 12e224f..6c65853 100644 --- a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig +++ b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig @@ -40,6 +40,7 @@ CONFIG_DM_I2C=y CONFIG_I2C_SET_DEFAULT_BUS_NUM=y CONFIG_I2C_DEFAULT_BUS_NUMBER=0 CONFIG_DM_MMC=y +CONFIG_MMC_HS400_SUPPORT=y CONFIG_FSL_ESDHC=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y diff --git a/configs/lx2160ardb_tfa_defconfig b/configs/lx2160ardb_tfa_defconfig index a5c78d2..a5c60c8 100644 --- a/configs/lx2160ardb_tfa_defconfig +++ b/configs/lx2160ardb_tfa_defconfig @@ -46,6 +46,7 @@ CONFIG_DM_I2C=y CONFIG_I2C_SET_DEFAULT_BUS_NUM=y CONFIG_I2C_DEFAULT_BUS_NUMBER=0 CONFIG_DM_MMC=y +CONFIG_MMC_HS400_SUPPORT=y CONFIG_FSL_ESDHC=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y diff --git a/configs/lx2160ardb_tfa_stmm_defconfig b/configs/lx2160ardb_tfa_stmm_defconfig index e97c9b0..869d4e2 100644 --- a/configs/lx2160ardb_tfa_stmm_defconfig +++ b/configs/lx2160ardb_tfa_stmm_defconfig @@ -48,6 +48,7 @@ CONFIG_DM_I2C=y CONFIG_I2C_SET_DEFAULT_BUS_NUM=y CONFIG_I2C_DEFAULT_BUS_NUMBER=0 CONFIG_DM_MMC=y +CONFIG_MMC_HS400_SUPPORT=y CONFIG_SUPPORT_EMMC_RPMB=y CONFIG_FSL_ESDHC=y CONFIG_MTD=y

Hi Yangbo,
On 7/16/20 11:29 AM, Yangbo Lu wrote:
This patch-set is to support eMMC HS200 and HS400 speed modes for eSDHC, and enable them on LX2160ARDB board.
Is there any result about performance?
Best Regards, Jaehoon Chung
CI build link https://travis-ci.org/github/yangbolu1991/u-boot-test/builds/708215558
Yangbo Lu (9): mmc: add a reinit() API mmc: fsl_esdhc: add a reinit() callback mmc: fsl_esdhc: support tuning for eMMC HS200 mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init mmc: add a hs400_tuning flag mmc: add a mmc_hs400_prepare_ddr() interface mmc: fsl_esdhc: support eMMC HS400 mode arm: dts: lx2160ardb: support eMMC HS400 mode configs: lx2160ardb: enable eMMC HS400 mode support
arch/arm/dts/fsl-lx2160a-rdb.dts | 2 + configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 + configs/lx2160ardb_tfa_defconfig | 1 + configs/lx2160ardb_tfa_stmm_defconfig | 1 + drivers/mmc/fsl_esdhc.c | 148 ++++++++++++++++++++++++++- drivers/mmc/mmc-uclass.c | 30 ++++++ drivers/mmc/mmc.c | 12 ++- include/fsl_esdhc.h | 29 +++++- include/mmc.h | 26 ++++- 9 files changed, 240 insertions(+), 10 deletions(-)

Hi Jaehoon,
Below is the full log of the performance and function tests for eMMC HS400 mode. Since I used date to record time, there must be some error more or less. I tested the r/w performance with 4G data size at 175MHz bus speed. The results were, Read: 273MB/s = 4096MB / 15s Write: 74MB/s = 4096MB / 55s
According to the eMMC data sheet the HS400 max performance for sequential r/w are, Read: 270MB/s Write: 90MB/s
The performance seems to be matched and good. BTW, the test was applied two more patches to fix stability issue. Let me send out v2 patch-set with them. Thanks.
============ log ====================== NOTICE: BL2: v1.5(release):LSDK-20.04 NOTICE: BL2: Built : 05:20:45, Apr 9 2020 NOTICE: UDIMM 18ADF2G72AZ-3G2E1 NOTICE: DDR4 UDIMM with 2-rank 64-bit bus (x8)
NOTICE: 32 GB DDR4, 64-bit, CL=22, ECC on, 256B, CS0+CS1 NOTICE: BL2: Booting BL31 NOTICE: BL31: v1.5(release):LSDK-20.04 NOTICE: BL31: Built : 11:00:17, Jul 15 2020 NOTICE: Welcome to LX2160 BL31 Phase
U-Boot 2020.07-00703-g1b677f8 (Jul 17 2020 - 16:30:43 +0800)
SoC: LX2160ACE Rev2.0 (0x87360020) Clock Configuration: CPU0(A72):2000 MHz CPU1(A72):2000 MHz CPU2(A72):2000 MHz CPU3(A72):2000 MHz CPU4(A72):2000 MHz CPU5(A72):2000 MHz CPU6(A72):2000 MHz CPU7(A72):2000 MHz CPU8(A72):2000 MHz CPU9(A72):2000 MHz CPU10(A72):2000 MHz CPU11(A72):2000 MHz CPU12(A72):2000 MHz CPU13(A72):2000 MHz CPU14(A72):2000 MHz CPU15(A72):2000 MHz Bus: 700 MHz DDR: 2900 MT/s Reset Configuration Word (RCW): 00000000: 50777738 24500050 00000000 00000000 00000010: 00000000 0c010000 00000000 00000000 00000020: 02e001a0 00002580 00000000 00000096 00000030: 00000000 00000000 00000000 00000000 00000040: 00000000 00000000 00000000 00000000 00000050: 00000000 00000000 00000000 00000000 00000060: 00000000 00000000 00027000 00000000 00000070: 08b30010 00150020 Model: NXP Layerscape LX2160ARDB Board Board: LX2160ACE Rev2.0-RDB, Board version: B, boot from FlexSPI DEV#1 FPGA: v7.0 SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz SERDES3 Reference: Clock1 = 100MHz Clock2 = 100MHz VID: Core voltage after adjustment is at 852 mV DRAM: 31.9 GiB DDR 31.9 GiB (DDR4, 64-bit, CL=22, ECC on) DDR Controller Interleaving Mode: 256B DDR Chip-Select Interleaving Mode: CS0+CS1 Using SERDES1 Protocol: 19 (0x13) Using SERDES2 Protocol: 5 (0x5) Using SERDES3 Protocol: 2 (0x2) PCIe0: pcie@3400000 disabled PCIe1: pcie@3500000 disabled PCIe2: pcie@3600000 Root Complex: x1 gen1 PCI: Failed autoconfig bar 18 PCIe3: pcie@3700000 disabled PCIe4: pcie@3800000 Root Complex: no link PCIe5: pcie@3900000 disabled MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from SPI Flash... SF: Detected mt35xu512aba with page size 256 Bytes, erase size 128 KiB, total 64 MiB *** Warning - bad CRC, using default environment
EEPROM: NXID v1 In: serial_pl01x Out: serial_pl01x Err: serial_pl01x Net: e1000: 68:05:ca:31:2c:73
Warning: e1000#0 MAC addresses don't match: Address in ROM is 68:05:ca:31:2c:73 Address in environment is 00:04:9f:05:84:57 eth0: DPMAC3@usxgmii, eth1: DPMAC4@usxgmii, eth2: DPMAC17@rgmii-id, eth3: DPMAC18@rgmii-id, eth4: e1000#0 SF: Detected mt35xu512aba with page size 256 Bytes, erase size 128 KiB, total 64 MiB device 0 offset 0x640000, size 0x80000 SF: 524288 bytes @ 0x640000 Read: OK device 0 offset 0xa00000, size 0x300000 SF: 3145728 bytes @ 0xa00000 Read: OK device 0 offset 0xe00000, size 0x100000 SF: 1048576 bytes @ 0xe00000 Read: OK crc32+ fsl-mc: Booting Management Complex ... SUCCESS fsl-mc: Management Complex booted (version: 10.20.4, boot status: 0x1) Hit any key to stop autoboot: 0 => mmc dev 1 switch to partitions #0, OK mmc1(part 0) is current device => mmcinfo Device: FSL_SDHC Manufacturer ID: 13 OEM: 14e Name: R1J59 Bus Speed: 175000000 Mode: HS400 (200MHz) Rd Block Len: 512 MMC version 5.0 High Capacity: Yes Capacity: 116.5 GiB Bus Width: 8-bit DDR Erase Group Size: 512 KiB HC WP Group Size: 32 MiB User Capacity: 116.5 GiB WRREL Boot Capacity: 8 MiB ENH RPMB Capacity: 4 MiB ENH Boot area 0 is not write protected Boot area 1 is not write protected => date;mmc read 81000000 0 200000;mmc read 81000000 0 200000;mmc read 81000000 0 200000;mmc read 81000000 0 200000;date Date: 2020-07-17 (Friday) Time: 7:46:18
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK Date: 2020-07-17 (Friday) Time: 7:46:33 => date;mmc write 81000000 0 200000;mmc write 81000000 0 200000;mmc write 81000000 0 200000;mmc write 81000000 0 200000;date Date: 2020-07-17 (Friday) Time: 7:47:08
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK Date: 2020-07-17 (Friday) Time: 7:48:03 => mw.l 81000000 55555555 1000;mw.l 82000000 aaaaaaaa 1000;mmc write 81000000 0 100;mmc read 82000000 0 100;cmp.b 81000000 82000000 100
MMC write: dev # 1, block # 0, count 256 ... 256 blocks written: OK
MMC read: dev # 1, block # 0, count 256 ... 256 blocks read: OK Total of 256 byte(s) were the same =>
Best regards, Yangbo Lu
-----Original Message----- From: Jaehoon Chung jh80.chung@samsung.com Sent: Friday, July 17, 2020 8:31 AM To: Y.b. Lu yangbo.lu@nxp.com; u-boot@lists.denx.de; Peng Fan peng.fan@nxp.com; Priyanka Jain priyanka.jain@nxp.com Subject: Re: [PATCH 0/9] mmc: fsl_esdhc: support eMMC HS200/HS400 modes
Hi Yangbo,
On 7/16/20 11:29 AM, Yangbo Lu wrote:
This patch-set is to support eMMC HS200 and HS400 speed modes for eSDHC, and enable them on LX2160ARDB board.
Is there any result about performance?
Best Regards, Jaehoon Chung
CI build link
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftravis-ci .org%2Fgithub%2Fyangbolu1991%2Fu-boot-test%2Fbuilds%2F708215558&a mp;data=02%7C01%7Cyangbo.lu%40nxp.com%7Ca438d5eb0d9b4c7c660708 d829e8bc25%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63730 5426855786897&sdata=h54G7iKDdtmVRyuU0mZ7aZ06To3EqDc%2BRL3 0SFYtaWE%3D&reserved=0
Yangbo Lu (9): mmc: add a reinit() API mmc: fsl_esdhc: add a reinit() callback mmc: fsl_esdhc: support tuning for eMMC HS200 mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init mmc: add a hs400_tuning flag mmc: add a mmc_hs400_prepare_ddr() interface mmc: fsl_esdhc: support eMMC HS400 mode arm: dts: lx2160ardb: support eMMC HS400 mode configs: lx2160ardb: enable eMMC HS400 mode support
arch/arm/dts/fsl-lx2160a-rdb.dts | 2 + configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 + configs/lx2160ardb_tfa_defconfig | 1 + configs/lx2160ardb_tfa_stmm_defconfig | 1 + drivers/mmc/fsl_esdhc.c | 148
++++++++++++++++++++++++++-
drivers/mmc/mmc-uclass.c | 30 ++++++ drivers/mmc/mmc.c | 12 ++- include/fsl_esdhc.h | 29 +++++- include/mmc.h | 26 ++++- 9 files changed, 240 insertions(+), 10 deletions(-)

On 7/17/20 5:48 PM, Y.b. Lu wrote:
Hi Jaehoon,
Below is the full log of the performance and function tests for eMMC HS400 mode. Since I used date to record time, there must be some error more or less. I tested the r/w performance with 4G data size at 175MHz bus speed. The results were, Read: 273MB/s = 4096MB / 15s Write: 74MB/s = 4096MB / 55s
According to the eMMC data sheet the HS400 max performance for sequential r/w are, Read: 270MB/s Write: 90MB/s
The performance seems to be matched and good. BTW, the test was applied two more patches to fix stability issue. Let me send out v2 patch-set with them. Thanks.
Thanks for sharing result. I will check your patch-v2.
Best Regards, Jaehoon Chung
============ log ====================== NOTICE: BL2: v1.5(release):LSDK-20.04 NOTICE: BL2: Built : 05:20:45, Apr 9 2020 NOTICE: UDIMM 18ADF2G72AZ-3G2E1 NOTICE: DDR4 UDIMM with 2-rank 64-bit bus (x8)
NOTICE: 32 GB DDR4, 64-bit, CL=22, ECC on, 256B, CS0+CS1 NOTICE: BL2: Booting BL31 NOTICE: BL31: v1.5(release):LSDK-20.04 NOTICE: BL31: Built : 11:00:17, Jul 15 2020 NOTICE: Welcome to LX2160 BL31 Phase
U-Boot 2020.07-00703-g1b677f8 (Jul 17 2020 - 16:30:43 +0800)
SoC: LX2160ACE Rev2.0 (0x87360020) Clock Configuration: CPU0(A72):2000 MHz CPU1(A72):2000 MHz CPU2(A72):2000 MHz CPU3(A72):2000 MHz CPU4(A72):2000 MHz CPU5(A72):2000 MHz CPU6(A72):2000 MHz CPU7(A72):2000 MHz CPU8(A72):2000 MHz CPU9(A72):2000 MHz CPU10(A72):2000 MHz CPU11(A72):2000 MHz CPU12(A72):2000 MHz CPU13(A72):2000 MHz CPU14(A72):2000 MHz CPU15(A72):2000 MHz Bus: 700 MHz DDR: 2900 MT/s Reset Configuration Word (RCW): 00000000: 50777738 24500050 00000000 00000000 00000010: 00000000 0c010000 00000000 00000000 00000020: 02e001a0 00002580 00000000 00000096 00000030: 00000000 00000000 00000000 00000000 00000040: 00000000 00000000 00000000 00000000 00000050: 00000000 00000000 00000000 00000000 00000060: 00000000 00000000 00027000 00000000 00000070: 08b30010 00150020 Model: NXP Layerscape LX2160ARDB Board Board: LX2160ACE Rev2.0-RDB, Board version: B, boot from FlexSPI DEV#1 FPGA: v7.0 SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz SERDES3 Reference: Clock1 = 100MHz Clock2 = 100MHz VID: Core voltage after adjustment is at 852 mV DRAM: 31.9 GiB DDR 31.9 GiB (DDR4, 64-bit, CL=22, ECC on) DDR Controller Interleaving Mode: 256B DDR Chip-Select Interleaving Mode: CS0+CS1 Using SERDES1 Protocol: 19 (0x13) Using SERDES2 Protocol: 5 (0x5) Using SERDES3 Protocol: 2 (0x2) PCIe0: pcie@3400000 disabled PCIe1: pcie@3500000 disabled PCIe2: pcie@3600000 Root Complex: x1 gen1 PCI: Failed autoconfig bar 18 PCIe3: pcie@3700000 disabled PCIe4: pcie@3800000 Root Complex: no link PCIe5: pcie@3900000 disabled MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from SPI Flash... SF: Detected mt35xu512aba with page size 256 Bytes, erase size 128 KiB, total 64 MiB *** Warning - bad CRC, using default environment
EEPROM: NXID v1 In: serial_pl01x Out: serial_pl01x Err: serial_pl01x Net: e1000: 68:05:ca:31:2c:73
Warning: e1000#0 MAC addresses don't match: Address in ROM is 68:05:ca:31:2c:73 Address in environment is 00:04:9f:05:84:57 eth0: DPMAC3@usxgmii, eth1: DPMAC4@usxgmii, eth2: DPMAC17@rgmii-id, eth3: DPMAC18@rgmii-id, eth4: e1000#0 SF: Detected mt35xu512aba with page size 256 Bytes, erase size 128 KiB, total 64 MiB device 0 offset 0x640000, size 0x80000 SF: 524288 bytes @ 0x640000 Read: OK device 0 offset 0xa00000, size 0x300000 SF: 3145728 bytes @ 0xa00000 Read: OK device 0 offset 0xe00000, size 0x100000 SF: 1048576 bytes @ 0xe00000 Read: OK crc32+ fsl-mc: Booting Management Complex ... SUCCESS fsl-mc: Management Complex booted (version: 10.20.4, boot status: 0x1) Hit any key to stop autoboot: 0 => mmc dev 1 switch to partitions #0, OK mmc1(part 0) is current device => mmcinfo Device: FSL_SDHC Manufacturer ID: 13 OEM: 14e Name: R1J59 Bus Speed: 175000000 Mode: HS400 (200MHz) Rd Block Len: 512 MMC version 5.0 High Capacity: Yes Capacity: 116.5 GiB Bus Width: 8-bit DDR Erase Group Size: 512 KiB HC WP Group Size: 32 MiB User Capacity: 116.5 GiB WRREL Boot Capacity: 8 MiB ENH RPMB Capacity: 4 MiB ENH Boot area 0 is not write protected Boot area 1 is not write protected => date;mmc read 81000000 0 200000;mmc read 81000000 0 200000;mmc read 81000000 0 200000;mmc read 81000000 0 200000;date Date: 2020-07-17 (Friday) Time: 7:46:18
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK Date: 2020-07-17 (Friday) Time: 7:46:33 => date;mmc write 81000000 0 200000;mmc write 81000000 0 200000;mmc write 81000000 0 200000;mmc write 81000000 0 200000;date Date: 2020-07-17 (Friday) Time: 7:47:08
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK
MMC write: dev # 1, block # 0, count 2097152 ... 2097152 blocks written: OK Date: 2020-07-17 (Friday) Time: 7:48:03 => mw.l 81000000 55555555 1000;mw.l 82000000 aaaaaaaa 1000;mmc write 81000000 0 100;mmc read 82000000 0 100;cmp.b 81000000 82000000 100
MMC write: dev # 1, block # 0, count 256 ... 256 blocks written: OK
MMC read: dev # 1, block # 0, count 256 ... 256 blocks read: OK Total of 256 byte(s) were the same =>
Best regards, Yangbo Lu
-----Original Message----- From: Jaehoon Chung jh80.chung@samsung.com Sent: Friday, July 17, 2020 8:31 AM To: Y.b. Lu yangbo.lu@nxp.com; u-boot@lists.denx.de; Peng Fan peng.fan@nxp.com; Priyanka Jain priyanka.jain@nxp.com Subject: Re: [PATCH 0/9] mmc: fsl_esdhc: support eMMC HS200/HS400 modes
Hi Yangbo,
On 7/16/20 11:29 AM, Yangbo Lu wrote:
This patch-set is to support eMMC HS200 and HS400 speed modes for eSDHC, and enable them on LX2160ARDB board.
Is there any result about performance?
Best Regards, Jaehoon Chung
CI build link
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftravis-ci .org%2Fgithub%2Fyangbolu1991%2Fu-boot-test%2Fbuilds%2F708215558&a mp;data=02%7C01%7Cyangbo.lu%40nxp.com%7Ca438d5eb0d9b4c7c660708 d829e8bc25%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63730 5426855786897&sdata=h54G7iKDdtmVRyuU0mZ7aZ06To3EqDc%2BRL3 0SFYtaWE%3D&reserved=0
Yangbo Lu (9): mmc: add a reinit() API mmc: fsl_esdhc: add a reinit() callback mmc: fsl_esdhc: support tuning for eMMC HS200 mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init mmc: add a hs400_tuning flag mmc: add a mmc_hs400_prepare_ddr() interface mmc: fsl_esdhc: support eMMC HS400 mode arm: dts: lx2160ardb: support eMMC HS400 mode configs: lx2160ardb: enable eMMC HS400 mode support
arch/arm/dts/fsl-lx2160a-rdb.dts | 2 + configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 + configs/lx2160ardb_tfa_defconfig | 1 + configs/lx2160ardb_tfa_stmm_defconfig | 1 + drivers/mmc/fsl_esdhc.c | 148
++++++++++++++++++++++++++-
drivers/mmc/mmc-uclass.c | 30 ++++++ drivers/mmc/mmc.c | 12 ++- include/fsl_esdhc.h | 29 +++++- include/mmc.h | 26 ++++- 9 files changed, 240 insertions(+), 10 deletions(-)
participants (3)
-
Jaehoon Chung
-
Y.b. Lu
-
Yangbo Lu