blob: e6a296a5762c939736d47aed83529f113c983635 [file] [log] [blame]
Andy Fleming272cc702008-10-30 16:41:01 -05001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Based vaguely on the Linux code
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26#include <config.h>
27#include <common.h>
28#include <command.h>
29#include <mmc.h>
30#include <part.h>
31#include <malloc.h>
32#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053033#include <div64.h>
Andy Fleming272cc702008-10-30 16:41:01 -050034
Matt Waddelce0fbcd2011-02-24 16:35:23 +000035/* Set block count limit because of 16 bit register limit on some hardware*/
36#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
37#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
38#endif
39
Andy Fleming272cc702008-10-30 16:41:01 -050040static struct list_head mmc_devices;
41static int cur_dev_num = -1;
42
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000043int __weak board_mmc_getwp(struct mmc *mmc)
44{
45 return -1;
46}
47
48int mmc_getwp(struct mmc *mmc)
49{
50 int wp;
51
52 wp = board_mmc_getwp(mmc);
53
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000054 if (wp < 0) {
55 if (mmc->getwp)
56 wp = mmc->getwp(mmc);
57 else
58 wp = 0;
59 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000060
61 return wp;
62}
63
Thierry Reding314284b2012-01-02 01:15:36 +000064int __board_mmc_getcd(struct mmc *mmc) {
Stefano Babic11fdade2010-02-05 15:04:43 +010065 return -1;
66}
67
Thierry Reding314284b2012-01-02 01:15:36 +000068int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
Stefano Babic11fdade2010-02-05 15:04:43 +010069 alias("__board_mmc_getcd")));
70
Kim Phillipsfdbb8732012-10-29 13:34:43 +000071static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
72 struct mmc_data *data)
Andy Fleming272cc702008-10-30 16:41:01 -050073{
Marek Vasut8635ff92012-03-15 18:41:35 +000074 struct mmc_data backup;
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000075 int ret;
Marek Vasut8635ff92012-03-15 18:41:35 +000076
77 memset(&backup, 0, sizeof(backup));
78
Marek Vasut8635ff92012-03-15 18:41:35 +000079#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000080 int i;
81 u8 *ptr;
82
83 printf("CMD_SEND:%d\n", cmd->cmdidx);
84 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000085 ret = mmc->send_cmd(mmc, cmd, data);
86 switch (cmd->resp_type) {
87 case MMC_RSP_NONE:
88 printf("\t\tMMC_RSP_NONE\n");
89 break;
90 case MMC_RSP_R1:
91 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
92 cmd->response[0]);
93 break;
94 case MMC_RSP_R1b:
95 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
96 cmd->response[0]);
97 break;
98 case MMC_RSP_R2:
99 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
100 cmd->response[0]);
101 printf("\t\t \t\t 0x%08X \n",
102 cmd->response[1]);
103 printf("\t\t \t\t 0x%08X \n",
104 cmd->response[2]);
105 printf("\t\t \t\t 0x%08X \n",
106 cmd->response[3]);
107 printf("\n");
108 printf("\t\t\t\t\tDUMPING DATA\n");
109 for (i = 0; i < 4; i++) {
110 int j;
111 printf("\t\t\t\t\t%03d - ", i*4);
Dirk Behme146bec72012-03-08 02:35:34 +0000112 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000113 ptr += 3;
114 for (j = 0; j < 4; j++)
115 printf("%02X ", *ptr--);
116 printf("\n");
117 }
118 break;
119 case MMC_RSP_R3:
120 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
121 cmd->response[0]);
122 break;
123 default:
124 printf("\t\tERROR MMC rsp not supported\n");
125 break;
126 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000127#else
Marek Vasut8635ff92012-03-15 18:41:35 +0000128 ret = mmc->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000129#endif
Marek Vasut8635ff92012-03-15 18:41:35 +0000130 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500131}
132
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000133static int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000134{
135 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000136 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000137#ifdef CONFIG_MMC_TRACE
138 int status;
139#endif
140
141 cmd.cmdidx = MMC_CMD_SEND_STATUS;
142 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200143 if (!mmc_host_is_spi(mmc))
144 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000145
146 do {
147 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000148 if (!err) {
149 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
150 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
151 MMC_STATE_PRG)
152 break;
153 else if (cmd.response[0] & MMC_STATUS_MASK) {
154 printf("Status Error: 0x%08X\n",
155 cmd.response[0]);
156 return COMM_ERR;
157 }
158 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000159 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000160
161 udelay(1000);
162
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000163 } while (timeout--);
164
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000165#ifdef CONFIG_MMC_TRACE
166 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
167 printf("CURR STATE:%d\n", status);
168#endif
Jongman Heo5b0c9422012-06-03 21:32:13 +0000169 if (timeout <= 0) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000170 printf("Timeout waiting card ready\n");
171 return TIMEOUT;
172 }
173
174 return 0;
175}
176
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000177static int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500178{
179 struct mmc_cmd cmd;
180
181 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
182 cmd.resp_type = MMC_RSP_R1;
183 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500184
185 return mmc_send_cmd(mmc, &cmd, NULL);
186}
187
188struct mmc *find_mmc_device(int dev_num)
189{
190 struct mmc *m;
191 struct list_head *entry;
192
193 list_for_each(entry, &mmc_devices) {
194 m = list_entry(entry, struct mmc, link);
195
196 if (m->block_dev.dev == dev_num)
197 return m;
198 }
199
200 printf("MMC Device %d not found\n", dev_num);
201
202 return NULL;
203}
204
Lei Wene6f99a52011-06-22 17:03:31 +0000205static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
206{
207 struct mmc_cmd cmd;
208 ulong end;
209 int err, start_cmd, end_cmd;
210
211 if (mmc->high_capacity)
212 end = start + blkcnt - 1;
213 else {
214 end = (start + blkcnt - 1) * mmc->write_bl_len;
215 start *= mmc->write_bl_len;
216 }
217
218 if (IS_SD(mmc)) {
219 start_cmd = SD_CMD_ERASE_WR_BLK_START;
220 end_cmd = SD_CMD_ERASE_WR_BLK_END;
221 } else {
222 start_cmd = MMC_CMD_ERASE_GROUP_START;
223 end_cmd = MMC_CMD_ERASE_GROUP_END;
224 }
225
226 cmd.cmdidx = start_cmd;
227 cmd.cmdarg = start;
228 cmd.resp_type = MMC_RSP_R1;
Lei Wene6f99a52011-06-22 17:03:31 +0000229
230 err = mmc_send_cmd(mmc, &cmd, NULL);
231 if (err)
232 goto err_out;
233
234 cmd.cmdidx = end_cmd;
235 cmd.cmdarg = end;
236
237 err = mmc_send_cmd(mmc, &cmd, NULL);
238 if (err)
239 goto err_out;
240
241 cmd.cmdidx = MMC_CMD_ERASE;
242 cmd.cmdarg = SECURE_ERASE;
243 cmd.resp_type = MMC_RSP_R1b;
244
245 err = mmc_send_cmd(mmc, &cmd, NULL);
246 if (err)
247 goto err_out;
248
249 return 0;
250
251err_out:
252 puts("mmc erase failed\n");
253 return err;
254}
255
256static unsigned long
257mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
258{
259 int err = 0;
260 struct mmc *mmc = find_mmc_device(dev_num);
261 lbaint_t blk = 0, blk_r = 0;
Jerry Huangd2d8afa2012-05-17 23:00:51 +0000262 int timeout = 1000;
Lei Wene6f99a52011-06-22 17:03:31 +0000263
264 if (!mmc)
265 return -1;
266
267 if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
268 printf("\n\nCaution! Your devices Erase group is 0x%x\n"
269 "The erase range would be change to 0x%lx~0x%lx\n\n",
270 mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
271 ((start + blkcnt + mmc->erase_grp_size)
272 & ~(mmc->erase_grp_size - 1)) - 1);
273
274 while (blk < blkcnt) {
275 blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
276 mmc->erase_grp_size : (blkcnt - blk);
277 err = mmc_erase_t(mmc, start + blk, blk_r);
278 if (err)
279 break;
280
281 blk += blk_r;
Jerry Huangd2d8afa2012-05-17 23:00:51 +0000282
283 /* Waiting for the ready status */
284 if (mmc_send_status(mmc, timeout))
285 return 0;
Lei Wene6f99a52011-06-22 17:03:31 +0000286 }
287
288 return blk;
289}
290
Andy Fleming272cc702008-10-30 16:41:01 -0500291static ulong
Lei Wen01581262010-10-14 13:38:11 +0800292mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
Andy Fleming272cc702008-10-30 16:41:01 -0500293{
294 struct mmc_cmd cmd;
295 struct mmc_data data;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000296 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500297
Lei Wend2bf29e2010-09-13 22:07:27 +0800298 if ((start + blkcnt) > mmc->block_dev.lba) {
Steve Sakomandef412b2010-10-28 09:00:26 -0700299 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800300 start + blkcnt, mmc->block_dev.lba);
301 return 0;
302 }
Andy Fleming272cc702008-10-30 16:41:01 -0500303
Ruud Commandeura586c0a2013-05-22 13:19:43 +0200304 if (blkcnt == 0)
305 return 0;
306 else if (blkcnt == 1)
Andy Fleming272cc702008-10-30 16:41:01 -0500307 cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
Ruud Commandeura586c0a2013-05-22 13:19:43 +0200308 else
309 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500310
311 if (mmc->high_capacity)
312 cmd.cmdarg = start;
313 else
Steve Sakomandef412b2010-10-28 09:00:26 -0700314 cmd.cmdarg = start * mmc->write_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500315
316 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500317
318 data.src = src;
319 data.blocks = blkcnt;
Steve Sakomandef412b2010-10-28 09:00:26 -0700320 data.blocksize = mmc->write_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500321 data.flags = MMC_DATA_WRITE;
322
Steve Sakomandef412b2010-10-28 09:00:26 -0700323 if (mmc_send_cmd(mmc, &cmd, &data)) {
324 printf("mmc write failed\n");
325 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500326 }
327
Thomas Choud52ebf12010-12-24 13:12:21 +0000328 /* SPI multiblock writes terminate using a special
329 * token, not a STOP_TRANSMISSION request.
330 */
331 if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500332 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
333 cmd.cmdarg = 0;
334 cmd.resp_type = MMC_RSP_R1b;
Steve Sakomandef412b2010-10-28 09:00:26 -0700335 if (mmc_send_cmd(mmc, &cmd, NULL)) {
336 printf("mmc fail to send stop cmd\n");
337 return 0;
Lei Wen01581262010-10-14 13:38:11 +0800338 }
Andy Fleming272cc702008-10-30 16:41:01 -0500339 }
340
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000341 /* Waiting for the ready status */
342 if (mmc_send_status(mmc, timeout))
343 return 0;
344
Andy Fleming272cc702008-10-30 16:41:01 -0500345 return blkcnt;
346}
347
Lei Wen01581262010-10-14 13:38:11 +0800348static ulong
349mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
350{
Lei Wen01581262010-10-14 13:38:11 +0800351 lbaint_t cur, blocks_todo = blkcnt;
352
Steve Sakomandef412b2010-10-28 09:00:26 -0700353 struct mmc *mmc = find_mmc_device(dev_num);
Lei Wen01581262010-10-14 13:38:11 +0800354 if (!mmc)
Steve Sakomandef412b2010-10-28 09:00:26 -0700355 return 0;
Lei Wen01581262010-10-14 13:38:11 +0800356
Steve Sakomandef412b2010-10-28 09:00:26 -0700357 if (mmc_set_blocklen(mmc, mmc->write_bl_len))
358 return 0;
Lei Wen01581262010-10-14 13:38:11 +0800359
360 do {
John Rigby8feafcc2011-04-18 05:50:08 +0000361 cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
Lei Wen01581262010-10-14 13:38:11 +0800362 if(mmc_write_blocks(mmc, start, cur, src) != cur)
Steve Sakomandef412b2010-10-28 09:00:26 -0700363 return 0;
Lei Wen01581262010-10-14 13:38:11 +0800364 blocks_todo -= cur;
365 start += cur;
366 src += cur * mmc->write_bl_len;
367 } while (blocks_todo > 0);
368
369 return blkcnt;
370}
371
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000372static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
373 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500374{
375 struct mmc_cmd cmd;
376 struct mmc_data data;
377
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700378 if (blkcnt > 1)
379 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
380 else
381 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500382
383 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700384 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500385 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700386 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500387
388 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500389
390 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700391 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500392 data.blocksize = mmc->read_bl_len;
393 data.flags = MMC_DATA_READ;
394
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700395 if (mmc_send_cmd(mmc, &cmd, &data))
396 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500397
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700398 if (blkcnt > 1) {
399 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
400 cmd.cmdarg = 0;
401 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700402 if (mmc_send_cmd(mmc, &cmd, NULL)) {
403 printf("mmc fail to send stop cmd\n");
404 return 0;
405 }
Andy Fleming272cc702008-10-30 16:41:01 -0500406 }
407
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700408 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500409}
410
411static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
412{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700413 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500414
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700415 if (blkcnt == 0)
416 return 0;
417
418 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500419 if (!mmc)
420 return 0;
421
Lei Wend2bf29e2010-09-13 22:07:27 +0800422 if ((start + blkcnt) > mmc->block_dev.lba) {
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700423 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800424 start + blkcnt, mmc->block_dev.lba);
425 return 0;
426 }
Andy Fleming272cc702008-10-30 16:41:01 -0500427
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700428 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500429 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500430
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700431 do {
John Rigby8feafcc2011-04-18 05:50:08 +0000432 cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700433 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
434 return 0;
435 blocks_todo -= cur;
436 start += cur;
437 dst += cur * mmc->read_bl_len;
438 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500439
440 return blkcnt;
441}
442
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000443static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500444{
445 struct mmc_cmd cmd;
446 int err;
447
448 udelay(1000);
449
450 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
451 cmd.cmdarg = 0;
452 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500453
454 err = mmc_send_cmd(mmc, &cmd, NULL);
455
456 if (err)
457 return err;
458
459 udelay(2000);
460
461 return 0;
462}
463
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000464static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500465{
466 int timeout = 1000;
467 int err;
468 struct mmc_cmd cmd;
469
470 do {
471 cmd.cmdidx = MMC_CMD_APP_CMD;
472 cmd.resp_type = MMC_RSP_R1;
473 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500474
475 err = mmc_send_cmd(mmc, &cmd, NULL);
476
477 if (err)
478 return err;
479
480 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
481 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100482
483 /*
484 * Most cards do not answer if some reserved bits
485 * in the ocr are set. However, Some controller
486 * can set bit 7 (reserved for low voltages), but
487 * how to manage low voltages SD card is not yet
488 * specified.
489 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000490 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
491 (mmc->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500492
493 if (mmc->version == SD_VERSION_2)
494 cmd.cmdarg |= OCR_HCS;
495
496 err = mmc_send_cmd(mmc, &cmd, NULL);
497
498 if (err)
499 return err;
500
501 udelay(1000);
502 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
503
504 if (timeout <= 0)
505 return UNUSABLE_ERR;
506
507 if (mmc->version != SD_VERSION_2)
508 mmc->version = SD_VERSION_1_0;
509
Thomas Choud52ebf12010-12-24 13:12:21 +0000510 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
511 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
512 cmd.resp_type = MMC_RSP_R3;
513 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000514
515 err = mmc_send_cmd(mmc, &cmd, NULL);
516
517 if (err)
518 return err;
519 }
520
Rabin Vincent998be3d2009-04-05 13:30:56 +0530521 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500522
523 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
524 mmc->rca = 0;
525
526 return 0;
527}
528
Che-Liang Chioue9550442012-11-28 15:21:13 +0000529/* We pass in the cmd since otherwise the init seems to fail */
530static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
531 int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500532{
Andy Fleming272cc702008-10-30 16:41:01 -0500533 int err;
534
Che-Liang Chioue9550442012-11-28 15:21:13 +0000535 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
536 cmd->resp_type = MMC_RSP_R3;
537 cmd->cmdarg = 0;
538 if (use_arg && !mmc_host_is_spi(mmc)) {
539 cmd->cmdarg =
540 (mmc->voltages &
541 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
542 (mmc->op_cond_response & OCR_ACCESS_MODE);
543
544 if (mmc->host_caps & MMC_MODE_HC)
545 cmd->cmdarg |= OCR_HCS;
546 }
547 err = mmc_send_cmd(mmc, cmd, NULL);
548 if (err)
549 return err;
550 mmc->op_cond_response = cmd->response[0];
551 return 0;
552}
553
554int mmc_send_op_cond(struct mmc *mmc)
555{
556 struct mmc_cmd cmd;
557 int err, i;
558
Andy Fleming272cc702008-10-30 16:41:01 -0500559 /* Some cards seem to need this */
560 mmc_go_idle(mmc);
561
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000562 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000563 mmc->op_cond_pending = 1;
564 for (i = 0; i < 2; i++) {
565 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500566 if (err)
567 return err;
568
Che-Liang Chioue9550442012-11-28 15:21:13 +0000569 /* exit if not busy (flag seems to be inverted) */
570 if (mmc->op_cond_response & OCR_BUSY)
571 return 0;
572 }
573 return IN_PROGRESS;
574}
Andy Fleming272cc702008-10-30 16:41:01 -0500575
Che-Liang Chioue9550442012-11-28 15:21:13 +0000576int mmc_complete_op_cond(struct mmc *mmc)
577{
578 struct mmc_cmd cmd;
579 int timeout = 1000;
580 uint start;
581 int err;
582
583 mmc->op_cond_pending = 0;
584 start = get_timer(0);
585 do {
586 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
587 if (err)
588 return err;
589 if (get_timer(start) > timeout)
590 return UNUSABLE_ERR;
591 udelay(100);
592 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Fleming272cc702008-10-30 16:41:01 -0500593
Thomas Choud52ebf12010-12-24 13:12:21 +0000594 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
595 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
596 cmd.resp_type = MMC_RSP_R3;
597 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000598
599 err = mmc_send_cmd(mmc, &cmd, NULL);
600
601 if (err)
602 return err;
603 }
604
Andy Fleming272cc702008-10-30 16:41:01 -0500605 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincent998be3d2009-04-05 13:30:56 +0530606 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500607
608 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
609 mmc->rca = 0;
610
611 return 0;
612}
613
614
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000615static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500616{
617 struct mmc_cmd cmd;
618 struct mmc_data data;
619 int err;
620
621 /* Get the Card Status Register */
622 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
623 cmd.resp_type = MMC_RSP_R1;
624 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500625
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000626 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500627 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000628 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500629 data.flags = MMC_DATA_READ;
630
631 err = mmc_send_cmd(mmc, &cmd, &data);
632
633 return err;
634}
635
636
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000637static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500638{
639 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000640 int timeout = 1000;
641 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500642
643 cmd.cmdidx = MMC_CMD_SWITCH;
644 cmd.resp_type = MMC_RSP_R1b;
645 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000646 (index << 16) |
647 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500648
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000649 ret = mmc_send_cmd(mmc, &cmd, NULL);
650
651 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000652 if (!ret)
653 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000654
655 return ret;
656
Andy Fleming272cc702008-10-30 16:41:01 -0500657}
658
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000659static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500660{
Simon Glass8bfa1952013-04-03 08:54:30 +0000661 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500662 char cardtype;
663 int err;
664
665 mmc->card_caps = 0;
666
Thomas Choud52ebf12010-12-24 13:12:21 +0000667 if (mmc_host_is_spi(mmc))
668 return 0;
669
Andy Fleming272cc702008-10-30 16:41:01 -0500670 /* Only version 4 supports high-speed */
671 if (mmc->version < MMC_VERSION_4)
672 return 0;
673
Andy Fleming272cc702008-10-30 16:41:01 -0500674 err = mmc_send_ext_csd(mmc, ext_csd);
675
676 if (err)
677 return err;
678
Lei Wen0560db12011-10-03 20:35:10 +0000679 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500680
681 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
682
683 if (err)
684 return err;
685
686 /* Now check to see that it worked */
687 err = mmc_send_ext_csd(mmc, ext_csd);
688
689 if (err)
690 return err;
691
692 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000693 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500694 return 0;
695
696 /* High Speed is set, there are two types: 52MHz and 26MHz */
697 if (cardtype & MMC_HS_52MHZ)
698 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
699 else
700 mmc->card_caps |= MMC_MODE_HS;
701
702 return 0;
703}
704
Stephen Warrenf866a462013-06-11 15:14:01 -0600705static int mmc_set_capacity(struct mmc *mmc, int part_num)
706{
707 switch (part_num) {
708 case 0:
709 mmc->capacity = mmc->capacity_user;
710 break;
711 case 1:
712 case 2:
713 mmc->capacity = mmc->capacity_boot;
714 break;
715 case 3:
716 mmc->capacity = mmc->capacity_rpmb;
717 break;
718 case 4:
719 case 5:
720 case 6:
721 case 7:
722 mmc->capacity = mmc->capacity_gp[part_num - 4];
723 break;
724 default:
725 return -1;
726 }
727
728 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
729
730 return 0;
731}
732
Lei Wenbc897b12011-05-02 16:26:26 +0000733int mmc_switch_part(int dev_num, unsigned int part_num)
734{
735 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600736 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000737
738 if (!mmc)
739 return -1;
740
Stephen Warrenf866a462013-06-11 15:14:01 -0600741 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
742 (mmc->part_config & ~PART_ACCESS_MASK)
743 | (part_num & PART_ACCESS_MASK));
744 if (ret)
745 return ret;
746
747 return mmc_set_capacity(mmc, part_num);
Lei Wenbc897b12011-05-02 16:26:26 +0000748}
749
Thierry Reding48972d92012-01-02 01:15:37 +0000750int mmc_getcd(struct mmc *mmc)
751{
752 int cd;
753
754 cd = board_mmc_getcd(mmc);
755
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000756 if (cd < 0) {
757 if (mmc->getcd)
758 cd = mmc->getcd(mmc);
759 else
760 cd = 1;
761 }
Thierry Reding48972d92012-01-02 01:15:37 +0000762
763 return cd;
764}
765
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000766static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500767{
768 struct mmc_cmd cmd;
769 struct mmc_data data;
770
771 /* Switch the frequency */
772 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
773 cmd.resp_type = MMC_RSP_R1;
774 cmd.cmdarg = (mode << 31) | 0xffffff;
775 cmd.cmdarg &= ~(0xf << (group * 4));
776 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500777
778 data.dest = (char *)resp;
779 data.blocksize = 64;
780 data.blocks = 1;
781 data.flags = MMC_DATA_READ;
782
783 return mmc_send_cmd(mmc, &cmd, &data);
784}
785
786
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000787static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500788{
789 int err;
790 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000791 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
792 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500793 struct mmc_data data;
794 int timeout;
795
796 mmc->card_caps = 0;
797
Thomas Choud52ebf12010-12-24 13:12:21 +0000798 if (mmc_host_is_spi(mmc))
799 return 0;
800
Andy Fleming272cc702008-10-30 16:41:01 -0500801 /* Read the SCR to find out if this card supports higher speeds */
802 cmd.cmdidx = MMC_CMD_APP_CMD;
803 cmd.resp_type = MMC_RSP_R1;
804 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500805
806 err = mmc_send_cmd(mmc, &cmd, NULL);
807
808 if (err)
809 return err;
810
811 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
812 cmd.resp_type = MMC_RSP_R1;
813 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500814
815 timeout = 3;
816
817retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000818 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500819 data.blocksize = 8;
820 data.blocks = 1;
821 data.flags = MMC_DATA_READ;
822
823 err = mmc_send_cmd(mmc, &cmd, &data);
824
825 if (err) {
826 if (timeout--)
827 goto retry_scr;
828
829 return err;
830 }
831
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300832 mmc->scr[0] = __be32_to_cpu(scr[0]);
833 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500834
835 switch ((mmc->scr[0] >> 24) & 0xf) {
836 case 0:
837 mmc->version = SD_VERSION_1_0;
838 break;
839 case 1:
840 mmc->version = SD_VERSION_1_10;
841 break;
842 case 2:
843 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000844 if ((mmc->scr[0] >> 15) & 0x1)
845 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500846 break;
847 default:
848 mmc->version = SD_VERSION_1_0;
849 break;
850 }
851
Alagu Sankarb44c7082010-05-12 15:08:24 +0530852 if (mmc->scr[0] & SD_DATA_4BIT)
853 mmc->card_caps |= MMC_MODE_4BIT;
854
Andy Fleming272cc702008-10-30 16:41:01 -0500855 /* Version 1.0 doesn't support switching */
856 if (mmc->version == SD_VERSION_1_0)
857 return 0;
858
859 timeout = 4;
860 while (timeout--) {
861 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000862 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500863
864 if (err)
865 return err;
866
867 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300868 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500869 break;
870 }
871
Andy Fleming272cc702008-10-30 16:41:01 -0500872 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300873 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500874 return 0;
875
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000876 /*
877 * If the host doesn't support SD_HIGHSPEED, do not switch card to
878 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
879 * This can avoid furthur problem when the card runs in different
880 * mode between the host.
881 */
882 if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
883 (mmc->host_caps & MMC_MODE_HS)))
884 return 0;
885
Anton staaff781dd32011-10-03 13:54:59 +0000886 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500887
888 if (err)
889 return err;
890
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300891 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500892 mmc->card_caps |= MMC_MODE_HS;
893
894 return 0;
895}
896
897/* frequency bases */
898/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000899static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500900 10000,
901 100000,
902 1000000,
903 10000000,
904};
905
906/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
907 * to platforms without floating point.
908 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000909static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500910 0, /* reserved */
911 10,
912 12,
913 13,
914 15,
915 20,
916 25,
917 30,
918 35,
919 40,
920 45,
921 50,
922 55,
923 60,
924 70,
925 80,
926};
927
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000928static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500929{
930 mmc->set_ios(mmc);
931}
932
933void mmc_set_clock(struct mmc *mmc, uint clock)
934{
935 if (clock > mmc->f_max)
936 clock = mmc->f_max;
937
938 if (clock < mmc->f_min)
939 clock = mmc->f_min;
940
941 mmc->clock = clock;
942
943 mmc_set_ios(mmc);
944}
945
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000946static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -0500947{
948 mmc->bus_width = width;
949
950 mmc_set_ios(mmc);
951}
952
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000953static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500954{
Stephen Warrenf866a462013-06-11 15:14:01 -0600955 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -0500956 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000957 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -0500958 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +0000959 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
960 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000961 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500962
Thomas Choud52ebf12010-12-24 13:12:21 +0000963#ifdef CONFIG_MMC_SPI_CRC_ON
964 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
965 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
966 cmd.resp_type = MMC_RSP_R1;
967 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000968 err = mmc_send_cmd(mmc, &cmd, NULL);
969
970 if (err)
971 return err;
972 }
973#endif
974
Andy Fleming272cc702008-10-30 16:41:01 -0500975 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000976 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
977 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -0500978 cmd.resp_type = MMC_RSP_R2;
979 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500980
981 err = mmc_send_cmd(mmc, &cmd, NULL);
982
983 if (err)
984 return err;
985
986 memcpy(mmc->cid, cmd.response, 16);
987
988 /*
989 * For MMC cards, set the Relative Address.
990 * For SD cards, get the Relatvie Address.
991 * This also puts the cards into Standby State
992 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000993 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
994 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
995 cmd.cmdarg = mmc->rca << 16;
996 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -0500997
Thomas Choud52ebf12010-12-24 13:12:21 +0000998 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500999
Thomas Choud52ebf12010-12-24 13:12:21 +00001000 if (err)
1001 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001002
Thomas Choud52ebf12010-12-24 13:12:21 +00001003 if (IS_SD(mmc))
1004 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1005 }
Andy Fleming272cc702008-10-30 16:41:01 -05001006
1007 /* Get the Card-Specific Data */
1008 cmd.cmdidx = MMC_CMD_SEND_CSD;
1009 cmd.resp_type = MMC_RSP_R2;
1010 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001011
1012 err = mmc_send_cmd(mmc, &cmd, NULL);
1013
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001014 /* Waiting for the ready status */
1015 mmc_send_status(mmc, timeout);
1016
Andy Fleming272cc702008-10-30 16:41:01 -05001017 if (err)
1018 return err;
1019
Rabin Vincent998be3d2009-04-05 13:30:56 +05301020 mmc->csd[0] = cmd.response[0];
1021 mmc->csd[1] = cmd.response[1];
1022 mmc->csd[2] = cmd.response[2];
1023 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001024
1025 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301026 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001027
1028 switch (version) {
1029 case 0:
1030 mmc->version = MMC_VERSION_1_2;
1031 break;
1032 case 1:
1033 mmc->version = MMC_VERSION_1_4;
1034 break;
1035 case 2:
1036 mmc->version = MMC_VERSION_2_2;
1037 break;
1038 case 3:
1039 mmc->version = MMC_VERSION_3;
1040 break;
1041 case 4:
1042 mmc->version = MMC_VERSION_4;
1043 break;
1044 default:
1045 mmc->version = MMC_VERSION_1_2;
1046 break;
1047 }
1048 }
1049
1050 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301051 freq = fbase[(cmd.response[0] & 0x7)];
1052 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001053
1054 mmc->tran_speed = freq * mult;
1055
Rabin Vincent998be3d2009-04-05 13:30:56 +05301056 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001057
1058 if (IS_SD(mmc))
1059 mmc->write_bl_len = mmc->read_bl_len;
1060 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301061 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001062
1063 if (mmc->high_capacity) {
1064 csize = (mmc->csd[1] & 0x3f) << 16
1065 | (mmc->csd[2] & 0xffff0000) >> 16;
1066 cmult = 8;
1067 } else {
1068 csize = (mmc->csd[1] & 0x3ff) << 2
1069 | (mmc->csd[2] & 0xc0000000) >> 30;
1070 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1071 }
1072
Stephen Warrenf866a462013-06-11 15:14:01 -06001073 mmc->capacity_user = (csize + 1) << (cmult + 2);
1074 mmc->capacity_user *= mmc->read_bl_len;
1075 mmc->capacity_boot = 0;
1076 mmc->capacity_rpmb = 0;
1077 for (i = 0; i < 4; i++)
1078 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001079
Simon Glass8bfa1952013-04-03 08:54:30 +00001080 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1081 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001082
Simon Glass8bfa1952013-04-03 08:54:30 +00001083 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1084 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001085
1086 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001087 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1088 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001089 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001090 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001091 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001092
Thomas Choud52ebf12010-12-24 13:12:21 +00001093 if (err)
1094 return err;
1095 }
Andy Fleming272cc702008-10-30 16:41:01 -05001096
Lei Wene6f99a52011-06-22 17:03:31 +00001097 /*
1098 * For SD, its erase group is always one sector
1099 */
1100 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001101 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301102 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1103 /* check ext_csd version and capacity */
1104 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001105 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001106 /*
1107 * According to the JEDEC Standard, the value of
1108 * ext_csd's capacity is valid if the value is more
1109 * than 2GB
1110 */
Lei Wen0560db12011-10-03 20:35:10 +00001111 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1112 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1113 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1114 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001115 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001116 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001117 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301118 }
Lei Wenbc897b12011-05-02 16:26:26 +00001119
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001120 switch (ext_csd[EXT_CSD_REV]) {
1121 case 1:
1122 mmc->version = MMC_VERSION_4_1;
1123 break;
1124 case 2:
1125 mmc->version = MMC_VERSION_4_2;
1126 break;
1127 case 3:
1128 mmc->version = MMC_VERSION_4_3;
1129 break;
1130 case 5:
1131 mmc->version = MMC_VERSION_4_41;
1132 break;
1133 case 6:
1134 mmc->version = MMC_VERSION_4_5;
1135 break;
1136 }
1137
Lei Wene6f99a52011-06-22 17:03:31 +00001138 /*
1139 * Check whether GROUP_DEF is set, if yes, read out
1140 * group size from ext_csd directly, or calculate
1141 * the group size from the csd value.
1142 */
Simon Glass8bfa1952013-04-03 08:54:30 +00001143 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
Lei Wen0560db12011-10-03 20:35:10 +00001144 mmc->erase_grp_size =
Simon Glass8bfa1952013-04-03 08:54:30 +00001145 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
1146 MMC_MAX_BLOCK_LEN * 1024;
1147 } else {
Lei Wene6f99a52011-06-22 17:03:31 +00001148 int erase_gsz, erase_gmul;
1149 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1150 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1151 mmc->erase_grp_size = (erase_gsz + 1)
1152 * (erase_gmul + 1);
1153 }
1154
Lei Wenbc897b12011-05-02 16:26:26 +00001155 /* store the partition info of emmc */
Stephen Warren8948ea82012-07-30 10:55:43 +00001156 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1157 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen0560db12011-10-03 20:35:10 +00001158 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrenf866a462013-06-11 15:14:01 -06001159
1160 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1161
1162 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1163
1164 for (i = 0; i < 4; i++) {
1165 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1166 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1167 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1168 mmc->capacity_gp[i] *=
1169 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1170 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1171 }
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301172 }
1173
Stephen Warrenf866a462013-06-11 15:14:01 -06001174 err = mmc_set_capacity(mmc, mmc->part_num);
1175 if (err)
1176 return err;
1177
Andy Fleming272cc702008-10-30 16:41:01 -05001178 if (IS_SD(mmc))
1179 err = sd_change_freq(mmc);
1180 else
1181 err = mmc_change_freq(mmc);
1182
1183 if (err)
1184 return err;
1185
1186 /* Restrict card's capabilities by what the host can do */
1187 mmc->card_caps &= mmc->host_caps;
1188
1189 if (IS_SD(mmc)) {
1190 if (mmc->card_caps & MMC_MODE_4BIT) {
1191 cmd.cmdidx = MMC_CMD_APP_CMD;
1192 cmd.resp_type = MMC_RSP_R1;
1193 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001194
1195 err = mmc_send_cmd(mmc, &cmd, NULL);
1196 if (err)
1197 return err;
1198
1199 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1200 cmd.resp_type = MMC_RSP_R1;
1201 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001202 err = mmc_send_cmd(mmc, &cmd, NULL);
1203 if (err)
1204 return err;
1205
1206 mmc_set_bus_width(mmc, 4);
1207 }
1208
1209 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001210 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001211 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001212 mmc->tran_speed = 25000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001213 } else {
Andy Fleming7798f6d2012-10-31 19:02:38 +00001214 int idx;
1215
1216 /* An array of possible bus widths in order of preference */
1217 static unsigned ext_csd_bits[] = {
1218 EXT_CSD_BUS_WIDTH_8,
1219 EXT_CSD_BUS_WIDTH_4,
1220 EXT_CSD_BUS_WIDTH_1,
1221 };
1222
1223 /* An array to map CSD bus widths to host cap bits */
1224 static unsigned ext_to_hostcaps[] = {
1225 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1226 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1227 };
1228
1229 /* An array to map chosen bus width to an integer */
1230 static unsigned widths[] = {
1231 8, 4, 1,
1232 };
1233
1234 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1235 unsigned int extw = ext_csd_bits[idx];
1236
1237 /*
1238 * Check to make sure the controller supports
1239 * this bus width, if it's more than 1
1240 */
1241 if (extw != EXT_CSD_BUS_WIDTH_1 &&
1242 !(mmc->host_caps & ext_to_hostcaps[extw]))
1243 continue;
1244
Andy Fleming272cc702008-10-30 16:41:01 -05001245 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001246 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001247
1248 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001249 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001250
Andy Fleming7798f6d2012-10-31 19:02:38 +00001251 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001252
Lei Wen41378942011-10-03 20:35:11 +00001253 err = mmc_send_ext_csd(mmc, test_csd);
1254 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1255 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1256 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1257 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1258 && ext_csd[EXT_CSD_REV] \
1259 == test_csd[EXT_CSD_REV]
1260 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1261 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1262 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1263 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Fleming272cc702008-10-30 16:41:01 -05001264
Andy Fleming7798f6d2012-10-31 19:02:38 +00001265 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen41378942011-10-03 20:35:11 +00001266 break;
1267 }
Andy Fleming272cc702008-10-30 16:41:01 -05001268 }
1269
1270 if (mmc->card_caps & MMC_MODE_HS) {
1271 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001272 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001273 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001274 mmc->tran_speed = 26000000;
1275 }
Andy Fleming272cc702008-10-30 16:41:01 -05001276 }
1277
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001278 mmc_set_clock(mmc, mmc->tran_speed);
1279
Andy Fleming272cc702008-10-30 16:41:01 -05001280 /* fill in device description */
1281 mmc->block_dev.lun = 0;
1282 mmc->block_dev.type = 0;
1283 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001284 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301285 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Taylor Huttbabce5f2012-10-20 17:15:59 +00001286 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1287 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1288 (mmc->cid[3] >> 16) & 0xffff);
1289 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1290 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1291 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1292 (mmc->cid[2] >> 24) & 0xff);
1293 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1294 (mmc->cid[2] >> 16) & 0xf);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001295#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001296 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001297#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001298
1299 return 0;
1300}
1301
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001302static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001303{
1304 struct mmc_cmd cmd;
1305 int err;
1306
1307 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1308 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
1309 cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
1310 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001311
1312 err = mmc_send_cmd(mmc, &cmd, NULL);
1313
1314 if (err)
1315 return err;
1316
Rabin Vincent998be3d2009-04-05 13:30:56 +05301317 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001318 return UNUSABLE_ERR;
1319 else
1320 mmc->version = SD_VERSION_2;
1321
1322 return 0;
1323}
1324
1325int mmc_register(struct mmc *mmc)
1326{
1327 /* Setup the universal parts of the block interface just once */
1328 mmc->block_dev.if_type = IF_TYPE_MMC;
1329 mmc->block_dev.dev = cur_dev_num++;
1330 mmc->block_dev.removable = 1;
1331 mmc->block_dev.block_read = mmc_bread;
1332 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001333 mmc->block_dev.block_erase = mmc_berase;
John Rigby8feafcc2011-04-18 05:50:08 +00001334 if (!mmc->b_max)
1335 mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
Andy Fleming272cc702008-10-30 16:41:01 -05001336
1337 INIT_LIST_HEAD (&mmc->link);
1338
1339 list_add_tail (&mmc->link, &mmc_devices);
1340
1341 return 0;
1342}
1343
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001344#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001345block_dev_desc_t *mmc_get_dev(int dev)
1346{
1347 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001348 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001349 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001350
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001351 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001352}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001353#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001354
Che-Liang Chioue9550442012-11-28 15:21:13 +00001355int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001356{
Macpaul Linafd59322011-11-14 23:35:39 +00001357 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001358
Thierry Reding48972d92012-01-02 01:15:37 +00001359 if (mmc_getcd(mmc) == 0) {
1360 mmc->has_init = 0;
1361 printf("MMC: no card present\n");
1362 return NO_CARD_ERR;
1363 }
1364
Lei Wenbc897b12011-05-02 16:26:26 +00001365 if (mmc->has_init)
1366 return 0;
1367
Andy Fleming272cc702008-10-30 16:41:01 -05001368 err = mmc->init(mmc);
1369
1370 if (err)
1371 return err;
1372
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001373 mmc_set_bus_width(mmc, 1);
1374 mmc_set_clock(mmc, 1);
1375
Andy Fleming272cc702008-10-30 16:41:01 -05001376 /* Reset the Card */
1377 err = mmc_go_idle(mmc);
1378
1379 if (err)
1380 return err;
1381
Lei Wenbc897b12011-05-02 16:26:26 +00001382 /* The internal partition reset to user partition(0) at every CMD0*/
1383 mmc->part_num = 0;
1384
Andy Fleming272cc702008-10-30 16:41:01 -05001385 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001386 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001387
Andy Fleming272cc702008-10-30 16:41:01 -05001388 /* Now try to get the SD card's operating condition */
1389 err = sd_send_op_cond(mmc);
1390
1391 /* If the command timed out, we check for an MMC card */
1392 if (err == TIMEOUT) {
1393 err = mmc_send_op_cond(mmc);
1394
Che-Liang Chioue9550442012-11-28 15:21:13 +00001395 if (err && err != IN_PROGRESS) {
Andy Fleming272cc702008-10-30 16:41:01 -05001396 printf("Card did not respond to voltage select!\n");
1397 return UNUSABLE_ERR;
1398 }
1399 }
1400
Che-Liang Chioue9550442012-11-28 15:21:13 +00001401 if (err == IN_PROGRESS)
1402 mmc->init_in_progress = 1;
1403
1404 return err;
1405}
1406
1407static int mmc_complete_init(struct mmc *mmc)
1408{
1409 int err = 0;
1410
1411 if (mmc->op_cond_pending)
1412 err = mmc_complete_op_cond(mmc);
1413
1414 if (!err)
1415 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001416 if (err)
1417 mmc->has_init = 0;
1418 else
1419 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001420 mmc->init_in_progress = 0;
1421 return err;
1422}
1423
1424int mmc_init(struct mmc *mmc)
1425{
1426 int err = IN_PROGRESS;
1427 unsigned start = get_timer(0);
1428
1429 if (mmc->has_init)
1430 return 0;
1431 if (!mmc->init_in_progress)
1432 err = mmc_start_init(mmc);
1433
1434 if (!err || err == IN_PROGRESS)
1435 err = mmc_complete_init(mmc);
1436 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001437 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001438}
1439
1440/*
1441 * CPU and board-specific MMC initializations. Aliased function
1442 * signals caller to move on
1443 */
1444static int __def_mmc_init(bd_t *bis)
1445{
1446 return -1;
1447}
1448
Peter Tyserf9a109b2009-04-20 11:08:46 -05001449int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1450int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Fleming272cc702008-10-30 16:41:01 -05001451
1452void print_mmc_devices(char separator)
1453{
1454 struct mmc *m;
1455 struct list_head *entry;
1456
1457 list_for_each(entry, &mmc_devices) {
1458 m = list_entry(entry, struct mmc, link);
1459
1460 printf("%s: %d", m->name, m->block_dev.dev);
1461
1462 if (entry->next != &mmc_devices)
1463 printf("%c ", separator);
1464 }
1465
1466 printf("\n");
1467}
1468
Lei Wenea6ebe22011-05-02 16:26:25 +00001469int get_mmc_num(void)
1470{
1471 return cur_dev_num;
1472}
1473
Che-Liang Chioue9550442012-11-28 15:21:13 +00001474void mmc_set_preinit(struct mmc *mmc, int preinit)
1475{
1476 mmc->preinit = preinit;
1477}
1478
1479static void do_preinit(void)
1480{
1481 struct mmc *m;
1482 struct list_head *entry;
1483
1484 list_for_each(entry, &mmc_devices) {
1485 m = list_entry(entry, struct mmc, link);
1486
1487 if (m->preinit)
1488 mmc_start_init(m);
1489 }
1490}
1491
1492
Andy Fleming272cc702008-10-30 16:41:01 -05001493int mmc_initialize(bd_t *bis)
1494{
1495 INIT_LIST_HEAD (&mmc_devices);
1496 cur_dev_num = 0;
1497
1498 if (board_mmc_init(bis) < 0)
1499 cpu_mmc_init(bis);
1500
1501 print_mmc_devices(',');
1502
Che-Liang Chioue9550442012-11-28 15:21:13 +00001503 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001504 return 0;
1505}