diff mbox

[U-Boot] MMC may wrongly regconize 2GB eMMC as high capacity

Message ID 1300687405-4078-1-git-send-email-r65388@freescale.com
State Superseded
Headers show

Commit Message

Terry Lv March 21, 2011, 6:03 a.m. UTC
MMC driver may wrongly regconize some 2GB eMMC as high capacity card.

This patch is based on the patch picked from community.

fc8a0985c2846292312556cba10b8a4182f55967
From: Hanumath Prasad <hanumath.prasad@stericsson.com>
Date: Tue, 10 Aug 2010 18:01:45 -0700
Subject: [PATCH] mmc: only set blockaddressed for > 2GiB cards

A non-zero value of SEC_COUNT does not indicate that the card is sector
addressed. According to the MMC specification, cards
with a densitygreater than 2GiB are sector addressed.

Signed-off-by: Terry Lv <r65388@freescale.com>
---
 drivers/mmc/mmc.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

Comments

Raffaele Recalcati March 23, 2011, 9:04 a.m. UTC | #1
Hi Terry,

On Mon, Mar 21, 2011 at 7:03 AM, Terry Lv <r65388@freescale.com> wrote:
> MMC driver may wrongly regconize some 2GB eMMC as high capacity card.
>
> This patch is based on the patch picked from community.
>
> fc8a0985c2846292312556cba10b8a4182f55967
> From: Hanumath Prasad <hanumath.prasad@stericsson.com>
> Date: Tue, 10 Aug 2010 18:01:45 -0700
> Subject: [PATCH] mmc: only set blockaddressed for > 2GiB cards
>
> A non-zero value of SEC_COUNT does not indicate that the card is sector
> addressed. According to the MMC specification, cards
> with a densitygreater than 2GiB are sector addressed.
>
> Signed-off-by: Terry Lv <r65388@freescale.com>
> ---
>  drivers/mmc/mmc.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 6805b33..6f97911 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -399,7 +399,9 @@ int mmc_change_freq(struct mmc *mmc)
>        if (err)
>                return err;
>
> -       if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
> +       /* Cards with density > 2GiB are sector addressed */
> +       if ((ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) &&
> +                       (mmc->capacity > (2u * 1024 * 1024 * 1024) / 512))
>                mmc->high_capacity = 1;
>
>        cardtype = ext_csd[196] & 0xf;
> --

I have applied your patch, but, with Toshiba v4.41 2GB it doesn't work,
because mmc->capacity is equal to 1962934272 and you are instead using
the block's number , not byte's number.
Changing the patch in the following way it works in my case.

-       if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
+       printf ("mmc->capacity = %lu\n", (long unsigned int)mmc->capacity);
+       if ((ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) &&
+               (mmc->capacity > (2u * 1024 * 1024 * 1024))) {
                mmc->high_capacity = 1;
+               printf("Setting high capacity\n");
+       }

Fixing that the situation is also better for me, in fact in my
situation I was not able to read 256KB starting from sector 8 (512
bytes size).
The card status reported ADDRESS_MISALIGN.
That happened because mmc_read_blocks was using high_capacity
addressing way, wrong for me.
I've also noticed that the capacity variable (expressed in number of
bytes) has to be re-calculated differently if <=2GB (high_capacity=0)
or if >2GB (high_capacity=1).
So capacity calculation depends on high_capacity.
But curiously high_capacity depends on capacity.
Not nice!
Looking at JEDEC Standard No. 84-A441 at the end of pag.42 we have to
use  mmc_send_op_cond.

So I guess:
mmc_init calls mmc_send_op_cond  that set  high_capacity,
than it calls mmc_startup, that, with MMC_CMD_SEND_CSD  command, set
the capacity, using values in CSD register.
So I guess that mmc_change_freq should not recalculate high_capacity.

It seems better, isn't it?

Regards,
Raffaele
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6805b33..6f97911 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -399,7 +399,9 @@  int mmc_change_freq(struct mmc *mmc)
 	if (err)
 		return err;
 
-	if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
+	/* Cards with density > 2GiB are sector addressed */
+	if ((ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) &&
+			(mmc->capacity > (2u * 1024 * 1024 * 1024) / 512))
 		mmc->high_capacity = 1;
 
 	cardtype = ext_csd[196] & 0xf;