mmc: extend the mmc hardware partitioning API with write reliability
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@spinetix.com>
This commit is contained in:
parent
c599f53b57
commit
8dda5b0e60
@ -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_PARTITION_SETTING] &
|
||||
EXT_CSD_PARTITION_SETTING_COMPLETED) {
|
||||
printf("Card already partitioned\n");
|
||||
@ -746,6 +774,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
|
||||
|
@ -155,6 +155,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
|
||||
@ -207,6 +209,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)
|
||||
|
||||
@ -337,10 +344,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];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user