All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode
@ 2019-07-10  9:35 Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 2/7] mmc: Parse HS400 Enhanced strobe DT properties Peng Fan
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

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;
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 2/7] mmc: Parse HS400 Enhanced strobe DT properties
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
@ 2019-07-10  9:35 ` Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 3/7] mmc: Parse no-1-8-v DT property Peng Fan
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

Add HS400 Enhanced strobe properties parsing support to mmc_of_parse().

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Cc: Marek Vasut <marek.vasut+renesas@gmail.com>
---

V2:
 Add R-b tag

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

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 890b380f1f..528e7671d4 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -187,6 +187,8 @@ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
 		cfg->host_caps |= MMC_CAP(MMC_HS_400);
 	if (dev_read_bool(dev, "mmc-hs400-1_2v"))
 		cfg->host_caps |= MMC_CAP(MMC_HS_400);
+	if (dev_read_bool(dev, "mmc-hs400-enhanced-strobe"))
+		cfg->host_caps |= MMC_CAP(MMC_HS_400_ES);
 
 	if (dev_read_bool(dev, "non-removable")) {
 		cfg->host_caps |= MMC_CAP_NONREMOVABLE;
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 3/7] mmc: Parse no-1-8-v DT property
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 2/7] mmc: Parse HS400 Enhanced strobe DT properties Peng Fan
@ 2019-07-10  9:35 ` Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 4/7] mmc: fsl_esdhc_imx: use mmc_of_parse to set host_caps Peng Fan
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

Parse no-1-8-v DT

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Cc: Marek Vasut <marek.vasut+renesas@gmail.com>
---

V2:
 Add R-b tag

 drivers/mmc/mmc-uclass.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 528e7671d4..9b354fd614 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -199,6 +199,11 @@ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
 			cfg->host_caps |= MMC_CAP_NEEDS_POLL;
 	}
 
+	if (dev_read_bool(dev, "no-1-8-v")) {
+		cfg->host_caps &= ~(UHS_CAPS | MMC_MODE_HS200 |
+				    MMC_MODE_HS400 | MMC_MODE_HS400_ES);
+	}
+
 	return 0;
 }
 
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 4/7] mmc: fsl_esdhc_imx: use mmc_of_parse to set host_caps
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 2/7] mmc: Parse HS400 Enhanced strobe DT properties Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 3/7] mmc: Parse no-1-8-v DT property Peng Fan
@ 2019-07-10  9:35 ` Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 5/7] mmc: fsl_esdhc_imx: add HS400 Enhanced strobe support Peng Fan
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

Use mmc_of_parse to set host_caps.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 None

 drivers/mmc/fsl_esdhc_imx.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index c0d47ba378..32d34ccf7c 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -101,7 +101,6 @@ struct fsl_esdhc_plat {
 
 struct esdhc_soc_data {
 	u32 flags;
-	u32 caps;
 };
 
 /**
@@ -1426,10 +1425,8 @@ static int fsl_esdhc_probe(struct udevice *dev)
 	priv->esdhc_regs = (struct fsl_esdhc *)addr;
 	priv->dev = dev;
 	priv->mode = -1;
-	if (data) {
+	if (data)
 		priv->flags = data->flags;
-		priv->caps = data->caps;
-	}
 
 	val = dev_read_u32_default(dev, "bus-width", -1);
 	if (val == 8)
@@ -1490,9 +1487,6 @@ static int fsl_esdhc_probe(struct udevice *dev)
 	}
 #endif
 
-	if (fdt_get_property(fdt, node, "no-1-8-v", NULL))
-		priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400);
-
 	/*
 	 * TODO:
 	 * Because lack of clk driver, if SDHC clk is not enabled,
@@ -1543,6 +1537,10 @@ static int fsl_esdhc_probe(struct udevice *dev)
 		return ret;
 	}
 
+	ret = mmc_of_parse(dev, &plat->cfg);
+	if (ret)
+		return ret;
+
 	mmc = &plat->mmc;
 	mmc->cfg = &plat->cfg;
 	mmc->dev = dev;
@@ -1610,8 +1608,6 @@ static struct esdhc_soc_data usdhc_imx7d_data = {
 	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
 			| ESDHC_FLAG_HS400,
-	.caps = UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_DDR_52MHz |
-		MMC_MODE_HS_52MHz | MMC_MODE_HS,
 };
 
 static const struct udevice_id fsl_esdhc_ids[] = {
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 5/7] mmc: fsl_esdhc_imx: add HS400 Enhanced strobe support
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
                   ` (2 preceding siblings ...)
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 4/7] mmc: fsl_esdhc_imx: use mmc_of_parse to set host_caps Peng Fan
@ 2019-07-10  9:35 ` Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 6/7] mmc: fsl_esdhc_imx: add i.MX8QM compatible Peng Fan
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

Implement set_enhanced_strobe hook for fsl_esdhc_imx,
,in esdhc_set_timing and esdhc_change_pinstate, also handle HS400_ES.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 None

 drivers/mmc/fsl_esdhc_imx.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 32d34ccf7c..e0767a1cb4 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -703,6 +703,7 @@ static int esdhc_change_pinstate(struct udevice *dev)
 	case UHS_SDR104:
 	case MMC_HS_200:
 	case MMC_HS_400:
+	case MMC_HS_400_ES:
 		ret = pinctrl_select_state(dev, "state_200mhz");
 		break;
 	default:
@@ -773,6 +774,7 @@ static int esdhc_set_timing(struct mmc *mmc)
 		writel(mixctrl, &regs->mixctrl);
 		break;
 	case MMC_HS_400:
+	case MMC_HS_400_ES:
 		mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
 		writel(mixctrl, &regs->mixctrl);
 		esdhc_set_strobe_dll(mmc);
@@ -1594,6 +1596,21 @@ static int fsl_esdhc_set_ios(struct udevice *dev)
 	return esdhc_set_ios_common(priv, &plat->mmc);
 }
 
+#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
+static int fsl_esdhc_set_enhanced_strobe(struct udevice *dev)
+{
+	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
+	struct fsl_esdhc *regs = priv->esdhc_regs;
+	u32 m;
+
+	m = readl(&regs->mixctrl);
+	m |= MIX_CTRL_HS400_ES;
+	writel(m, &regs->mixctrl);
+
+	return 0;
+}
+#endif
+
 static const struct dm_mmc_ops fsl_esdhc_ops = {
 	.get_cd		= fsl_esdhc_get_cd,
 	.send_cmd	= fsl_esdhc_send_cmd,
@@ -1601,6 +1618,9 @@ static const struct dm_mmc_ops fsl_esdhc_ops = {
 #ifdef MMC_SUPPORTS_TUNING
 	.execute_tuning	= fsl_esdhc_execute_tuning,
 #endif
+#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
+	.set_enhanced_strobe = fsl_esdhc_set_enhanced_strobe,
+#endif
 };
 #endif
 
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 6/7] mmc: fsl_esdhc_imx: add i.MX8QM compatible
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
                   ` (3 preceding siblings ...)
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 5/7] mmc: fsl_esdhc_imx: add HS400 Enhanced strobe support Peng Fan
@ 2019-07-10  9:35 ` Peng Fan
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 7/7] mmc: fsl_esdhc_imx: enlarge mmc timeout Peng Fan
  2019-07-15  7:08 ` [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

Add i.MX8QM compatible and soc data, the soc data is following Linux
i.MX SDHC driver.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 None

 drivers/mmc/fsl_esdhc_imx.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index e0767a1cb4..db8694faa8 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -1630,6 +1630,12 @@ static struct esdhc_soc_data usdhc_imx7d_data = {
 			| ESDHC_FLAG_HS400,
 };
 
+static struct esdhc_soc_data usdhc_imx8qm_data = {
+	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
+		ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
+		ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES,
+};
+
 static const struct udevice_id fsl_esdhc_ids[] = {
 	{ .compatible = "fsl,imx53-esdhc", },
 	{ .compatible = "fsl,imx6ul-usdhc", },
@@ -1638,6 +1644,7 @@ static const struct udevice_id fsl_esdhc_ids[] = {
 	{ .compatible = "fsl,imx6q-usdhc", },
 	{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
 	{ .compatible = "fsl,imx7ulp-usdhc", },
+	{ .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
 	{ .compatible = "fsl,esdhc", },
 	{ /* sentinel */ }
 };
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 7/7] mmc: fsl_esdhc_imx: enlarge mmc timeout
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
                   ` (4 preceding siblings ...)
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 6/7] mmc: fsl_esdhc_imx: add i.MX8QM compatible Peng Fan
@ 2019-07-10  9:35 ` Peng Fan
  2019-07-15  7:08 ` [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-10  9:35 UTC (permalink / raw)
  To: u-boot

Flash system partition with fastboot will earse the partition firstly
The 600ms timeout will fail on some SD Card. Enlarge it to 5s to make
it works for most of sdcard

Cc: guoyin.chen <guoyin.chen@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 None

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

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index db8694faa8..c65c90475a 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -513,9 +513,9 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 
 	/* Workaround for ESDHC errata ENGcm03648 */
 	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
-		int timeout = 6000;
+		int timeout = 50000;
 
-		/* Poll on DATA0 line for cmd with busy signal for 600 ms */
+		/* Poll on DATA0 line for cmd with busy signal for 5000 ms */
 		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
 					PRSSTAT_DAT0)) {
 			udelay(100);
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode
  2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
                   ` (5 preceding siblings ...)
  2019-07-10  9:35 ` [U-Boot] [PATCH V2 7/7] mmc: fsl_esdhc_imx: enlarge mmc timeout Peng Fan
@ 2019-07-15  7:08 ` Peng Fan
  6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-07-15  7:08 UTC (permalink / raw)
  To: u-boot

> 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-07-15  7:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-10  9:35 [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan
2019-07-10  9:35 ` [U-Boot] [PATCH V2 2/7] mmc: Parse HS400 Enhanced strobe DT properties Peng Fan
2019-07-10  9:35 ` [U-Boot] [PATCH V2 3/7] mmc: Parse no-1-8-v DT property Peng Fan
2019-07-10  9:35 ` [U-Boot] [PATCH V2 4/7] mmc: fsl_esdhc_imx: use mmc_of_parse to set host_caps Peng Fan
2019-07-10  9:35 ` [U-Boot] [PATCH V2 5/7] mmc: fsl_esdhc_imx: add HS400 Enhanced strobe support Peng Fan
2019-07-10  9:35 ` [U-Boot] [PATCH V2 6/7] mmc: fsl_esdhc_imx: add i.MX8QM compatible Peng Fan
2019-07-10  9:35 ` [U-Boot] [PATCH V2 7/7] mmc: fsl_esdhc_imx: enlarge mmc timeout Peng Fan
2019-07-15  7:08 ` [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Peng Fan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.