xref: /nrf52832-nimble/rt-thread/components/drivers/sdio/mmc.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  *
4*10465441SEvalZero  * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero  *
6*10465441SEvalZero  * Change Logs:
7*10465441SEvalZero  * Date           Author        Notes
8*10465441SEvalZero  * 2015-06-15     hichard     first version
9*10465441SEvalZero  */
10*10465441SEvalZero 
11*10465441SEvalZero #include <drivers/mmcsd_core.h>
12*10465441SEvalZero #include <drivers/mmc.h>
13*10465441SEvalZero 
14*10465441SEvalZero #define DBG_ENABLE
15*10465441SEvalZero #define DBG_SECTION_NAME               "SDIO"
16*10465441SEvalZero #ifdef RT_SDIO_DEBUG
17*10465441SEvalZero #define DBG_LEVEL                      DBG_LOG
18*10465441SEvalZero #else
19*10465441SEvalZero #define DBG_LEVEL                      DBG_INFO
20*10465441SEvalZero #endif /* RT_SDIO_DEBUG */
21*10465441SEvalZero #define DBG_COLOR
22*10465441SEvalZero #include <rtdbg.h>
23*10465441SEvalZero 
24*10465441SEvalZero static const rt_uint32_t tran_unit[] =
25*10465441SEvalZero {
26*10465441SEvalZero     10000, 100000, 1000000, 10000000,
27*10465441SEvalZero     0,     0,      0,       0
28*10465441SEvalZero };
29*10465441SEvalZero 
30*10465441SEvalZero static const rt_uint8_t tran_value[] =
31*10465441SEvalZero {
32*10465441SEvalZero     0,  10, 12, 13, 15, 20, 25, 30,
33*10465441SEvalZero     35, 40, 45, 50, 55, 60, 70, 80,
34*10465441SEvalZero };
35*10465441SEvalZero 
36*10465441SEvalZero static const rt_uint32_t tacc_uint[] =
37*10465441SEvalZero {
38*10465441SEvalZero     1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
39*10465441SEvalZero };
40*10465441SEvalZero 
41*10465441SEvalZero static const rt_uint8_t tacc_value[] =
42*10465441SEvalZero {
43*10465441SEvalZero     0,  10, 12, 13, 15, 20, 25, 30,
44*10465441SEvalZero     35, 40, 45, 50, 55, 60, 70, 80,
45*10465441SEvalZero };
46*10465441SEvalZero 
GET_BITS(rt_uint32_t * resp,rt_uint32_t start,rt_uint32_t size)47*10465441SEvalZero rt_inline rt_uint32_t GET_BITS(rt_uint32_t *resp,
48*10465441SEvalZero                                rt_uint32_t  start,
49*10465441SEvalZero                                rt_uint32_t  size)
50*10465441SEvalZero {
51*10465441SEvalZero         const rt_int32_t __size = size;
52*10465441SEvalZero         const rt_uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1;
53*10465441SEvalZero         const rt_int32_t __off = 3 - ((start) / 32);
54*10465441SEvalZero         const rt_int32_t __shft = (start) & 31;
55*10465441SEvalZero         rt_uint32_t __res;
56*10465441SEvalZero 
57*10465441SEvalZero         __res = resp[__off] >> __shft;
58*10465441SEvalZero         if (__size + __shft > 32)
59*10465441SEvalZero             __res |= resp[__off-1] << ((32 - __shft) % 32);
60*10465441SEvalZero 
61*10465441SEvalZero         return __res & __mask;
62*10465441SEvalZero }
63*10465441SEvalZero 
64*10465441SEvalZero /*
65*10465441SEvalZero  * Given a 128-bit response, decode to our card CSD structure.
66*10465441SEvalZero  */
mmcsd_parse_csd(struct rt_mmcsd_card * card)67*10465441SEvalZero static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card)
68*10465441SEvalZero {
69*10465441SEvalZero       rt_uint32_t a, b;
70*10465441SEvalZero       struct rt_mmcsd_csd *csd = &card->csd;
71*10465441SEvalZero       rt_uint32_t *resp = card->resp_csd;
72*10465441SEvalZero 
73*10465441SEvalZero       /*
74*10465441SEvalZero       * We only understand CSD structure v1.1 and v1.2.
75*10465441SEvalZero       * v1.2 has extra information in bits 15, 11 and 10.
76*10465441SEvalZero       * We also support eMMC v4.4 & v4.41.
77*10465441SEvalZero       */
78*10465441SEvalZero       csd->csd_structure = GET_BITS(resp, 126, 2);
79*10465441SEvalZero       if (csd->csd_structure == 0) {
80*10465441SEvalZero         LOG_E("unrecognised CSD structure version %d!", csd->csd_structure);
81*10465441SEvalZero 
82*10465441SEvalZero         return -RT_ERROR;
83*10465441SEvalZero       }
84*10465441SEvalZero 
85*10465441SEvalZero       csd->taac = GET_BITS(resp, 112, 8);
86*10465441SEvalZero       csd->nsac = GET_BITS(resp, 104, 8);
87*10465441SEvalZero       csd->tran_speed = GET_BITS(resp, 96, 8);
88*10465441SEvalZero       csd->card_cmd_class = GET_BITS(resp, 84, 12);
89*10465441SEvalZero       csd->rd_blk_len = GET_BITS(resp, 80, 4);
90*10465441SEvalZero       csd->rd_blk_part = GET_BITS(resp, 79, 1);
91*10465441SEvalZero       csd->wr_blk_misalign = GET_BITS(resp, 78, 1);
92*10465441SEvalZero       csd->rd_blk_misalign = GET_BITS(resp, 77, 1);
93*10465441SEvalZero       csd->dsr_imp = GET_BITS(resp, 76, 1);
94*10465441SEvalZero       csd->c_size = GET_BITS(resp, 62, 12);
95*10465441SEvalZero       csd->c_size_mult = GET_BITS(resp, 47, 3);
96*10465441SEvalZero       csd->r2w_factor = GET_BITS(resp, 26, 3);
97*10465441SEvalZero       csd->wr_blk_len = GET_BITS(resp, 22, 4);
98*10465441SEvalZero       csd->wr_blk_partial = GET_BITS(resp, 21, 1);
99*10465441SEvalZero       csd->csd_crc = GET_BITS(resp, 1, 7);
100*10465441SEvalZero 
101*10465441SEvalZero       card->card_blksize = 1 << csd->rd_blk_len;
102*10465441SEvalZero       card->tacc_clks = csd->nsac * 100;
103*10465441SEvalZero       card->tacc_ns = (tacc_uint[csd->taac&0x07] * tacc_value[(csd->taac&0x78)>>3] + 9) / 10;
104*10465441SEvalZero       card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3];
105*10465441SEvalZero       if (csd->wr_blk_len >= 9) {
106*10465441SEvalZero         a = GET_BITS(resp, 42, 5);
107*10465441SEvalZero         b = GET_BITS(resp, 37, 5);
108*10465441SEvalZero         card->erase_size = (a + 1) * (b + 1);
109*10465441SEvalZero         card->erase_size <<= csd->wr_blk_len - 9;
110*10465441SEvalZero       }
111*10465441SEvalZero 
112*10465441SEvalZero       return 0;
113*10465441SEvalZero }
114*10465441SEvalZero 
115*10465441SEvalZero /*
116*10465441SEvalZero  * Read extended CSD.
117*10465441SEvalZero  */
mmc_get_ext_csd(struct rt_mmcsd_card * card,rt_uint8_t ** new_ext_csd)118*10465441SEvalZero static int mmc_get_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t **new_ext_csd)
119*10465441SEvalZero {
120*10465441SEvalZero   void *ext_csd;
121*10465441SEvalZero   struct rt_mmcsd_req req;
122*10465441SEvalZero   struct rt_mmcsd_cmd cmd;
123*10465441SEvalZero   struct rt_mmcsd_data data;
124*10465441SEvalZero 
125*10465441SEvalZero   *new_ext_csd = RT_NULL;
126*10465441SEvalZero 
127*10465441SEvalZero   if (GET_BITS(card->resp_cid, 122, 4) < 4)
128*10465441SEvalZero      return 0;
129*10465441SEvalZero 
130*10465441SEvalZero   /*
131*10465441SEvalZero   * As the ext_csd is so large and mostly unused, we don't store the
132*10465441SEvalZero   * raw block in mmc_card.
133*10465441SEvalZero   */
134*10465441SEvalZero   ext_csd = rt_malloc(512);
135*10465441SEvalZero   if (!ext_csd) {
136*10465441SEvalZero     LOG_E("alloc memory failed when get ext csd!");
137*10465441SEvalZero     return -RT_ENOMEM;
138*10465441SEvalZero   }
139*10465441SEvalZero 
140*10465441SEvalZero   rt_memset(&req, 0, sizeof(struct rt_mmcsd_req));
141*10465441SEvalZero   rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
142*10465441SEvalZero   rt_memset(&data, 0, sizeof(struct rt_mmcsd_data));
143*10465441SEvalZero 
144*10465441SEvalZero   req.cmd = &cmd;
145*10465441SEvalZero   req.data = &data;
146*10465441SEvalZero 
147*10465441SEvalZero   cmd.cmd_code = SEND_EXT_CSD;
148*10465441SEvalZero   cmd.arg = 0;
149*10465441SEvalZero 
150*10465441SEvalZero   /* NOTE HACK:  the RESP_SPI_R1 is always correct here, but we
151*10465441SEvalZero   * rely on callers to never use this with "native" calls for reading
152*10465441SEvalZero   * CSD or CID.  Native versions of those commands use the R2 type,
153*10465441SEvalZero   * not R1 plus a data block.
154*10465441SEvalZero   */
155*10465441SEvalZero   cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC;
156*10465441SEvalZero 
157*10465441SEvalZero   data.blksize = 512;
158*10465441SEvalZero   data.blks = 1;
159*10465441SEvalZero   data.flags = DATA_DIR_READ;
160*10465441SEvalZero   data.buf = ext_csd;
161*10465441SEvalZero 
162*10465441SEvalZero   /*
163*10465441SEvalZero   * Some cards require longer data read timeout than indicated in CSD.
164*10465441SEvalZero   * Address this by setting the read timeout to a "reasonably high"
165*10465441SEvalZero   * value. For the cards tested, 300ms has proven enough. If necessary,
166*10465441SEvalZero   * this value can be increased if other problematic cards require this.
167*10465441SEvalZero   */
168*10465441SEvalZero   data.timeout_ns = 300000000;
169*10465441SEvalZero   data.timeout_clks = 0;
170*10465441SEvalZero 
171*10465441SEvalZero   mmcsd_send_request(card->host, &req);
172*10465441SEvalZero 
173*10465441SEvalZero   if (cmd.err)
174*10465441SEvalZero     return cmd.err;
175*10465441SEvalZero   if (data.err)
176*10465441SEvalZero     return data.err;
177*10465441SEvalZero 
178*10465441SEvalZero   *new_ext_csd = ext_csd;
179*10465441SEvalZero   return 0;
180*10465441SEvalZero }
181*10465441SEvalZero 
182*10465441SEvalZero /*
183*10465441SEvalZero  * Decode extended CSD.
184*10465441SEvalZero  */
mmc_parse_ext_csd(struct rt_mmcsd_card * card,rt_uint8_t * ext_csd)185*10465441SEvalZero static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
186*10465441SEvalZero {
187*10465441SEvalZero   if(card == RT_NULL || ext_csd == RT_NULL)
188*10465441SEvalZero   {
189*10465441SEvalZero     LOG_E("emmc parse ext csd fail, invaild args");
190*10465441SEvalZero     return -1;
191*10465441SEvalZero   }
192*10465441SEvalZero 
193*10465441SEvalZero   card->flags |=  CARD_FLAG_HIGHSPEED;
194*10465441SEvalZero   card->hs_max_data_rate = 200000000;
195*10465441SEvalZero 
196*10465441SEvalZero   card->card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]);
197*10465441SEvalZero   card->card_capacity *= card->card_blksize;
198*10465441SEvalZero   card->card_capacity >>= 10; /* unit:KB */
199*10465441SEvalZero   LOG_I("emmc card capacity %d KB.", card->card_capacity);
200*10465441SEvalZero 
201*10465441SEvalZero   return 0;
202*10465441SEvalZero }
203*10465441SEvalZero 
204*10465441SEvalZero /**
205*10465441SEvalZero  *   mmc_switch - modify EXT_CSD register
206*10465441SEvalZero  *   @card: the MMC card associated with the data transfer
207*10465441SEvalZero  *   @set: cmd set values
208*10465441SEvalZero  *   @index: EXT_CSD register index
209*10465441SEvalZero  *   @value: value to program into EXT_CSD register
210*10465441SEvalZero  *
211*10465441SEvalZero  *   Modifies the EXT_CSD register for selected card.
212*10465441SEvalZero  */
mmc_switch(struct rt_mmcsd_card * card,rt_uint8_t set,rt_uint8_t index,rt_uint8_t value)213*10465441SEvalZero static int mmc_switch(struct rt_mmcsd_card *card, rt_uint8_t set,
214*10465441SEvalZero                       rt_uint8_t index, rt_uint8_t value)
215*10465441SEvalZero {
216*10465441SEvalZero   int err;
217*10465441SEvalZero   struct rt_mmcsd_host *host = card->host;
218*10465441SEvalZero   struct rt_mmcsd_cmd cmd = {0};
219*10465441SEvalZero 
220*10465441SEvalZero   cmd.cmd_code = SWITCH;
221*10465441SEvalZero   cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
222*10465441SEvalZero     (index << 16) | (value << 8) | set;
223*10465441SEvalZero   cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_AC;
224*10465441SEvalZero 
225*10465441SEvalZero   err = mmcsd_send_cmd(host, &cmd, 3);
226*10465441SEvalZero   if (err)
227*10465441SEvalZero     return err;
228*10465441SEvalZero 
229*10465441SEvalZero   return 0;
230*10465441SEvalZero }
231*10465441SEvalZero 
mmc_compare_ext_csds(struct rt_mmcsd_card * card,rt_uint8_t * ext_csd,rt_uint32_t bus_width)232*10465441SEvalZero static int mmc_compare_ext_csds(struct rt_mmcsd_card *card,
233*10465441SEvalZero                                 rt_uint8_t *ext_csd, rt_uint32_t bus_width)
234*10465441SEvalZero {
235*10465441SEvalZero   rt_uint8_t *bw_ext_csd;
236*10465441SEvalZero   int err;
237*10465441SEvalZero 
238*10465441SEvalZero   if (bus_width == MMCSD_BUS_WIDTH_1)
239*10465441SEvalZero     return 0;
240*10465441SEvalZero 
241*10465441SEvalZero   err = mmc_get_ext_csd(card, &bw_ext_csd);
242*10465441SEvalZero 
243*10465441SEvalZero   if (err || bw_ext_csd == RT_NULL) {
244*10465441SEvalZero     err = -RT_ERROR;
245*10465441SEvalZero     goto out;
246*10465441SEvalZero   }
247*10465441SEvalZero 
248*10465441SEvalZero   /* only compare read only fields */
249*10465441SEvalZero   err = !((ext_csd[EXT_CSD_PARTITION_SUPPORT] == bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
250*10465441SEvalZero           (ext_csd[EXT_CSD_ERASED_MEM_CONT] == bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
251*10465441SEvalZero           (ext_csd[EXT_CSD_REV] == bw_ext_csd[EXT_CSD_REV]) &&
252*10465441SEvalZero           (ext_csd[EXT_CSD_STRUCTURE] == bw_ext_csd[EXT_CSD_STRUCTURE]) &&
253*10465441SEvalZero           (ext_csd[EXT_CSD_CARD_TYPE] == bw_ext_csd[EXT_CSD_CARD_TYPE]) &&
254*10465441SEvalZero           (ext_csd[EXT_CSD_S_A_TIMEOUT] == bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) &&
255*10465441SEvalZero           (ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
256*10465441SEvalZero           (ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] == bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) &&
257*10465441SEvalZero           (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
258*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_TRIM_MULT] == bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) &&
259*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_ERASE_MULT] == bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) &&
260*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] == bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) &&
261*10465441SEvalZero           (ext_csd[EXT_CSD_TRIM_MULT] == bw_ext_csd[EXT_CSD_TRIM_MULT]) &&
262*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_CNT + 0] == bw_ext_csd[EXT_CSD_SEC_CNT + 0]) &&
263*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_CNT + 1] == bw_ext_csd[EXT_CSD_SEC_CNT + 1]) &&
264*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_CNT + 2] == bw_ext_csd[EXT_CSD_SEC_CNT + 2]) &&
265*10465441SEvalZero           (ext_csd[EXT_CSD_SEC_CNT + 3] == bw_ext_csd[EXT_CSD_SEC_CNT + 3]) &&
266*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_52_195] == bw_ext_csd[EXT_CSD_PWR_CL_52_195]) &&
267*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_26_195] == bw_ext_csd[EXT_CSD_PWR_CL_26_195]) &&
268*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_52_360] == bw_ext_csd[EXT_CSD_PWR_CL_52_360]) &&
269*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_26_360] == bw_ext_csd[EXT_CSD_PWR_CL_26_360]) &&
270*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_200_195] == bw_ext_csd[EXT_CSD_PWR_CL_200_195]) &&
271*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_200_360] == bw_ext_csd[EXT_CSD_PWR_CL_200_360]) &&
272*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_DDR_52_195] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
273*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_DDR_52_360] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) &&
274*10465441SEvalZero           (ext_csd[EXT_CSD_PWR_CL_DDR_200_360] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360]));
275*10465441SEvalZero 
276*10465441SEvalZero   if (err)
277*10465441SEvalZero      err = -RT_ERROR;
278*10465441SEvalZero 
279*10465441SEvalZero out:
280*10465441SEvalZero   rt_free(bw_ext_csd);
281*10465441SEvalZero   return err;
282*10465441SEvalZero }
283*10465441SEvalZero 
284*10465441SEvalZero /*
285*10465441SEvalZero  * Select the bus width amoung 4-bit and 8-bit(SDR).
286*10465441SEvalZero  * If the bus width is changed successfully, return the selected width value.
287*10465441SEvalZero  * Zero is returned instead of error value if the wide width is not supported.
288*10465441SEvalZero  */
mmc_select_bus_width(struct rt_mmcsd_card * card,rt_uint8_t * ext_csd)289*10465441SEvalZero static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
290*10465441SEvalZero {
291*10465441SEvalZero   rt_uint32_t ext_csd_bits[] = {
292*10465441SEvalZero     EXT_CSD_BUS_WIDTH_8,
293*10465441SEvalZero     EXT_CSD_BUS_WIDTH_4,
294*10465441SEvalZero     EXT_CSD_BUS_WIDTH_1
295*10465441SEvalZero   };
296*10465441SEvalZero   rt_uint32_t bus_widths[] = {
297*10465441SEvalZero     MMCSD_BUS_WIDTH_8,
298*10465441SEvalZero     MMCSD_BUS_WIDTH_4,
299*10465441SEvalZero     MMCSD_BUS_WIDTH_1
300*10465441SEvalZero   };
301*10465441SEvalZero   struct rt_mmcsd_host *host = card->host;
302*10465441SEvalZero   unsigned idx, bus_width = 0;
303*10465441SEvalZero   int err = 0;
304*10465441SEvalZero 
305*10465441SEvalZero   if (GET_BITS(card->resp_cid, 122, 4) < 4)
306*10465441SEvalZero      return 0;
307*10465441SEvalZero 
308*10465441SEvalZero   /*
309*10465441SEvalZero   * Unlike SD, MMC cards dont have a configuration register to notify
310*10465441SEvalZero   * supported bus width. So bus test command should be run to identify
311*10465441SEvalZero   * the supported bus width or compare the ext csd values of current
312*10465441SEvalZero   * bus width and ext csd values of 1 bit mode read earlier.
313*10465441SEvalZero   */
314*10465441SEvalZero   for (idx = 0; idx < sizeof(bus_widths)/sizeof(rt_uint32_t); idx++) {
315*10465441SEvalZero     /*
316*10465441SEvalZero     * Host is capable of 8bit transfer, then switch
317*10465441SEvalZero     * the device to work in 8bit transfer mode. If the
318*10465441SEvalZero     * mmc switch command returns error then switch to
319*10465441SEvalZero     * 4bit transfer mode. On success set the corresponding
320*10465441SEvalZero     * bus width on the host.
321*10465441SEvalZero     */
322*10465441SEvalZero     err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
323*10465441SEvalZero                      EXT_CSD_BUS_WIDTH,
324*10465441SEvalZero                      ext_csd_bits[idx]);
325*10465441SEvalZero     if (err)
326*10465441SEvalZero       continue;
327*10465441SEvalZero 
328*10465441SEvalZero     bus_width = bus_widths[idx];
329*10465441SEvalZero     mmcsd_set_bus_width(host, bus_width);
330*10465441SEvalZero     mmcsd_delay_ms(20); //delay 10ms
331*10465441SEvalZero     err = mmc_compare_ext_csds(card, ext_csd, bus_width);
332*10465441SEvalZero     if (!err) {
333*10465441SEvalZero       err = bus_width;
334*10465441SEvalZero       break;
335*10465441SEvalZero     } else {
336*10465441SEvalZero       switch(ext_csd_bits[idx]){
337*10465441SEvalZero           case 0:
338*10465441SEvalZero             LOG_E("switch to bus width 1 bit failed!");
339*10465441SEvalZero             break;
340*10465441SEvalZero           case 1:
341*10465441SEvalZero             LOG_E("switch to bus width 4 bit failed!");
342*10465441SEvalZero             break;
343*10465441SEvalZero           case 2:
344*10465441SEvalZero             LOG_E("switch to bus width 8 bit failed!");
345*10465441SEvalZero             break;
346*10465441SEvalZero           default:
347*10465441SEvalZero             break;
348*10465441SEvalZero       }
349*10465441SEvalZero     }
350*10465441SEvalZero   }
351*10465441SEvalZero 
352*10465441SEvalZero   return err;
353*10465441SEvalZero }
mmc_send_op_cond(struct rt_mmcsd_host * host,rt_uint32_t ocr,rt_uint32_t * rocr)354*10465441SEvalZero rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host,
355*10465441SEvalZero                           rt_uint32_t ocr, rt_uint32_t *rocr)
356*10465441SEvalZero {
357*10465441SEvalZero     struct rt_mmcsd_cmd cmd;
358*10465441SEvalZero     rt_uint32_t i;
359*10465441SEvalZero     rt_err_t err = RT_EOK;
360*10465441SEvalZero 
361*10465441SEvalZero     rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
362*10465441SEvalZero 
363*10465441SEvalZero     cmd.cmd_code = SEND_OP_COND;
364*10465441SEvalZero     cmd.arg = controller_is_spi(host) ? 0 : ocr;
365*10465441SEvalZero     cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR;
366*10465441SEvalZero 
367*10465441SEvalZero     for (i = 100; i; i--) {
368*10465441SEvalZero       err = mmcsd_send_cmd(host, &cmd, 3);
369*10465441SEvalZero       if (err)
370*10465441SEvalZero         break;
371*10465441SEvalZero 
372*10465441SEvalZero       /* if we're just probing, do a single pass */
373*10465441SEvalZero       if (ocr == 0)
374*10465441SEvalZero         break;
375*10465441SEvalZero 
376*10465441SEvalZero       /* otherwise wait until reset completes */
377*10465441SEvalZero       if (controller_is_spi(host)) {
378*10465441SEvalZero         if (!(cmd.resp[0] & R1_SPI_IDLE))
379*10465441SEvalZero           break;
380*10465441SEvalZero       } else {
381*10465441SEvalZero         if (cmd.resp[0] & CARD_BUSY)
382*10465441SEvalZero           break;
383*10465441SEvalZero       }
384*10465441SEvalZero 
385*10465441SEvalZero       err = -RT_ETIMEOUT;
386*10465441SEvalZero 
387*10465441SEvalZero       mmcsd_delay_ms(10); //delay 10ms
388*10465441SEvalZero     }
389*10465441SEvalZero 
390*10465441SEvalZero   if (rocr && !controller_is_spi(host))
391*10465441SEvalZero     *rocr = cmd.resp[0];
392*10465441SEvalZero 
393*10465441SEvalZero   return err;
394*10465441SEvalZero }
395*10465441SEvalZero 
mmc_set_card_addr(struct rt_mmcsd_host * host,rt_uint32_t rca)396*10465441SEvalZero static rt_err_t mmc_set_card_addr(struct rt_mmcsd_host *host, rt_uint32_t rca)
397*10465441SEvalZero {
398*10465441SEvalZero   rt_err_t err;
399*10465441SEvalZero   struct rt_mmcsd_cmd cmd;
400*10465441SEvalZero 
401*10465441SEvalZero   rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
402*10465441SEvalZero 
403*10465441SEvalZero   cmd.cmd_code = SET_RELATIVE_ADDR;
404*10465441SEvalZero   cmd.arg = rca << 16;
405*10465441SEvalZero   cmd.flags = RESP_R1 | CMD_AC;
406*10465441SEvalZero 
407*10465441SEvalZero   err = mmcsd_send_cmd(host, &cmd, 3);
408*10465441SEvalZero   if (err)
409*10465441SEvalZero     return err;
410*10465441SEvalZero 
411*10465441SEvalZero   return 0;
412*10465441SEvalZero }
413*10465441SEvalZero 
mmcsd_mmc_init_card(struct rt_mmcsd_host * host,rt_uint32_t ocr)414*10465441SEvalZero static rt_int32_t mmcsd_mmc_init_card(struct rt_mmcsd_host *host,
415*10465441SEvalZero                                      rt_uint32_t           ocr)
416*10465441SEvalZero {
417*10465441SEvalZero     rt_int32_t err;
418*10465441SEvalZero     rt_uint32_t resp[4];
419*10465441SEvalZero     rt_uint32_t rocr = 0;
420*10465441SEvalZero     rt_uint32_t max_data_rate;
421*10465441SEvalZero     rt_uint8_t *ext_csd = RT_NULL;
422*10465441SEvalZero     struct rt_mmcsd_card *card = RT_NULL;
423*10465441SEvalZero 
424*10465441SEvalZero     mmcsd_go_idle(host);
425*10465441SEvalZero 
426*10465441SEvalZero     /* The extra bit indicates that we support high capacity */
427*10465441SEvalZero     err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr);
428*10465441SEvalZero     if (err)
429*10465441SEvalZero       goto err;
430*10465441SEvalZero 
431*10465441SEvalZero     if (controller_is_spi(host))
432*10465441SEvalZero     {
433*10465441SEvalZero         err = mmcsd_spi_use_crc(host, 1);
434*10465441SEvalZero         if (err)
435*10465441SEvalZero             goto err1;
436*10465441SEvalZero     }
437*10465441SEvalZero 
438*10465441SEvalZero     if (controller_is_spi(host))
439*10465441SEvalZero         err = mmcsd_get_cid(host, resp);
440*10465441SEvalZero     else
441*10465441SEvalZero         err = mmcsd_all_get_cid(host, resp);
442*10465441SEvalZero     if (err)
443*10465441SEvalZero         goto err;
444*10465441SEvalZero 
445*10465441SEvalZero     card = rt_malloc(sizeof(struct rt_mmcsd_card));
446*10465441SEvalZero     if (!card)
447*10465441SEvalZero     {
448*10465441SEvalZero         LOG_E("malloc card failed!");
449*10465441SEvalZero         err = -RT_ENOMEM;
450*10465441SEvalZero         goto err;
451*10465441SEvalZero     }
452*10465441SEvalZero     rt_memset(card, 0, sizeof(struct rt_mmcsd_card));
453*10465441SEvalZero 
454*10465441SEvalZero     card->card_type = CARD_TYPE_MMC;
455*10465441SEvalZero     card->host = host;
456*10465441SEvalZero     card->rca = 1;
457*10465441SEvalZero     rt_memcpy(card->resp_cid, resp, sizeof(card->resp_cid));
458*10465441SEvalZero 
459*10465441SEvalZero     /*
460*10465441SEvalZero      * For native busses:  get card RCA and quit open drain mode.
461*10465441SEvalZero      */
462*10465441SEvalZero     if (!controller_is_spi(host))
463*10465441SEvalZero     {
464*10465441SEvalZero         err = mmc_set_card_addr(host, card->rca);
465*10465441SEvalZero         if (err)
466*10465441SEvalZero             goto err1;
467*10465441SEvalZero 
468*10465441SEvalZero         mmcsd_set_bus_mode(host, MMCSD_BUSMODE_PUSHPULL);
469*10465441SEvalZero     }
470*10465441SEvalZero 
471*10465441SEvalZero     err = mmcsd_get_csd(card, card->resp_csd);
472*10465441SEvalZero     if (err)
473*10465441SEvalZero         goto err1;
474*10465441SEvalZero 
475*10465441SEvalZero     err = mmcsd_parse_csd(card);
476*10465441SEvalZero     if (err)
477*10465441SEvalZero         goto err1;
478*10465441SEvalZero 
479*10465441SEvalZero     if (!controller_is_spi(host))
480*10465441SEvalZero     {
481*10465441SEvalZero         err = mmcsd_select_card(card);
482*10465441SEvalZero         if (err)
483*10465441SEvalZero             goto err1;
484*10465441SEvalZero     }
485*10465441SEvalZero 
486*10465441SEvalZero     /*
487*10465441SEvalZero     * Fetch and process extended CSD.
488*10465441SEvalZero     */
489*10465441SEvalZero 
490*10465441SEvalZero     err = mmc_get_ext_csd(card, &ext_csd);
491*10465441SEvalZero     if (err)
492*10465441SEvalZero       goto err1;
493*10465441SEvalZero     err = mmc_parse_ext_csd(card, ext_csd);
494*10465441SEvalZero     if (err)
495*10465441SEvalZero       goto err1;
496*10465441SEvalZero 
497*10465441SEvalZero     /* If doing byte addressing, check if required to do sector
498*10465441SEvalZero     * addressing.  Handle the case of <2GB cards needing sector
499*10465441SEvalZero     * addressing.  See section 8.1 JEDEC Standard JED84-A441;
500*10465441SEvalZero     * ocr register has bit 30 set for sector addressing.
501*10465441SEvalZero     */
502*10465441SEvalZero     if (!(card->flags & CARD_FLAG_SDHC) && (rocr & (1<<30)))
503*10465441SEvalZero         card->flags |= CARD_FLAG_SDHC;
504*10465441SEvalZero 
505*10465441SEvalZero     /* set bus speed */
506*10465441SEvalZero     max_data_rate = (unsigned int)-1;
507*10465441SEvalZero     if (card->flags & CARD_FLAG_HIGHSPEED)
508*10465441SEvalZero     {
509*10465441SEvalZero         if (max_data_rate > card->hs_max_data_rate)
510*10465441SEvalZero             max_data_rate = card->hs_max_data_rate;
511*10465441SEvalZero     }
512*10465441SEvalZero     else if (max_data_rate > card->max_data_rate)
513*10465441SEvalZero     {
514*10465441SEvalZero         max_data_rate = card->max_data_rate;
515*10465441SEvalZero     }
516*10465441SEvalZero 
517*10465441SEvalZero     mmcsd_set_clock(host, max_data_rate);
518*10465441SEvalZero 
519*10465441SEvalZero     /*switch bus width*/
520*10465441SEvalZero     mmc_select_bus_width(card, ext_csd);
521*10465441SEvalZero 
522*10465441SEvalZero     host->card = card;
523*10465441SEvalZero 
524*10465441SEvalZero     rt_free(ext_csd);
525*10465441SEvalZero     return 0;
526*10465441SEvalZero 
527*10465441SEvalZero err1:
528*10465441SEvalZero     rt_free(card);
529*10465441SEvalZero err:
530*10465441SEvalZero 
531*10465441SEvalZero     return err;
532*10465441SEvalZero }
533*10465441SEvalZero 
534*10465441SEvalZero /*
535*10465441SEvalZero  * Starting point for mmc card init.
536*10465441SEvalZero  */
init_mmc(struct rt_mmcsd_host * host,rt_uint32_t ocr)537*10465441SEvalZero rt_int32_t init_mmc(struct rt_mmcsd_host *host, rt_uint32_t ocr)
538*10465441SEvalZero {
539*10465441SEvalZero     rt_int32_t err;
540*10465441SEvalZero     rt_uint32_t  current_ocr;
541*10465441SEvalZero     /*
542*10465441SEvalZero      * We need to get OCR a different way for SPI.
543*10465441SEvalZero      */
544*10465441SEvalZero     if (controller_is_spi(host))
545*10465441SEvalZero     {
546*10465441SEvalZero         err = mmcsd_spi_read_ocr(host, 0, &ocr);
547*10465441SEvalZero         if (err)
548*10465441SEvalZero             goto err;
549*10465441SEvalZero     }
550*10465441SEvalZero 
551*10465441SEvalZero     current_ocr = mmcsd_select_voltage(host, ocr);
552*10465441SEvalZero 
553*10465441SEvalZero     /*
554*10465441SEvalZero      * Can we support the voltage(s) of the card(s)?
555*10465441SEvalZero      */
556*10465441SEvalZero     if (!current_ocr)
557*10465441SEvalZero     {
558*10465441SEvalZero         err = -RT_ERROR;
559*10465441SEvalZero         goto err;
560*10465441SEvalZero     }
561*10465441SEvalZero 
562*10465441SEvalZero     /*
563*10465441SEvalZero      * Detect and init the card.
564*10465441SEvalZero      */
565*10465441SEvalZero     err = mmcsd_mmc_init_card(host, current_ocr);
566*10465441SEvalZero     if (err)
567*10465441SEvalZero         goto err;
568*10465441SEvalZero 
569*10465441SEvalZero     mmcsd_host_unlock(host);
570*10465441SEvalZero 
571*10465441SEvalZero     err = rt_mmcsd_blk_probe(host->card);
572*10465441SEvalZero     if (err)
573*10465441SEvalZero         goto remove_card;
574*10465441SEvalZero     mmcsd_host_lock(host);
575*10465441SEvalZero 
576*10465441SEvalZero     return 0;
577*10465441SEvalZero 
578*10465441SEvalZero remove_card:
579*10465441SEvalZero     mmcsd_host_lock(host);
580*10465441SEvalZero     rt_mmcsd_blk_remove(host->card);
581*10465441SEvalZero     rt_free(host->card);
582*10465441SEvalZero     host->card = RT_NULL;
583*10465441SEvalZero err:
584*10465441SEvalZero 
585*10465441SEvalZero     LOG_E("init MMC card failed!");
586*10465441SEvalZero 
587*10465441SEvalZero     return err;
588*10465441SEvalZero }
589