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

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;

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

Hi Terry,
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
Finally I think that it is enough to apply the following patch in order to fix the issue.
Regards, Raffaele
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 3819fcf..1dfbab9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -538,9 +538,6 @@ int mmc_change_freq(struct mmc *mmc) if (err) return err;
- if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) - mmc->high_capacity = 1; - cardtype = ext_csd[196] & 0xf;
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
--
participants (2)
-
Raffaele Recalcati
-
Terry Lv