[U-Boot] [PATCH v3 16/18] mmc: extend the mmc hardware partitioning API with write reliability

Diego Santa Cruz Diego.SantaCruz at spinetix.com
Mon Dec 15 10:27:19 CET 2014


The eMMC partition write reliability settings are to be set while
partitioning a device, as per the eMMC spec, so changes to these
attributes needs to be done in the hardware partitioning API.
This commit adds such support.

Signed-off-by: Diego Santa Cruz <Diego.SantaCruz at spinetix.com>
---
 drivers/mmc/mmc.c |   39 +++++++++++++++++++++++++++++++++++++++
 include/mmc.h     |   13 ++++++++++++-
 2 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 058f347..643a622 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -615,6 +615,7 @@ int mmc_hwpart_config(struct mmc *mmc,
 	u32 gp_size_mult[4];
 	u32 max_enh_size_mult;
 	u32 tot_enh_size_mult = 0;
+	u8 wr_rel_set;
 	int i, pidx, err;
 	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
 
@@ -689,6 +690,33 @@ int mmc_hwpart_config(struct mmc *mmc,
 		return -EMEDIUMTYPE;
 	}
 
+	/* The default value of EXT_CSD_WR_REL_SET is device
+	 * dependent, the values can only be changed if the
+	 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
+	 * changed only once and before partitioning is completed. */
+	wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
+	if (conf->user.wr_rel_change) {
+		if (conf->user.wr_rel_set)
+			wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
+		else
+			wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
+	}
+	for (pidx = 0; pidx < 4; pidx++) {
+		if (conf->gp_part[pidx].wr_rel_change) {
+			if (conf->gp_part[pidx].wr_rel_set)
+				wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
+			else
+				wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
+		}
+	}
+
+	if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
+	    !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
+		puts("Card does not support host controlled partition write "
+		     "reliability settings\n");
+		return -EMEDIUMTYPE;
+	}
+
 	if (ext_csd[EXT_CSD_PART_SETTING_COMPLETED] & PART_SETTING_COMPLETED) {
 		printf("Card already partitioned\n");
 		return -EPERM;
@@ -745,6 +773,17 @@ int mmc_hwpart_config(struct mmc *mmc,
 	if (mode == MMC_HWPART_CONF_SET)
 		return 0;
 
+	/* The WR_REL_SET is a write-once register but shall be
+	 * written before setting PART_SETTING_COMPLETED. As it is
+	 * write-once we can only write it when completing the
+	 * partitioning. */
+	if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
+		err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_WR_REL_SET, wr_rel_set);
+		if (err)
+			return err;
+	}
+
 	/* Setting PART_SETTING_COMPLETED confirms the partition
 	 * configuration but it only becomes effective after power
 	 * cycle, so we do not adjust the partition related settings
diff --git a/include/mmc.h b/include/mmc.h
index 9f9e6f7..b024f1c 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -154,6 +154,8 @@
 #define EXT_CSD_MAX_ENH_SIZE_MULT	157	/* R */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
+#define EXT_CSD_WR_REL_PARAM		166	/* R */
+#define EXT_CSD_WR_REL_SET		167	/* R/W */
 #define EXT_CSD_RPMB_MULT		168	/* RO */
 #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
 #define EXT_CSD_BOOT_BUS_WIDTH		177
@@ -204,6 +206,11 @@
 #define EXT_CSD_ENH_USR		(1 << 0)	/* user data area is enhanced */
 #define EXT_CSD_ENH_GP(x)	(1 << ((x)+1))	/* GP part (x+1) is enhanced */
 
+#define EXT_CSD_HS_CTRL_REL	(1 << 0)	/* host controlled WR_REL_SET */
+
+#define EXT_CSD_WR_DATA_REL_USR		(1 << 0)	/* user data area WR_REL */
+#define EXT_CSD_WR_DATA_REL_GP(x)	(1 << ((x)+1))	/* GP part (x+1) WR_REL */
+
 #define R1_ILLEGAL_COMMAND		(1 << 22)
 #define R1_APP_CMD			(1 << 5)
 
@@ -334,10 +341,14 @@ struct mmc_hwpart_conf {
 	struct {
 		uint enh_start;	/* in 512-byte sectors */
 		uint enh_size;	/* in 512-byte sectors, if 0 no enh area */
+		unsigned wr_rel_change : 1;
+		unsigned wr_rel_set : 1;
 	} user;
 	struct {
 		uint size;	/* in 512-byte sectors */
-		int enhanced;
+		unsigned enhanced : 1;
+		unsigned wr_rel_change : 1;
+		unsigned wr_rel_set : 1;
 	} gp_part[4];
 };
 
-- 
1.7.1



More information about the U-Boot mailing list