All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH V4 1/2] mmc: add HS400 support
@ 2018-08-10  6:07 Peng Fan
  2018-08-10  6:07 ` [U-Boot] [PATCH V4 2/2] mmc: fsl_esdhc: enable HS400 feature Peng Fan
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Peng Fan @ 2018-08-10  6:07 UTC (permalink / raw)
  To: u-boot

Add HS400 support.
Selecting HS400 needs first select HS200 according to spec, so use
a dedicated function for HS400.
Add HS400 related macros.
Remove the restriction of only using the low 6 bits of
EXT_CSD_CARD_TYPE, using all the 8 bits.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Faiz Abbas <faiz_abbas@ti.com>
Cc: Marek Vasut <marex@denx.de>
---

V4:
 Add SPL_MMC_HS400_SUPPORT Kconfig entry
 typo fix, HS199->HS200 in commit log.

V3:
 Simplify code
 add error msg

V2:
 remove 4bits support from HS400, as HS400 does not support 4bits per spec.

 drivers/mmc/Kconfig |  13 +++++
 drivers/mmc/mmc.c   | 137 +++++++++++++++++++++++++++++++++++++++++-----------
 include/mmc.h       |  11 +++++
 3 files changed, 134 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 377b1c4b3b..1616022b91 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -111,6 +111,19 @@ 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_SUPPORT
+	bool "enable HS400 support"
+	select MMC_HS200_SUPPORT
+	help
+	  The HS400 mode is support by some eMMC. The bus frequency is up to
+	  200MHz. This mode requires tuning the IO.
+
+config SPL_MMC_HS400_SUPPORT
+	bool "enable HS400 support in SPL"
+	help
+	  The HS400 mode is support by some eMMC. The bus frequency is up to
+	  200MHz. This mode requires tuning the IO.
+
 config MMC_HS200_SUPPORT
 	bool "enable HS200 support"
 	help
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ad429f49c9..585951cd78 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -147,6 +147,7 @@ const char *mmc_mode_name(enum bus_mode mode)
 	      [MMC_HS_52]	= "MMC High Speed (52MHz)",
 	      [MMC_DDR_52]	= "MMC DDR52 (52MHz)",
 	      [MMC_HS_200]	= "HS200 (200MHz)",
+	      [MMC_HS_400]	= "HS400 (200MHz)",
 	};
 
 	if (mode >= MMC_MODES_END)
@@ -171,6 +172,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
 	      [UHS_DDR50]	= 50000000,
 	      [UHS_SDR104]	= 208000000,
 	      [MMC_HS_200]	= 200000000,
+	      [MMC_HS_400]	= 200000000,
 	};
 
 	if (mode == MMC_LEGACY)
@@ -769,6 +771,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
 	case MMC_HS_200:
 		speed_bits = EXT_CSD_TIMING_HS200;
 		break;
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	case MMC_HS_400:
+		speed_bits = EXT_CSD_TIMING_HS400;
+		break;
 #endif
 	case MMC_LEGACY:
 		speed_bits = EXT_CSD_TIMING_LEGACY;
@@ -816,7 +823,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
 
 	mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 
-	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
+	cardtype = ext_csd[EXT_CSD_CARD_TYPE];
 	mmc->cardtype = cardtype;
 
 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
@@ -824,6 +831,12 @@ static int mmc_get_capabilities(struct mmc *mmc)
 			EXT_CSD_CARD_TYPE_HS200_1_8V)) {
 		mmc->card_caps |= MMC_MODE_HS200;
 	}
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
+			EXT_CSD_CARD_TYPE_HS400_1_8V)) {
+		mmc->card_caps |= MMC_MODE_HS400;
+	}
 #endif
 	if (cardtype & EXT_CSD_CARD_TYPE_52) {
 		if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
@@ -1734,10 +1747,13 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
 	u32 card_mask = 0;
 
 	switch (mode) {
+	case MMC_HS_400:
 	case MMC_HS_200:
-		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
+		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
+		    EXT_CSD_CARD_TYPE_HS400_1_8V))
 			card_mask |= MMC_SIGNAL_VOLTAGE_180;
-		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V)
+		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
+		    EXT_CSD_CARD_TYPE_HS400_1_2V))
 			card_mask |= MMC_SIGNAL_VOLTAGE_120;
 		break;
 	case MMC_DDR_52:
@@ -1773,6 +1789,13 @@ 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_SUPPORT)
+	{
+		.mode = MMC_HS_400,
+		.widths = MMC_MODE_8BIT,
+		.tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
+	},
+#endif
 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
 	{
 		.mode = MMC_HS_200,
@@ -1816,6 +1839,54 @@ static const struct ext_csd_bus_width {
 	{MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
 };
 
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+static int mmc_select_hs400(struct mmc *mmc)
+{
+	int err;
+
+	/* Set timing to HS200 for tuning */
+	err = mmc_set_card_speed(mmc, MMC_HS_200);
+	if (err)
+		return err;
+
+	/* configure the bus mode (host) */
+	mmc_select_mode(mmc, MMC_HS_200);
+	mmc_set_clock(mmc, mmc->tran_speed, false);
+
+	/* execute tuning if needed */
+	err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
+	if (err) {
+		debug("tuning failed\n");
+		return err;
+	}
+
+	/* Set back to HS */
+	mmc_set_card_speed(mmc, MMC_HS);
+	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
+
+	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
+	if (err)
+		return err;
+
+	err = mmc_set_card_speed(mmc, MMC_HS_400);
+	if (err)
+		return err;
+
+	mmc_select_mode(mmc, MMC_HS_400);
+	err = mmc_set_clock(mmc, mmc->tran_speed, false);
+	if (err)
+		return err;
+
+	return 0;
+}
+#else
+static int mmc_select_hs400(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);\
@@ -1869,37 +1940,49 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
 				goto error;
 			mmc_set_bus_width(mmc, bus_width(ecbw->cap));
 
-			/* configure the bus speed (card) */
-			err = mmc_set_card_speed(mmc, mwt->mode);
-			if (err)
-				goto error;
-
-			/*
-			 * configure the bus width AND the ddr mode (card)
-			 * The host side will be taken care of in the next step
-			 */
-			if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
-				err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-						 EXT_CSD_BUS_WIDTH,
-						 ecbw->ext_csd_bits);
+			if (mwt->mode == MMC_HS_400) {
+				err = mmc_select_hs400(mmc);
+				if (err) {
+					printf("Select HS400 failed %d\n", err);
+					goto error;
+				}
+			} else {
+				/* configure the bus speed (card) */
+				err = mmc_set_card_speed(mmc, mwt->mode);
 				if (err)
 					goto error;
-			}
 
-			/* configure the bus mode (host) */
-			mmc_select_mode(mmc, mwt->mode);
-			mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
+				/*
+				 * configure the bus width AND the ddr mode
+				 * (card). The host side will be taken care
+				 * of in the next step
+				 */
+				if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
+					err = mmc_switch(mmc,
+							 EXT_CSD_CMD_SET_NORMAL,
+							 EXT_CSD_BUS_WIDTH,
+							 ecbw->ext_csd_bits);
+					if (err)
+						goto error;
+				}
+
+				/* configure the bus mode (host) */
+				mmc_select_mode(mmc, mwt->mode);
+				mmc_set_clock(mmc, mmc->tran_speed,
+					      MMC_CLK_ENABLE);
 #ifdef MMC_SUPPORTS_TUNING
 
-			/* execute tuning if needed */
-			if (mwt->tuning) {
-				err = mmc_execute_tuning(mmc, mwt->tuning);
-				if (err) {
-					pr_debug("tuning failed\n");
-					goto error;
+				/* execute tuning if needed */
+				if (mwt->tuning) {
+					err = mmc_execute_tuning(mmc,
+								 mwt->tuning);
+					if (err) {
+						pr_debug("tuning failed\n");
+						goto error;
+					}
 				}
-			}
 #endif
+			}
 
 			/* do a transfer to check the configuration */
 			err = mmc_read_and_compare_ext_csd(mmc);
diff --git a/include/mmc.h b/include/mmc.h
index df4255b828..9b9cbedadc 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -64,6 +64,7 @@
 #define MMC_MODE_HS_52MHz	MMC_CAP(MMC_HS_52)
 #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_8BIT		BIT(30)
 #define MMC_MODE_4BIT		BIT(29)
@@ -248,6 +249,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 						/* SDR mode @1.2V I/O */
 #define EXT_CSD_CARD_TYPE_HS200		(EXT_CSD_CARD_TYPE_HS200_1_8V | \
 					 EXT_CSD_CARD_TYPE_HS200_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400_1_8V	BIT(6)
+#define EXT_CSD_CARD_TYPE_HS400_1_2V	BIT(7)
+#define EXT_CSD_CARD_TYPE_HS400		(EXT_CSD_CARD_TYPE_HS400_1_8V | \
+					 EXT_CSD_CARD_TYPE_HS400_1_2V)
 
 #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 */
@@ -259,6 +264,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #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_BOOT_ACK_ENABLE			(1 << 6)
 #define EXT_CSD_BOOT_PARTITION_ENABLE		(1 << 3)
@@ -519,6 +525,7 @@ enum bus_mode {
 	UHS_DDR50,
 	UHS_SDR104,
 	MMC_HS_200,
+	MMC_HS_400,
 	MMC_MODES_END
 };
 
@@ -532,6 +539,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode)
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 	else if (mode == UHS_DDR50)
 		return true;
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	else if (mode == MMC_HS_400)
+		return true;
 #endif
 	else
 		return false;
-- 
2.14.1

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

* [U-Boot] [PATCH V4 2/2] mmc: fsl_esdhc: enable HS400 feature
  2018-08-10  6:07 [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
@ 2018-08-10  6:07 ` Peng Fan
  2018-09-11 12:25   ` [U-Boot] [U-Boot,V4,2/2] " Tom Rini
  2018-08-29  5:32 ` [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Peng Fan @ 2018-08-10  6:07 UTC (permalink / raw)
  To: u-boot

The strobe dll code is ported from Linux Kernel:
drivers/mmc/host/sdhci-esdhc-imx.c
The comments are from the above file,
"For HS400 eMMC, there is a data_strobe line. This signal is generated
by the device and used for data output and CRC status response output
in HS400 mode. The frequency of this signal follows the frequency of
CLK generated by host. The host receives the data which is aligned to the
edge of data_strobe line. Due to the time delay between CLK line and
data_strobe line, if the delay time is larger than one clock cycle,
then CLK and data_strobe line will be misaligned, read error shows up.
So when the CLK is higher than 100MHz, each clock cycle is short enough,
host should configure the delay target. "

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Stefano Babic <sbabic@denx.de>
---

V4:
 None
V3:
 remove DDR and HS400 when SD/MMC Legacy mode.
V2:
 None


 drivers/mmc/fsl_esdhc.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 70243b99d2..100d58d8f6 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -664,6 +664,7 @@ static int esdhc_change_pinstate(struct udevice *dev)
 		break;
 	case UHS_SDR104:
 	case MMC_HS_200:
+	case MMC_HS_400:
 		ret = pinctrl_select_state(dev, "state_200mhz");
 		break;
 	default:
@@ -691,6 +692,33 @@ static void esdhc_reset_tuning(struct mmc *mmc)
 	}
 }
 
+static void esdhc_set_strobe_dll(struct mmc *mmc)
+{
+	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
+	struct fsl_esdhc *regs = priv->esdhc_regs;
+	u32 val;
+
+	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
+		 */
+		val = ESDHC_STROBE_DLL_CTRL_ENABLE |
+			(priv->strobe_dll_delay_target <<
+			 ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+		writel(val, &regs->strobe_dllctrl);
+		/* wait 1us to make sure strobe dll status register stable */
+		mdelay(1);
+		val = readl(&regs->strobe_dllstat);
+		if (!(val & ESDHC_STROBE_DLL_STS_REF_LOCK))
+			pr_warn("HS400 strobe DLL status REF not lock!\n");
+		if (!(val & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+			pr_warn("HS400 strobe DLL status SLV not lock!\n");
+	}
+}
+
 static int esdhc_set_timing(struct mmc *mmc)
 {
 	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
@@ -704,6 +732,12 @@ static int esdhc_set_timing(struct mmc *mmc)
 	case MMC_LEGACY:
 	case SD_LEGACY:
 		esdhc_reset_tuning(mmc);
+		writel(mixctrl, &regs->mixctrl);
+		break;
+	case MMC_HS_400:
+		mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
+		writel(mixctrl, &regs->mixctrl);
+		esdhc_set_strobe_dll(mmc);
 		break;
 	case MMC_HS:
 	case MMC_HS_52:
@@ -1440,7 +1474,7 @@ 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);
+		priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400);
 
 	/*
 	 * TODO:
-- 
2.14.1

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

* [U-Boot] [PATCH V4 1/2] mmc: add HS400 support
  2018-08-10  6:07 [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
  2018-08-10  6:07 ` [U-Boot] [PATCH V4 2/2] mmc: fsl_esdhc: enable HS400 feature Peng Fan
@ 2018-08-29  5:32 ` Peng Fan
  2018-08-29 10:35   ` Marek Vasut
  2018-09-11 12:25 ` [U-Boot] [U-Boot,V4,1/2] " Tom Rini
  2019-03-27 20:43 ` Trent Piepho
  3 siblings, 1 reply; 11+ messages in thread
From: Peng Fan @ 2018-08-29  5:32 UTC (permalink / raw)
  To: u-boot

Hi,

Would anyone pick up this patchset? Tom, I delegated the patchset to you, would you mind pick it up? 

Thanks,
Peng.

-----Original Message-----
From: Peng Fan 
Sent: 2018年8月10日 14:08
To: jh80.chung at samsung.com; sbabic at denx.de
Cc: u-boot at lists.denx.de; dl-linux-imx <linux-imx@nxp.com>; Peng Fan <peng.fan@nxp.com>; Jean-Jacques Hiblot <jjhiblot@ti.com>; Kishon Vijay Abraham I <kishon@ti.com>; Faiz Abbas <faiz_abbas@ti.com>; Marek Vasut <marex@denx.de>
Subject: [PATCH V4 1/2] mmc: add HS400 support

Add HS400 support.
Selecting HS400 needs first select HS200 according to spec, so use a dedicated function for HS400.
Add HS400 related macros.
Remove the restriction of only using the low 6 bits of EXT_CSD_CARD_TYPE, using all the 8 bits.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Faiz Abbas <faiz_abbas@ti.com>
Cc: Marek Vasut <marex@denx.de>
---

V4:
 Add SPL_MMC_HS400_SUPPORT Kconfig entry  typo fix, HS199->HS200 in commit log.

V3:
 Simplify code
 add error msg

V2:
 remove 4bits support from HS400, as HS400 does not support 4bits per spec.

 drivers/mmc/Kconfig |  13 +++++
 drivers/mmc/mmc.c   | 137 +++++++++++++++++++++++++++++++++++++++++-----------
 include/mmc.h       |  11 +++++
 3 files changed, 134 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 377b1c4b3b..1616022b91 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -111,6 +111,19 @@ 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_SUPPORT
+	bool "enable HS400 support"
+	select MMC_HS200_SUPPORT
+	help
+	  The HS400 mode is support by some eMMC. The bus frequency is up to
+	  200MHz. This mode requires tuning the IO.
+
+config SPL_MMC_HS400_SUPPORT
+	bool "enable HS400 support in SPL"
+	help
+	  The HS400 mode is support by some eMMC. The bus frequency is up to
+	  200MHz. This mode requires tuning the IO.
+
 config MMC_HS200_SUPPORT
 	bool "enable HS200 support"
 	help
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ad429f49c9..585951cd78 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -147,6 +147,7 @@ const char *mmc_mode_name(enum bus_mode mode)
 	      [MMC_HS_52]	= "MMC High Speed (52MHz)",
 	      [MMC_DDR_52]	= "MMC DDR52 (52MHz)",
 	      [MMC_HS_200]	= "HS200 (200MHz)",
+	      [MMC_HS_400]	= "HS400 (200MHz)",
 	};
 
 	if (mode >= MMC_MODES_END)
@@ -171,6 +172,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
 	      [UHS_DDR50]	= 50000000,
 	      [UHS_SDR104]	= 208000000,
 	      [MMC_HS_200]	= 200000000,
+	      [MMC_HS_400]	= 200000000,
 	};
 
 	if (mode == MMC_LEGACY)
@@ -769,6 +771,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
 	case MMC_HS_200:
 		speed_bits = EXT_CSD_TIMING_HS200;
 		break;
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	case MMC_HS_400:
+		speed_bits = EXT_CSD_TIMING_HS400;
+		break;
 #endif
 	case MMC_LEGACY:
 		speed_bits = EXT_CSD_TIMING_LEGACY;
@@ -816,7 +823,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
 
 	mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 
-	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
+	cardtype = ext_csd[EXT_CSD_CARD_TYPE];
 	mmc->cardtype = cardtype;
 
 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
@@ -824,6 +831,12 @@ static int mmc_get_capabilities(struct mmc *mmc)
 			EXT_CSD_CARD_TYPE_HS200_1_8V)) {
 		mmc->card_caps |= MMC_MODE_HS200;
 	}
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
+			EXT_CSD_CARD_TYPE_HS400_1_8V)) {
+		mmc->card_caps |= MMC_MODE_HS400;
+	}
 #endif
 	if (cardtype & EXT_CSD_CARD_TYPE_52) {
 		if (cardtype & EXT_CSD_CARD_TYPE_DDR_52) @@ -1734,10 +1747,13 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
 	u32 card_mask = 0;
 
 	switch (mode) {
+	case MMC_HS_400:
 	case MMC_HS_200:
-		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
+		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
+		    EXT_CSD_CARD_TYPE_HS400_1_8V))
 			card_mask |= MMC_SIGNAL_VOLTAGE_180;
-		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V)
+		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
+		    EXT_CSD_CARD_TYPE_HS400_1_2V))
 			card_mask |= MMC_SIGNAL_VOLTAGE_120;
 		break;
 	case MMC_DDR_52:
@@ -1773,6 +1789,13 @@ 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_SUPPORT)
+	{
+		.mode = MMC_HS_400,
+		.widths = MMC_MODE_8BIT,
+		.tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
+	},
+#endif
 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
 	{
 		.mode = MMC_HS_200,
@@ -1816,6 +1839,54 @@ static const struct ext_csd_bus_width {
 	{MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},  };
 
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+static int mmc_select_hs400(struct mmc *mmc) {
+	int err;
+
+	/* Set timing to HS200 for tuning */
+	err = mmc_set_card_speed(mmc, MMC_HS_200);
+	if (err)
+		return err;
+
+	/* configure the bus mode (host) */
+	mmc_select_mode(mmc, MMC_HS_200);
+	mmc_set_clock(mmc, mmc->tran_speed, false);
+
+	/* execute tuning if needed */
+	err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
+	if (err) {
+		debug("tuning failed\n");
+		return err;
+	}
+
+	/* Set back to HS */
+	mmc_set_card_speed(mmc, MMC_HS);
+	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
+
+	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
+	if (err)
+		return err;
+
+	err = mmc_set_card_speed(mmc, MMC_HS_400);
+	if (err)
+		return err;
+
+	mmc_select_mode(mmc, MMC_HS_400);
+	err = mmc_set_clock(mmc, mmc->tran_speed, false);
+	if (err)
+		return err;
+
+	return 0;
+}
+#else
+static int mmc_select_hs400(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);\ @@ -1869,37 +1940,49 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
 				goto error;
 			mmc_set_bus_width(mmc, bus_width(ecbw->cap));
 
-			/* configure the bus speed (card) */
-			err = mmc_set_card_speed(mmc, mwt->mode);
-			if (err)
-				goto error;
-
-			/*
-			 * configure the bus width AND the ddr mode (card)
-			 * The host side will be taken care of in the next step
-			 */
-			if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
-				err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-						 EXT_CSD_BUS_WIDTH,
-						 ecbw->ext_csd_bits);
+			if (mwt->mode == MMC_HS_400) {
+				err = mmc_select_hs400(mmc);
+				if (err) {
+					printf("Select HS400 failed %d\n", err);
+					goto error;
+				}
+			} else {
+				/* configure the bus speed (card) */
+				err = mmc_set_card_speed(mmc, mwt->mode);
 				if (err)
 					goto error;
-			}
 
-			/* configure the bus mode (host) */
-			mmc_select_mode(mmc, mwt->mode);
-			mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
+				/*
+				 * configure the bus width AND the ddr mode
+				 * (card). The host side will be taken care
+				 * of in the next step
+				 */
+				if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
+					err = mmc_switch(mmc,
+							 EXT_CSD_CMD_SET_NORMAL,
+							 EXT_CSD_BUS_WIDTH,
+							 ecbw->ext_csd_bits);
+					if (err)
+						goto error;
+				}
+
+				/* configure the bus mode (host) */
+				mmc_select_mode(mmc, mwt->mode);
+				mmc_set_clock(mmc, mmc->tran_speed,
+					      MMC_CLK_ENABLE);
 #ifdef MMC_SUPPORTS_TUNING
 
-			/* execute tuning if needed */
-			if (mwt->tuning) {
-				err = mmc_execute_tuning(mmc, mwt->tuning);
-				if (err) {
-					pr_debug("tuning failed\n");
-					goto error;
+				/* execute tuning if needed */
+				if (mwt->tuning) {
+					err = mmc_execute_tuning(mmc,
+								 mwt->tuning);
+					if (err) {
+						pr_debug("tuning failed\n");
+						goto error;
+					}
 				}
-			}
 #endif
+			}
 
 			/* do a transfer to check the configuration */
 			err = mmc_read_and_compare_ext_csd(mmc);
diff --git a/include/mmc.h b/include/mmc.h index df4255b828..9b9cbedadc 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -64,6 +64,7 @@
 #define MMC_MODE_HS_52MHz	MMC_CAP(MMC_HS_52)
 #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_8BIT		BIT(30)
 #define MMC_MODE_4BIT		BIT(29)
@@ -248,6 +249,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 						/* SDR mode @1.2V I/O */
 #define EXT_CSD_CARD_TYPE_HS200		(EXT_CSD_CARD_TYPE_HS200_1_8V | \
 					 EXT_CSD_CARD_TYPE_HS200_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400_1_8V	BIT(6)
+#define EXT_CSD_CARD_TYPE_HS400_1_2V	BIT(7)
+#define EXT_CSD_CARD_TYPE_HS400		(EXT_CSD_CARD_TYPE_HS400_1_8V | \
+					 EXT_CSD_CARD_TYPE_HS400_1_2V)
 
 #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 */
@@ -259,6 +264,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #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_BOOT_ACK_ENABLE			(1 << 6)
 #define EXT_CSD_BOOT_PARTITION_ENABLE		(1 << 3)
@@ -519,6 +525,7 @@ enum bus_mode {
 	UHS_DDR50,
 	UHS_SDR104,
 	MMC_HS_200,
+	MMC_HS_400,
 	MMC_MODES_END
 };
 
@@ -532,6 +539,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode)  #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 	else if (mode == UHS_DDR50)
 		return true;
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	else if (mode == MMC_HS_400)
+		return true;
 #endif
 	else
 		return false;
--
2.14.1

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

* [U-Boot] [PATCH V4 1/2] mmc: add HS400 support
  2018-08-29  5:32 ` [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
@ 2018-08-29 10:35   ` Marek Vasut
  2018-08-29 11:21     ` Tom Rini
  0 siblings, 1 reply; 11+ messages in thread
From: Marek Vasut @ 2018-08-29 10:35 UTC (permalink / raw)
  To: u-boot

On 08/29/2018 07:32 AM, Peng Fan wrote:
> Hi,

Hi,

> Would anyone pick up this patchset? Tom, I delegated the patchset to you, would you mind pick it up? 

I've been nagging Tom about this for a while , he said he will pick it
for next release, but having it in this one would be IMO fine, since it
doesn't interfere with anything and it's been posted way before the RC
cycle started.

> Thanks,
> Peng.
> 
> -----Original Message-----
> From: Peng Fan 
> Sent: 2018年8月10日 14:08
> To: jh80.chung at samsung.com; sbabic at denx.de
> Cc: u-boot at lists.denx.de; dl-linux-imx <linux-imx@nxp.com>; Peng Fan <peng.fan@nxp.com>; Jean-Jacques Hiblot <jjhiblot@ti.com>; Kishon Vijay Abraham I <kishon@ti.com>; Faiz Abbas <faiz_abbas@ti.com>; Marek Vasut <marex@denx.de>
> Subject: [PATCH V4 1/2] mmc: add HS400 support
> 
> Add HS400 support.
> Selecting HS400 needs first select HS200 according to spec, so use a dedicated function for HS400.
> Add HS400 related macros.
> Remove the restriction of only using the low 6 bits of EXT_CSD_CARD_TYPE, using all the 8 bits.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: Faiz Abbas <faiz_abbas@ti.com>
> Cc: Marek Vasut <marex@denx.de>
> ---
> 
> V4:
>  Add SPL_MMC_HS400_SUPPORT Kconfig entry  typo fix, HS199->HS200 in commit log.
> 
> V3:
>  Simplify code
>  add error msg
> 
> V2:
>  remove 4bits support from HS400, as HS400 does not support 4bits per spec.
> 
>  drivers/mmc/Kconfig |  13 +++++
>  drivers/mmc/mmc.c   | 137 +++++++++++++++++++++++++++++++++++++++++-----------
>  include/mmc.h       |  11 +++++
>  3 files changed, 134 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 377b1c4b3b..1616022b91 100644
> --- a/drivers/mmc/Kconfig
> +++ b/drivers/mmc/Kconfig
> @@ -111,6 +111,19 @@ 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_SUPPORT
> +	bool "enable HS400 support"
> +	select MMC_HS200_SUPPORT
> +	help
> +	  The HS400 mode is support by some eMMC. The bus frequency is up to
> +	  200MHz. This mode requires tuning the IO.
> +
> +config SPL_MMC_HS400_SUPPORT
> +	bool "enable HS400 support in SPL"
> +	help
> +	  The HS400 mode is support by some eMMC. The bus frequency is up to
> +	  200MHz. This mode requires tuning the IO.
> +
>  config MMC_HS200_SUPPORT
>  	bool "enable HS200 support"
>  	help
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ad429f49c9..585951cd78 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -147,6 +147,7 @@ const char *mmc_mode_name(enum bus_mode mode)
>  	      [MMC_HS_52]	= "MMC High Speed (52MHz)",
>  	      [MMC_DDR_52]	= "MMC DDR52 (52MHz)",
>  	      [MMC_HS_200]	= "HS200 (200MHz)",
> +	      [MMC_HS_400]	= "HS400 (200MHz)",
>  	};
>  
>  	if (mode >= MMC_MODES_END)
> @@ -171,6 +172,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
>  	      [UHS_DDR50]	= 50000000,
>  	      [UHS_SDR104]	= 208000000,
>  	      [MMC_HS_200]	= 200000000,
> +	      [MMC_HS_400]	= 200000000,
>  	};
>  
>  	if (mode == MMC_LEGACY)
> @@ -769,6 +771,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
>  	case MMC_HS_200:
>  		speed_bits = EXT_CSD_TIMING_HS200;
>  		break;
> +#endif
> +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> +	case MMC_HS_400:
> +		speed_bits = EXT_CSD_TIMING_HS400;
> +		break;
>  #endif
>  	case MMC_LEGACY:
>  		speed_bits = EXT_CSD_TIMING_LEGACY;
> @@ -816,7 +823,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
>  
>  	mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
>  
> -	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
> +	cardtype = ext_csd[EXT_CSD_CARD_TYPE];
>  	mmc->cardtype = cardtype;
>  
>  #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
> @@ -824,6 +831,12 @@ static int mmc_get_capabilities(struct mmc *mmc)
>  			EXT_CSD_CARD_TYPE_HS200_1_8V)) {
>  		mmc->card_caps |= MMC_MODE_HS200;
>  	}
> +#endif
> +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> +	if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
> +			EXT_CSD_CARD_TYPE_HS400_1_8V)) {
> +		mmc->card_caps |= MMC_MODE_HS400;
> +	}
>  #endif
>  	if (cardtype & EXT_CSD_CARD_TYPE_52) {
>  		if (cardtype & EXT_CSD_CARD_TYPE_DDR_52) @@ -1734,10 +1747,13 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
>  	u32 card_mask = 0;
>  
>  	switch (mode) {
> +	case MMC_HS_400:
>  	case MMC_HS_200:
> -		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
> +		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
> +		    EXT_CSD_CARD_TYPE_HS400_1_8V))
>  			card_mask |= MMC_SIGNAL_VOLTAGE_180;
> -		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V)
> +		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
> +		    EXT_CSD_CARD_TYPE_HS400_1_2V))
>  			card_mask |= MMC_SIGNAL_VOLTAGE_120;
>  		break;
>  	case MMC_DDR_52:
> @@ -1773,6 +1789,13 @@ 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_SUPPORT)
> +	{
> +		.mode = MMC_HS_400,
> +		.widths = MMC_MODE_8BIT,
> +		.tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
> +	},
> +#endif
>  #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
>  	{
>  		.mode = MMC_HS_200,
> @@ -1816,6 +1839,54 @@ static const struct ext_csd_bus_width {
>  	{MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},  };
>  
> +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> +static int mmc_select_hs400(struct mmc *mmc) {
> +	int err;
> +
> +	/* Set timing to HS200 for tuning */
> +	err = mmc_set_card_speed(mmc, MMC_HS_200);
> +	if (err)
> +		return err;
> +
> +	/* configure the bus mode (host) */
> +	mmc_select_mode(mmc, MMC_HS_200);
> +	mmc_set_clock(mmc, mmc->tran_speed, false);
> +
> +	/* execute tuning if needed */
> +	err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
> +	if (err) {
> +		debug("tuning failed\n");
> +		return err;
> +	}
> +
> +	/* Set back to HS */
> +	mmc_set_card_speed(mmc, MMC_HS);
> +	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
> +
> +	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
> +			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
> +	if (err)
> +		return err;
> +
> +	err = mmc_set_card_speed(mmc, MMC_HS_400);
> +	if (err)
> +		return err;
> +
> +	mmc_select_mode(mmc, MMC_HS_400);
> +	err = mmc_set_clock(mmc, mmc->tran_speed, false);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +#else
> +static int mmc_select_hs400(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);\ @@ -1869,37 +1940,49 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
>  				goto error;
>  			mmc_set_bus_width(mmc, bus_width(ecbw->cap));
>  
> -			/* configure the bus speed (card) */
> -			err = mmc_set_card_speed(mmc, mwt->mode);
> -			if (err)
> -				goto error;
> -
> -			/*
> -			 * configure the bus width AND the ddr mode (card)
> -			 * The host side will be taken care of in the next step
> -			 */
> -			if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
> -				err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> -						 EXT_CSD_BUS_WIDTH,
> -						 ecbw->ext_csd_bits);
> +			if (mwt->mode == MMC_HS_400) {
> +				err = mmc_select_hs400(mmc);
> +				if (err) {
> +					printf("Select HS400 failed %d\n", err);
> +					goto error;
> +				}
> +			} else {
> +				/* configure the bus speed (card) */
> +				err = mmc_set_card_speed(mmc, mwt->mode);
>  				if (err)
>  					goto error;
> -			}
>  
> -			/* configure the bus mode (host) */
> -			mmc_select_mode(mmc, mwt->mode);
> -			mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
> +				/*
> +				 * configure the bus width AND the ddr mode
> +				 * (card). The host side will be taken care
> +				 * of in the next step
> +				 */
> +				if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
> +					err = mmc_switch(mmc,
> +							 EXT_CSD_CMD_SET_NORMAL,
> +							 EXT_CSD_BUS_WIDTH,
> +							 ecbw->ext_csd_bits);
> +					if (err)
> +						goto error;
> +				}
> +
> +				/* configure the bus mode (host) */
> +				mmc_select_mode(mmc, mwt->mode);
> +				mmc_set_clock(mmc, mmc->tran_speed,
> +					      MMC_CLK_ENABLE);
>  #ifdef MMC_SUPPORTS_TUNING
>  
> -			/* execute tuning if needed */
> -			if (mwt->tuning) {
> -				err = mmc_execute_tuning(mmc, mwt->tuning);
> -				if (err) {
> -					pr_debug("tuning failed\n");
> -					goto error;
> +				/* execute tuning if needed */
> +				if (mwt->tuning) {
> +					err = mmc_execute_tuning(mmc,
> +								 mwt->tuning);
> +					if (err) {
> +						pr_debug("tuning failed\n");
> +						goto error;
> +					}
>  				}
> -			}
>  #endif
> +			}
>  
>  			/* do a transfer to check the configuration */
>  			err = mmc_read_and_compare_ext_csd(mmc);
> diff --git a/include/mmc.h b/include/mmc.h index df4255b828..9b9cbedadc 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -64,6 +64,7 @@
>  #define MMC_MODE_HS_52MHz	MMC_CAP(MMC_HS_52)
>  #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_8BIT		BIT(30)
>  #define MMC_MODE_4BIT		BIT(29)
> @@ -248,6 +249,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
>  						/* SDR mode @1.2V I/O */
>  #define EXT_CSD_CARD_TYPE_HS200		(EXT_CSD_CARD_TYPE_HS200_1_8V | \
>  					 EXT_CSD_CARD_TYPE_HS200_1_2V)
> +#define EXT_CSD_CARD_TYPE_HS400_1_8V	BIT(6)
> +#define EXT_CSD_CARD_TYPE_HS400_1_2V	BIT(7)
> +#define EXT_CSD_CARD_TYPE_HS400		(EXT_CSD_CARD_TYPE_HS400_1_8V | \
> +					 EXT_CSD_CARD_TYPE_HS400_1_2V)
>  
>  #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 */
> @@ -259,6 +264,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
>  #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_BOOT_ACK_ENABLE			(1 << 6)
>  #define EXT_CSD_BOOT_PARTITION_ENABLE		(1 << 3)
> @@ -519,6 +525,7 @@ enum bus_mode {
>  	UHS_DDR50,
>  	UHS_SDR104,
>  	MMC_HS_200,
> +	MMC_HS_400,
>  	MMC_MODES_END
>  };
>  
> @@ -532,6 +539,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode)  #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
>  	else if (mode == UHS_DDR50)
>  		return true;
> +#endif
> +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> +	else if (mode == MMC_HS_400)
> +		return true;
>  #endif
>  	else
>  		return false;
> --
> 2.14.1
> 


-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH V4 1/2] mmc: add HS400 support
  2018-08-29 10:35   ` Marek Vasut
@ 2018-08-29 11:21     ` Tom Rini
  0 siblings, 0 replies; 11+ messages in thread
From: Tom Rini @ 2018-08-29 11:21 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 29, 2018 at 12:35:05PM +0200, Marek Vasut wrote:

> On 08/29/2018 07:32 AM, Peng Fan wrote:
> > Hi,
> 
> Hi,
> 
> > Would anyone pick up this patchset? Tom, I delegated the patchset to you, would you mind pick it up? 
> 
> I've been nagging Tom about this for a while , he said he will pick it
> for next release, but having it in this one would be IMO fine, since it
> doesn't interfere with anything and it's been posted way before the RC
> cycle started.

Yes, I still intend to pick it up after v2018.09.  Thanks for the
reminder!

> 

> > Thanks,
> > Peng.
> > 
> > -----Original Message-----
> > From: Peng Fan 
> > Sent: 2018年8月10日 14:08
> > To: jh80.chung at samsung.com; sbabic at denx.de
> > Cc: u-boot at lists.denx.de; dl-linux-imx <linux-imx@nxp.com>; Peng Fan <peng.fan@nxp.com>; Jean-Jacques Hiblot <jjhiblot@ti.com>; Kishon Vijay Abraham I <kishon@ti.com>; Faiz Abbas <faiz_abbas@ti.com>; Marek Vasut <marex@denx.de>
> > Subject: [PATCH V4 1/2] mmc: add HS400 support
> > 
> > Add HS400 support.
> > Selecting HS400 needs first select HS200 according to spec, so use a dedicated function for HS400.
> > Add HS400 related macros.
> > Remove the restriction of only using the low 6 bits of EXT_CSD_CARD_TYPE, using all the 8 bits.
> > 
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > Cc: Jaehoon Chung <jh80.chung@samsung.com>
> > Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
> > Cc: Stefano Babic <sbabic@denx.de>
> > Cc: Kishon Vijay Abraham I <kishon@ti.com>
> > Cc: Faiz Abbas <faiz_abbas@ti.com>
> > Cc: Marek Vasut <marex@denx.de>
> > ---
> > 
> > V4:
> >  Add SPL_MMC_HS400_SUPPORT Kconfig entry  typo fix, HS199->HS200 in commit log.
> > 
> > V3:
> >  Simplify code
> >  add error msg
> > 
> > V2:
> >  remove 4bits support from HS400, as HS400 does not support 4bits per spec.
> > 
> >  drivers/mmc/Kconfig |  13 +++++
> >  drivers/mmc/mmc.c   | 137 +++++++++++++++++++++++++++++++++++++++++-----------
> >  include/mmc.h       |  11 +++++
> >  3 files changed, 134 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 377b1c4b3b..1616022b91 100644
> > --- a/drivers/mmc/Kconfig
> > +++ b/drivers/mmc/Kconfig
> > @@ -111,6 +111,19 @@ 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_SUPPORT
> > +	bool "enable HS400 support"
> > +	select MMC_HS200_SUPPORT
> > +	help
> > +	  The HS400 mode is support by some eMMC. The bus frequency is up to
> > +	  200MHz. This mode requires tuning the IO.
> > +
> > +config SPL_MMC_HS400_SUPPORT
> > +	bool "enable HS400 support in SPL"
> > +	help
> > +	  The HS400 mode is support by some eMMC. The bus frequency is up to
> > +	  200MHz. This mode requires tuning the IO.
> > +
> >  config MMC_HS200_SUPPORT
> >  	bool "enable HS200 support"
> >  	help
> > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ad429f49c9..585951cd78 100644
> > --- a/drivers/mmc/mmc.c
> > +++ b/drivers/mmc/mmc.c
> > @@ -147,6 +147,7 @@ const char *mmc_mode_name(enum bus_mode mode)
> >  	      [MMC_HS_52]	= "MMC High Speed (52MHz)",
> >  	      [MMC_DDR_52]	= "MMC DDR52 (52MHz)",
> >  	      [MMC_HS_200]	= "HS200 (200MHz)",
> > +	      [MMC_HS_400]	= "HS400 (200MHz)",
> >  	};
> >  
> >  	if (mode >= MMC_MODES_END)
> > @@ -171,6 +172,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
> >  	      [UHS_DDR50]	= 50000000,
> >  	      [UHS_SDR104]	= 208000000,
> >  	      [MMC_HS_200]	= 200000000,
> > +	      [MMC_HS_400]	= 200000000,
> >  	};
> >  
> >  	if (mode == MMC_LEGACY)
> > @@ -769,6 +771,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
> >  	case MMC_HS_200:
> >  		speed_bits = EXT_CSD_TIMING_HS200;
> >  		break;
> > +#endif
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > +	case MMC_HS_400:
> > +		speed_bits = EXT_CSD_TIMING_HS400;
> > +		break;
> >  #endif
> >  	case MMC_LEGACY:
> >  		speed_bits = EXT_CSD_TIMING_LEGACY;
> > @@ -816,7 +823,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
> >  
> >  	mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
> >  
> > -	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
> > +	cardtype = ext_csd[EXT_CSD_CARD_TYPE];
> >  	mmc->cardtype = cardtype;
> >  
> >  #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
> > @@ -824,6 +831,12 @@ static int mmc_get_capabilities(struct mmc *mmc)
> >  			EXT_CSD_CARD_TYPE_HS200_1_8V)) {
> >  		mmc->card_caps |= MMC_MODE_HS200;
> >  	}
> > +#endif
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > +	if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
> > +			EXT_CSD_CARD_TYPE_HS400_1_8V)) {
> > +		mmc->card_caps |= MMC_MODE_HS400;
> > +	}
> >  #endif
> >  	if (cardtype & EXT_CSD_CARD_TYPE_52) {
> >  		if (cardtype & EXT_CSD_CARD_TYPE_DDR_52) @@ -1734,10 +1747,13 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
> >  	u32 card_mask = 0;
> >  
> >  	switch (mode) {
> > +	case MMC_HS_400:
> >  	case MMC_HS_200:
> > -		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
> > +		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
> > +		    EXT_CSD_CARD_TYPE_HS400_1_8V))
> >  			card_mask |= MMC_SIGNAL_VOLTAGE_180;
> > -		if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V)
> > +		if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
> > +		    EXT_CSD_CARD_TYPE_HS400_1_2V))
> >  			card_mask |= MMC_SIGNAL_VOLTAGE_120;
> >  		break;
> >  	case MMC_DDR_52:
> > @@ -1773,6 +1789,13 @@ 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_SUPPORT)
> > +	{
> > +		.mode = MMC_HS_400,
> > +		.widths = MMC_MODE_8BIT,
> > +		.tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
> > +	},
> > +#endif
> >  #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
> >  	{
> >  		.mode = MMC_HS_200,
> > @@ -1816,6 +1839,54 @@ static const struct ext_csd_bus_width {
> >  	{MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},  };
> >  
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > +static int mmc_select_hs400(struct mmc *mmc) {
> > +	int err;
> > +
> > +	/* Set timing to HS200 for tuning */
> > +	err = mmc_set_card_speed(mmc, MMC_HS_200);
> > +	if (err)
> > +		return err;
> > +
> > +	/* configure the bus mode (host) */
> > +	mmc_select_mode(mmc, MMC_HS_200);
> > +	mmc_set_clock(mmc, mmc->tran_speed, false);
> > +
> > +	/* execute tuning if needed */
> > +	err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
> > +	if (err) {
> > +		debug("tuning failed\n");
> > +		return err;
> > +	}
> > +
> > +	/* Set back to HS */
> > +	mmc_set_card_speed(mmc, MMC_HS);
> > +	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
> > +
> > +	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
> > +			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
> > +	if (err)
> > +		return err;
> > +
> > +	err = mmc_set_card_speed(mmc, MMC_HS_400);
> > +	if (err)
> > +		return err;
> > +
> > +	mmc_select_mode(mmc, MMC_HS_400);
> > +	err = mmc_set_clock(mmc, mmc->tran_speed, false);
> > +	if (err)
> > +		return err;
> > +
> > +	return 0;
> > +}
> > +#else
> > +static int mmc_select_hs400(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);\ @@ -1869,37 +1940,49 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
> >  				goto error;
> >  			mmc_set_bus_width(mmc, bus_width(ecbw->cap));
> >  
> > -			/* configure the bus speed (card) */
> > -			err = mmc_set_card_speed(mmc, mwt->mode);
> > -			if (err)
> > -				goto error;
> > -
> > -			/*
> > -			 * configure the bus width AND the ddr mode (card)
> > -			 * The host side will be taken care of in the next step
> > -			 */
> > -			if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
> > -				err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> > -						 EXT_CSD_BUS_WIDTH,
> > -						 ecbw->ext_csd_bits);
> > +			if (mwt->mode == MMC_HS_400) {
> > +				err = mmc_select_hs400(mmc);
> > +				if (err) {
> > +					printf("Select HS400 failed %d\n", err);
> > +					goto error;
> > +				}
> > +			} else {
> > +				/* configure the bus speed (card) */
> > +				err = mmc_set_card_speed(mmc, mwt->mode);
> >  				if (err)
> >  					goto error;
> > -			}
> >  
> > -			/* configure the bus mode (host) */
> > -			mmc_select_mode(mmc, mwt->mode);
> > -			mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
> > +				/*
> > +				 * configure the bus width AND the ddr mode
> > +				 * (card). The host side will be taken care
> > +				 * of in the next step
> > +				 */
> > +				if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
> > +					err = mmc_switch(mmc,
> > +							 EXT_CSD_CMD_SET_NORMAL,
> > +							 EXT_CSD_BUS_WIDTH,
> > +							 ecbw->ext_csd_bits);
> > +					if (err)
> > +						goto error;
> > +				}
> > +
> > +				/* configure the bus mode (host) */
> > +				mmc_select_mode(mmc, mwt->mode);
> > +				mmc_set_clock(mmc, mmc->tran_speed,
> > +					      MMC_CLK_ENABLE);
> >  #ifdef MMC_SUPPORTS_TUNING
> >  
> > -			/* execute tuning if needed */
> > -			if (mwt->tuning) {
> > -				err = mmc_execute_tuning(mmc, mwt->tuning);
> > -				if (err) {
> > -					pr_debug("tuning failed\n");
> > -					goto error;
> > +				/* execute tuning if needed */
> > +				if (mwt->tuning) {
> > +					err = mmc_execute_tuning(mmc,
> > +								 mwt->tuning);
> > +					if (err) {
> > +						pr_debug("tuning failed\n");
> > +						goto error;
> > +					}
> >  				}
> > -			}
> >  #endif
> > +			}
> >  
> >  			/* do a transfer to check the configuration */
> >  			err = mmc_read_and_compare_ext_csd(mmc);
> > diff --git a/include/mmc.h b/include/mmc.h index df4255b828..9b9cbedadc 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -64,6 +64,7 @@
> >  #define MMC_MODE_HS_52MHz	MMC_CAP(MMC_HS_52)
> >  #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_8BIT		BIT(30)
> >  #define MMC_MODE_4BIT		BIT(29)
> > @@ -248,6 +249,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
> >  						/* SDR mode @1.2V I/O */
> >  #define EXT_CSD_CARD_TYPE_HS200		(EXT_CSD_CARD_TYPE_HS200_1_8V | \
> >  					 EXT_CSD_CARD_TYPE_HS200_1_2V)
> > +#define EXT_CSD_CARD_TYPE_HS400_1_8V	BIT(6)
> > +#define EXT_CSD_CARD_TYPE_HS400_1_2V	BIT(7)
> > +#define EXT_CSD_CARD_TYPE_HS400		(EXT_CSD_CARD_TYPE_HS400_1_8V | \
> > +					 EXT_CSD_CARD_TYPE_HS400_1_2V)
> >  
> >  #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 */
> > @@ -259,6 +264,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
> >  #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_BOOT_ACK_ENABLE			(1 << 6)
> >  #define EXT_CSD_BOOT_PARTITION_ENABLE		(1 << 3)
> > @@ -519,6 +525,7 @@ enum bus_mode {
> >  	UHS_DDR50,
> >  	UHS_SDR104,
> >  	MMC_HS_200,
> > +	MMC_HS_400,
> >  	MMC_MODES_END
> >  };
> >  
> > @@ -532,6 +539,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode)  #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
> >  	else if (mode == UHS_DDR50)
> >  		return true;
> > +#endif
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > +	else if (mode == MMC_HS_400)
> > +		return true;
> >  #endif
> >  	else
> >  		return false;
> > --
> > 2.14.1
> > 
> 
> 
> -- 
> Best regards,
> Marek Vasut

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180829/dbfda43d/attachment.sig>

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

* [U-Boot] [U-Boot,V4,1/2] mmc: add HS400 support
  2018-08-10  6:07 [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
  2018-08-10  6:07 ` [U-Boot] [PATCH V4 2/2] mmc: fsl_esdhc: enable HS400 feature Peng Fan
  2018-08-29  5:32 ` [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
@ 2018-09-11 12:25 ` Tom Rini
  2019-03-27 20:43 ` Trent Piepho
  3 siblings, 0 replies; 11+ messages in thread
From: Tom Rini @ 2018-09-11 12:25 UTC (permalink / raw)
  To: u-boot

On Fri, Aug 10, 2018 at 02:07:54PM +0800, Peng Fan wrote:

> Add HS400 support.
> Selecting HS400 needs first select HS200 according to spec, so use
> a dedicated function for HS400.
> Add HS400 related macros.
> Remove the restriction of only using the low 6 bits of
> EXT_CSD_CARD_TYPE, using all the 8 bits.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: Faiz Abbas <faiz_abbas@ti.com>
> Cc: Marek Vasut <marex@denx.de>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180911/6832cf14/attachment.sig>

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

* [U-Boot] [U-Boot,V4,2/2] mmc: fsl_esdhc: enable HS400 feature
  2018-08-10  6:07 ` [U-Boot] [PATCH V4 2/2] mmc: fsl_esdhc: enable HS400 feature Peng Fan
@ 2018-09-11 12:25   ` Tom Rini
  0 siblings, 0 replies; 11+ messages in thread
From: Tom Rini @ 2018-09-11 12:25 UTC (permalink / raw)
  To: u-boot

On Fri, Aug 10, 2018 at 02:07:55PM +0800, Peng Fan wrote:

> The strobe dll code is ported from Linux Kernel:
> drivers/mmc/host/sdhci-esdhc-imx.c
> The comments are from the above file,
> "For HS400 eMMC, there is a data_strobe line. This signal is generated
> by the device and used for data output and CRC status response output
> in HS400 mode. The frequency of this signal follows the frequency of
> CLK generated by host. The host receives the data which is aligned to the
> edge of data_strobe line. Due to the time delay between CLK line and
> data_strobe line, if the delay time is larger than one clock cycle,
> then CLK and data_strobe line will be misaligned, read error shows up.
> So when the CLK is higher than 100MHz, each clock cycle is short enough,
> host should configure the delay target. "
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Stefano Babic <sbabic@denx.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180911/096a8ce1/attachment.sig>

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

* [U-Boot] [U-Boot,V4,1/2] mmc: add HS400 support
  2018-08-10  6:07 [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
                   ` (2 preceding siblings ...)
  2018-09-11 12:25 ` [U-Boot] [U-Boot,V4,1/2] " Tom Rini
@ 2019-03-27 20:43 ` Trent Piepho
  2019-03-28  2:42   ` Marek Vasut
  2019-03-28  8:00   ` Peng Fan
  3 siblings, 2 replies; 11+ messages in thread
From: Trent Piepho @ 2019-03-27 20:43 UTC (permalink / raw)
  To: u-boot

I didn't see HS400 working on my IMX7d, even thought it appears it
should be supported.

The problem appears to be when this bit of code in fsl_esdhc.c, which
dates to a patch "mmc: fsl_esdhc: support SDR104 and HS200":

 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,
 };

Notice that MMC_MODE_HS400 isn't in the caps list.  Once I add that
uboot will attempt HS400 and it appears to work correctly.

I think maybe this patch should have added this to the caps?

Alternatively, there is a property that can be added to the device
tree, mmc-hs400-1_8v, that will add this cap.  But the code to parse
those dt properties, mmc_of_parse(), isn't used by the fsl_esdhc
driver, which has its own parsing code that doesn't know about mmc-
hs400-1_8v.

So maybe fsl-esdhc should use mmc_of_parse() and the appropriate iMX
DTs should add those properties?

I think the DT method might be better, since it would allow the DT to
not list a mode that doesn't work due to the the board.  I.e., the iMX
host supports the mode, the eMMC supports the mode, but the board
layout doesn't have traces that can support it.  Too long, not matched
well enough, etc.  It doesn't seem like there's an nice way to remove a
mode otherwise.

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

* [U-Boot] [U-Boot,V4,1/2] mmc: add HS400 support
  2019-03-27 20:43 ` Trent Piepho
@ 2019-03-28  2:42   ` Marek Vasut
  2019-03-29 18:12     ` Trent Piepho
  2019-03-28  8:00   ` Peng Fan
  1 sibling, 1 reply; 11+ messages in thread
From: Marek Vasut @ 2019-03-28  2:42 UTC (permalink / raw)
  To: u-boot

On 3/27/19 9:43 PM, Trent Piepho wrote:
> I didn't see HS400 working on my IMX7d, even thought it appears it
> should be supported.
> 
> The problem appears to be when this bit of code in fsl_esdhc.c, which
> dates to a patch "mmc: fsl_esdhc: support SDR104 and HS200":
> 
>  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,
>  };
> 
> Notice that MMC_MODE_HS400 isn't in the caps list.  Once I add that
> uboot will attempt HS400 and it appears to work correctly.
> 
> I think maybe this patch should have added this to the caps?
> 
> Alternatively, there is a property that can be added to the device
> tree, mmc-hs400-1_8v, that will add this cap.  But the code to parse
> those dt properties, mmc_of_parse(), isn't used by the fsl_esdhc
> driver, which has its own parsing code that doesn't know about mmc-
> hs400-1_8v.
> 
> So maybe fsl-esdhc should use mmc_of_parse() and the appropriate iMX
> DTs should add those properties?
> 
> I think the DT method might be better, since it would allow the DT to
> not list a mode that doesn't work due to the the board.

Right, please submit a patch switching over to the generic parsing code.
Thanks

> I.e., the iMX
> host supports the mode, the eMMC supports the mode, but the board
> layout doesn't have traces that can support it.  Too long, not matched
> well enough, etc.  It doesn't seem like there's an nice way to remove a
> mode otherwise.
> 


-- 
Best regards,
Marek Vasut

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

* [U-Boot] [U-Boot,V4,1/2] mmc: add HS400 support
  2019-03-27 20:43 ` Trent Piepho
  2019-03-28  2:42   ` Marek Vasut
@ 2019-03-28  8:00   ` Peng Fan
  1 sibling, 0 replies; 11+ messages in thread
From: Peng Fan @ 2019-03-28  8:00 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Trent Piepho [mailto:tpiepho at impinj.com]
> Sent: 2019年3月28日 4:43
> To: Peng Fan <peng.fan@nxp.com>; jh80.chung at samsung.com;
> sbabic at denx.de
> Cc: marex at denx.de; kishon at ti.com; dl-linux-imx <linux-imx@nxp.com>;
> u-boot at lists.denx.de
> Subject: Re: [U-Boot,V4,1/2] mmc: add HS400 support
> 
> I didn't see HS400 working on my IMX7d, even thought it appears it should be
> supported.
> 
> The problem appears to be when this bit of code in fsl_esdhc.c, which dates to
> a patch "mmc: fsl_esdhc: support SDR104 and HS200":
> 
>  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,  };
> 
> Notice that MMC_MODE_HS400 isn't in the caps list.  Once I add that uboot
> will attempt HS400 and it appears to work correctly.
> 
> I think maybe this patch should have added this to the caps?
> 
> Alternatively, there is a property that can be added to the device tree,
> mmc-hs400-1_8v, that will add this cap.  But the code to parse those dt
> properties, mmc_of_parse(), isn't used by the fsl_esdhc driver, which has its
> own parsing code that doesn't know about mmc- hs400-1_8v.
> 
> So maybe fsl-esdhc should use mmc_of_parse() and the appropriate iMX DTs
> should add those properties?
> 
> I think the DT method might be better, since it would allow the DT to not list a
> mode that doesn't work due to the the board.  I.e., the iMX host supports
> the mode, the eMMC supports the mode, but the board layout doesn't have
> traces that can support it.  Too long, not matched well enough, etc.  It
> doesn't seem like there's an nice way to remove a mode otherwise.

Yes. Parse device tree will be better.

Regards,
Peng.

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

* [U-Boot] [U-Boot,V4,1/2] mmc: add HS400 support
  2019-03-28  2:42   ` Marek Vasut
@ 2019-03-29 18:12     ` Trent Piepho
  0 siblings, 0 replies; 11+ messages in thread
From: Trent Piepho @ 2019-03-29 18:12 UTC (permalink / raw)
  To: u-boot

On Thu, 2019-03-28 at 03:42 +0100, Marek Vasut wrote:
> On 3/27/19 9:43 PM, Trent Piepho wrote:
> > I didn't see HS400 working on my IMX7d, even thought it appears it
> > should be supported.
> > 
> > Alternatively, there is a property that can be added to the device
> > tree, mmc-hs400-1_8v, that will add this cap.  But the code to parse
> > those dt properties, mmc_of_parse(), isn't used by the fsl_esdhc
> > driver, which has its own parsing code that doesn't know about mmc-
> > hs400-1_8v.
> > 

> Right, please submit a patch switching over to the generic parsing code.
> Thanks
> 

So I looked into it a bit more, and while using the generic parsing
code seems like a good idea, there is still an issue.  None of the
kernel dts files for imx use any of the those properties to indicate
support.  The kernel driver has a built-in list of supported modes for
each device type and uses that.

So maybe consistency with the kernel is more important and the table of
OF device names to capabilities in u-boot should just be updated to
match what the kernel does.

But use the generic parsing code too.  I think I can add a property to
the generic that is described as a standard in the kernel mmc binding
and leave in just the imx some properties that are fsl specific.

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

end of thread, other threads:[~2019-03-29 18:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-10  6:07 [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
2018-08-10  6:07 ` [U-Boot] [PATCH V4 2/2] mmc: fsl_esdhc: enable HS400 feature Peng Fan
2018-09-11 12:25   ` [U-Boot] [U-Boot,V4,2/2] " Tom Rini
2018-08-29  5:32 ` [U-Boot] [PATCH V4 1/2] mmc: add HS400 support Peng Fan
2018-08-29 10:35   ` Marek Vasut
2018-08-29 11:21     ` Tom Rini
2018-09-11 12:25 ` [U-Boot] [U-Boot,V4,1/2] " Tom Rini
2019-03-27 20:43 ` Trent Piepho
2019-03-28  2:42   ` Marek Vasut
2019-03-29 18:12     ` Trent Piepho
2019-03-28  8:00   ` 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.