blob: 36f80fa09f1c6d5b2778505eb999034b8172076f [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
Stefano Babic11fdade2010-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 Fleming272cc702008-10-30 16:41:01 -050050int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
51{
Raffaele Recalcati5db2fe32011-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 Fleming272cc702008-10-30 16:41:01 -0500104 return mmc->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000105#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500106}
107
Raffaele Recalcati5d4fc8d2011-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 Recalcati5db2fe32011-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 Recalcati5d4fc8d2011-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 Fleming272cc702008-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 Wen01581262010-10-14 13:38:11 +0800178mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
Andy Fleming272cc702008-10-30 16:41:01 -0500179{
180 struct mmc_cmd cmd;
181 struct mmc_data data;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000182 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500183
Lei Wend2bf29e2010-09-13 22:07:27 +0800184 if ((start + blkcnt) > mmc->block_dev.lba) {
Steve Sakomandef412b2010-10-28 09:00:26 -0700185 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800186 start + blkcnt, mmc->block_dev.lba);
187 return 0;
188 }
Andy Fleming272cc702008-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 Sakomandef412b2010-10-28 09:00:26 -0700198 cmd.cmdarg = start * mmc->write_bl_len;
Andy Fleming272cc702008-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 Sakomandef412b2010-10-28 09:00:26 -0700205 data.blocksize = mmc->write_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500206 data.flags = MMC_DATA_WRITE;
207
Steve Sakomandef412b2010-10-28 09:00:26 -0700208 if (mmc_send_cmd(mmc, &cmd, &data)) {
209 printf("mmc write failed\n");
210 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500211 }
212
Thomas Choud52ebf12010-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 Fleming272cc702008-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 Sakomandef412b2010-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 Wen01581262010-10-14 13:38:11 +0800224 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000225
226 /* Waiting for the ready status */
227 mmc_send_status(mmc, timeout);
Andy Fleming272cc702008-10-30 16:41:01 -0500228 }
229
230 return blkcnt;
231}
232
Lei Wen01581262010-10-14 13:38:11 +0800233static ulong
234mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
235{
Lei Wen01581262010-10-14 13:38:11 +0800236 lbaint_t cur, blocks_todo = blkcnt;
237
Steve Sakomandef412b2010-10-28 09:00:26 -0700238 struct mmc *mmc = find_mmc_device(dev_num);
Lei Wen01581262010-10-14 13:38:11 +0800239 if (!mmc)
Steve Sakomandef412b2010-10-28 09:00:26 -0700240 return 0;
Lei Wen01581262010-10-14 13:38:11 +0800241
Steve Sakomandef412b2010-10-28 09:00:26 -0700242 if (mmc_set_blocklen(mmc, mmc->write_bl_len))
243 return 0;
Lei Wen01581262010-10-14 13:38:11 +0800244
245 do {
Matt Waddelce0fbcd2011-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 Wen01581262010-10-14 13:38:11 +0800248 if(mmc_write_blocks(mmc, start, cur, src) != cur)
Steve Sakomandef412b2010-10-28 09:00:26 -0700249 return 0;
Lei Wen01581262010-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
255 return blkcnt;
256}
257
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700258int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500259{
260 struct mmc_cmd cmd;
261 struct mmc_data data;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000262 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500263
Alagu Sankar4a1a06b2010-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 Fleming272cc702008-10-30 16:41:01 -0500268
269 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700270 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500271 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700272 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500273
274 cmd.resp_type = MMC_RSP_R1;
275 cmd.flags = 0;
276
277 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700278 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500279 data.blocksize = mmc->read_bl_len;
280 data.flags = MMC_DATA_READ;
281
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700282 if (mmc_send_cmd(mmc, &cmd, &data))
283 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500284
Alagu Sankar4a1a06b2010-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 Recalcati5d4fc8d2011-03-11 02:01:12 +0000294
295 /* Waiting for the ready status */
296 mmc_send_status(mmc, timeout);
Andy Fleming272cc702008-10-30 16:41:01 -0500297 }
298
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700299 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500300}
301
302static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
303{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700304 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500305
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700306 if (blkcnt == 0)
307 return 0;
308
309 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500310 if (!mmc)
311 return 0;
312
Lei Wend2bf29e2010-09-13 22:07:27 +0800313 if ((start + blkcnt) > mmc->block_dev.lba) {
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700314 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800315 start + blkcnt, mmc->block_dev.lba);
316 return 0;
317 }
Andy Fleming272cc702008-10-30 16:41:01 -0500318
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700319 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500320 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500321
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700322 do {
Matt Waddelce0fbcd2011-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 Sankar4a1a06b2010-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 Fleming272cc702008-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 Babic250de122010-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 Choud52ebf12010-12-24 13:12:21 +0000385 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
386 (mmc->voltages & 0xff8000);
Andy Fleming272cc702008-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 Choud52ebf12010-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 Vincent998be3d2009-04-05 13:30:56 +0530417 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-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 Recalcati31cacba2011-03-11 02:01:13 +0000427 int timeout = 10000;
Andy Fleming272cc702008-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 Recalcati31cacba2011-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 Fleming272cc702008-10-30 16:41:01 -0500447 do {
448 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
449 cmd.resp_type = MMC_RSP_R3;
Raffaele Recalcati31cacba2011-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 Fleming272cc702008-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 Choud52ebf12010-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 Fleming272cc702008-10-30 16:41:01 -0500479 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincent998be3d2009-04-05 13:30:56 +0530480 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-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 Recalcati5d4fc8d2011-03-11 02:01:12 +0000515 int timeout = 1000;
516 int ret;
Andy Fleming272cc702008-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 Recalcati5d4fc8d2011-03-11 02:01:12 +0000521 (index << 16) |
522 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500523 cmd.flags = 0;
524
Raffaele Recalcati5d4fc8d2011-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 Fleming272cc702008-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 Choud52ebf12010-12-24 13:12:21 +0000542 if (mmc_host_is_spi(mmc))
543 return 0;
544
Andy Fleming272cc702008-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
556 if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
557 mmc->high_capacity = 1;
558
559 cardtype = ext_csd[196] & 0xf;
560
561 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
562
563 if (err)
564 return err;
565
566 /* Now check to see that it worked */
567 err = mmc_send_ext_csd(mmc, ext_csd);
568
569 if (err)
570 return err;
571
572 /* No high-speed support */
573 if (!ext_csd[185])
574 return 0;
575
576 /* High Speed is set, there are two types: 52MHz and 26MHz */
577 if (cardtype & MMC_HS_52MHZ)
578 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
579 else
580 mmc->card_caps |= MMC_MODE_HS;
581
582 return 0;
583}
584
585int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
586{
587 struct mmc_cmd cmd;
588 struct mmc_data data;
589
590 /* Switch the frequency */
591 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
592 cmd.resp_type = MMC_RSP_R1;
593 cmd.cmdarg = (mode << 31) | 0xffffff;
594 cmd.cmdarg &= ~(0xf << (group * 4));
595 cmd.cmdarg |= value << (group * 4);
596 cmd.flags = 0;
597
598 data.dest = (char *)resp;
599 data.blocksize = 64;
600 data.blocks = 1;
601 data.flags = MMC_DATA_READ;
602
603 return mmc_send_cmd(mmc, &cmd, &data);
604}
605
606
607int sd_change_freq(struct mmc *mmc)
608{
609 int err;
610 struct mmc_cmd cmd;
611 uint scr[2];
612 uint switch_status[16];
613 struct mmc_data data;
614 int timeout;
615
616 mmc->card_caps = 0;
617
Thomas Choud52ebf12010-12-24 13:12:21 +0000618 if (mmc_host_is_spi(mmc))
619 return 0;
620
Andy Fleming272cc702008-10-30 16:41:01 -0500621 /* Read the SCR to find out if this card supports higher speeds */
622 cmd.cmdidx = MMC_CMD_APP_CMD;
623 cmd.resp_type = MMC_RSP_R1;
624 cmd.cmdarg = mmc->rca << 16;
625 cmd.flags = 0;
626
627 err = mmc_send_cmd(mmc, &cmd, NULL);
628
629 if (err)
630 return err;
631
632 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
633 cmd.resp_type = MMC_RSP_R1;
634 cmd.cmdarg = 0;
635 cmd.flags = 0;
636
637 timeout = 3;
638
639retry_scr:
640 data.dest = (char *)&scr;
641 data.blocksize = 8;
642 data.blocks = 1;
643 data.flags = MMC_DATA_READ;
644
645 err = mmc_send_cmd(mmc, &cmd, &data);
646
647 if (err) {
648 if (timeout--)
649 goto retry_scr;
650
651 return err;
652 }
653
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300654 mmc->scr[0] = __be32_to_cpu(scr[0]);
655 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500656
657 switch ((mmc->scr[0] >> 24) & 0xf) {
658 case 0:
659 mmc->version = SD_VERSION_1_0;
660 break;
661 case 1:
662 mmc->version = SD_VERSION_1_10;
663 break;
664 case 2:
665 mmc->version = SD_VERSION_2;
666 break;
667 default:
668 mmc->version = SD_VERSION_1_0;
669 break;
670 }
671
Alagu Sankarb44c7082010-05-12 15:08:24 +0530672 if (mmc->scr[0] & SD_DATA_4BIT)
673 mmc->card_caps |= MMC_MODE_4BIT;
674
Andy Fleming272cc702008-10-30 16:41:01 -0500675 /* Version 1.0 doesn't support switching */
676 if (mmc->version == SD_VERSION_1_0)
677 return 0;
678
679 timeout = 4;
680 while (timeout--) {
681 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
682 (u8 *)&switch_status);
683
684 if (err)
685 return err;
686
687 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300688 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500689 break;
690 }
691
Andy Fleming272cc702008-10-30 16:41:01 -0500692 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300693 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500694 return 0;
695
696 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
697
698 if (err)
699 return err;
700
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300701 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500702 mmc->card_caps |= MMC_MODE_HS;
703
704 return 0;
705}
706
707/* frequency bases */
708/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000709static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500710 10000,
711 100000,
712 1000000,
713 10000000,
714};
715
716/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
717 * to platforms without floating point.
718 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000719static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500720 0, /* reserved */
721 10,
722 12,
723 13,
724 15,
725 20,
726 25,
727 30,
728 35,
729 40,
730 45,
731 50,
732 55,
733 60,
734 70,
735 80,
736};
737
738void mmc_set_ios(struct mmc *mmc)
739{
740 mmc->set_ios(mmc);
741}
742
743void mmc_set_clock(struct mmc *mmc, uint clock)
744{
745 if (clock > mmc->f_max)
746 clock = mmc->f_max;
747
748 if (clock < mmc->f_min)
749 clock = mmc->f_min;
750
751 mmc->clock = clock;
752
753 mmc_set_ios(mmc);
754}
755
756void mmc_set_bus_width(struct mmc *mmc, uint width)
757{
758 mmc->bus_width = width;
759
760 mmc_set_ios(mmc);
761}
762
763int mmc_startup(struct mmc *mmc)
764{
765 int err;
766 uint mult, freq;
767 u64 cmult, csize;
768 struct mmc_cmd cmd;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530769 char ext_csd[512];
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000770 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500771
Thomas Choud52ebf12010-12-24 13:12:21 +0000772#ifdef CONFIG_MMC_SPI_CRC_ON
773 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
774 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
775 cmd.resp_type = MMC_RSP_R1;
776 cmd.cmdarg = 1;
777 cmd.flags = 0;
778 err = mmc_send_cmd(mmc, &cmd, NULL);
779
780 if (err)
781 return err;
782 }
783#endif
784
Andy Fleming272cc702008-10-30 16:41:01 -0500785 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000786 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
787 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -0500788 cmd.resp_type = MMC_RSP_R2;
789 cmd.cmdarg = 0;
790 cmd.flags = 0;
791
792 err = mmc_send_cmd(mmc, &cmd, NULL);
793
794 if (err)
795 return err;
796
797 memcpy(mmc->cid, cmd.response, 16);
798
799 /*
800 * For MMC cards, set the Relative Address.
801 * For SD cards, get the Relatvie Address.
802 * This also puts the cards into Standby State
803 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000804 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
805 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
806 cmd.cmdarg = mmc->rca << 16;
807 cmd.resp_type = MMC_RSP_R6;
808 cmd.flags = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500809
Thomas Choud52ebf12010-12-24 13:12:21 +0000810 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500811
Thomas Choud52ebf12010-12-24 13:12:21 +0000812 if (err)
813 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500814
Thomas Choud52ebf12010-12-24 13:12:21 +0000815 if (IS_SD(mmc))
816 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
817 }
Andy Fleming272cc702008-10-30 16:41:01 -0500818
819 /* Get the Card-Specific Data */
820 cmd.cmdidx = MMC_CMD_SEND_CSD;
821 cmd.resp_type = MMC_RSP_R2;
822 cmd.cmdarg = mmc->rca << 16;
823 cmd.flags = 0;
824
825 err = mmc_send_cmd(mmc, &cmd, NULL);
826
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000827 /* Waiting for the ready status */
828 mmc_send_status(mmc, timeout);
829
Andy Fleming272cc702008-10-30 16:41:01 -0500830 if (err)
831 return err;
832
Rabin Vincent998be3d2009-04-05 13:30:56 +0530833 mmc->csd[0] = cmd.response[0];
834 mmc->csd[1] = cmd.response[1];
835 mmc->csd[2] = cmd.response[2];
836 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -0500837
838 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530839 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500840
841 switch (version) {
842 case 0:
843 mmc->version = MMC_VERSION_1_2;
844 break;
845 case 1:
846 mmc->version = MMC_VERSION_1_4;
847 break;
848 case 2:
849 mmc->version = MMC_VERSION_2_2;
850 break;
851 case 3:
852 mmc->version = MMC_VERSION_3;
853 break;
854 case 4:
855 mmc->version = MMC_VERSION_4;
856 break;
857 default:
858 mmc->version = MMC_VERSION_1_2;
859 break;
860 }
861 }
862
863 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530864 freq = fbase[(cmd.response[0] & 0x7)];
865 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -0500866
867 mmc->tran_speed = freq * mult;
868
Rabin Vincent998be3d2009-04-05 13:30:56 +0530869 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500870
871 if (IS_SD(mmc))
872 mmc->write_bl_len = mmc->read_bl_len;
873 else
Rabin Vincent998be3d2009-04-05 13:30:56 +0530874 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500875
876 if (mmc->high_capacity) {
877 csize = (mmc->csd[1] & 0x3f) << 16
878 | (mmc->csd[2] & 0xffff0000) >> 16;
879 cmult = 8;
880 } else {
881 csize = (mmc->csd[1] & 0x3ff) << 2
882 | (mmc->csd[2] & 0xc0000000) >> 30;
883 cmult = (mmc->csd[2] & 0x00038000) >> 15;
884 }
885
886 mmc->capacity = (csize + 1) << (cmult + 2);
887 mmc->capacity *= mmc->read_bl_len;
888
889 if (mmc->read_bl_len > 512)
890 mmc->read_bl_len = 512;
891
892 if (mmc->write_bl_len > 512)
893 mmc->write_bl_len = 512;
894
895 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000896 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
897 cmd.cmdidx = MMC_CMD_SELECT_CARD;
898 cmd.resp_type = MMC_RSP_R1b;
899 cmd.cmdarg = mmc->rca << 16;
900 cmd.flags = 0;
901 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500902
Thomas Choud52ebf12010-12-24 13:12:21 +0000903 if (err)
904 return err;
905 }
Andy Fleming272cc702008-10-30 16:41:01 -0500906
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530907 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
908 /* check ext_csd version and capacity */
909 err = mmc_send_ext_csd(mmc, ext_csd);
910 if (!err & (ext_csd[192] >= 2)) {
911 mmc->capacity = ext_csd[212] << 0 | ext_csd[213] << 8 |
912 ext_csd[214] << 16 | ext_csd[215] << 24;
913 mmc->capacity *= 512;
914 }
915 }
916
Andy Fleming272cc702008-10-30 16:41:01 -0500917 if (IS_SD(mmc))
918 err = sd_change_freq(mmc);
919 else
920 err = mmc_change_freq(mmc);
921
922 if (err)
923 return err;
924
925 /* Restrict card's capabilities by what the host can do */
926 mmc->card_caps &= mmc->host_caps;
927
928 if (IS_SD(mmc)) {
929 if (mmc->card_caps & MMC_MODE_4BIT) {
930 cmd.cmdidx = MMC_CMD_APP_CMD;
931 cmd.resp_type = MMC_RSP_R1;
932 cmd.cmdarg = mmc->rca << 16;
933 cmd.flags = 0;
934
935 err = mmc_send_cmd(mmc, &cmd, NULL);
936 if (err)
937 return err;
938
939 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
940 cmd.resp_type = MMC_RSP_R1;
941 cmd.cmdarg = 2;
942 cmd.flags = 0;
943 err = mmc_send_cmd(mmc, &cmd, NULL);
944 if (err)
945 return err;
946
947 mmc_set_bus_width(mmc, 4);
948 }
949
950 if (mmc->card_caps & MMC_MODE_HS)
951 mmc_set_clock(mmc, 50000000);
952 else
953 mmc_set_clock(mmc, 25000000);
954 } else {
955 if (mmc->card_caps & MMC_MODE_4BIT) {
956 /* Set the card to use 4 bit*/
957 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
958 EXT_CSD_BUS_WIDTH,
959 EXT_CSD_BUS_WIDTH_4);
960
961 if (err)
962 return err;
963
964 mmc_set_bus_width(mmc, 4);
965 } else if (mmc->card_caps & MMC_MODE_8BIT) {
966 /* Set the card to use 8 bit*/
967 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
968 EXT_CSD_BUS_WIDTH,
969 EXT_CSD_BUS_WIDTH_8);
970
971 if (err)
972 return err;
973
974 mmc_set_bus_width(mmc, 8);
975 }
976
977 if (mmc->card_caps & MMC_MODE_HS) {
978 if (mmc->card_caps & MMC_MODE_HS_52MHz)
979 mmc_set_clock(mmc, 52000000);
980 else
981 mmc_set_clock(mmc, 26000000);
982 } else
983 mmc_set_clock(mmc, 20000000);
984 }
985
986 /* fill in device description */
987 mmc->block_dev.lun = 0;
988 mmc->block_dev.type = 0;
989 mmc->block_dev.blksz = mmc->read_bl_len;
Rabin Vincent9b1f9422009-04-05 13:30:54 +0530990 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530991 sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8,
992 (mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
993 sprintf(mmc->block_dev.product, "%c%c%c%c%c", mmc->cid[0] & 0xff,
994 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
995 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
996 sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
997 (mmc->cid[2] >> 24) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500998 init_part(&mmc->block_dev);
999
1000 return 0;
1001}
1002
1003int mmc_send_if_cond(struct mmc *mmc)
1004{
1005 struct mmc_cmd cmd;
1006 int err;
1007
1008 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1009 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
1010 cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
1011 cmd.resp_type = MMC_RSP_R7;
1012 cmd.flags = 0;
1013
1014 err = mmc_send_cmd(mmc, &cmd, NULL);
1015
1016 if (err)
1017 return err;
1018
Rabin Vincent998be3d2009-04-05 13:30:56 +05301019 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001020 return UNUSABLE_ERR;
1021 else
1022 mmc->version = SD_VERSION_2;
1023
1024 return 0;
1025}
1026
1027int mmc_register(struct mmc *mmc)
1028{
1029 /* Setup the universal parts of the block interface just once */
1030 mmc->block_dev.if_type = IF_TYPE_MMC;
1031 mmc->block_dev.dev = cur_dev_num++;
1032 mmc->block_dev.removable = 1;
1033 mmc->block_dev.block_read = mmc_bread;
1034 mmc->block_dev.block_write = mmc_bwrite;
1035
1036 INIT_LIST_HEAD (&mmc->link);
1037
1038 list_add_tail (&mmc->link, &mmc_devices);
1039
1040 return 0;
1041}
1042
1043block_dev_desc_t *mmc_get_dev(int dev)
1044{
1045 struct mmc *mmc = find_mmc_device(dev);
1046
Rabin Vincente85649c2009-04-05 13:30:53 +05301047 return mmc ? &mmc->block_dev : NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001048}
1049
1050int mmc_init(struct mmc *mmc)
1051{
1052 int err;
1053
1054 err = mmc->init(mmc);
1055
1056 if (err)
1057 return err;
1058
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001059 mmc_set_bus_width(mmc, 1);
1060 mmc_set_clock(mmc, 1);
1061
Andy Fleming272cc702008-10-30 16:41:01 -05001062 /* Reset the Card */
1063 err = mmc_go_idle(mmc);
1064
1065 if (err)
1066 return err;
1067
1068 /* Test for SD version 2 */
1069 err = mmc_send_if_cond(mmc);
1070
Andy Fleming272cc702008-10-30 16:41:01 -05001071 /* Now try to get the SD card's operating condition */
1072 err = sd_send_op_cond(mmc);
1073
1074 /* If the command timed out, we check for an MMC card */
1075 if (err == TIMEOUT) {
1076 err = mmc_send_op_cond(mmc);
1077
1078 if (err) {
1079 printf("Card did not respond to voltage select!\n");
1080 return UNUSABLE_ERR;
1081 }
1082 }
1083
1084 return mmc_startup(mmc);
1085}
1086
1087/*
1088 * CPU and board-specific MMC initializations. Aliased function
1089 * signals caller to move on
1090 */
1091static int __def_mmc_init(bd_t *bis)
1092{
1093 return -1;
1094}
1095
Peter Tyserf9a109b2009-04-20 11:08:46 -05001096int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1097int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Fleming272cc702008-10-30 16:41:01 -05001098
1099void print_mmc_devices(char separator)
1100{
1101 struct mmc *m;
1102 struct list_head *entry;
1103
1104 list_for_each(entry, &mmc_devices) {
1105 m = list_entry(entry, struct mmc, link);
1106
1107 printf("%s: %d", m->name, m->block_dev.dev);
1108
1109 if (entry->next != &mmc_devices)
1110 printf("%c ", separator);
1111 }
1112
1113 printf("\n");
1114}
1115
1116int mmc_initialize(bd_t *bis)
1117{
1118 INIT_LIST_HEAD (&mmc_devices);
1119 cur_dev_num = 0;
1120
1121 if (board_mmc_init(bis) < 0)
1122 cpu_mmc_init(bis);
1123
1124 print_mmc_devices(',');
1125
1126 return 0;
1127}