blob: 9c0652d9abcf9683d2d5dcc168b482a70bacc562 [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
304 if (blkcnt > 1)
305 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
306 else
307 cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
308
309 if (mmc->high_capacity)
310 cmd.cmdarg = start;
311 else
Steve Sakomaneb288862010-10-28 09:00:26 -0700312 cmd.cmdarg = start * mmc->write_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500313
314 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500315
316 data.src = src;
317 data.blocks = blkcnt;
Steve Sakomaneb288862010-10-28 09:00:26 -0700318 data.blocksize = mmc->write_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500319 data.flags = MMC_DATA_WRITE;
320
Steve Sakomaneb288862010-10-28 09:00:26 -0700321 if (mmc_send_cmd(mmc, &cmd, &data)) {
322 printf("mmc write failed\n");
323 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500324 }
325
Thomas Chou1254c3d2010-12-24 13:12:21 +0000326 /* SPI multiblock writes terminate using a special
327 * token, not a STOP_TRANSMISSION request.
328 */
329 if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
Andy Flemingad347bb2008-10-30 16:41:01 -0500330 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
331 cmd.cmdarg = 0;
332 cmd.resp_type = MMC_RSP_R1b;
Steve Sakomaneb288862010-10-28 09:00:26 -0700333 if (mmc_send_cmd(mmc, &cmd, NULL)) {
334 printf("mmc fail to send stop cmd\n");
335 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800336 }
337 }
338
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000339 /* Waiting for the ready status */
340 if (mmc_send_status(mmc, timeout))
341 return 0;
342
Lei Wen6b405b72010-10-14 13:38:11 +0800343 return blkcnt;
344}
345
346static ulong
347mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
348{
Lei Wen6b405b72010-10-14 13:38:11 +0800349 lbaint_t cur, blocks_todo = blkcnt;
350
Steve Sakomaneb288862010-10-28 09:00:26 -0700351 struct mmc *mmc = find_mmc_device(dev_num);
Lei Wen6b405b72010-10-14 13:38:11 +0800352 if (!mmc)
Steve Sakomaneb288862010-10-28 09:00:26 -0700353 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800354
Steve Sakomaneb288862010-10-28 09:00:26 -0700355 if (mmc_set_blocklen(mmc, mmc->write_bl_len))
356 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500357
Lei Wen6b405b72010-10-14 13:38:11 +0800358 do {
John Rigbyf2f43662011-04-18 05:50:08 +0000359 cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
Lei Wen6b405b72010-10-14 13:38:11 +0800360 if(mmc_write_blocks(mmc, start, cur, src) != cur)
Steve Sakomaneb288862010-10-28 09:00:26 -0700361 return 0;
Lei Wen6b405b72010-10-14 13:38:11 +0800362 blocks_todo -= cur;
363 start += cur;
364 src += cur * mmc->write_bl_len;
365 } while (blocks_todo > 0);
366
Andy Flemingad347bb2008-10-30 16:41:01 -0500367 return blkcnt;
368}
369
Kim Phillips87ea3892012-10-29 13:34:43 +0000370static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
371 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500372{
373 struct mmc_cmd cmd;
374 struct mmc_data data;
375
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700376 if (blkcnt > 1)
377 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
378 else
379 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500380
381 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700382 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500383 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700384 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500385
386 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500387
388 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700389 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500390 data.blocksize = mmc->read_bl_len;
391 data.flags = MMC_DATA_READ;
392
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700393 if (mmc_send_cmd(mmc, &cmd, &data))
394 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500395
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700396 if (blkcnt > 1) {
397 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
398 cmd.cmdarg = 0;
399 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700400 if (mmc_send_cmd(mmc, &cmd, NULL)) {
401 printf("mmc fail to send stop cmd\n");
402 return 0;
403 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500404 }
405
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700406 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500407}
408
409static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
410{
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700411 lbaint_t cur, blocks_todo = blkcnt;
412
413 if (blkcnt == 0)
414 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500415
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700416 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500417 if (!mmc)
418 return 0;
419
Lei Wene1cc9c82010-09-13 22:07:27 +0800420 if ((start + blkcnt) > mmc->block_dev.lba) {
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700421 printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800422 start + blkcnt, mmc->block_dev.lba);
423 return 0;
424 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500425
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700426 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Flemingad347bb2008-10-30 16:41:01 -0500427 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500428
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700429 do {
John Rigbyf2f43662011-04-18 05:50:08 +0000430 cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700431 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
432 return 0;
433 blocks_todo -= cur;
434 start += cur;
435 dst += cur * mmc->read_bl_len;
436 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500437
438 return blkcnt;
439}
440
Kim Phillips87ea3892012-10-29 13:34:43 +0000441static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500442{
443 struct mmc_cmd cmd;
444 int err;
445
446 udelay(1000);
447
448 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
449 cmd.cmdarg = 0;
450 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500451
452 err = mmc_send_cmd(mmc, &cmd, NULL);
453
454 if (err)
455 return err;
456
457 udelay(2000);
458
459 return 0;
460}
461
Kim Phillips87ea3892012-10-29 13:34:43 +0000462static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500463{
464 int timeout = 1000;
465 int err;
466 struct mmc_cmd cmd;
467
468 do {
469 cmd.cmdidx = MMC_CMD_APP_CMD;
470 cmd.resp_type = MMC_RSP_R1;
471 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500472
473 err = mmc_send_cmd(mmc, &cmd, NULL);
474
475 if (err)
476 return err;
477
478 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
479 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100480
481 /*
482 * Most cards do not answer if some reserved bits
483 * in the ocr are set. However, Some controller
484 * can set bit 7 (reserved for low voltages), but
485 * how to manage low voltages SD card is not yet
486 * specified.
487 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000488 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
489 (mmc->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500490
491 if (mmc->version == SD_VERSION_2)
492 cmd.cmdarg |= OCR_HCS;
493
494 err = mmc_send_cmd(mmc, &cmd, NULL);
495
496 if (err)
497 return err;
498
499 udelay(1000);
500 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
501
502 if (timeout <= 0)
503 return UNUSABLE_ERR;
504
505 if (mmc->version != SD_VERSION_2)
506 mmc->version = SD_VERSION_1_0;
507
Thomas Chou1254c3d2010-12-24 13:12:21 +0000508 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
509 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
510 cmd.resp_type = MMC_RSP_R3;
511 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000512
513 err = mmc_send_cmd(mmc, &cmd, NULL);
514
515 if (err)
516 return err;
517 }
518
Rabin Vincentb6eed942009-04-05 13:30:56 +0530519 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500520
521 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
522 mmc->rca = 0;
523
524 return 0;
525}
526
Kim Phillips87ea3892012-10-29 13:34:43 +0000527static int mmc_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500528{
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000529 int timeout = 10000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500530 struct mmc_cmd cmd;
531 int err;
532
533 /* Some cards seem to need this */
534 mmc_go_idle(mmc);
535
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000536 /* Asking to the card its capabilities */
537 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
538 cmd.resp_type = MMC_RSP_R3;
539 cmd.cmdarg = 0;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200540
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000541 err = mmc_send_cmd(mmc, &cmd, NULL);
Wolfgang Denk80f70212011-05-19 22:21:41 +0200542
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000543 if (err)
544 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200545
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000546 udelay(1000);
Wolfgang Denk80f70212011-05-19 22:21:41 +0200547
Andy Flemingad347bb2008-10-30 16:41:01 -0500548 do {
549 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
550 cmd.resp_type = MMC_RSP_R3;
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000551 cmd.cmdarg = (mmc_host_is_spi(mmc) ? 0 :
552 (mmc->voltages &
553 (cmd.response[0] & OCR_VOLTAGE_MASK)) |
554 (cmd.response[0] & OCR_ACCESS_MODE));
Łukasz Majewski237823e2011-07-05 02:19:44 +0000555
556 if (mmc->host_caps & MMC_MODE_HC)
557 cmd.cmdarg |= OCR_HCS;
558
Andy Flemingad347bb2008-10-30 16:41:01 -0500559 err = mmc_send_cmd(mmc, &cmd, NULL);
560
561 if (err)
562 return err;
563
564 udelay(1000);
565 } while (!(cmd.response[0] & OCR_BUSY) && timeout--);
566
567 if (timeout <= 0)
568 return UNUSABLE_ERR;
569
Thomas Chou1254c3d2010-12-24 13:12:21 +0000570 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
571 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
572 cmd.resp_type = MMC_RSP_R3;
573 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000574
575 err = mmc_send_cmd(mmc, &cmd, NULL);
576
577 if (err)
578 return err;
579 }
580
Andy Flemingad347bb2008-10-30 16:41:01 -0500581 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincentb6eed942009-04-05 13:30:56 +0530582 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500583
584 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
585 mmc->rca = 0;
586
587 return 0;
588}
589
590
Kim Phillips87ea3892012-10-29 13:34:43 +0000591static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500592{
593 struct mmc_cmd cmd;
594 struct mmc_data data;
595 int err;
596
597 /* Get the Card Status Register */
598 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
599 cmd.resp_type = MMC_RSP_R1;
600 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500601
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000602 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500603 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000604 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500605 data.flags = MMC_DATA_READ;
606
607 err = mmc_send_cmd(mmc, &cmd, &data);
608
609 return err;
610}
611
612
Kim Phillips87ea3892012-10-29 13:34:43 +0000613static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500614{
615 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000616 int timeout = 1000;
617 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500618
619 cmd.cmdidx = MMC_CMD_SWITCH;
620 cmd.resp_type = MMC_RSP_R1b;
621 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000622 (index << 16) |
623 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500624
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000625 ret = mmc_send_cmd(mmc, &cmd, NULL);
626
627 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000628 if (!ret)
629 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000630
631 return ret;
632
Andy Flemingad347bb2008-10-30 16:41:01 -0500633}
634
Kim Phillips87ea3892012-10-29 13:34:43 +0000635static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500636{
Simon Glassa09c2b72013-04-03 08:54:30 +0000637 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500638 char cardtype;
639 int err;
640
641 mmc->card_caps = 0;
642
Thomas Chou1254c3d2010-12-24 13:12:21 +0000643 if (mmc_host_is_spi(mmc))
644 return 0;
645
Andy Flemingad347bb2008-10-30 16:41:01 -0500646 /* Only version 4 supports high-speed */
647 if (mmc->version < MMC_VERSION_4)
648 return 0;
649
Andy Flemingad347bb2008-10-30 16:41:01 -0500650 err = mmc_send_ext_csd(mmc, ext_csd);
651
652 if (err)
653 return err;
654
Lei Wen217467f2011-10-03 20:35:10 +0000655 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500656
657 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
658
659 if (err)
660 return err;
661
662 /* Now check to see that it worked */
663 err = mmc_send_ext_csd(mmc, ext_csd);
664
665 if (err)
666 return err;
667
668 /* No high-speed support */
Lei Wen217467f2011-10-03 20:35:10 +0000669 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500670 return 0;
671
672 /* High Speed is set, there are two types: 52MHz and 26MHz */
673 if (cardtype & MMC_HS_52MHZ)
674 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
675 else
676 mmc->card_caps |= MMC_MODE_HS;
677
678 return 0;
679}
680
Lei Wen31b99802011-05-02 16:26:26 +0000681int mmc_switch_part(int dev_num, unsigned int part_num)
682{
683 struct mmc *mmc = find_mmc_device(dev_num);
684
685 if (!mmc)
686 return -1;
687
688 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
689 (mmc->part_config & ~PART_ACCESS_MASK)
690 | (part_num & PART_ACCESS_MASK));
691}
692
Thierry Redingb9c8b772012-01-02 01:15:37 +0000693int mmc_getcd(struct mmc *mmc)
694{
695 int cd;
696
697 cd = board_mmc_getcd(mmc);
698
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000699 if (cd < 0) {
700 if (mmc->getcd)
701 cd = mmc->getcd(mmc);
702 else
703 cd = 1;
704 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000705
706 return cd;
707}
708
Kim Phillips87ea3892012-10-29 13:34:43 +0000709static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -0500710{
711 struct mmc_cmd cmd;
712 struct mmc_data data;
713
714 /* Switch the frequency */
715 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
716 cmd.resp_type = MMC_RSP_R1;
717 cmd.cmdarg = (mode << 31) | 0xffffff;
718 cmd.cmdarg &= ~(0xf << (group * 4));
719 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -0500720
721 data.dest = (char *)resp;
722 data.blocksize = 64;
723 data.blocks = 1;
724 data.flags = MMC_DATA_READ;
725
726 return mmc_send_cmd(mmc, &cmd, &data);
727}
728
729
Kim Phillips87ea3892012-10-29 13:34:43 +0000730static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500731{
732 int err;
733 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000734 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
735 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500736 struct mmc_data data;
737 int timeout;
738
739 mmc->card_caps = 0;
740
Thomas Chou1254c3d2010-12-24 13:12:21 +0000741 if (mmc_host_is_spi(mmc))
742 return 0;
743
Andy Flemingad347bb2008-10-30 16:41:01 -0500744 /* Read the SCR to find out if this card supports higher speeds */
745 cmd.cmdidx = MMC_CMD_APP_CMD;
746 cmd.resp_type = MMC_RSP_R1;
747 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500748
749 err = mmc_send_cmd(mmc, &cmd, NULL);
750
751 if (err)
752 return err;
753
754 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
755 cmd.resp_type = MMC_RSP_R1;
756 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500757
758 timeout = 3;
759
760retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000761 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -0500762 data.blocksize = 8;
763 data.blocks = 1;
764 data.flags = MMC_DATA_READ;
765
766 err = mmc_send_cmd(mmc, &cmd, &data);
767
768 if (err) {
769 if (timeout--)
770 goto retry_scr;
771
772 return err;
773 }
774
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300775 mmc->scr[0] = __be32_to_cpu(scr[0]);
776 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500777
778 switch ((mmc->scr[0] >> 24) & 0xf) {
779 case 0:
780 mmc->version = SD_VERSION_1_0;
781 break;
782 case 1:
783 mmc->version = SD_VERSION_1_10;
784 break;
785 case 2:
786 mmc->version = SD_VERSION_2;
Jaehoon Chungd552bd12013-01-29 22:58:16 +0000787 if ((mmc->scr[0] >> 15) & 0x1)
788 mmc->version = SD_VERSION_3;
Andy Flemingad347bb2008-10-30 16:41:01 -0500789 break;
790 default:
791 mmc->version = SD_VERSION_1_0;
792 break;
793 }
794
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530795 if (mmc->scr[0] & SD_DATA_4BIT)
796 mmc->card_caps |= MMC_MODE_4BIT;
797
Andy Flemingad347bb2008-10-30 16:41:01 -0500798 /* Version 1.0 doesn't support switching */
799 if (mmc->version == SD_VERSION_1_0)
800 return 0;
801
802 timeout = 4;
803 while (timeout--) {
804 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +0000805 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500806
807 if (err)
808 return err;
809
810 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300811 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500812 break;
813 }
814
Andy Flemingad347bb2008-10-30 16:41:01 -0500815 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300816 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500817 return 0;
818
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000819 /*
820 * If the host doesn't support SD_HIGHSPEED, do not switch card to
821 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
822 * This can avoid furthur problem when the card runs in different
823 * mode between the host.
824 */
825 if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
826 (mmc->host_caps & MMC_MODE_HS)))
827 return 0;
828
Anton staaf9b00f0d2011-10-03 13:54:59 +0000829 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500830
831 if (err)
832 return err;
833
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300834 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500835 mmc->card_caps |= MMC_MODE_HS;
836
837 return 0;
838}
839
840/* frequency bases */
841/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000842static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500843 10000,
844 100000,
845 1000000,
846 10000000,
847};
848
849/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
850 * to platforms without floating point.
851 */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000852static const int multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500853 0, /* reserved */
854 10,
855 12,
856 13,
857 15,
858 20,
859 25,
860 30,
861 35,
862 40,
863 45,
864 50,
865 55,
866 60,
867 70,
868 80,
869};
870
Kim Phillips87ea3892012-10-29 13:34:43 +0000871static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500872{
873 mmc->set_ios(mmc);
874}
875
876void mmc_set_clock(struct mmc *mmc, uint clock)
877{
878 if (clock > mmc->f_max)
879 clock = mmc->f_max;
880
881 if (clock < mmc->f_min)
882 clock = mmc->f_min;
883
884 mmc->clock = clock;
885
886 mmc_set_ios(mmc);
887}
888
Kim Phillips87ea3892012-10-29 13:34:43 +0000889static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -0500890{
891 mmc->bus_width = width;
892
893 mmc_set_ios(mmc);
894}
895
Kim Phillips87ea3892012-10-29 13:34:43 +0000896static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500897{
Andy Flemingeb766ad2012-10-31 19:02:38 +0000898 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500899 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000900 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -0500901 struct mmc_cmd cmd;
Simon Glassa09c2b72013-04-03 08:54:30 +0000902 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
903 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000904 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500905
Thomas Chou1254c3d2010-12-24 13:12:21 +0000906#ifdef CONFIG_MMC_SPI_CRC_ON
907 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
908 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
909 cmd.resp_type = MMC_RSP_R1;
910 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000911 err = mmc_send_cmd(mmc, &cmd, NULL);
912
913 if (err)
914 return err;
915 }
916#endif
917
Andy Flemingad347bb2008-10-30 16:41:01 -0500918 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000919 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
920 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -0500921 cmd.resp_type = MMC_RSP_R2;
922 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500923
924 err = mmc_send_cmd(mmc, &cmd, NULL);
925
926 if (err)
927 return err;
928
929 memcpy(mmc->cid, cmd.response, 16);
930
931 /*
932 * For MMC cards, set the Relative Address.
933 * For SD cards, get the Relatvie Address.
934 * This also puts the cards into Standby State
935 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000936 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
937 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
938 cmd.cmdarg = mmc->rca << 16;
939 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -0500940
Thomas Chou1254c3d2010-12-24 13:12:21 +0000941 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500942
Thomas Chou1254c3d2010-12-24 13:12:21 +0000943 if (err)
944 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500945
Thomas Chou1254c3d2010-12-24 13:12:21 +0000946 if (IS_SD(mmc))
947 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
948 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500949
950 /* Get the Card-Specific Data */
951 cmd.cmdidx = MMC_CMD_SEND_CSD;
952 cmd.resp_type = MMC_RSP_R2;
953 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500954
955 err = mmc_send_cmd(mmc, &cmd, NULL);
956
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000957 /* Waiting for the ready status */
958 mmc_send_status(mmc, timeout);
959
Andy Flemingad347bb2008-10-30 16:41:01 -0500960 if (err)
961 return err;
962
Rabin Vincentb6eed942009-04-05 13:30:56 +0530963 mmc->csd[0] = cmd.response[0];
964 mmc->csd[1] = cmd.response[1];
965 mmc->csd[2] = cmd.response[2];
966 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -0500967
968 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530969 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500970
971 switch (version) {
972 case 0:
973 mmc->version = MMC_VERSION_1_2;
974 break;
975 case 1:
976 mmc->version = MMC_VERSION_1_4;
977 break;
978 case 2:
979 mmc->version = MMC_VERSION_2_2;
980 break;
981 case 3:
982 mmc->version = MMC_VERSION_3;
983 break;
984 case 4:
985 mmc->version = MMC_VERSION_4;
986 break;
987 default:
988 mmc->version = MMC_VERSION_1_2;
989 break;
990 }
991 }
992
993 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530994 freq = fbase[(cmd.response[0] & 0x7)];
995 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -0500996
997 mmc->tran_speed = freq * mult;
998
Rabin Vincentb6eed942009-04-05 13:30:56 +0530999 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001000
1001 if (IS_SD(mmc))
1002 mmc->write_bl_len = mmc->read_bl_len;
1003 else
Rabin Vincentb6eed942009-04-05 13:30:56 +05301004 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001005
1006 if (mmc->high_capacity) {
1007 csize = (mmc->csd[1] & 0x3f) << 16
1008 | (mmc->csd[2] & 0xffff0000) >> 16;
1009 cmult = 8;
1010 } else {
1011 csize = (mmc->csd[1] & 0x3ff) << 2
1012 | (mmc->csd[2] & 0xc0000000) >> 30;
1013 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1014 }
1015
1016 mmc->capacity = (csize + 1) << (cmult + 2);
1017 mmc->capacity *= mmc->read_bl_len;
1018
Simon Glassa09c2b72013-04-03 08:54:30 +00001019 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1020 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001021
Simon Glassa09c2b72013-04-03 08:54:30 +00001022 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1023 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001024
1025 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001026 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1027 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +00001028 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001029 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001030 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001031
Thomas Chou1254c3d2010-12-24 13:12:21 +00001032 if (err)
1033 return err;
1034 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001035
Lei Wenea526762011-06-22 17:03:31 +00001036 /*
1037 * For SD, its erase group is always one sector
1038 */
1039 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +00001040 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301041 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1042 /* check ext_csd version and capacity */
1043 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillips87ea3892012-10-29 13:34:43 +00001044 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001045 /*
1046 * According to the JEDEC Standard, the value of
1047 * ext_csd's capacity is valid if the value is more
1048 * than 2GB
1049 */
Lei Wen217467f2011-10-03 20:35:10 +00001050 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1051 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1052 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1053 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glassa09c2b72013-04-03 08:54:30 +00001054 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +00001055 if ((capacity >> 20) > 2 * 1024)
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001056 mmc->capacity = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301057 }
Lei Wen31b99802011-05-02 16:26:26 +00001058
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001059 switch (ext_csd[EXT_CSD_REV]) {
1060 case 1:
1061 mmc->version = MMC_VERSION_4_1;
1062 break;
1063 case 2:
1064 mmc->version = MMC_VERSION_4_2;
1065 break;
1066 case 3:
1067 mmc->version = MMC_VERSION_4_3;
1068 break;
1069 case 5:
1070 mmc->version = MMC_VERSION_4_41;
1071 break;
1072 case 6:
1073 mmc->version = MMC_VERSION_4_5;
1074 break;
1075 }
1076
Lei Wenea526762011-06-22 17:03:31 +00001077 /*
1078 * Check whether GROUP_DEF is set, if yes, read out
1079 * group size from ext_csd directly, or calculate
1080 * the group size from the csd value.
1081 */
Simon Glassa09c2b72013-04-03 08:54:30 +00001082 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
Lei Wen217467f2011-10-03 20:35:10 +00001083 mmc->erase_grp_size =
Simon Glassa09c2b72013-04-03 08:54:30 +00001084 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
1085 MMC_MAX_BLOCK_LEN * 1024;
1086 } else {
Lei Wenea526762011-06-22 17:03:31 +00001087 int erase_gsz, erase_gmul;
1088 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1089 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1090 mmc->erase_grp_size = (erase_gsz + 1)
1091 * (erase_gmul + 1);
1092 }
1093
Lei Wen31b99802011-05-02 16:26:26 +00001094 /* store the partition info of emmc */
Stephen Warren009784c2012-07-30 10:55:43 +00001095 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1096 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen217467f2011-10-03 20:35:10 +00001097 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301098 }
1099
Andy Flemingad347bb2008-10-30 16:41:01 -05001100 if (IS_SD(mmc))
1101 err = sd_change_freq(mmc);
1102 else
1103 err = mmc_change_freq(mmc);
1104
1105 if (err)
1106 return err;
1107
1108 /* Restrict card's capabilities by what the host can do */
1109 mmc->card_caps &= mmc->host_caps;
1110
1111 if (IS_SD(mmc)) {
1112 if (mmc->card_caps & MMC_MODE_4BIT) {
1113 cmd.cmdidx = MMC_CMD_APP_CMD;
1114 cmd.resp_type = MMC_RSP_R1;
1115 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001116
1117 err = mmc_send_cmd(mmc, &cmd, NULL);
1118 if (err)
1119 return err;
1120
1121 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1122 cmd.resp_type = MMC_RSP_R1;
1123 cmd.cmdarg = 2;
Andy Flemingad347bb2008-10-30 16:41:01 -05001124 err = mmc_send_cmd(mmc, &cmd, NULL);
1125 if (err)
1126 return err;
1127
1128 mmc_set_bus_width(mmc, 4);
1129 }
1130
1131 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001132 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001133 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001134 mmc->tran_speed = 25000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001135 } else {
Andy Flemingeb766ad2012-10-31 19:02:38 +00001136 int idx;
1137
1138 /* An array of possible bus widths in order of preference */
1139 static unsigned ext_csd_bits[] = {
1140 EXT_CSD_BUS_WIDTH_8,
1141 EXT_CSD_BUS_WIDTH_4,
1142 EXT_CSD_BUS_WIDTH_1,
1143 };
1144
1145 /* An array to map CSD bus widths to host cap bits */
1146 static unsigned ext_to_hostcaps[] = {
1147 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1148 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1149 };
1150
1151 /* An array to map chosen bus width to an integer */
1152 static unsigned widths[] = {
1153 8, 4, 1,
1154 };
1155
1156 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1157 unsigned int extw = ext_csd_bits[idx];
1158
1159 /*
1160 * Check to make sure the controller supports
1161 * this bus width, if it's more than 1
1162 */
1163 if (extw != EXT_CSD_BUS_WIDTH_1 &&
1164 !(mmc->host_caps & ext_to_hostcaps[extw]))
1165 continue;
1166
Andy Flemingad347bb2008-10-30 16:41:01 -05001167 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001168 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001169
1170 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001171 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001172
Andy Flemingeb766ad2012-10-31 19:02:38 +00001173 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001174
Lei Wen4f5a6a52011-10-03 20:35:11 +00001175 err = mmc_send_ext_csd(mmc, test_csd);
1176 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1177 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1178 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1179 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1180 && ext_csd[EXT_CSD_REV] \
1181 == test_csd[EXT_CSD_REV]
1182 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1183 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1184 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1185 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Flemingad347bb2008-10-30 16:41:01 -05001186
Andy Flemingeb766ad2012-10-31 19:02:38 +00001187 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen4f5a6a52011-10-03 20:35:11 +00001188 break;
1189 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001190 }
1191
1192 if (mmc->card_caps & MMC_MODE_HS) {
1193 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001194 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001195 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001196 mmc->tran_speed = 26000000;
1197 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001198 }
1199
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001200 mmc_set_clock(mmc, mmc->tran_speed);
1201
Andy Flemingad347bb2008-10-30 16:41:01 -05001202 /* fill in device description */
1203 mmc->block_dev.lun = 0;
1204 mmc->block_dev.type = 0;
1205 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich2eec2ab2013-04-09 21:11:56 +00001206 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent69d4e2c2009-04-05 13:30:54 +05301207 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Taylor Hutt7367ec22012-10-20 17:15:59 +00001208 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1209 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1210 (mmc->cid[3] >> 16) & 0xffff);
1211 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1212 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1213 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1214 (mmc->cid[2] >> 24) & 0xff);
1215 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1216 (mmc->cid[2] >> 16) & 0xf);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001217#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001218 init_part(&mmc->block_dev);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001219#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001220
1221 return 0;
1222}
1223
Kim Phillips87ea3892012-10-29 13:34:43 +00001224static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001225{
1226 struct mmc_cmd cmd;
1227 int err;
1228
1229 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1230 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
1231 cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
1232 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001233
1234 err = mmc_send_cmd(mmc, &cmd, NULL);
1235
1236 if (err)
1237 return err;
1238
Rabin Vincentb6eed942009-04-05 13:30:56 +05301239 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-10-30 16:41:01 -05001240 return UNUSABLE_ERR;
1241 else
1242 mmc->version = SD_VERSION_2;
1243
1244 return 0;
1245}
1246
1247int mmc_register(struct mmc *mmc)
1248{
1249 /* Setup the universal parts of the block interface just once */
1250 mmc->block_dev.if_type = IF_TYPE_MMC;
1251 mmc->block_dev.dev = cur_dev_num++;
1252 mmc->block_dev.removable = 1;
1253 mmc->block_dev.block_read = mmc_bread;
1254 mmc->block_dev.block_write = mmc_bwrite;
Lei Wenea526762011-06-22 17:03:31 +00001255 mmc->block_dev.block_erase = mmc_berase;
John Rigbyf2f43662011-04-18 05:50:08 +00001256 if (!mmc->b_max)
1257 mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
Andy Flemingad347bb2008-10-30 16:41:01 -05001258
1259 INIT_LIST_HEAD (&mmc->link);
1260
1261 list_add_tail (&mmc->link, &mmc_devices);
1262
1263 return 0;
1264}
1265
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001266#ifdef CONFIG_PARTITIONS
Andy Flemingad347bb2008-10-30 16:41:01 -05001267block_dev_desc_t *mmc_get_dev(int dev)
1268{
1269 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6ce8aed2012-08-10 08:59:12 +00001270 if (!mmc || mmc_init(mmc))
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001271 return NULL;
Andy Flemingad347bb2008-10-30 16:41:01 -05001272
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001273 return &mmc->block_dev;
Andy Flemingad347bb2008-10-30 16:41:01 -05001274}
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001275#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001276
1277int mmc_init(struct mmc *mmc)
1278{
Macpaul Lin028bde12011-11-14 23:35:39 +00001279 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001280
Thierry Redingb9c8b772012-01-02 01:15:37 +00001281 if (mmc_getcd(mmc) == 0) {
1282 mmc->has_init = 0;
1283 printf("MMC: no card present\n");
1284 return NO_CARD_ERR;
1285 }
1286
Lei Wen31b99802011-05-02 16:26:26 +00001287 if (mmc->has_init)
1288 return 0;
1289
Andy Flemingad347bb2008-10-30 16:41:01 -05001290 err = mmc->init(mmc);
1291
1292 if (err)
1293 return err;
1294
Ilya Yanok8459aab2009-06-29 17:53:16 +04001295 mmc_set_bus_width(mmc, 1);
1296 mmc_set_clock(mmc, 1);
1297
Andy Flemingad347bb2008-10-30 16:41:01 -05001298 /* Reset the Card */
1299 err = mmc_go_idle(mmc);
1300
1301 if (err)
1302 return err;
1303
Lei Wen31b99802011-05-02 16:26:26 +00001304 /* The internal partition reset to user partition(0) at every CMD0*/
1305 mmc->part_num = 0;
1306
Andy Flemingad347bb2008-10-30 16:41:01 -05001307 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001308 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001309
Andy Flemingad347bb2008-10-30 16:41:01 -05001310 /* Now try to get the SD card's operating condition */
1311 err = sd_send_op_cond(mmc);
1312
1313 /* If the command timed out, we check for an MMC card */
1314 if (err == TIMEOUT) {
1315 err = mmc_send_op_cond(mmc);
1316
1317 if (err) {
1318 printf("Card did not respond to voltage select!\n");
1319 return UNUSABLE_ERR;
1320 }
1321 }
1322
Lei Wen31b99802011-05-02 16:26:26 +00001323 err = mmc_startup(mmc);
1324 if (err)
1325 mmc->has_init = 0;
1326 else
1327 mmc->has_init = 1;
1328 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001329}
1330
1331/*
1332 * CPU and board-specific MMC initializations. Aliased function
1333 * signals caller to move on
1334 */
1335static int __def_mmc_init(bd_t *bis)
1336{
1337 return -1;
1338}
1339
Peter Tyser21d2cd22009-04-20 11:08:46 -05001340int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1341int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Flemingad347bb2008-10-30 16:41:01 -05001342
1343void print_mmc_devices(char separator)
1344{
1345 struct mmc *m;
1346 struct list_head *entry;
1347
1348 list_for_each(entry, &mmc_devices) {
1349 m = list_entry(entry, struct mmc, link);
1350
1351 printf("%s: %d", m->name, m->block_dev.dev);
1352
1353 if (entry->next != &mmc_devices)
1354 printf("%c ", separator);
1355 }
1356
1357 printf("\n");
1358}
1359
Lei Wend430d7c2011-05-02 16:26:25 +00001360int get_mmc_num(void)
1361{
1362 return cur_dev_num;
1363}
1364
Andy Flemingad347bb2008-10-30 16:41:01 -05001365int mmc_initialize(bd_t *bis)
1366{
1367 INIT_LIST_HEAD (&mmc_devices);
1368 cur_dev_num = 0;
1369
1370 if (board_mmc_init(bis) < 0)
1371 cpu_mmc_init(bis);
1372
1373 print_mmc_devices(',');
1374
1375 return 0;
1376}
Amar1104e9b2013-04-27 11:42:58 +05301377
1378#ifdef CONFIG_SUPPORT_EMMC_BOOT
1379/*
1380 * This function changes the size of boot partition and the size of rpmb
1381 * partition present on EMMC devices.
1382 *
1383 * Input Parameters:
1384 * struct *mmc: pointer for the mmc device strcuture
1385 * bootsize: size of boot partition
1386 * rpmbsize: size of rpmb partition
1387 *
1388 * Returns 0 on success.
1389 */
1390
1391int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1392 unsigned long rpmbsize)
1393{
1394 int err;
1395 struct mmc_cmd cmd;
1396
1397 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1398 cmd.cmdidx = MMC_CMD_RES_MAN;
1399 cmd.resp_type = MMC_RSP_R1b;
1400 cmd.cmdarg = MMC_CMD62_ARG1;
1401
1402 err = mmc_send_cmd(mmc, &cmd, NULL);
1403 if (err) {
1404 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1405 return err;
1406 }
1407
1408 /* Boot partition changing mode */
1409 cmd.cmdidx = MMC_CMD_RES_MAN;
1410 cmd.resp_type = MMC_RSP_R1b;
1411 cmd.cmdarg = MMC_CMD62_ARG2;
1412
1413 err = mmc_send_cmd(mmc, &cmd, NULL);
1414 if (err) {
1415 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1416 return err;
1417 }
1418 /* boot partition size is multiple of 128KB */
1419 bootsize = (bootsize * 1024) / 128;
1420
1421 /* Arg: boot partition size */
1422 cmd.cmdidx = MMC_CMD_RES_MAN;
1423 cmd.resp_type = MMC_RSP_R1b;
1424 cmd.cmdarg = bootsize;
1425
1426 err = mmc_send_cmd(mmc, &cmd, NULL);
1427 if (err) {
1428 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1429 return err;
1430 }
1431 /* RPMB partition size is multiple of 128KB */
1432 rpmbsize = (rpmbsize * 1024) / 128;
1433 /* Arg: RPMB partition size */
1434 cmd.cmdidx = MMC_CMD_RES_MAN;
1435 cmd.resp_type = MMC_RSP_R1b;
1436 cmd.cmdarg = rpmbsize;
1437
1438 err = mmc_send_cmd(mmc, &cmd, NULL);
1439 if (err) {
1440 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1441 return err;
1442 }
1443 return 0;
1444}
1445
1446/*
1447 * This function shall form and send the commands to open / close the
1448 * boot partition specified by user.
1449 *
1450 * Input Parameters:
1451 * ack: 0x0 - No boot acknowledge sent (default)
1452 * 0x1 - Boot acknowledge sent during boot operation
1453 * part_num: User selects boot data that will be sent to master
1454 * 0x0 - Device not boot enabled (default)
1455 * 0x1 - Boot partition 1 enabled for boot
1456 * 0x2 - Boot partition 2 enabled for boot
1457 * access: User selects partitions to access
1458 * 0x0 : No access to boot partition (default)
1459 * 0x1 : R/W boot partition 1
1460 * 0x2 : R/W boot partition 2
1461 * 0x3 : R/W Replay Protected Memory Block (RPMB)
1462 *
1463 * Returns 0 on success.
1464 */
1465int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1466{
1467 int err;
1468 struct mmc_cmd cmd;
1469
1470 /* Boot ack enable, boot partition enable , boot partition access */
1471 cmd.cmdidx = MMC_CMD_SWITCH;
1472 cmd.resp_type = MMC_RSP_R1b;
1473
1474 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
1475 (EXT_CSD_PART_CONF << 16) |
1476 ((EXT_CSD_BOOT_ACK(ack) |
1477 EXT_CSD_BOOT_PART_NUM(part_num) |
1478 EXT_CSD_PARTITION_ACCESS(access)) << 8);
1479
1480 err = mmc_send_cmd(mmc, &cmd, NULL);
1481 if (err) {
1482 if (access) {
1483 debug("mmc boot partition#%d open fail:Error1 = %d\n",
1484 part_num, err);
1485 } else {
1486 debug("mmc boot partition#%d close fail:Error = %d\n",
1487 part_num, err);
1488 }
1489 return err;
1490 }
1491
1492 if (access) {
1493 /* 4bit transfer mode at booting time. */
1494 cmd.cmdidx = MMC_CMD_SWITCH;
1495 cmd.resp_type = MMC_RSP_R1b;
1496
1497 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
1498 (EXT_CSD_BOOT_BUS_WIDTH << 16) |
1499 ((1 << 0) << 8);
1500
1501 err = mmc_send_cmd(mmc, &cmd, NULL);
1502 if (err) {
1503 debug("mmc boot partition#%d open fail:Error2 = %d\n",
1504 part_num, err);
1505 return err;
1506 }
1507 }
1508 return 0;
1509}
1510#endif