Patchwork [U-Boot,2/2] mmc: Fix erase_grp_size for partitioned card

login
register
mail settings
Submitter Oliver Metz
Date Oct. 1, 2013, 6:32 p.m.
Message ID <1380652327-8688-3-git-send-email-oliver@freetz.org>
Download mbox | patch
Permalink /patch/279557/
State Accepted
Delegated to: Pantelis Antoniou
Headers show

Comments

Oliver Metz - Oct. 1, 2013, 6:32 p.m.
EXT_CSD_ERASE_GROUP_DEF is lost every time after a reset or
 power off. Set it if device has enhanced partitions.

Signed-off-by: Oliver Metz <oliver@freetz.org>
---
 drivers/mmc/mmc.c | 17 +++++++++++++----
 include/mmc.h     |  2 ++
 2 files changed, 15 insertions(+), 4 deletions(-)
Pantelis Antoniou - Oct. 31, 2013, 7:47 a.m.
Hi Oliver,

On Oct 1, 2013, at 9:32 PM, Oliver Metz wrote:

> EXT_CSD_ERASE_GROUP_DEF is lost every time after a reset or
> power off. Set it if device has enhanced partitions.
> 
> Signed-off-by: Oliver Metz <oliver@freetz.org>
> ---
> drivers/mmc/mmc.c | 17 +++++++++++++----
> include/mmc.h     |  2 ++
> 2 files changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index ff11ff9..17c6b11 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -948,15 +948,24 @@ static int mmc_startup(struct mmc *mmc)
> 		}
> 
> 		/*
> -		 * Check whether GROUP_DEF is set, if yes, read out
> -		 * group size from ext_csd directly, or calculate
> -		 * the group size from the csd value.
> +		 * Host needs to enable ERASE_GRP_DEF bit if device is
> +		 * partitioned. This bit will be lost every time after a reset
> +		 * or power off. This will affect erase size.
> 		 */
> -		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
> +		if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
> +		    (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
> +			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> +				EXT_CSD_ERASE_GROUP_DEF, 1);
> +
> +			if (err)
> +				return err;
> +
> +			/* Read out group size from ext_csd */
> 			mmc->erase_grp_size =
> 				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
> 					MMC_MAX_BLOCK_LEN * 1024;
> 		} else {
> +			/* Calculate the group size from the csd value. */
> 			int erase_gsz, erase_gmul;
> 			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
> 			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
> diff --git a/include/mmc.h b/include/mmc.h
> index 214b9ed..cb558da 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -148,6 +148,7 @@
>  * EXT_CSD fields
>  */
> #define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
> +#define EXT_CSD_PARTITIONS_ATTRIBUTE	156	/* R/W */
> #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
> #define EXT_CSD_RPMB_MULT		168	/* RO */
> #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
> @@ -210,6 +211,7 @@
> #define MMCPART_NOAVAILABLE	(0xff)
> #define PART_ACCESS_MASK	(0x7)
> #define PART_SUPPORT		(0x1)
> +#define PART_ENH_ATTRIB		(0x1f)
> 
> /* Maximum block size for MMC */
> #define MMC_MAX_BLOCK_LEN	512
> -- 
> 1.8.4
> 

Applied, thanks.

Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ff11ff9..17c6b11 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -948,15 +948,24 @@  static int mmc_startup(struct mmc *mmc)
 		}
 
 		/*
-		 * Check whether GROUP_DEF is set, if yes, read out
-		 * group size from ext_csd directly, or calculate
-		 * the group size from the csd value.
+		 * Host needs to enable ERASE_GRP_DEF bit if device is
+		 * partitioned. This bit will be lost every time after a reset
+		 * or power off. This will affect erase size.
 		 */
-		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
+		if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
+		    (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
+			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+				EXT_CSD_ERASE_GROUP_DEF, 1);
+
+			if (err)
+				return err;
+
+			/* Read out group size from ext_csd */
 			mmc->erase_grp_size =
 				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
 					MMC_MAX_BLOCK_LEN * 1024;
 		} else {
+			/* Calculate the group size from the csd value. */
 			int erase_gsz, erase_gmul;
 			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
 			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
diff --git a/include/mmc.h b/include/mmc.h
index 214b9ed..cb558da 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -148,6 +148,7 @@ 
  * EXT_CSD fields
  */
 #define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
+#define EXT_CSD_PARTITIONS_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_RPMB_MULT		168	/* RO */
 #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
@@ -210,6 +211,7 @@ 
 #define MMCPART_NOAVAILABLE	(0xff)
 #define PART_ACCESS_MASK	(0x7)
 #define PART_SUPPORT		(0x1)
+#define PART_ENH_ATTRIB		(0x1f)
 
 /* Maximum block size for MMC */
 #define MMC_MAX_BLOCK_LEN	512