blob: e6a296a5762c939736d47aed83529f113c983635 [file] [log] [blame]
Andy Flemingad347bb2008-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 Vincent69d4e2c2009-04-05 13:30:54 +053033#include <div64.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050034
Matt Waddeld0e3c802011-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 Flemingad347bb2008-10-30 16:41:01 -050040static struct list_head mmc_devices;
41static int cur_dev_num = -1;
42
Nikita Kiryanov020f2612012-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 Korsgaardf7b15102013-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 Kiryanov020f2612012-12-03 02:19:46 +000060
61 return wp;
62}
63
Thierry Redingd7aebf42012-01-02 01:15:36 +000064int __board_mmc_getcd(struct mmc *mmc) {
Stefano Babic6e00edf2010-02-05 15:04:43 +010065 return -1;
66}
67
Thierry Redingd7aebf42012-01-02 01:15:36 +000068int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
Stefano Babic6e00edf2010-02-05 15:04:43 +010069 alias("__board_mmc_getcd")));
70
Kim Phillips87ea3892012-10-29 13:34:43 +000071static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
72 struct mmc_data *data)
Andy Flemingad347bb2008-10-30 16:41:01 -050073{
Marek Vasutdccb6082012-03-15 18:41:35 +000074 struct mmc_data backup;
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000075 int ret;
Marek Vasutdccb6082012-03-15 18:41:35 +000076
77 memset(&backup, 0, sizeof(backup));
78
Marek Vasutdccb6082012-03-15 18:41:35 +000079#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati894b1e22011-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 Recalcati894b1e22011-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 Behmec9cb4a92012-03-08 02:35:34 +0000112 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati894b1e22011-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 Recalcati894b1e22011-03-11 02:01:14 +0000127#else
Marek Vasutdccb6082012-03-15 18:41:35 +0000128 ret = mmc->send_cmd(mmc, cmd, data);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000129#endif
Marek Vasutdccb6082012-03-15 18:41:35 +0000130 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500131}
132
Kim Phillips87ea3892012-10-29 13:34:43 +0000133static int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000134{
135 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000136 int err, retries = 5;
Raffaele Recalcati01a0dc62011-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 Vasutc4427392011-08-10 09:24:48 +0200143 if (!mmc_host_is_spi(mmc))
144 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000145
146 do {
147 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-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 Recalcati01a0dc62011-03-11 02:01:12 +0000159 return err;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000160
161 udelay(1000);
162
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000163 } while (timeout--);
164
Raffaele Recalcati894b1e22011-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 Heo1be00d92012-06-03 21:32:13 +0000169 if (timeout <= 0) {
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000170 printf("Timeout waiting card ready\n");
171 return TIMEOUT;
172 }
173
174 return 0;
175}
176
Kim Phillips87ea3892012-10-29 13:34:43 +0000177static int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Wenea526762011-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 Wenea526762011-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 Huang15c9ad92012-05-17 23:00:51 +0000262 int timeout = 1000;
Lei Wenea526762011-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 Huang15c9ad92012-05-17 23:00:51 +0000282
283 /* Waiting for the ready status */
284 if (mmc_send_status(mmc, timeout))
285 return 0;
Lei Wenea526762011-06-22 17:03:31 +0000286 }
287
288 return blk;
289}
290
Andy Flemingad347bb2008-10-30 16:41:01 -0500291static ulong
Lei Wen6b405b72010-10-14 13:38:11 +0800292mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
Andy Flemingad347bb2008-10-30 16:41:01 -0500293{
294 struct mmc_cmd cmd;
295 struct mmc_data data;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000296 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500297
Lei Wene1cc9c82010-09-13 22:07:27 +0800298 if ((start + blkcnt) > mmc->block_dev.lba) {
Steve Sakomaneb288862010-10-28 09:00:26 -0700299 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800300 start + blkcnt, mmc->block_dev.lba);
301 return 0;
302 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500303
Ruud Commandeuraa05e012013-05-22 13:19:43 +0200304 if (blkcnt == 0)
305 return 0;
306 else if (blkcnt == 1)
Andy Flemingad347bb2008-10-30 16:41:01 -0500307 cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
Ruud Commandeuraa05e012013-05-22 13:19:43 +0200308 else
309 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500310
311 if (mmc->high_capacity)
312 cmd.cmdarg = start;
313 else
Steve Sakomaneb288862010-10-28 09:00:26 -0700314 cmd.cmdarg = start * mmc->write_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500315
316 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500317
318 data.src = src;
319 data.blocks = blkcnt;
Steve Sakomaneb288862010-10-28 09:00:26 -0700320 data.blocksize = mmc->write_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500321 data.flags = MMC_DATA_WRITE;
322
Steve Sakomaneb288862010-10-28 09:00:26 -0700323 if (mmc_send_cmd(mmc, &cmd, &data)) {
324 printf("mmc write failed\n");
325 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500326 }
327
Thomas Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500332 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
333 cmd.cmdarg = 0;
334 cmd.resp_type = MMC_RSP_R1b;
Steve Sakomaneb288862010-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 Wen6b405b72010-10-14 13:38:11 +0800338 }
339 }
340
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000341 /* Waiting for the ready status */
342 if (mmc_send_status(mmc, timeout))
343 return 0;
344
Lei Wen6b405b72010-10-14 13:38:11 +0800345 return blkcnt;
346}
347
348static ulong
349mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
350{
Lei Wen6b405b72010-10-14 13:38:11 +0800351 lbaint_t cur, blocks_todo = blkcnt;
352
Steve Sakomaneb288862010-10-28 09:00:26 -0700353 struct mmc *mmc = find_mmc_device(dev_num);
Lei Wen6b405b72010-10-14 13:38:11 +0800354 if (!mmc)
Steve Sakomaneb288862010-10-28 09:00:26 -0700355 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800356
Steve Sakomaneb288862010-10-28 09:00:26 -0700357 if (mmc_set_blocklen(mmc, mmc->write_bl_len))
358 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500359
Lei Wen6b405b72010-10-14 13:38:11 +0800360 do {
John Rigbyf2f43662011-04-18 05:50:08 +0000361 cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
Lei Wen6b405b72010-10-14 13:38:11 +0800362 if(mmc_write_blocks(mmc, start, cur, src) != cur)
Steve Sakomaneb288862010-10-28 09:00:26 -0700363 return 0;
Lei Wen6b405b72010-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
Andy Flemingad347bb2008-10-30 16:41:01 -0500369 return blkcnt;
370}
371
Kim Phillips87ea3892012-10-29 13:34:43 +0000372static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
373 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500374{
375 struct mmc_cmd cmd;
376 struct mmc_data data;
377
Alagu Sankarc25d1b92010-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 Flemingad347bb2008-10-30 16:41:01 -0500382
383 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700384 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500385 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700386 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500387
388 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500389
390 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700391 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500392 data.blocksize = mmc->read_bl_len;
393 data.flags = MMC_DATA_READ;
394
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700395 if (mmc_send_cmd(mmc, &cmd, &data))
396 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500397
Alagu Sankarc25d1b92010-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 Sankarc25d1b92010-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 Flemingad347bb2008-10-30 16:41:01 -0500406 }
407
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700408 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500409}
410
411static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
412{
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700413 lbaint_t cur, blocks_todo = blkcnt;
414
415 if (blkcnt == 0)
416 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500417
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700418 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500419 if (!mmc)
420 return 0;
421
Lei Wene1cc9c82010-09-13 22:07:27 +0800422 if ((start + blkcnt) > mmc->block_dev.lba) {
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700423 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800424 start + blkcnt, mmc->block_dev.lba);
425 return 0;
426 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500427
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700428 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Flemingad347bb2008-10-30 16:41:01 -0500429 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500430
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700431 do {
John Rigbyf2f43662011-04-18 05:50:08 +0000432 cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
Alagu Sankarc25d1b92010-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 Flemingad347bb2008-10-30 16:41:01 -0500439
440 return blkcnt;
441}
442
Kim Phillips87ea3892012-10-29 13:34:43 +0000443static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000464static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Babicf8e9a212010-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 Chou1254c3d2010-12-24 13:12:21 +0000490 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
491 (mmc->voltages & 0xff8000);
Andy Flemingad347bb2008-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 Chou1254c3d2010-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 Chou1254c3d2010-12-24 13:12:21 +0000514
515 err = mmc_send_cmd(mmc, &cmd, NULL);
516
517 if (err)
518 return err;
519 }
520
Rabin Vincentb6eed942009-04-05 13:30:56 +0530521 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-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 Chiou4a2c7d72012-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 Flemingad347bb2008-10-30 16:41:01 -0500532{
Andy Flemingad347bb2008-10-30 16:41:01 -0500533 int err;
534
Che-Liang Chiou4a2c7d72012-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 Flemingad347bb2008-10-30 16:41:01 -0500559 /* Some cards seem to need this */
560 mmc_go_idle(mmc);
561
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000562 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-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);
566 if (err)
567 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200568
Che-Liang Chiou4a2c7d72012-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}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200575
Che-Liang Chiou4a2c7d72012-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;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200582
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000583 mmc->op_cond_pending = 0;
584 start = get_timer(0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500585 do {
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000586 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
Andy Flemingad347bb2008-10-30 16:41:01 -0500587 if (err)
588 return err;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000589 if (get_timer(start) > timeout)
590 return UNUSABLE_ERR;
591 udelay(100);
592 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Flemingad347bb2008-10-30 16:41:01 -0500593
Thomas Chou1254c3d2010-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 Chou1254c3d2010-12-24 13:12:21 +0000598
599 err = mmc_send_cmd(mmc, &cmd, NULL);
600
601 if (err)
602 return err;
603 }
604
Andy Flemingad347bb2008-10-30 16:41:01 -0500605 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincentb6eed942009-04-05 13:30:56 +0530606 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000615static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -0500625
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000626 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500627 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000628 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000637static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500638{
639 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000640 int timeout = 1000;
641 int ret;
Andy Flemingad347bb2008-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 Recalcati01a0dc62011-03-11 02:01:12 +0000646 (index << 16) |
647 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500648
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000649 ret = mmc_send_cmd(mmc, &cmd, NULL);
650
651 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000652 if (!ret)
653 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000654
655 return ret;
656
Andy Flemingad347bb2008-10-30 16:41:01 -0500657}
658
Kim Phillips87ea3892012-10-29 13:34:43 +0000659static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500660{
Simon Glassa09c2b72013-04-03 08:54:30 +0000661 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500662 char cardtype;
663 int err;
664
665 mmc->card_caps = 0;
666
Thomas Chou1254c3d2010-12-24 13:12:21 +0000667 if (mmc_host_is_spi(mmc))
668 return 0;
669
Andy Flemingad347bb2008-10-30 16:41:01 -0500670 /* Only version 4 supports high-speed */
671 if (mmc->version < MMC_VERSION_4)
672 return 0;
673
Andy Flemingad347bb2008-10-30 16:41:01 -0500674 err = mmc_send_ext_csd(mmc, ext_csd);
675
676 if (err)
677 return err;
678
Lei Wen217467f2011-10-03 20:35:10 +0000679 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-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 Wen217467f2011-10-03 20:35:10 +0000693 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-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 Warrene315ae82013-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 Wen31b99802011-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 Warrene315ae82013-06-11 15:14:01 -0600736 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000737
738 if (!mmc)
739 return -1;
740
Stephen Warrene315ae82013-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 Wen31b99802011-05-02 16:26:26 +0000748}
749
Thierry Redingb9c8b772012-01-02 01:15:37 +0000750int mmc_getcd(struct mmc *mmc)
751{
752 int cd;
753
754 cd = board_mmc_getcd(mmc);
755
Peter Korsgaardf7b15102013-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 Redingb9c8b772012-01-02 01:15:37 +0000762
763 return cd;
764}
765
Kim Phillips87ea3892012-10-29 13:34:43 +0000766static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000787static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500788{
789 int err;
790 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000791 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
792 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500793 struct mmc_data data;
794 int timeout;
795
796 mmc->card_caps = 0;
797
Thomas Chou1254c3d2010-12-24 13:12:21 +0000798 if (mmc_host_is_spi(mmc))
799 return 0;
800
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -0500814
815 timeout = 3;
816
817retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000818 data.dest = (char *)scr;
Andy Flemingad347bb2008-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 Kharuzhy6e8edf42009-05-07 00:43:30 +0300832 mmc->scr[0] = __be32_to_cpu(scr[0]);
833 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-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 Chungd552bd12013-01-29 22:58:16 +0000844 if ((mmc->scr[0] >> 15) & 0x1)
845 mmc->version = SD_VERSION_3;
Andy Flemingad347bb2008-10-30 16:41:01 -0500846 break;
847 default:
848 mmc->version = SD_VERSION_1_0;
849 break;
850 }
851
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530852 if (mmc->scr[0] & SD_DATA_4BIT)
853 mmc->card_caps |= MMC_MODE_4BIT;
854
Andy Flemingad347bb2008-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 staaf9b00f0d2011-10-03 13:54:59 +0000862 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500863
864 if (err)
865 return err;
866
867 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300868 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500869 break;
870 }
871
Andy Flemingad347bb2008-10-30 16:41:01 -0500872 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300873 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500874 return 0;
875
Macpaul Lin24e92ec2011-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 staaf9b00f0d2011-10-03 13:54:59 +0000886 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500887
888 if (err)
889 return err;
890
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300891 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-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 Frysingerb588caf2010-10-20 01:15:53 +0000899static const int fbase[] = {
Andy Flemingad347bb2008-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 Frysingerb588caf2010-10-20 01:15:53 +0000909static const int multipliers[] = {
Andy Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000928static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000946static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -0500947{
948 mmc->bus_width = width;
949
950 mmc_set_ios(mmc);
951}
952
Kim Phillips87ea3892012-10-29 13:34:43 +0000953static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500954{
Stephen Warrene315ae82013-06-11 15:14:01 -0600955 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -0500956 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000957 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -0500958 struct mmc_cmd cmd;
Simon Glassa09c2b72013-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 Recalcati01a0dc62011-03-11 02:01:12 +0000961 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500962
Thomas Chou1254c3d2010-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 Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500975 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500978 cmd.resp_type = MMC_RSP_R2;
979 cmd.cmdarg = 0;
Andy Flemingad347bb2008-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 Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500997
Thomas Chou1254c3d2010-12-24 13:12:21 +0000998 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500999
Thomas Chou1254c3d2010-12-24 13:12:21 +00001000 if (err)
1001 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001002
Thomas Chou1254c3d2010-12-24 13:12:21 +00001003 if (IS_SD(mmc))
1004 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1005 }
Andy Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -05001011
1012 err = mmc_send_cmd(mmc, &cmd, NULL);
1013
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001014 /* Waiting for the ready status */
1015 mmc_send_status(mmc, timeout);
1016
Andy Flemingad347bb2008-10-30 16:41:01 -05001017 if (err)
1018 return err;
1019
Rabin Vincentb6eed942009-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 Flemingad347bb2008-10-30 16:41:01 -05001024
1025 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301026 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-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 Vincentbdf7a682009-04-05 13:30:55 +05301051 freq = fbase[(cmd.response[0] & 0x7)];
1052 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -05001053
1054 mmc->tran_speed = freq * mult;
1055
Rabin Vincentb6eed942009-04-05 13:30:56 +05301056 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001057
1058 if (IS_SD(mmc))
1059 mmc->write_bl_len = mmc->read_bl_len;
1060 else
Rabin Vincentb6eed942009-04-05 13:30:56 +05301061 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-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 Warrene315ae82013-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 Flemingad347bb2008-10-30 16:41:01 -05001079
Simon Glassa09c2b72013-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 Flemingad347bb2008-10-30 16:41:01 -05001082
Simon Glassa09c2b72013-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 Flemingad347bb2008-10-30 16:41:01 -05001085
1086 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-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 Bhargav4a32fba2011-10-05 03:13:23 +00001089 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001090 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001091 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001092
Thomas Chou1254c3d2010-12-24 13:12:21 +00001093 if (err)
1094 return err;
1095 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001096
Lei Wenea526762011-06-22 17:03:31 +00001097 /*
1098 * For SD, its erase group is always one sector
1099 */
1100 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +00001101 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-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 Phillips87ea3892012-10-29 13:34:43 +00001105 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda7d88de52011-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 Wen217467f2011-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 Glassa09c2b72013-04-03 08:54:30 +00001115 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +00001116 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -06001117 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301118 }
Lei Wen31b99802011-05-02 16:26:26 +00001119
Jaehoon Chung6108ef62013-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 Wenea526762011-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 Glassa09c2b72013-04-03 08:54:30 +00001143 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
Lei Wen217467f2011-10-03 20:35:10 +00001144 mmc->erase_grp_size =
Simon Glassa09c2b72013-04-03 08:54:30 +00001145 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
1146 MMC_MAX_BLOCK_LEN * 1024;
1147 } else {
Lei Wenea526762011-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 Wen31b99802011-05-02 16:26:26 +00001155 /* store the partition info of emmc */
Stephen Warren009784c2012-07-30 10:55:43 +00001156 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1157 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen217467f2011-10-03 20:35:10 +00001158 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrene315ae82013-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 Ghorai232293c2010-09-20 18:29:29 +05301172 }
1173
Stephen Warrene315ae82013-06-11 15:14:01 -06001174 err = mmc_set_capacity(mmc, mmc->part_num);
1175 if (err)
1176 return err;
1177
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Flemingad347bb2008-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 Chunge1d4c7b2012-03-26 21:16:03 +00001210 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001211 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001212 mmc->tran_speed = 25000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001213 } else {
Andy Flemingeb766ad2012-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 Flemingad347bb2008-10-30 16:41:01 -05001245 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001246 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001247
1248 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001249 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001250
Andy Flemingeb766ad2012-10-31 19:02:38 +00001251 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001252
Lei Wen4f5a6a52011-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 Flemingad347bb2008-10-30 16:41:01 -05001264
Andy Flemingeb766ad2012-10-31 19:02:38 +00001265 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen4f5a6a52011-10-03 20:35:11 +00001266 break;
1267 }
Andy Flemingad347bb2008-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 Chunge1d4c7b2012-03-26 21:16:03 +00001272 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001273 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001274 mmc->tran_speed = 26000000;
1275 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001276 }
1277
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001278 mmc_set_clock(mmc, mmc->tran_speed);
1279
Andy Flemingad347bb2008-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 Eich2eec2ab2013-04-09 21:11:56 +00001284 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent69d4e2c2009-04-05 13:30:54 +05301285 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Taylor Hutt7367ec22012-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 Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001295#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001296 init_part(&mmc->block_dev);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001297#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001298
1299 return 0;
1300}
1301
Kim Phillips87ea3892012-10-29 13:34:43 +00001302static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -05001311
1312 err = mmc_send_cmd(mmc, &cmd, NULL);
1313
1314 if (err)
1315 return err;
1316
Rabin Vincentb6eed942009-04-05 13:30:56 +05301317 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-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 Wenea526762011-06-22 17:03:31 +00001333 mmc->block_dev.block_erase = mmc_berase;
John Rigbyf2f43662011-04-18 05:50:08 +00001334 if (!mmc->b_max)
1335 mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
Andy Flemingad347bb2008-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 McClintock6252b4f2011-05-24 05:31:19 +00001344#ifdef CONFIG_PARTITIONS
Andy Flemingad347bb2008-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ébaudeau6ce8aed2012-08-10 08:59:12 +00001348 if (!mmc || mmc_init(mmc))
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001349 return NULL;
Andy Flemingad347bb2008-10-30 16:41:01 -05001350
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001351 return &mmc->block_dev;
Andy Flemingad347bb2008-10-30 16:41:01 -05001352}
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001353#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001354
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001355int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001356{
Macpaul Lin028bde12011-11-14 23:35:39 +00001357 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001358
Thierry Redingb9c8b772012-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 Wen31b99802011-05-02 16:26:26 +00001365 if (mmc->has_init)
1366 return 0;
1367
Andy Flemingad347bb2008-10-30 16:41:01 -05001368 err = mmc->init(mmc);
1369
1370 if (err)
1371 return err;
1372
Ilya Yanok8459aab2009-06-29 17:53:16 +04001373 mmc_set_bus_width(mmc, 1);
1374 mmc_set_clock(mmc, 1);
1375
Andy Flemingad347bb2008-10-30 16:41:01 -05001376 /* Reset the Card */
1377 err = mmc_go_idle(mmc);
1378
1379 if (err)
1380 return err;
1381
Lei Wen31b99802011-05-02 16:26:26 +00001382 /* The internal partition reset to user partition(0) at every CMD0*/
1383 mmc->part_num = 0;
1384
Andy Flemingad347bb2008-10-30 16:41:01 -05001385 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001386 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001387
Andy Flemingad347bb2008-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 Chiou4a2c7d72012-11-28 15:21:13 +00001395 if (err && err != IN_PROGRESS) {
Andy Flemingad347bb2008-10-30 16:41:01 -05001396 printf("Card did not respond to voltage select!\n");
1397 return UNUSABLE_ERR;
1398 }
1399 }
1400
Che-Liang Chiou4a2c7d72012-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 Wen31b99802011-05-02 16:26:26 +00001416 if (err)
1417 mmc->has_init = 0;
1418 else
1419 mmc->has_init = 1;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001420 mmc->init_in_progress = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001421 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001422}
1423
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001424int 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));
1437 return err;
1438}
1439
Andy Flemingad347bb2008-10-30 16:41:01 -05001440/*
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 Tyser21d2cd22009-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 Flemingad347bb2008-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 Wend430d7c2011-05-02 16:26:25 +00001469int get_mmc_num(void)
1470{
1471 return cur_dev_num;
1472}
1473
Che-Liang Chiou4a2c7d72012-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 Flemingad347bb2008-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 Chiou4a2c7d72012-11-28 15:21:13 +00001503 do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001504 return 0;
1505}