1 From 04e98be5c3950fbe18db6cb6533c0695f23a72d7 Mon Sep 17 00:00:00 2001
2 From: Terry Lv <r65388@freescale.com>
3 Date: Wed, 25 Nov 2009 19:20:41 +0800
4 Subject: [PATCH] ENGR00118751: Some mmc card can't read and write from right offset.
6 Some mmc card can't read and write from right offset.
7 Driver see these card as high capacity and use sector mode for them.
8 This will lead to read and write corrupt.
10 Signed-off-by: Terry Lv <r65388@freescale.com>
12 drivers/mmc/mmc.c | 59 +++++++++++++++++++++++++++++++++++++++++-----------
13 1 files changed, 46 insertions(+), 13 deletions(-)
15 diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
16 index f8510b2..f78b8a8 100644
17 --- a/drivers/mmc/mmc.c
18 +++ b/drivers/mmc/mmc.c
19 @@ -407,7 +407,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
21 int mmc_change_freq(struct mmc *mmc)
28 @@ -419,30 +419,42 @@ int mmc_change_freq(struct mmc *mmc)
30 mmc->card_caps |= MMC_MODE_4BIT;
32 + ext_csd = (char *)malloc(512);
35 + puts("Could not allocate buffer for MMC ext csd!\n");
39 err = mmc_send_ext_csd(mmc, ext_csd);
45 - if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
47 + if (ext_csd[EXT_CSD_SEC_CNT] ||
48 + ext_csd[EXT_CSD_SEC_CNT + 1] ||
49 + ext_csd[EXT_CSD_SEC_CNT + 2] ||
50 + ext_csd[EXT_CSD_SEC_CNT + 3])
51 mmc->high_capacity = 1;
54 - cardtype = ext_csd[196] & 0xf;
55 + cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
57 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
63 /* Now check to see that it worked */
64 err = mmc_send_ext_csd(mmc, ext_csd);
70 /* No high-speed support */
73 + if (!ext_csd[EXT_CSD_HS_TIMING])
76 /* High Speed is set, there are two types: 52MHz and 26MHz */
77 if (cardtype & MMC_HS_52MHZ)
78 @@ -450,7 +462,13 @@ int mmc_change_freq(struct mmc *mmc)
80 mmc->card_caps |= MMC_MODE_HS;
91 int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
92 @@ -720,14 +738,29 @@ int mmc_startup(struct mmc *mmc)
94 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
96 - if (mmc->high_capacity) {
98 + int csd_struct = (cmd.response[0] >> 30) & 0x3;
100 + switch (csd_struct) {
102 + csize = (mmc->csd[1] & 0x3f) << 16
103 + | (mmc->csd[2] & 0xffff0000) >> 16;
108 + if (0 != csd_struct)
109 + printf("unrecognised CSD structure version %d\n",
111 + csize = (mmc->csd[1] & 0x3ff) << 2
112 + | (mmc->csd[2] & 0xc0000000) >> 30;
113 + cmult = (mmc->csd[2] & 0x00038000) >> 15;
117 csize = (mmc->csd[1] & 0x3f) << 16
118 | (mmc->csd[2] & 0xffff0000) >> 16;
121 - csize = (mmc->csd[1] & 0x3ff) << 2
122 - | (mmc->csd[2] & 0xc0000000) >> 30;
123 - cmult = (mmc->csd[2] & 0x00038000) >> 15;
126 mmc->capacity = (csize + 1) << (cmult + 2);