All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/2] mmc: Fix capacity calculation and erase_group_size
@ 2013-10-01 18:32 Oliver Metz
  2013-10-01 18:32 ` [U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards Oliver Metz
  2013-10-01 18:32 ` [U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card Oliver Metz
  0 siblings, 2 replies; 5+ messages in thread
From: Oliver Metz @ 2013-10-01 18:32 UTC (permalink / raw)
  To: u-boot

These patches are addressing two issues that I had after activating
enhanced user area feature for a 4GB card so the capacity was less
than 2 GB afterwards.

1. The capacity for a high density device is calculated in a wrong way.
I was not able to find any hints for this implementation in JEDEC 4.41.
Anyhow, if we have ext_csd revision >= 2 we can use SEC_COUNT field to
calculate the size.

2. If we have a partitioned device, e.g. enhanced user area, the
ERASE_GROUP_DEF bit in ext_csd shall be set (see JEDEC 4.41,
chapter 7.2.3 Configure partitions). This bit defaults to "0" on power
on.

Oliver Metz (2):
  When using a high capacity card with a density less than 2 GB a wrong
    size is shown. According to JEDEC 4.41 there is no differentiation
    for C_SIZE register between low and high capacity cards
  EXT_CSD_ERASE_GROUP_DEF is lost every time after a reset or reboot.
    Set it if device has enhanced partitions.

 drivers/mmc/mmc.c | 49 +++++++++++++++++++++++--------------------------
 include/mmc.h     |  2 ++
 2 files changed, 25 insertions(+), 26 deletions(-)

-- 
1.8.4

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

* [U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards
  2013-10-01 18:32 [U-Boot] [PATCH 0/2] mmc: Fix capacity calculation and erase_group_size Oliver Metz
@ 2013-10-01 18:32 ` Oliver Metz
  2013-10-31  7:30   ` Pantelis Antoniou
  2013-10-01 18:32 ` [U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card Oliver Metz
  1 sibling, 1 reply; 5+ messages in thread
From: Oliver Metz @ 2013-10-01 18:32 UTC (permalink / raw)
  To: u-boot

 When using a high capacity card with a density less than
 2 GB a wrong size is calculated. According to JEDEC 4.41 there is no
 differentiation for C_SIZE register between low and high capacity cards.
 Use ext_csd sector count to calculate capacity instead.

Signed-off-by: Oliver Metz <oliver@freetz.org>
---
 drivers/mmc/mmc.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 84dae4d..ff11ff9 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -884,15 +884,9 @@ static int mmc_startup(struct mmc *mmc)
 	else
 		mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
 
-	if (mmc->high_capacity) {
-		csize = (mmc->csd[1] & 0x3f) << 16
-			| (mmc->csd[2] & 0xffff0000) >> 16;
-		cmult = 8;
-	} else {
-		csize = (mmc->csd[1] & 0x3ff) << 2
-			| (mmc->csd[2] & 0xc0000000) >> 30;
-		cmult = (mmc->csd[2] & 0x00038000) >> 15;
-	}
+	csize = (mmc->csd[1] & 0x3ff) << 2
+		| (mmc->csd[2] & 0xc0000000) >> 30;
+	cmult = (mmc->csd[2] & 0x00038000) >> 15;
 
 	mmc->capacity_user = (csize + 1) << (cmult + 2);
 	mmc->capacity_user *= mmc->read_bl_len;
@@ -927,18 +921,12 @@ static int mmc_startup(struct mmc *mmc)
 		/* check  ext_csd version and capacity */
 		err = mmc_send_ext_csd(mmc, ext_csd);
 		if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
-			/*
-			 * According to the JEDEC Standard, the value of
-			 * ext_csd's capacity is valid if the value is more
-			 * than 2GB
-			 */
 			capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
 					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
 					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
 					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
 			capacity *= MMC_MAX_BLOCK_LEN;
-			if ((capacity >> 20) > 2 * 1024)
-				mmc->capacity_user = capacity;
+			mmc->capacity_user = capacity;
 		}
 
 		switch (ext_csd[EXT_CSD_REV]) {
-- 
1.8.4

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

* [U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card
  2013-10-01 18:32 [U-Boot] [PATCH 0/2] mmc: Fix capacity calculation and erase_group_size Oliver Metz
  2013-10-01 18:32 ` [U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards Oliver Metz
@ 2013-10-01 18:32 ` Oliver Metz
  2013-10-31  7:47   ` Pantelis Antoniou
  1 sibling, 1 reply; 5+ messages in thread
From: Oliver Metz @ 2013-10-01 18:32 UTC (permalink / raw)
  To: u-boot

 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

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

* [U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards
  2013-10-01 18:32 ` [U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards Oliver Metz
@ 2013-10-31  7:30   ` Pantelis Antoniou
  0 siblings, 0 replies; 5+ messages in thread
From: Pantelis Antoniou @ 2013-10-31  7:30 UTC (permalink / raw)
  To: u-boot

Hi Oliver,

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

> When using a high capacity card with a density less than
> 2 GB a wrong size is calculated. According to JEDEC 4.41 there is no
> differentiation for C_SIZE register between low and high capacity cards.
> Use ext_csd sector count to calculate capacity instead.
> 
> Signed-off-by: Oliver Metz <oliver@freetz.org>
> ---
> drivers/mmc/mmc.c | 20 ++++----------------
> 1 file changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 84dae4d..ff11ff9 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -884,15 +884,9 @@ static int mmc_startup(struct mmc *mmc)
> 	else
> 		mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
> 
> -	if (mmc->high_capacity) {
> -		csize = (mmc->csd[1] & 0x3f) << 16
> -			| (mmc->csd[2] & 0xffff0000) >> 16;
> -		cmult = 8;
> -	} else {
> -		csize = (mmc->csd[1] & 0x3ff) << 2
> -			| (mmc->csd[2] & 0xc0000000) >> 30;
> -		cmult = (mmc->csd[2] & 0x00038000) >> 15;
> -	}
> +	csize = (mmc->csd[1] & 0x3ff) << 2
> +		| (mmc->csd[2] & 0xc0000000) >> 30;
> +	cmult = (mmc->csd[2] & 0x00038000) >> 15;
> 
> 	mmc->capacity_user = (csize + 1) << (cmult + 2);
> 	mmc->capacity_user *= mmc->read_bl_len;
> @@ -927,18 +921,12 @@ static int mmc_startup(struct mmc *mmc)
> 		/* check  ext_csd version and capacity */
> 		err = mmc_send_ext_csd(mmc, ext_csd);
> 		if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
> -			/*
> -			 * According to the JEDEC Standard, the value of
> -			 * ext_csd's capacity is valid if the value is more
> -			 * than 2GB
> -			 */
> 			capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
> 					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
> 					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
> 					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
> 			capacity *= MMC_MAX_BLOCK_LEN;
> -			if ((capacity >> 20) > 2 * 1024)
> -				mmc->capacity_user = capacity;
> +			mmc->capacity_user = capacity;
> 		}
> 
> 		switch (ext_csd[EXT_CSD_REV]) {
> -- 
> 1.8.4
> 

Something's not right with this:

> U-Boot SPL 2013.10-00105-g2ea5f3f (Oct 31 2013 - 09:24:02)
> reading args
> MMC: block number 0x15c exceeds max(0x100)
> spl: error reading image args, err - -1
> reading u-boot.img
> MMC: block number 0x15c exceeds max(0x100)
> spl: error reading image u-boot.img, err - -1
> ### ERROR ### Please RESET the board ###
> 

This happens on beaglebone black for both external MMC card (Kingston 4GB)
and the internal eMMC part.

When I have some free time I'll try to debug this, but for the moment
the patch is rejected.

Regards

-- Pantelis

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

* [U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card
  2013-10-01 18:32 ` [U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card Oliver Metz
@ 2013-10-31  7:47   ` Pantelis Antoniou
  0 siblings, 0 replies; 5+ messages in thread
From: Pantelis Antoniou @ 2013-10-31  7:47 UTC (permalink / raw)
  To: u-boot

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>

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

end of thread, other threads:[~2013-10-31  7:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-01 18:32 [U-Boot] [PATCH 0/2] mmc: Fix capacity calculation and erase_group_size Oliver Metz
2013-10-01 18:32 ` [U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards Oliver Metz
2013-10-31  7:30   ` Pantelis Antoniou
2013-10-01 18:32 ` [U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card Oliver Metz
2013-10-31  7:47   ` Pantelis Antoniou

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.