]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - patches/0052-ENGR00118751-Some-mmc-card-can-t-read-and-write-fro.patch
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / patches / 0052-ENGR00118751-Some-mmc-card-can-t-read-and-write-fro.patch
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.
5
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.
9
10 Signed-off-by: Terry Lv <r65388@freescale.com>
11 ---
12  drivers/mmc/mmc.c |   59 +++++++++++++++++++++++++++++++++++++++++-----------
13  1 files changed, 46 insertions(+), 13 deletions(-)
14
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)
20  
21  int mmc_change_freq(struct mmc *mmc)
22  {
23 -       char ext_csd[512];
24 +       char *ext_csd;
25         char cardtype;
26         int err;
27  
28 @@ -419,30 +419,42 @@ int mmc_change_freq(struct mmc *mmc)
29  
30         mmc->card_caps |= MMC_MODE_4BIT;
31  
32 +       ext_csd = (char *)malloc(512);
33 +
34 +       if (!ext_csd) {
35 +               puts("Could not allocate buffer for MMC ext csd!\n");
36 +               return -1;
37 +       }
38 +
39         err = mmc_send_ext_csd(mmc, ext_csd);
40  
41         if (err)
42 -               return err;
43 +               goto err_rtn;
44  
45 -       if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
46 +/*
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;
52 +*/
53  
54 -       cardtype = ext_csd[196] & 0xf;
55 +       cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
56  
57         err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
58  
59         if (err)
60 -               return err;
61 +               goto err_rtn;
62  
63         /* Now check to see that it worked */
64         err = mmc_send_ext_csd(mmc, ext_csd);
65  
66         if (err)
67 -               return err;
68 +               goto err_rtn;
69  
70         /* No high-speed support */
71 -       if (!ext_csd[185])
72 -               return 0;
73 +       if (!ext_csd[EXT_CSD_HS_TIMING])
74 +               goto no_err_rtn;
75  
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)
79         else
80                 mmc->card_caps |= MMC_MODE_HS;
81  
82 +no_err_rtn:
83 +       free(ext_csd);
84         return 0;
85 +
86 +err_rtn:
87 +       free(ext_csd);
88 +       return err;
89  }
90  
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)
93         else
94                 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
95  
96 -       if (mmc->high_capacity) {
97 +       if (IS_SD(mmc)) {
98 +               int csd_struct = (cmd.response[0] >> 30) & 0x3;
99 +
100 +               switch (csd_struct) {
101 +               case 1:
102 +                       csize = (mmc->csd[1] & 0x3f) << 16
103 +                               | (mmc->csd[2] & 0xffff0000) >> 16;
104 +                       cmult = 8;
105 +                       break;
106 +               case 0:
107 +               default:
108 +                       if (0 != csd_struct)
109 +                               printf("unrecognised CSD structure version %d\n",
110 +                                               csd_struct);
111 +                       csize = (mmc->csd[1] & 0x3ff) << 2
112 +                               | (mmc->csd[2] & 0xc0000000) >> 30;
113 +                       cmult = (mmc->csd[2] & 0x00038000) >> 15;
114 +                       break;
115 +               }
116 +       } else {
117                 csize = (mmc->csd[1] & 0x3f) << 16
118                         | (mmc->csd[2] & 0xffff0000) >> 16;
119                 cmult = 8;
120 -       } else {
121 -               csize = (mmc->csd[1] & 0x3ff) << 2
122 -                       | (mmc->csd[2] & 0xc0000000) >> 30;
123 -               cmult = (mmc->csd[2] & 0x00038000) >> 15;
124         }
125  
126         mmc->capacity = (csize + 1) << (cmult + 2);
127 -- 
128 1.5.4.4
129