Skip to contentSkip to conversation

mmc: fixes for HS200/UHS core support

PATCH Superseded Jean-Jacques Hiblot 3 participants 18 messages Nov 29, 2017 – Dec 6, 2017 MMC, SD and SDIO

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v4 cover mmc: fixes for HS200/UHS core support

This series applies on top of "[PATCH v2 00/26] mmc: Add support for HS200 and UHS modes"

It fixes a bug with old SD and MMC cards that support only the legacy mode. This series also adresses the problem of increased code size that broke some platform (openrd and omapl138_lcdk) by making more things optional.

It also addresses other comments made on the mailing list:
* dump card and host capabilities in debug mode
* use 1-bit if the DTS property 'bus-width' is not present.
* recognize the "mmc-ddr-1_2v" and "mmc-hs200-1_2v" DTS properties
* convert mmc_of_parse to livetree

Tested on DRA72

changes since v3:
* Make UHS support optional. Disabled by default
* Make HS200 support optional. Disabled by default
* Make eMMC Hardware Partitioning optional. Enabled by default
* Display most of the error messages only if MMC_VERBOSE is set (it's set by default)

changes since v2:
* use the device-oriented helpers like dev_read_u32_default() instead of using the livetree API
* Dump the host and card capabilities only in when debug is enabled. Also dump the capabilities when 'mmc info' is executed if the verbose option is enabled

changes since v1:
* convert mmc_of_parse to livetree
* squashed all changes to mmc_of_parse in a single patch

Jean-Jacques Hiblot (10):
mmc: dump card and host capabilities if debug is enabled
dm: mmc: update mmc_of_parse()
mmc: Fixed a problem with old sd or mmc that do not support High speed
mmc: all hosts support 1-bit bus width and legacy timings
mmc: fix for old MMCs (below version 4)
mmc: don't use malloc_cache_aligned()
mmc: allow to compile out the error messages
mmc: make UHS and HS200 optional
mmc: make optional the support for eMMMC hardware partitioning
configs: openrd: removed support for eMMC hardware partitioning

 cmd/mmc.c                         |   8 ++
 configs/openrd_base_defconfig     |   1 +
 configs/openrd_client_defconfig   |   1 +
 configs/openrd_ultimate_defconfig |   1 +
 drivers/mmc/Kconfig               |  54 +++++++++++++
 drivers/mmc/mmc-uclass.c          |  40 ++++++----
 drivers/mmc/mmc.c                 | 162 +++++++++++++++++++++++++++++---------
 include/mmc.h                     |  38 +++++++--
 8 files changed, 245 insertions(+), 60 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH v4 1/10 mmc: dump card and host capabilities if debug is enabled

This is a useful information while debugging the initialization process or performance issues.
Also dump this information with the other mmc info if the verbose option is selected

---

no changes since v3

 cmd/mmc.c         | 4 ++++
 drivers/mmc/mmc.c | 9 +++++++++
 2 files changed, 13 insertions(+)
cmd/mmc.c +4 -0
index 6d48ecb..25795e0 100644
@@ -24,7 +24,11 @@ static void print_mmcinfo(struct mmc *mmc)
 			(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
 
 	printf("Bus Speed: %d\n", mmc->clock);
+#if CONFIG_IS_ENABLED(MMC_VERBOSE)
 	printf("Mode : %s\n", mmc_mode_name(mmc->selected_mode));
+	mmc_dump_capabilities("card capabilities", mmc->card_caps);
+	mmc_dump_capabilities("host capabilities", mmc->host_caps);
+#endif
 	printf("Rd Block Len: %d\n", mmc->read_bl_len);
 
 	printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC",
drivers/mmc/mmc.c +9 -0
index ab2483e..9b5c982 100644
@@ -1582,6 +1582,10 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
 	bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
 	uint caps;
 
+#ifdef DEBUG
+	mmc_dump_capabilities("sd card", card_caps);
+	mmc_dump_capabilities("host", mmc->host_caps | MMC_MODE_1BIT);
+#endif
 
 	/* Restrict card's capabilities by what the host can do */
 	caps = card_caps & (mmc->host_caps | MMC_MODE_1BIT);
@@ -1764,6 +1768,11 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
 	const struct mode_width_tuning *mwt;
 	const struct ext_csd_bus_width *ecbw;
 
+#ifdef DEBUG
+	mmc_dump_capabilities("mmc", card_caps);
+	mmc_dump_capabilities("host", mmc->host_caps | MMC_MODE_1BIT);
+#endif
+
 	/* Restrict card's capabilities by what the host can do */
 	card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
 
Signature · 1 line
1.9.1
#2 lore raw

PATCH v4 1/10 mmc: dump card and host capabilities if debug is enabled

Quoted 5 lines · Jean-Jacques Hiblot

This is a useful information while debugging the initialization process or performance issues.
Also dump this information with the other mmc info if the verbose option is selected

Quoted 8 lines

---

no changes since v3

 cmd/mmc.c         | 4 ++++
 drivers/mmc/mmc.c | 9 +++++++++
 2 files changed, 13 insertions(+)
#3 lore raw

PATCH v4 2/10 dm: mmc: update mmc_of_parse()

In reply to Jean-Jacques Hiblot

* convert to livetree API
* don't fail because of an invalid bus-width, instead default to 1-bit.
* recognize 1.2v DDR and 1.2v HS200 flags

---

no changes since v3

 drivers/mmc/mmc-uclass.c | 36 ++++++++++++++++++++----------------
 include/mmc.h            | 11 ++++++++++-
 2 files changed, 30 insertions(+), 17 deletions(-)
drivers/mmc/mmc-uclass.c +20 -16
index e30cde7..bfda942 100644
@@ -10,7 +10,6 @@
 #include <dm.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
-#include <dm/root.h>
 #include "mmc_private.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -120,11 +119,11 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode)
 	return dm_mmc_execute_tuning(mmc->dev, opcode);
 }
 
-int mmc_of_parse(const void *fdt, int node, struct mmc_config *cfg)
+int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
 {
 	int val;
 
-	val = fdtdec_get_int(fdt, node, "bus-width", 1);
+	val = dev_read_u32_default(dev, "bus-width", 1);
 
 	switch (val) {
 	case 0x8:
@@ -137,30 +136,35 @@ int mmc_of_parse(const void *fdt, int node, struct mmc_config *cfg)
 		cfg->host_caps |= MMC_MODE_1BIT;
 		break;
 	default:
-		printf("error: %s invalid bus-width property %d\n",
-		       fdt_get_name(fdt, node, NULL), val);
-		return -ENOENT;
+		debug("warning: %s invalid bus-width property. using 1-bit\n",
+		      dev_read_name(dev));
+		cfg->host_caps |= MMC_MODE_1BIT;
+		break;
 	}
 
-	cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
+	cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000);
 
-	if (fdtdec_get_bool(fdt, node, "cap-sd-highspeed"))
+	if (dev_read_bool(dev, "cap-sd-highspeed"))
 		cfg->host_caps |= MMC_CAP(SD_HS);
-	if (fdtdec_get_bool(fdt, node, "cap-mmc-highspeed"))
+	if (dev_read_bool(dev, "cap-mmc-highspeed"))
 		cfg->host_caps |= MMC_CAP(MMC_HS);
-	if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr12"))
+	if (dev_read_bool(dev, "sd-uhs-sdr12"))
 		cfg->host_caps |= MMC_CAP(UHS_SDR12);
-	if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr25"))
+	if (dev_read_bool(dev, "sd-uhs-sdr25"))
 		cfg->host_caps |= MMC_CAP(UHS_SDR25);
-	if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr50"))
+	if (dev_read_bool(dev, "sd-uhs-sdr50"))
 		cfg->host_caps |= MMC_CAP(UHS_SDR50);
-	if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr104"))
+	if (dev_read_bool(dev, "sd-uhs-sdr104"))
 		cfg->host_caps |= MMC_CAP(UHS_SDR104);
-	if (fdtdec_get_bool(fdt, node, "sd-uhs-ddr50"))
+	if (dev_read_bool(dev, "sd-uhs-ddr50"))
 		cfg->host_caps |= MMC_CAP(UHS_DDR50);
-	if (fdtdec_get_bool(fdt, node, "mmc-ddr-1_8v"))
+	if (dev_read_bool(dev, "mmc-ddr-1_8v"))
 		cfg->host_caps |= MMC_CAP(MMC_DDR_52);
-	if (fdtdec_get_bool(fdt, node, "mmc-hs200-1_8v"))
+	if (dev_read_bool(dev, "mmc-ddr-1_2v"))
+		cfg->host_caps |= MMC_CAP(MMC_DDR_52);
+	if (dev_read_bool(dev, "mmc-hs200-1_8v"))
+		cfg->host_caps |= MMC_CAP(MMC_HS_200);
+	if (dev_read_bool(dev, "mmc-hs200-1_2v"))
 		cfg->host_caps |= MMC_CAP(MMC_HS_200);
 
 	return 0;
include/mmc.h +10 -1
index 6230a32..e3f777f 100644
@@ -651,7 +651,16 @@ int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
-int mmc_of_parse(const void *fdt, int node, struct mmc_config *cfg);
+
+/**
+ * mmc_of_parse() - Parse the device tree to get the capabilities of the host
+ *
+ * @dev:	MMC device
+ * @cfg:	MMC configuration
+ * @return 0 if OK, -ve on error
+ */
+int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
+
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
 
 /**
Signature · 1 line
1.9.1
#4 lore raw

PATCH v4 2/10 dm: mmc: update mmc_of_parse()

Quoted 4 lines · Jean-Jacques Hiblot

* convert to livetree API
* don't fail because of an invalid bus-width, instead default to 1-bit.
* recognize 1.2v DDR and 1.2v HS200 flags

Quoted 8 lines

---

no changes since v3

 drivers/mmc/mmc-uclass.c | 36 ++++++++++++++++++++----------------
 include/mmc.h            | 11 ++++++++++-
 2 files changed, 30 insertions(+), 17 deletions(-)

I thought I already reviewed this?

#5 lore raw

PATCH v4 3/10 mmc: Fixed a problem with old sd or mmc that do not support High speed

In reply to Jean-Jacques Hiblot

As the legacy modes were not added to the list of supported modes, old cards that do not support other modes could not be used.

---
no change since v1

 drivers/mmc/mmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/mmc.c +2 -2
index 9b5c982..c1f8851 100644
@@ -818,7 +818,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
 	u8 *ext_csd = mmc->ext_csd;
 	char cardtype;
 
-	mmc->card_caps = MMC_MODE_1BIT;
+	mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
 
 	if (mmc_host_is_spi(mmc))
 		return 0;
@@ -1171,7 +1171,7 @@ static int sd_get_capabilities(struct mmc *mmc)
 	int timeout;
 	u32 sd3_bus_mode;
 
-	mmc->card_caps = MMC_MODE_1BIT;
+	mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
 
 	if (mmc_host_is_spi(mmc))
 		return 0;
Signature · 1 line
1.9.1
#6 lore raw

PATCH v4 4/10 mmc: all hosts support 1-bit bus width and legacy timings

In reply to Jean-Jacques Hiblot

Make sure that those basic capabilities are advertised by the host.

---

no change since v1

 drivers/mmc/mmc.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/mmc/mmc.c +10 -5
index c1f8851..0ebcc45 100644
@@ -1584,11 +1584,11 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
 
 #ifdef DEBUG
 	mmc_dump_capabilities("sd card", card_caps);
-	mmc_dump_capabilities("host", mmc->host_caps | MMC_MODE_1BIT);
+	mmc_dump_capabilities("host", mmc->host_caps);
 #endif
 
 	/* Restrict card's capabilities by what the host can do */
-	caps = card_caps & (mmc->host_caps | MMC_MODE_1BIT);
+	caps = card_caps & mmc->host_caps;
 
 	if (!uhs_en)
 		caps &= ~UHS_CAPS;
@@ -1770,11 +1770,11 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
 
 #ifdef DEBUG
 	mmc_dump_capabilities("mmc", card_caps);
-	mmc_dump_capabilities("host", mmc->host_caps | MMC_MODE_1BIT);
+	mmc_dump_capabilities("host", mmc->host_caps);
 #endif
 
 	/* Restrict card's capabilities by what the host can do */
-	card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
+	card_caps &= mmc->host_caps;
 
 	/* Only version 4 of MMC supports wider bus widths */
 	if (mmc->version < MMC_VERSION_4)
@@ -2389,7 +2389,12 @@ int mmc_start_init(struct mmc *mmc)
 	bool uhs_en = supports_uhs(mmc->cfg->host_caps);
 	int err;
 
-	mmc->host_caps = mmc->cfg->host_caps;
+	/*
+	 * all hosts are capable of 1 bit bus-width and able to use the legacy
+	 * timings.
+	 */
+	mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
+			 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
 
 	/* we pretend there's no card when init is NULL */
 	no_card = mmc_getcd(mmc) == 0;
Signature · 1 line
1.9.1
#7 lore raw

PATCH v4 5/10 mmc: fix for old MMCs (below version 4)

In reply to Jean-Jacques Hiblot

The ext_csd is allocated only for MMC above version 4. The compare will crash or fail for older MMCs.

---
 drivers/mmc/mmc.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/mmc/mmc.c +3 -0
index 0ebcc45..2a58031 100644
@@ -1657,6 +1657,9 @@ static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
 	const u8 *ext_csd = mmc->ext_csd;
 	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
 
+	if (mmc->version < MMC_VERSION_4)
+		return 0;
+
 	err = mmc_send_ext_csd(mmc, test_csd);
 	if (err)
 		return err;
Signature · 1 line
1.9.1
#9 lore raw

PATCH v4 6/10 mmc: don't use malloc_cache_aligned()

In reply to Jean-Jacques Hiblot

Not using this function reduces the size of the binary. It's replaces by a standard malloc() and the alignment requirement is handled by an intermediate buffer on the stack.

Also make sure that the allocated buffer is freed in case of error.

---
 drivers/mmc/mmc.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)
drivers/mmc/mmc.c +17 -9
index 2a58031..13979a5 100644
@@ -1867,21 +1867,23 @@ static int mmc_startup_v4(struct mmc *mmc)
 	u64 capacity;
 	bool has_parts = false;
 	bool part_completed;
-	u8 *ext_csd;
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
 
 	if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
 		return 0;
 
-	ext_csd = malloc_cache_aligned(MMC_MAX_BLOCK_LEN);
-	if (!ext_csd)
-		return -ENOMEM;
-
-	mmc->ext_csd = ext_csd;
-
 	/* check  ext_csd version and capacity */
 	err = mmc_send_ext_csd(mmc, ext_csd);
 	if (err)
-		return err;
+		goto error;
+
+	/* store the ext csd for future reference */
+	if (!mmc->ext_csd)
+		mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
+	if (!mmc->ext_csd)
+		return -ENOMEM;
+	memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
+
 	if (ext_csd[EXT_CSD_REV] >= 2) {
 		/*
 		 * According to the JEDEC Standard, the value of
@@ -1990,7 +1992,7 @@ static int mmc_startup_v4(struct mmc *mmc)
 				 EXT_CSD_ERASE_GROUP_DEF, 1);
 
 		if (err)
-			return err;
+			goto error;
 
 		ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
 	}
@@ -2029,6 +2031,12 @@ static int mmc_startup_v4(struct mmc *mmc)
 	mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
 
 	return 0;
+error:
+	if (mmc->ext_csd) {
+		free(mmc->ext_csd);
+		mmc->ext_csd = NULL;
+	}
+	return err;
 }
 
 static int mmc_startup(struct mmc *mmc)
Signature · 1 line
1.9.1
#10 lore raw

PATCH v4 6/10 mmc: don't use malloc_cache_aligned()

Quoted 10 lines · Jean-Jacques Hiblot

Not using this function reduces the size of the binary. It's replaces by a standard malloc() and the alignment requirement is handled by an intermediate buffer on the stack.

Also make sure that the allocated buffer is freed in case of error.

---
 drivers/mmc/mmc.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

Somewhat unsure of this one but it looks right to me.

#11 lore raw

PATCH v4 7/10 mmc: allow to compile out the error messages

In reply to Jean-Jacques Hiblot

Error messages may not be as valued as code space. Allow to compile out most of them to free space.

---
 drivers/mmc/Kconfig |  1 +
 drivers/mmc/mmc.c   | 44 ++++++++++++++++++++------------------------
 2 files changed, 21 insertions(+), 24 deletions(-)
drivers/mmc/Kconfig +1 -0
index dbbef5a..7a45d4b 100644
@@ -60,6 +60,7 @@ config MMC_VERBOSE
 
 config SPL_MMC_VERBOSE
 	bool "Output more information about the MMC in SPL"
+	depends on SPL_LIBCOMMON_SUPPORT
 	default n
 	help
 	  Enable the output of more information about the card such as the
drivers/mmc/mmc.c +20 -24

122 lines not on this page · raw message

Signature · 1 line
1.9.1
#12 lore raw

PATCH v4 7/10 mmc: allow to compile out the error messages

Quoted 26 lines · Jean-Jacques Hiblot

Error messages may not be as valued as code space. Allow to compile out most of them to free space.

---
 drivers/mmc/Kconfig |  1 +
 drivers/mmc/mmc.c   | 44 ++++++++++++++++++++------------------------
 2 files changed, 21 insertions(+), 24 deletions(-)
drivers/mmc/Kconfig +1 -0
index dbbef5a..7a45d4b 100644
@@ -60,6 +60,7 @@ config MMC_VERBOSE
 
 config SPL_MMC_VERBOSE
 	bool "Output more information about the MMC in SPL"
+	depends on SPL_LIBCOMMON_SUPPORT
 	default n
 	help
 	  Enable the output of more information about the card such as the
drivers/mmc/mmc.c +0 -0
index 13979a5..af303b3 100644

drivers/mmc/mmc.c line 29

Quoted 8 lines
drivers/mmc/mmc.c +5 -0
@@ -22,6 +22,12 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+#if CONFIG_IS_ENABLED(MMC_VERBOSE)
+#define error printf
+#else
+#define error(...)
+#endif

Lets switch to pr_XXX so that we can make use of the normal log level tweaking to keep / drop these, thanks!

Signature · 8 lines
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/20171129/62f32748/attachment.sig>
#13 lore raw

PATCH v4 8/10 mmc: make UHS and HS200 optional

In reply to Jean-Jacques Hiblot

Supporting USH and HS200 increases the code size as it brings in IO voltage control, tuning and fatter data structures.
Use Kconfig configuration to select which of those features should be built in.

---
 drivers/mmc/Kconfig      | 46 +++++++++++++++++++++++++++++++++++
 drivers/mmc/mmc-uclass.c |  4 +++
 drivers/mmc/mmc.c        | 63 +++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h            | 27 ++++++++++++++++++---
 4 files changed, 135 insertions(+), 5 deletions(-)
drivers/mmc/Kconfig +46 -0
index 7a45d4b..63d7f08 100644
@@ -51,6 +51,52 @@ config MMC_QUIRKS
 	  are enabled by default, other may require additionnal flags or are
 	  enabled by the host driver.
 
+config MMC_UHS_SUPPORT
+	bool "enable UHS support"
+	depends on MMC_IO_VOLTAGE
+	help
+	  The Ultra High Speed (UHS) bus is available on some SDHC and SDXC
+	  cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus
+	  frequency can go up to 208MHz (SDR104)
+
+config SPL_MMC_UHS_SUPPORT
+	bool "enable UHS support in SPL"
+	depends on SPL_MMC_IO_VOLTAGE
+	help
+	  The Ultra High Speed (UHS) bus is available on some SDHC and SDXC
+	  cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus
+	  frequency can go up to 208MHz (SDR104)
+
+config MMC_HS200_SUPPORT
+	bool "enable HS200 support"
+	help
+	  The HS200 mode is support by some eMMC. The bus frequency is up to
+	  200MHz. This mode requires tuning the IO.
+
+
+config SPL_MMC_HS200_SUPPORT
+	bool "enable HS200 support in SPL"
+	help
+	  The HS200 mode is support by some eMMC. The bus frequency is up to
+	  200MHz. This mode requires tuning the IO.
+
+config MMC_IO_VOLTAGE
+	bool "Support IO voltage configuration"
+	help
+	  IO voltage configuration allows selecting the voltage level of the IO
+	  lines (not the level of main supply). This is required for UHS
+	  support. For eMMC this not mandatory, but not enabling this option may
+	  prevent the driver of using the faster modes.
+
+config SPL_MMC_IO_VOLTAGE
+	bool "Support IO voltage configuration in SPL"
+	default n
+	help
+	  IO voltage configuration allows selecting the voltage level of the IO
+	  lines (not the level of main supply). This is required for UHS
+	  support. For eMMC this not mandatory, but not enabling this option may
+	  prevent the driver of using the faster modes.
+
 config MMC_VERBOSE
 	bool "Output more information about the MMC"
 	default y
drivers/mmc/mmc-uclass.c +4 -0
index bfda942..793196b 100644
@@ -63,6 +63,7 @@ void mmc_send_init_stream(struct mmc *mmc)
 	dm_mmc_send_init_stream(mmc->dev);
 }
 
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout)
 {
 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
@@ -76,6 +77,7 @@ int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
 {
 	return dm_mmc_wait_dat0(mmc->dev, state, timeout);
 }
+#endif
 
 int dm_mmc_get_wp(struct udevice *dev)
 {
@@ -105,6 +107,7 @@ int mmc_getcd(struct mmc *mmc)
 	return dm_mmc_get_cd(mmc->dev);
 }
 
+#ifdef MMC_SUPPORTS_TUNING
 int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
 {
 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
@@ -118,6 +121,7 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode)
 {
 	return dm_mmc_execute_tuning(mmc->dev, opcode);
 }
+#endif
 
 int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
 {
drivers/mmc/mmc.c +62 -1

249 lines not on this page · raw message

include/mmc.h +23 -4
index e3f777f..e89ba95 100644
@@ -15,6 +15,13 @@
 #include <linux/compiler.h>
 #include <part.h>
 
+#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+#define MMC_SUPPORTS_TUNING
+#endif
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
+#define MMC_SUPPORTS_TUNING
+#endif
+
 /* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */
 #define SD_VERSION_SD	(1U << 31)
 #define MMC_VERSION_MMC	(1U << 30)
@@ -425,6 +432,7 @@ struct dm_mmc_ops {
 	 */
 	int (*get_wp)(struct udevice *dev);
 
+#ifdef MMC_SUPPORTS_TUNING
 	/**
 	 * execute_tuning() - Start the tuning process
 	 *
@@ -433,7 +441,9 @@ struct dm_mmc_ops {
 	 * @return 0 if OK, -ve on error
 	 */
 	int (*execute_tuning)(struct udevice *dev, uint opcode);
+#endif
 
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 	/**
 	 * wait_dat0() - wait until dat0 is in the target state
 	 *		(CLK must be running during the wait)
@@ -444,6 +454,7 @@ struct dm_mmc_ops {
 	 * @return 0 if dat0 is in the target state, -ve on error
 	 */
 	int (*wait_dat0)(struct udevice *dev, int state, int timeout);
+#endif
 };
 
 #define mmc_get_ops(dev)        ((struct dm_mmc_ops *)(dev)->driver->ops)
@@ -500,13 +511,13 @@ enum bus_mode {
 	SD_LEGACY,
 	MMC_HS,
 	SD_HS,
+	MMC_HS_52,
+	MMC_DDR_52,
 	UHS_SDR12,
 	UHS_SDR25,
 	UHS_SDR50,
-	UHS_SDR104,
 	UHS_DDR50,
-	MMC_HS_52,
-	MMC_DDR_52,
+	UHS_SDR104,
 	MMC_HS_200,
 	MMC_MODES_END
 };
@@ -516,8 +527,12 @@ void mmc_dump_capabilities(const char *text, uint caps);
 
 static inline bool mmc_is_mode_ddr(enum bus_mode mode)
 {
-	if ((mode == MMC_DDR_52) || (mode == UHS_DDR50))
+	if (mode == MMC_DDR_52)
+		return true;
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
+	else if (mode == UHS_DDR50)
 		return true;
+#endif
 	else
 		return false;
 }
@@ -528,7 +543,11 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode)
 
 static inline bool supports_uhs(uint caps)
 {
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 	return (caps & UHS_CAPS) ? true : false;
+#else
+	return false;
+#endif
 }
 
 /*
Signature · 1 line
1.9.1
#14 lore raw

PATCH v4 8/10 mmc: make UHS and HS200 optional

Hi Jean-Jacques,

Quoted 5 lines · Jean-Jacques Hiblot

Supporting USH and HS200 increases the code size as it brings in IO voltage control, tuning and fatter data structures.
Use Kconfig configuration to select which of those features should be built in.

Quoted 7 lines
---
 drivers/mmc/Kconfig      | 46 +++++++++++++++++++++++++++++++++++
 drivers/mmc/mmc-uclass.c |  4 +++
 drivers/mmc/mmc.c        | 63 +++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h            | 27 ++++++++++++++++++---
 4 files changed, 135 insertions(+), 5 deletions(-)

A few things:

- Can these default to on? I think going fast is best, and reducing functionality can be an option
- Can you use if (IS_ENABLED) instead of #if within functions?

Regards,
Simon

#15 lore raw

PATCH v4 8/10 mmc: make UHS and HS200 optional

Quoted 15 lines · Simon Glass

Hi Jean-Jacques,

Quoted 5 lines · Jean-Jacques Hiblot

Supporting USH and HS200 increases the code size as it brings in IO voltage control, tuning and fatter data structures.
Use Kconfig configuration to select which of those features should be built in.

Quoted 7 lines
---
  drivers/mmc/Kconfig      | 46 +++++++++++++++++++++++++++++++++++
  drivers/mmc/mmc-uclass.c |  4 +++
  drivers/mmc/mmc.c        | 63 +++++++++++++++++++++++++++++++++++++++++++++++-
  include/mmc.h            | 27 ++++++++++++++++++---
  4 files changed, 135 insertions(+), 5 deletions(-)
Quoted 4 lines

A few things:

- Can these default to on? I think going fast is best, and reducing functionality can be an option

This is conservative decision. The patches are less likely to break untested platforms if this is not enabled if only because of the increased footprint.
Most platforms won't benefit from it at first because the host driver has to implement a few more callbacks to support those modes. We can always default to 'y' later when more host support this.

Quoted 1 line

- Can you use if (IS_ENABLED) instead of #if within functions?

I wasn't sure about the ability of the compiler to always throw away unused code this way. I'll give it a try.

Quoted 4 lines

Regards,
Simon

#16 lore raw

PATCH v4 9/10 mmc: make optional the support for eMMMC hardware partitioning

In reply to Jean-Jacques Hiblot

Not all boards have an eMMC and not all users have a need for this. Allow to compile it out. By default it is still included.

---
 cmd/mmc.c           | 4 ++++
 drivers/mmc/Kconfig | 7 +++++++
 drivers/mmc/mmc.c   | 2 ++
 3 files changed, 13 insertions(+)
cmd/mmc.c +4 -0
index 25795e0..9a95293 100644
@@ -438,6 +438,7 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
 	return CMD_RET_SUCCESS;
 }
 
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
 static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
 			     int argc, char * const argv[])
 {
@@ -587,6 +588,7 @@ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
 		return CMD_RET_FAILURE;
 	}
 }
+#endif
 
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
 static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
@@ -796,7 +798,9 @@ static cmd_tbl_t cmd_mmc[] = {
 	U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
 	U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
 	U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
 	U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
+#endif
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
 	U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
 	U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
drivers/mmc/Kconfig +7 -0
index 63d7f08..831d6ae 100644
@@ -51,6 +51,13 @@ config MMC_QUIRKS
 	  are enabled by default, other may require additionnal flags or are
 	  enabled by the host driver.
 
+config MMC_HW_PARTITIONING
+	bool "Support for HW partitioning command(eMMC)"
+	default y
+	help
+	  This adds a command and an API to do hardware partitioning on eMMC
+	  devices.
+
 config MMC_UHS_SUPPORT
 	bool "enable UHS support"
 	depends on MMC_IO_VOLTAGE
drivers/mmc/mmc.c +2 -0
index b6d3f96..bb89542 100644
@@ -948,6 +948,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 	return ret;
 }
 
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
 int mmc_hwpart_config(struct mmc *mmc,
 		      const struct mmc_hwpart_conf *conf,
 		      enum mmc_hwpart_conf_mode mode)
@@ -1141,6 +1142,7 @@ int mmc_hwpart_config(struct mmc *mmc,
 
 	return 0;
 }
+#endif
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
 int mmc_getcd(struct mmc *mmc)
Signature · 1 line
1.9.1
#17 lore raw

PATCH v4 9/10 mmc: make optional the support for eMMMC hardware partitioning

Quoted 4 lines · Jean-Jacques Hiblot

Not all boards have an eMMC and not all users have a need for this. Allow to compile it out. By default it is still included.

Seems good, subject is "eMMMC" however, thanks!

Signature · 8 lines
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/20171129/13116ee1/attachment.sig>