blob: f27b7c79e50e310fc047fbcbf6e4bd19bb03698c [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
Stefano Babic6e00edf2010-02-05 15:04:43 +010043int __board_mmc_getcd(u8 *cd, struct mmc *mmc) {
44 return -1;
45}
46
47int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak,
48 alias("__board_mmc_getcd")));
49
Andy Flemingad347bb2008-10-30 16:41:01 -050050int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
51{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000052#ifdef CONFIG_MMC_TRACE
53 int ret;
54 int i;
55 u8 *ptr;
56
57 printf("CMD_SEND:%d\n", cmd->cmdidx);
58 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
59 printf("\t\tFLAG\t\t\t %d\n", cmd->flags);
60 ret = mmc->send_cmd(mmc, cmd, data);
61 switch (cmd->resp_type) {
62 case MMC_RSP_NONE:
63 printf("\t\tMMC_RSP_NONE\n");
64 break;
65 case MMC_RSP_R1:
66 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
67 cmd->response[0]);
68 break;
69 case MMC_RSP_R1b:
70 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
71 cmd->response[0]);
72 break;
73 case MMC_RSP_R2:
74 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
75 cmd->response[0]);
76 printf("\t\t \t\t 0x%08X \n",
77 cmd->response[1]);
78 printf("\t\t \t\t 0x%08X \n",
79 cmd->response[2]);
80 printf("\t\t \t\t 0x%08X \n",
81 cmd->response[3]);
82 printf("\n");
83 printf("\t\t\t\t\tDUMPING DATA\n");
84 for (i = 0; i < 4; i++) {
85 int j;
86 printf("\t\t\t\t\t%03d - ", i*4);
87 ptr = &cmd->response[i];
88 ptr += 3;
89 for (j = 0; j < 4; j++)
90 printf("%02X ", *ptr--);
91 printf("\n");
92 }
93 break;
94 case MMC_RSP_R3:
95 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
96 cmd->response[0]);
97 break;
98 default:
99 printf("\t\tERROR MMC rsp not supported\n");
100 break;
101 }
102 return ret;
103#else
Andy Flemingad347bb2008-10-30 16:41:01 -0500104 return mmc->send_cmd(mmc, cmd, data);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000105#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500106}
107
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000108int mmc_send_status(struct mmc *mmc, int timeout)
109{
110 struct mmc_cmd cmd;
111 int err;
112#ifdef CONFIG_MMC_TRACE
113 int status;
114#endif
115
116 cmd.cmdidx = MMC_CMD_SEND_STATUS;
117 cmd.resp_type = MMC_RSP_R1;
118 cmd.cmdarg = 0;
119 cmd.flags = 0;
120
121 do {
122 err = mmc_send_cmd(mmc, &cmd, NULL);
123 if (err)
124 return err;
125 else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
126 break;
127
128 udelay(1000);
129
130 if (cmd.response[0] & MMC_STATUS_MASK) {
131 printf("Status Error: 0x%08X\n", cmd.response[0]);
132 return COMM_ERR;
133 }
134 } while (timeout--);
135
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000136#ifdef CONFIG_MMC_TRACE
137 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
138 printf("CURR STATE:%d\n", status);
139#endif
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000140 if (!timeout) {
141 printf("Timeout waiting card ready\n");
142 return TIMEOUT;
143 }
144
145 return 0;
146}
147
Andy Flemingad347bb2008-10-30 16:41:01 -0500148int mmc_set_blocklen(struct mmc *mmc, int len)
149{
150 struct mmc_cmd cmd;
151
152 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
153 cmd.resp_type = MMC_RSP_R1;
154 cmd.cmdarg = len;
155 cmd.flags = 0;
156
157 return mmc_send_cmd(mmc, &cmd, NULL);
158}
159
160struct mmc *find_mmc_device(int dev_num)
161{
162 struct mmc *m;
163 struct list_head *entry;
164
165 list_for_each(entry, &mmc_devices) {
166 m = list_entry(entry, struct mmc, link);
167
168 if (m->block_dev.dev == dev_num)
169 return m;
170 }
171
172 printf("MMC Device %d not found\n", dev_num);
173
174 return NULL;
175}
176
177static ulong
Lei Wen6b405b72010-10-14 13:38:11 +0800178mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
Andy Flemingad347bb2008-10-30 16:41:01 -0500179{
180 struct mmc_cmd cmd;
181 struct mmc_data data;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000182 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500183
Lei Wene1cc9c82010-09-13 22:07:27 +0800184 if ((start + blkcnt) > mmc->block_dev.lba) {
Steve Sakomaneb288862010-10-28 09:00:26 -0700185 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800186 start + blkcnt, mmc->block_dev.lba);
187 return 0;
188 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500189
190 if (blkcnt > 1)
191 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
192 else
193 cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
194
195 if (mmc->high_capacity)
196 cmd.cmdarg = start;
197 else
Steve Sakomaneb288862010-10-28 09:00:26 -0700198 cmd.cmdarg = start * mmc->write_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500199
200 cmd.resp_type = MMC_RSP_R1;
201 cmd.flags = 0;
202
203 data.src = src;
204 data.blocks = blkcnt;
Steve Sakomaneb288862010-10-28 09:00:26 -0700205 data.blocksize = mmc->write_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500206 data.flags = MMC_DATA_WRITE;
207
Steve Sakomaneb288862010-10-28 09:00:26 -0700208 if (mmc_send_cmd(mmc, &cmd, &data)) {
209 printf("mmc write failed\n");
210 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500211 }
212
Thomas Chou1254c3d2010-12-24 13:12:21 +0000213 /* SPI multiblock writes terminate using a special
214 * token, not a STOP_TRANSMISSION request.
215 */
216 if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
Andy Flemingad347bb2008-10-30 16:41:01 -0500217 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
218 cmd.cmdarg = 0;
219 cmd.resp_type = MMC_RSP_R1b;
220 cmd.flags = 0;
Steve Sakomaneb288862010-10-28 09:00:26 -0700221 if (mmc_send_cmd(mmc, &cmd, NULL)) {
222 printf("mmc fail to send stop cmd\n");
223 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800224 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000225
226 /* Waiting for the ready status */
227 mmc_send_status(mmc, timeout);
Lei Wen6b405b72010-10-14 13:38:11 +0800228 }
229
230 return blkcnt;
231}
232
233static ulong
234mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
235{
Lei Wen6b405b72010-10-14 13:38:11 +0800236 lbaint_t cur, blocks_todo = blkcnt;
237
Steve Sakomaneb288862010-10-28 09:00:26 -0700238 struct mmc *mmc = find_mmc_device(dev_num);
Lei Wen6b405b72010-10-14 13:38:11 +0800239 if (!mmc)
Steve Sakomaneb288862010-10-28 09:00:26 -0700240 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800241
Steve Sakomaneb288862010-10-28 09:00:26 -0700242 if (mmc_set_blocklen(mmc, mmc->write_bl_len))
243 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500244
Lei Wen6b405b72010-10-14 13:38:11 +0800245 do {
Matt Waddeld0e3c802011-02-24 16:35:23 +0000246 cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
247 CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
Lei Wen6b405b72010-10-14 13:38:11 +0800248 if(mmc_write_blocks(mmc, start, cur, src) != cur)
Steve Sakomaneb288862010-10-28 09:00:26 -0700249 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800250 blocks_todo -= cur;
251 start += cur;
252 src += cur * mmc->write_bl_len;
253 } while (blocks_todo > 0);
254
Andy Flemingad347bb2008-10-30 16:41:01 -0500255 return blkcnt;
256}
257
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700258int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500259{
260 struct mmc_cmd cmd;
261 struct mmc_data data;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000262 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500263
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700264 if (blkcnt > 1)
265 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
266 else
267 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500268
269 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700270 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500271 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700272 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500273
274 cmd.resp_type = MMC_RSP_R1;
275 cmd.flags = 0;
276
277 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700278 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500279 data.blocksize = mmc->read_bl_len;
280 data.flags = MMC_DATA_READ;
281
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700282 if (mmc_send_cmd(mmc, &cmd, &data))
283 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500284
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700285 if (blkcnt > 1) {
286 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
287 cmd.cmdarg = 0;
288 cmd.resp_type = MMC_RSP_R1b;
289 cmd.flags = 0;
290 if (mmc_send_cmd(mmc, &cmd, NULL)) {
291 printf("mmc fail to send stop cmd\n");
292 return 0;
293 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000294
295 /* Waiting for the ready status */
296 mmc_send_status(mmc, timeout);
Andy Flemingad347bb2008-10-30 16:41:01 -0500297 }
298
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700299 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500300}
301
302static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
303{
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700304 lbaint_t cur, blocks_todo = blkcnt;
305
306 if (blkcnt == 0)
307 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500308
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700309 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500310 if (!mmc)
311 return 0;
312
Lei Wene1cc9c82010-09-13 22:07:27 +0800313 if ((start + blkcnt) > mmc->block_dev.lba) {
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700314 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800315 start + blkcnt, mmc->block_dev.lba);
316 return 0;
317 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500318
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700319 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Flemingad347bb2008-10-30 16:41:01 -0500320 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500321
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700322 do {
Matt Waddeld0e3c802011-02-24 16:35:23 +0000323 cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
324 CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700325 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
326 return 0;
327 blocks_todo -= cur;
328 start += cur;
329 dst += cur * mmc->read_bl_len;
330 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500331
332 return blkcnt;
333}
334
335int mmc_go_idle(struct mmc* mmc)
336{
337 struct mmc_cmd cmd;
338 int err;
339
340 udelay(1000);
341
342 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
343 cmd.cmdarg = 0;
344 cmd.resp_type = MMC_RSP_NONE;
345 cmd.flags = 0;
346
347 err = mmc_send_cmd(mmc, &cmd, NULL);
348
349 if (err)
350 return err;
351
352 udelay(2000);
353
354 return 0;
355}
356
357int
358sd_send_op_cond(struct mmc *mmc)
359{
360 int timeout = 1000;
361 int err;
362 struct mmc_cmd cmd;
363
364 do {
365 cmd.cmdidx = MMC_CMD_APP_CMD;
366 cmd.resp_type = MMC_RSP_R1;
367 cmd.cmdarg = 0;
368 cmd.flags = 0;
369
370 err = mmc_send_cmd(mmc, &cmd, NULL);
371
372 if (err)
373 return err;
374
375 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
376 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100377
378 /*
379 * Most cards do not answer if some reserved bits
380 * in the ocr are set. However, Some controller
381 * can set bit 7 (reserved for low voltages), but
382 * how to manage low voltages SD card is not yet
383 * specified.
384 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000385 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
386 (mmc->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500387
388 if (mmc->version == SD_VERSION_2)
389 cmd.cmdarg |= OCR_HCS;
390
391 err = mmc_send_cmd(mmc, &cmd, NULL);
392
393 if (err)
394 return err;
395
396 udelay(1000);
397 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
398
399 if (timeout <= 0)
400 return UNUSABLE_ERR;
401
402 if (mmc->version != SD_VERSION_2)
403 mmc->version = SD_VERSION_1_0;
404
Thomas Chou1254c3d2010-12-24 13:12:21 +0000405 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
406 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
407 cmd.resp_type = MMC_RSP_R3;
408 cmd.cmdarg = 0;
409 cmd.flags = 0;
410
411 err = mmc_send_cmd(mmc, &cmd, NULL);
412
413 if (err)
414 return err;
415 }
416
Rabin Vincentb6eed942009-04-05 13:30:56 +0530417 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500418
419 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
420 mmc->rca = 0;
421
422 return 0;
423}
424
425int mmc_send_op_cond(struct mmc *mmc)
426{
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000427 int timeout = 10000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500428 struct mmc_cmd cmd;
429 int err;
430
431 /* Some cards seem to need this */
432 mmc_go_idle(mmc);
433
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000434 /* Asking to the card its capabilities */
435 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
436 cmd.resp_type = MMC_RSP_R3;
437 cmd.cmdarg = 0;
438 cmd.flags = 0;
439
440 err = mmc_send_cmd(mmc, &cmd, NULL);
441
442 if (err)
443 return err;
444
445 udelay(1000);
446
Andy Flemingad347bb2008-10-30 16:41:01 -0500447 do {
448 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
449 cmd.resp_type = MMC_RSP_R3;
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000450 cmd.cmdarg = (mmc_host_is_spi(mmc) ? 0 :
451 (mmc->voltages &
452 (cmd.response[0] & OCR_VOLTAGE_MASK)) |
453 (cmd.response[0] & OCR_ACCESS_MODE));
Andy Flemingad347bb2008-10-30 16:41:01 -0500454 cmd.flags = 0;
455
456 err = mmc_send_cmd(mmc, &cmd, NULL);
457
458 if (err)
459 return err;
460
461 udelay(1000);
462 } while (!(cmd.response[0] & OCR_BUSY) && timeout--);
463
464 if (timeout <= 0)
465 return UNUSABLE_ERR;
466
Thomas Chou1254c3d2010-12-24 13:12:21 +0000467 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
468 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
469 cmd.resp_type = MMC_RSP_R3;
470 cmd.cmdarg = 0;
471 cmd.flags = 0;
472
473 err = mmc_send_cmd(mmc, &cmd, NULL);
474
475 if (err)
476 return err;
477 }
478
Andy Flemingad347bb2008-10-30 16:41:01 -0500479 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincentb6eed942009-04-05 13:30:56 +0530480 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500481
482 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
483 mmc->rca = 0;
484
485 return 0;
486}
487
488
489int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
490{
491 struct mmc_cmd cmd;
492 struct mmc_data data;
493 int err;
494
495 /* Get the Card Status Register */
496 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
497 cmd.resp_type = MMC_RSP_R1;
498 cmd.cmdarg = 0;
499 cmd.flags = 0;
500
501 data.dest = ext_csd;
502 data.blocks = 1;
503 data.blocksize = 512;
504 data.flags = MMC_DATA_READ;
505
506 err = mmc_send_cmd(mmc, &cmd, &data);
507
508 return err;
509}
510
511
512int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
513{
514 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000515 int timeout = 1000;
516 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500517
518 cmd.cmdidx = MMC_CMD_SWITCH;
519 cmd.resp_type = MMC_RSP_R1b;
520 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000521 (index << 16) |
522 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500523 cmd.flags = 0;
524
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000525 ret = mmc_send_cmd(mmc, &cmd, NULL);
526
527 /* Waiting for the ready status */
528 mmc_send_status(mmc, timeout);
529
530 return ret;
531
Andy Flemingad347bb2008-10-30 16:41:01 -0500532}
533
534int mmc_change_freq(struct mmc *mmc)
535{
536 char ext_csd[512];
537 char cardtype;
538 int err;
539
540 mmc->card_caps = 0;
541
Thomas Chou1254c3d2010-12-24 13:12:21 +0000542 if (mmc_host_is_spi(mmc))
543 return 0;
544
Andy Flemingad347bb2008-10-30 16:41:01 -0500545 /* Only version 4 supports high-speed */
546 if (mmc->version < MMC_VERSION_4)
547 return 0;
548
549 mmc->card_caps |= MMC_MODE_4BIT;
550
551 err = mmc_send_ext_csd(mmc, ext_csd);
552
553 if (err)
554 return err;
555
Andy Flemingad347bb2008-10-30 16:41:01 -0500556 cardtype = ext_csd[196] & 0xf;
557
558 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
559
560 if (err)
561 return err;
562
563 /* Now check to see that it worked */
564 err = mmc_send_ext_csd(mmc, ext_csd);
565
566 if (err)
567 return err;
568
569 /* No high-speed support */
570 if (!ext_csd[185])
571 return 0;
572
573 /* High Speed is set, there are two types: 52MHz and 26MHz */
574 if (cardtype & MMC_HS_52MHZ)
575 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
576 else
577 mmc->card_caps |= MMC_MODE_HS;
578
579 return 0;
580}
581
582int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
583{
584 struct mmc_cmd cmd;
585 struct mmc_data data;
586
587 /* Switch the frequency */
588 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
589 cmd.resp_type = MMC_RSP_R1;
590 cmd.cmdarg = (mode << 31) | 0xffffff;
591 cmd.cmdarg &= ~(0xf << (group * 4));
592 cmd.cmdarg |= value << (group * 4);
593 cmd.flags = 0;
594
595 data.dest = (char *)resp;
596 data.blocksize = 64;
597 data.blocks = 1;
598 data.flags = MMC_DATA_READ;
599
600 return mmc_send_cmd(mmc, &cmd, &data);
601}
602
603
604int sd_change_freq(struct mmc *mmc)
605{
606 int err;
607 struct mmc_cmd cmd;
608 uint scr[2];
609 uint switch_status[16];
610 struct mmc_data data;
611 int timeout;
612
613 mmc->card_caps = 0;
614
Thomas Chou1254c3d2010-12-24 13:12:21 +0000615 if (mmc_host_is_spi(mmc))
616 return 0;
617
Andy Flemingad347bb2008-10-30 16:41:01 -0500618 /* Read the SCR to find out if this card supports higher speeds */
619 cmd.cmdidx = MMC_CMD_APP_CMD;
620 cmd.resp_type = MMC_RSP_R1;
621 cmd.cmdarg = mmc->rca << 16;
622 cmd.flags = 0;
623
624 err = mmc_send_cmd(mmc, &cmd, NULL);
625
626 if (err)
627 return err;
628
629 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
630 cmd.resp_type = MMC_RSP_R1;
631 cmd.cmdarg = 0;
632 cmd.flags = 0;
633
634 timeout = 3;
635
636retry_scr:
637 data.dest = (char *)&scr;
638 data.blocksize = 8;
639 data.blocks = 1;
640 data.flags = MMC_DATA_READ;
641
642 err = mmc_send_cmd(mmc, &cmd, &data);
643
644 if (err) {
645 if (timeout--)
646 goto retry_scr;
647
648 return err;
649 }
650
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300651 mmc->scr[0] = __be32_to_cpu(scr[0]);
652 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500653
654 switch ((mmc->scr[0] >> 24) & 0xf) {
655 case 0:
656 mmc->version = SD_VERSION_1_0;
657 break;
658 case 1:
659 mmc->version = SD_VERSION_1_10;
660 break;
661 case 2:
662 mmc->version = SD_VERSION_2;
663 break;
664 default:
665 mmc->version = SD_VERSION_1_0;
666 break;
667 }
668
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530669 if (mmc->scr[0] & SD_DATA_4BIT)
670 mmc->card_caps |= MMC_MODE_4BIT;
671
Andy Flemingad347bb2008-10-30 16:41:01 -0500672 /* Version 1.0 doesn't support switching */
673 if (mmc->version == SD_VERSION_1_0)
674 return 0;
675
676 timeout = 4;
677 while (timeout--) {
678 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
679 (u8 *)&switch_status);
680
681 if (err)
682 return err;
683
684 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300685 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500686 break;
687 }
688
Andy Flemingad347bb2008-10-30 16:41:01 -0500689 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300690 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500691 return 0;
692
693 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
694
695 if (err)
696 return err;
697
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300698 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500699 mmc->card_caps |= MMC_MODE_HS;
700
701 return 0;
702}
703
704/* frequency bases */
705/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000706static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500707 10000,
708 100000,
709 1000000,
710 10000000,
711};
712
713/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
714 * to platforms without floating point.
715 */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000716static const int multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500717 0, /* reserved */
718 10,
719 12,
720 13,
721 15,
722 20,
723 25,
724 30,
725 35,
726 40,
727 45,
728 50,
729 55,
730 60,
731 70,
732 80,
733};
734
735void mmc_set_ios(struct mmc *mmc)
736{
737 mmc->set_ios(mmc);
738}
739
740void mmc_set_clock(struct mmc *mmc, uint clock)
741{
742 if (clock > mmc->f_max)
743 clock = mmc->f_max;
744
745 if (clock < mmc->f_min)
746 clock = mmc->f_min;
747
748 mmc->clock = clock;
749
750 mmc_set_ios(mmc);
751}
752
753void mmc_set_bus_width(struct mmc *mmc, uint width)
754{
755 mmc->bus_width = width;
756
757 mmc_set_ios(mmc);
758}
759
760int mmc_startup(struct mmc *mmc)
761{
762 int err;
763 uint mult, freq;
764 u64 cmult, csize;
765 struct mmc_cmd cmd;
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530766 char ext_csd[512];
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000767 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500768
Thomas Chou1254c3d2010-12-24 13:12:21 +0000769#ifdef CONFIG_MMC_SPI_CRC_ON
770 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
771 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
772 cmd.resp_type = MMC_RSP_R1;
773 cmd.cmdarg = 1;
774 cmd.flags = 0;
775 err = mmc_send_cmd(mmc, &cmd, NULL);
776
777 if (err)
778 return err;
779 }
780#endif
781
Andy Flemingad347bb2008-10-30 16:41:01 -0500782 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000783 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
784 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -0500785 cmd.resp_type = MMC_RSP_R2;
786 cmd.cmdarg = 0;
787 cmd.flags = 0;
788
789 err = mmc_send_cmd(mmc, &cmd, NULL);
790
791 if (err)
792 return err;
793
794 memcpy(mmc->cid, cmd.response, 16);
795
796 /*
797 * For MMC cards, set the Relative Address.
798 * For SD cards, get the Relatvie Address.
799 * This also puts the cards into Standby State
800 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000801 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
802 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
803 cmd.cmdarg = mmc->rca << 16;
804 cmd.resp_type = MMC_RSP_R6;
805 cmd.flags = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500806
Thomas Chou1254c3d2010-12-24 13:12:21 +0000807 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500808
Thomas Chou1254c3d2010-12-24 13:12:21 +0000809 if (err)
810 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500811
Thomas Chou1254c3d2010-12-24 13:12:21 +0000812 if (IS_SD(mmc))
813 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
814 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500815
816 /* Get the Card-Specific Data */
817 cmd.cmdidx = MMC_CMD_SEND_CSD;
818 cmd.resp_type = MMC_RSP_R2;
819 cmd.cmdarg = mmc->rca << 16;
820 cmd.flags = 0;
821
822 err = mmc_send_cmd(mmc, &cmd, NULL);
823
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000824 /* Waiting for the ready status */
825 mmc_send_status(mmc, timeout);
826
Andy Flemingad347bb2008-10-30 16:41:01 -0500827 if (err)
828 return err;
829
Rabin Vincentb6eed942009-04-05 13:30:56 +0530830 mmc->csd[0] = cmd.response[0];
831 mmc->csd[1] = cmd.response[1];
832 mmc->csd[2] = cmd.response[2];
833 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -0500834
835 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530836 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500837
838 switch (version) {
839 case 0:
840 mmc->version = MMC_VERSION_1_2;
841 break;
842 case 1:
843 mmc->version = MMC_VERSION_1_4;
844 break;
845 case 2:
846 mmc->version = MMC_VERSION_2_2;
847 break;
848 case 3:
849 mmc->version = MMC_VERSION_3;
850 break;
851 case 4:
852 mmc->version = MMC_VERSION_4;
853 break;
854 default:
855 mmc->version = MMC_VERSION_1_2;
856 break;
857 }
858 }
859
860 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530861 freq = fbase[(cmd.response[0] & 0x7)];
862 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -0500863
864 mmc->tran_speed = freq * mult;
865
Rabin Vincentb6eed942009-04-05 13:30:56 +0530866 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500867
868 if (IS_SD(mmc))
869 mmc->write_bl_len = mmc->read_bl_len;
870 else
Rabin Vincentb6eed942009-04-05 13:30:56 +0530871 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500872
873 if (mmc->high_capacity) {
874 csize = (mmc->csd[1] & 0x3f) << 16
875 | (mmc->csd[2] & 0xffff0000) >> 16;
876 cmult = 8;
877 } else {
878 csize = (mmc->csd[1] & 0x3ff) << 2
879 | (mmc->csd[2] & 0xc0000000) >> 30;
880 cmult = (mmc->csd[2] & 0x00038000) >> 15;
881 }
882
883 mmc->capacity = (csize + 1) << (cmult + 2);
884 mmc->capacity *= mmc->read_bl_len;
885
886 if (mmc->read_bl_len > 512)
887 mmc->read_bl_len = 512;
888
889 if (mmc->write_bl_len > 512)
890 mmc->write_bl_len = 512;
891
892 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000893 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
894 cmd.cmdidx = MMC_CMD_SELECT_CARD;
895 cmd.resp_type = MMC_RSP_R1b;
896 cmd.cmdarg = mmc->rca << 16;
897 cmd.flags = 0;
898 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500899
Thomas Chou1254c3d2010-12-24 13:12:21 +0000900 if (err)
901 return err;
902 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500903
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530904 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
905 /* check ext_csd version and capacity */
906 err = mmc_send_ext_csd(mmc, ext_csd);
907 if (!err & (ext_csd[192] >= 2)) {
908 mmc->capacity = ext_csd[212] << 0 | ext_csd[213] << 8 |
909 ext_csd[214] << 16 | ext_csd[215] << 24;
910 mmc->capacity *= 512;
911 }
912 }
913
Andy Flemingad347bb2008-10-30 16:41:01 -0500914 if (IS_SD(mmc))
915 err = sd_change_freq(mmc);
916 else
917 err = mmc_change_freq(mmc);
918
919 if (err)
920 return err;
921
922 /* Restrict card's capabilities by what the host can do */
923 mmc->card_caps &= mmc->host_caps;
924
925 if (IS_SD(mmc)) {
926 if (mmc->card_caps & MMC_MODE_4BIT) {
927 cmd.cmdidx = MMC_CMD_APP_CMD;
928 cmd.resp_type = MMC_RSP_R1;
929 cmd.cmdarg = mmc->rca << 16;
930 cmd.flags = 0;
931
932 err = mmc_send_cmd(mmc, &cmd, NULL);
933 if (err)
934 return err;
935
936 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
937 cmd.resp_type = MMC_RSP_R1;
938 cmd.cmdarg = 2;
939 cmd.flags = 0;
940 err = mmc_send_cmd(mmc, &cmd, NULL);
941 if (err)
942 return err;
943
944 mmc_set_bus_width(mmc, 4);
945 }
946
947 if (mmc->card_caps & MMC_MODE_HS)
948 mmc_set_clock(mmc, 50000000);
949 else
950 mmc_set_clock(mmc, 25000000);
951 } else {
952 if (mmc->card_caps & MMC_MODE_4BIT) {
953 /* Set the card to use 4 bit*/
954 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
955 EXT_CSD_BUS_WIDTH,
956 EXT_CSD_BUS_WIDTH_4);
957
958 if (err)
959 return err;
960
961 mmc_set_bus_width(mmc, 4);
962 } else if (mmc->card_caps & MMC_MODE_8BIT) {
963 /* Set the card to use 8 bit*/
964 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
965 EXT_CSD_BUS_WIDTH,
966 EXT_CSD_BUS_WIDTH_8);
967
968 if (err)
969 return err;
970
971 mmc_set_bus_width(mmc, 8);
972 }
973
974 if (mmc->card_caps & MMC_MODE_HS) {
975 if (mmc->card_caps & MMC_MODE_HS_52MHz)
976 mmc_set_clock(mmc, 52000000);
977 else
978 mmc_set_clock(mmc, 26000000);
979 } else
980 mmc_set_clock(mmc, 20000000);
981 }
982
983 /* fill in device description */
984 mmc->block_dev.lun = 0;
985 mmc->block_dev.type = 0;
986 mmc->block_dev.blksz = mmc->read_bl_len;
Rabin Vincent69d4e2c2009-04-05 13:30:54 +0530987 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530988 sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8,
989 (mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
990 sprintf(mmc->block_dev.product, "%c%c%c%c%c", mmc->cid[0] & 0xff,
991 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
992 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
993 sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
994 (mmc->cid[2] >> 24) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500995 init_part(&mmc->block_dev);
996
997 return 0;
998}
999
1000int mmc_send_if_cond(struct mmc *mmc)
1001{
1002 struct mmc_cmd cmd;
1003 int err;
1004
1005 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1006 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
1007 cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
1008 cmd.resp_type = MMC_RSP_R7;
1009 cmd.flags = 0;
1010
1011 err = mmc_send_cmd(mmc, &cmd, NULL);
1012
1013 if (err)
1014 return err;
1015
Rabin Vincentb6eed942009-04-05 13:30:56 +05301016 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-10-30 16:41:01 -05001017 return UNUSABLE_ERR;
1018 else
1019 mmc->version = SD_VERSION_2;
1020
1021 return 0;
1022}
1023
1024int mmc_register(struct mmc *mmc)
1025{
1026 /* Setup the universal parts of the block interface just once */
1027 mmc->block_dev.if_type = IF_TYPE_MMC;
1028 mmc->block_dev.dev = cur_dev_num++;
1029 mmc->block_dev.removable = 1;
1030 mmc->block_dev.block_read = mmc_bread;
1031 mmc->block_dev.block_write = mmc_bwrite;
1032
1033 INIT_LIST_HEAD (&mmc->link);
1034
1035 list_add_tail (&mmc->link, &mmc_devices);
1036
1037 return 0;
1038}
1039
1040block_dev_desc_t *mmc_get_dev(int dev)
1041{
1042 struct mmc *mmc = find_mmc_device(dev);
1043
Rabin Vincent3e448aa2009-04-05 13:30:53 +05301044 return mmc ? &mmc->block_dev : NULL;
Andy Flemingad347bb2008-10-30 16:41:01 -05001045}
1046
1047int mmc_init(struct mmc *mmc)
1048{
1049 int err;
1050
1051 err = mmc->init(mmc);
1052
1053 if (err)
1054 return err;
1055
Ilya Yanok8459aab2009-06-29 17:53:16 +04001056 mmc_set_bus_width(mmc, 1);
1057 mmc_set_clock(mmc, 1);
1058
Andy Flemingad347bb2008-10-30 16:41:01 -05001059 /* Reset the Card */
1060 err = mmc_go_idle(mmc);
1061
1062 if (err)
1063 return err;
1064
1065 /* Test for SD version 2 */
1066 err = mmc_send_if_cond(mmc);
1067
Andy Flemingad347bb2008-10-30 16:41:01 -05001068 /* Now try to get the SD card's operating condition */
1069 err = sd_send_op_cond(mmc);
1070
1071 /* If the command timed out, we check for an MMC card */
1072 if (err == TIMEOUT) {
1073 err = mmc_send_op_cond(mmc);
1074
1075 if (err) {
1076 printf("Card did not respond to voltage select!\n");
1077 return UNUSABLE_ERR;
1078 }
1079 }
1080
1081 return mmc_startup(mmc);
1082}
1083
1084/*
1085 * CPU and board-specific MMC initializations. Aliased function
1086 * signals caller to move on
1087 */
1088static int __def_mmc_init(bd_t *bis)
1089{
1090 return -1;
1091}
1092
Peter Tyser21d2cd22009-04-20 11:08:46 -05001093int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1094int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Flemingad347bb2008-10-30 16:41:01 -05001095
1096void print_mmc_devices(char separator)
1097{
1098 struct mmc *m;
1099 struct list_head *entry;
1100
1101 list_for_each(entry, &mmc_devices) {
1102 m = list_entry(entry, struct mmc, link);
1103
1104 printf("%s: %d", m->name, m->block_dev.dev);
1105
1106 if (entry->next != &mmc_devices)
1107 printf("%c ", separator);
1108 }
1109
1110 printf("\n");
1111}
1112
1113int mmc_initialize(bd_t *bis)
1114{
1115 INIT_LIST_HEAD (&mmc_devices);
1116 cur_dev_num = 0;
1117
1118 if (board_mmc_init(bis) < 0)
1119 cpu_mmc_init(bis);
1120
1121 print_mmc_devices(',');
1122
1123 return 0;
1124}