blob: bb9014dc064296daacd7c548a427dcacac6420c4 [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 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Andy Fleming272cc702008-10-30 16:41:01 -05008 */
9
10#include <config.h>
11#include <common.h>
12#include <command.h>
13#include <mmc.h>
14#include <part.h>
15#include <malloc.h>
16#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053017#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010018#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050019
20static struct list_head mmc_devices;
21static int cur_dev_num = -1;
22
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000023int __weak board_mmc_getwp(struct mmc *mmc)
24{
25 return -1;
26}
27
28int mmc_getwp(struct mmc *mmc)
29{
30 int wp;
31
32 wp = board_mmc_getwp(mmc);
33
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000034 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020035 if (mmc->cfg->ops->getwp)
36 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000037 else
38 wp = 0;
39 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000040
41 return wp;
42}
43
Thierry Reding314284b2012-01-02 01:15:36 +000044int __board_mmc_getcd(struct mmc *mmc) {
Stefano Babic11fdade2010-02-05 15:04:43 +010045 return -1;
46}
47
Thierry Reding314284b2012-01-02 01:15:36 +000048int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
Stefano Babic11fdade2010-02-05 15:04:43 +010049 alias("__board_mmc_getcd")));
50
Paul Burtonda61fa52013-09-09 15:30:26 +010051int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
Andy Fleming272cc702008-10-30 16:41:01 -050052{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000053 int ret;
Marek Vasut8635ff92012-03-15 18:41:35 +000054
Marek Vasut8635ff92012-03-15 18:41:35 +000055#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000056 int i;
57 u8 *ptr;
58
59 printf("CMD_SEND:%d\n", cmd->cmdidx);
60 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020061 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000062 switch (cmd->resp_type) {
63 case MMC_RSP_NONE:
64 printf("\t\tMMC_RSP_NONE\n");
65 break;
66 case MMC_RSP_R1:
67 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
68 cmd->response[0]);
69 break;
70 case MMC_RSP_R1b:
71 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
72 cmd->response[0]);
73 break;
74 case MMC_RSP_R2:
75 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
76 cmd->response[0]);
77 printf("\t\t \t\t 0x%08X \n",
78 cmd->response[1]);
79 printf("\t\t \t\t 0x%08X \n",
80 cmd->response[2]);
81 printf("\t\t \t\t 0x%08X \n",
82 cmd->response[3]);
83 printf("\n");
84 printf("\t\t\t\t\tDUMPING DATA\n");
85 for (i = 0; i < 4; i++) {
86 int j;
87 printf("\t\t\t\t\t%03d - ", i*4);
Dirk Behme146bec72012-03-08 02:35:34 +000088 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000089 ptr += 3;
90 for (j = 0; j < 4; j++)
91 printf("%02X ", *ptr--);
92 printf("\n");
93 }
94 break;
95 case MMC_RSP_R3:
96 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
97 cmd->response[0]);
98 break;
99 default:
100 printf("\t\tERROR MMC rsp not supported\n");
101 break;
102 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000103#else
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200104 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000105#endif
Marek Vasut8635ff92012-03-15 18:41:35 +0000106 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500107}
108
Paul Burtonda61fa52013-09-09 15:30:26 +0100109int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000110{
111 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000112 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000113#ifdef CONFIG_MMC_TRACE
114 int status;
115#endif
116
117 cmd.cmdidx = MMC_CMD_SEND_STATUS;
118 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200119 if (!mmc_host_is_spi(mmc))
120 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000121
122 do {
123 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000124 if (!err) {
125 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
126 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
127 MMC_STATE_PRG)
128 break;
129 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton56196822013-09-04 16:12:25 +0100130#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000131 printf("Status Error: 0x%08X\n",
132 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100133#endif
Jan Kloetzked617c422012-02-05 22:29:12 +0000134 return COMM_ERR;
135 }
136 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000137 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000138
139 udelay(1000);
140
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000141 } while (timeout--);
142
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000143#ifdef CONFIG_MMC_TRACE
144 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
145 printf("CURR STATE:%d\n", status);
146#endif
Jongman Heo5b0c9422012-06-03 21:32:13 +0000147 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100148#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000149 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100150#endif
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000151 return TIMEOUT;
152 }
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500153 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
154 return SWITCH_ERR;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000155
156 return 0;
157}
158
Paul Burtonda61fa52013-09-09 15:30:26 +0100159int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500160{
161 struct mmc_cmd cmd;
162
163 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
164 cmd.resp_type = MMC_RSP_R1;
165 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500166
167 return mmc_send_cmd(mmc, &cmd, NULL);
168}
169
170struct mmc *find_mmc_device(int dev_num)
171{
172 struct mmc *m;
173 struct list_head *entry;
174
175 list_for_each(entry, &mmc_devices) {
176 m = list_entry(entry, struct mmc, link);
177
178 if (m->block_dev.dev == dev_num)
179 return m;
180 }
181
Paul Burton56196822013-09-04 16:12:25 +0100182#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -0500183 printf("MMC Device %d not found\n", dev_num);
Paul Burton56196822013-09-04 16:12:25 +0100184#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500185
186 return NULL;
187}
188
Sascha Silbeff8fef52013-06-14 13:07:25 +0200189static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000190 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500191{
192 struct mmc_cmd cmd;
193 struct mmc_data data;
194
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700195 if (blkcnt > 1)
196 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
197 else
198 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500199
200 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700201 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500202 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700203 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500204
205 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500206
207 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700208 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500209 data.blocksize = mmc->read_bl_len;
210 data.flags = MMC_DATA_READ;
211
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700212 if (mmc_send_cmd(mmc, &cmd, &data))
213 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500214
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700215 if (blkcnt > 1) {
216 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
217 cmd.cmdarg = 0;
218 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700219 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100220#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700221 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100222#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700223 return 0;
224 }
Andy Fleming272cc702008-10-30 16:41:01 -0500225 }
226
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700227 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500228}
229
Sascha Silbeff8fef52013-06-14 13:07:25 +0200230static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500231{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700232 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500233
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700234 if (blkcnt == 0)
235 return 0;
236
237 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500238 if (!mmc)
239 return 0;
240
Lei Wend2bf29e2010-09-13 22:07:27 +0800241 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton56196822013-09-04 16:12:25 +0100242#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200243 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800244 start + blkcnt, mmc->block_dev.lba);
Paul Burton56196822013-09-04 16:12:25 +0100245#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800246 return 0;
247 }
Andy Fleming272cc702008-10-30 16:41:01 -0500248
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700249 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500250 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500251
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700252 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200253 cur = (blocks_todo > mmc->cfg->b_max) ?
254 mmc->cfg->b_max : blocks_todo;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700255 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
256 return 0;
257 blocks_todo -= cur;
258 start += cur;
259 dst += cur * mmc->read_bl_len;
260 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500261
262 return blkcnt;
263}
264
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000265static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500266{
267 struct mmc_cmd cmd;
268 int err;
269
270 udelay(1000);
271
272 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
273 cmd.cmdarg = 0;
274 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500275
276 err = mmc_send_cmd(mmc, &cmd, NULL);
277
278 if (err)
279 return err;
280
281 udelay(2000);
282
283 return 0;
284}
285
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000286static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500287{
288 int timeout = 1000;
289 int err;
290 struct mmc_cmd cmd;
291
292 do {
293 cmd.cmdidx = MMC_CMD_APP_CMD;
294 cmd.resp_type = MMC_RSP_R1;
295 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500296
297 err = mmc_send_cmd(mmc, &cmd, NULL);
298
299 if (err)
300 return err;
301
302 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
303 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100304
305 /*
306 * Most cards do not answer if some reserved bits
307 * in the ocr are set. However, Some controller
308 * can set bit 7 (reserved for low voltages), but
309 * how to manage low voltages SD card is not yet
310 * specified.
311 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000312 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200313 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500314
315 if (mmc->version == SD_VERSION_2)
316 cmd.cmdarg |= OCR_HCS;
317
318 err = mmc_send_cmd(mmc, &cmd, NULL);
319
320 if (err)
321 return err;
322
323 udelay(1000);
324 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
325
326 if (timeout <= 0)
327 return UNUSABLE_ERR;
328
329 if (mmc->version != SD_VERSION_2)
330 mmc->version = SD_VERSION_1_0;
331
Thomas Choud52ebf12010-12-24 13:12:21 +0000332 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
333 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
334 cmd.resp_type = MMC_RSP_R3;
335 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000336
337 err = mmc_send_cmd(mmc, &cmd, NULL);
338
339 if (err)
340 return err;
341 }
342
Rabin Vincent998be3d2009-04-05 13:30:56 +0530343 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500344
345 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
346 mmc->rca = 0;
347
348 return 0;
349}
350
Che-Liang Chioue9550442012-11-28 15:21:13 +0000351/* We pass in the cmd since otherwise the init seems to fail */
352static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
353 int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500354{
Andy Fleming272cc702008-10-30 16:41:01 -0500355 int err;
356
Che-Liang Chioue9550442012-11-28 15:21:13 +0000357 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
358 cmd->resp_type = MMC_RSP_R3;
359 cmd->cmdarg = 0;
360 if (use_arg && !mmc_host_is_spi(mmc)) {
361 cmd->cmdarg =
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200362 (mmc->cfg->voltages &
Che-Liang Chioue9550442012-11-28 15:21:13 +0000363 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
364 (mmc->op_cond_response & OCR_ACCESS_MODE);
365
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200366 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000367 cmd->cmdarg |= OCR_HCS;
368 }
369 err = mmc_send_cmd(mmc, cmd, NULL);
370 if (err)
371 return err;
372 mmc->op_cond_response = cmd->response[0];
373 return 0;
374}
375
376int mmc_send_op_cond(struct mmc *mmc)
377{
378 struct mmc_cmd cmd;
379 int err, i;
380
Andy Fleming272cc702008-10-30 16:41:01 -0500381 /* Some cards seem to need this */
382 mmc_go_idle(mmc);
383
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000384 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000385 mmc->op_cond_pending = 1;
386 for (i = 0; i < 2; i++) {
387 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500388 if (err)
389 return err;
390
Che-Liang Chioue9550442012-11-28 15:21:13 +0000391 /* exit if not busy (flag seems to be inverted) */
392 if (mmc->op_cond_response & OCR_BUSY)
393 return 0;
394 }
395 return IN_PROGRESS;
396}
Andy Fleming272cc702008-10-30 16:41:01 -0500397
Che-Liang Chioue9550442012-11-28 15:21:13 +0000398int mmc_complete_op_cond(struct mmc *mmc)
399{
400 struct mmc_cmd cmd;
401 int timeout = 1000;
402 uint start;
403 int err;
404
405 mmc->op_cond_pending = 0;
406 start = get_timer(0);
407 do {
408 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
409 if (err)
410 return err;
411 if (get_timer(start) > timeout)
412 return UNUSABLE_ERR;
413 udelay(100);
414 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Fleming272cc702008-10-30 16:41:01 -0500415
Thomas Choud52ebf12010-12-24 13:12:21 +0000416 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
417 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
418 cmd.resp_type = MMC_RSP_R3;
419 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000420
421 err = mmc_send_cmd(mmc, &cmd, NULL);
422
423 if (err)
424 return err;
425 }
426
Andy Fleming272cc702008-10-30 16:41:01 -0500427 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincent998be3d2009-04-05 13:30:56 +0530428 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500429
430 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700431 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500432
433 return 0;
434}
435
436
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000437static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500438{
439 struct mmc_cmd cmd;
440 struct mmc_data data;
441 int err;
442
443 /* Get the Card Status Register */
444 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
445 cmd.resp_type = MMC_RSP_R1;
446 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500447
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000448 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500449 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000450 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500451 data.flags = MMC_DATA_READ;
452
453 err = mmc_send_cmd(mmc, &cmd, &data);
454
455 return err;
456}
457
458
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000459static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500460{
461 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000462 int timeout = 1000;
463 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500464
465 cmd.cmdidx = MMC_CMD_SWITCH;
466 cmd.resp_type = MMC_RSP_R1b;
467 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000468 (index << 16) |
469 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500470
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000471 ret = mmc_send_cmd(mmc, &cmd, NULL);
472
473 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000474 if (!ret)
475 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000476
477 return ret;
478
Andy Fleming272cc702008-10-30 16:41:01 -0500479}
480
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000481static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500482{
Simon Glass8bfa1952013-04-03 08:54:30 +0000483 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500484 char cardtype;
485 int err;
486
487 mmc->card_caps = 0;
488
Thomas Choud52ebf12010-12-24 13:12:21 +0000489 if (mmc_host_is_spi(mmc))
490 return 0;
491
Andy Fleming272cc702008-10-30 16:41:01 -0500492 /* Only version 4 supports high-speed */
493 if (mmc->version < MMC_VERSION_4)
494 return 0;
495
Andy Fleming272cc702008-10-30 16:41:01 -0500496 err = mmc_send_ext_csd(mmc, ext_csd);
497
498 if (err)
499 return err;
500
Lei Wen0560db12011-10-03 20:35:10 +0000501 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500502
503 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
504
505 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500506 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500507
508 /* Now check to see that it worked */
509 err = mmc_send_ext_csd(mmc, ext_csd);
510
511 if (err)
512 return err;
513
514 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000515 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500516 return 0;
517
518 /* High Speed is set, there are two types: 52MHz and 26MHz */
519 if (cardtype & MMC_HS_52MHZ)
520 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
521 else
522 mmc->card_caps |= MMC_MODE_HS;
523
524 return 0;
525}
526
Stephen Warrenf866a462013-06-11 15:14:01 -0600527static int mmc_set_capacity(struct mmc *mmc, int part_num)
528{
529 switch (part_num) {
530 case 0:
531 mmc->capacity = mmc->capacity_user;
532 break;
533 case 1:
534 case 2:
535 mmc->capacity = mmc->capacity_boot;
536 break;
537 case 3:
538 mmc->capacity = mmc->capacity_rpmb;
539 break;
540 case 4:
541 case 5:
542 case 6:
543 case 7:
544 mmc->capacity = mmc->capacity_gp[part_num - 4];
545 break;
546 default:
547 return -1;
548 }
549
550 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
551
552 return 0;
553}
554
Lei Wenbc897b12011-05-02 16:26:26 +0000555int mmc_switch_part(int dev_num, unsigned int part_num)
556{
557 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600558 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000559
560 if (!mmc)
561 return -1;
562
Stephen Warrenf866a462013-06-11 15:14:01 -0600563 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
564 (mmc->part_config & ~PART_ACCESS_MASK)
565 | (part_num & PART_ACCESS_MASK));
566 if (ret)
567 return ret;
568
569 return mmc_set_capacity(mmc, part_num);
Lei Wenbc897b12011-05-02 16:26:26 +0000570}
571
Thierry Reding48972d92012-01-02 01:15:37 +0000572int mmc_getcd(struct mmc *mmc)
573{
574 int cd;
575
576 cd = board_mmc_getcd(mmc);
577
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000578 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200579 if (mmc->cfg->ops->getcd)
580 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000581 else
582 cd = 1;
583 }
Thierry Reding48972d92012-01-02 01:15:37 +0000584
585 return cd;
586}
587
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000588static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500589{
590 struct mmc_cmd cmd;
591 struct mmc_data data;
592
593 /* Switch the frequency */
594 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
595 cmd.resp_type = MMC_RSP_R1;
596 cmd.cmdarg = (mode << 31) | 0xffffff;
597 cmd.cmdarg &= ~(0xf << (group * 4));
598 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500599
600 data.dest = (char *)resp;
601 data.blocksize = 64;
602 data.blocks = 1;
603 data.flags = MMC_DATA_READ;
604
605 return mmc_send_cmd(mmc, &cmd, &data);
606}
607
608
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000609static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500610{
611 int err;
612 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000613 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
614 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500615 struct mmc_data data;
616 int timeout;
617
618 mmc->card_caps = 0;
619
Thomas Choud52ebf12010-12-24 13:12:21 +0000620 if (mmc_host_is_spi(mmc))
621 return 0;
622
Andy Fleming272cc702008-10-30 16:41:01 -0500623 /* Read the SCR to find out if this card supports higher speeds */
624 cmd.cmdidx = MMC_CMD_APP_CMD;
625 cmd.resp_type = MMC_RSP_R1;
626 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500627
628 err = mmc_send_cmd(mmc, &cmd, NULL);
629
630 if (err)
631 return err;
632
633 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
634 cmd.resp_type = MMC_RSP_R1;
635 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500636
637 timeout = 3;
638
639retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000640 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500641 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;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000666 if ((mmc->scr[0] >> 15) & 0x1)
667 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500668 break;
669 default:
670 mmc->version = SD_VERSION_1_0;
671 break;
672 }
673
Alagu Sankarb44c7082010-05-12 15:08:24 +0530674 if (mmc->scr[0] & SD_DATA_4BIT)
675 mmc->card_caps |= MMC_MODE_4BIT;
676
Andy Fleming272cc702008-10-30 16:41:01 -0500677 /* Version 1.0 doesn't support switching */
678 if (mmc->version == SD_VERSION_1_0)
679 return 0;
680
681 timeout = 4;
682 while (timeout--) {
683 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000684 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500685
686 if (err)
687 return err;
688
689 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300690 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500691 break;
692 }
693
Andy Fleming272cc702008-10-30 16:41:01 -0500694 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300695 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500696 return 0;
697
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000698 /*
699 * If the host doesn't support SD_HIGHSPEED, do not switch card to
700 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
701 * This can avoid furthur problem when the card runs in different
702 * mode between the host.
703 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200704 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
705 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000706 return 0;
707
Anton staaff781dd32011-10-03 13:54:59 +0000708 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500709
710 if (err)
711 return err;
712
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300713 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500714 mmc->card_caps |= MMC_MODE_HS;
715
716 return 0;
717}
718
719/* frequency bases */
720/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000721static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500722 10000,
723 100000,
724 1000000,
725 10000000,
726};
727
728/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
729 * to platforms without floating point.
730 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000731static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500732 0, /* reserved */
733 10,
734 12,
735 13,
736 15,
737 20,
738 25,
739 30,
740 35,
741 40,
742 45,
743 50,
744 55,
745 60,
746 70,
747 80,
748};
749
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000750static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500751{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200752 if (mmc->cfg->ops->set_ios)
753 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500754}
755
756void mmc_set_clock(struct mmc *mmc, uint clock)
757{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200758 if (clock > mmc->cfg->f_max)
759 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500760
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200761 if (clock < mmc->cfg->f_min)
762 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -0500763
764 mmc->clock = clock;
765
766 mmc_set_ios(mmc);
767}
768
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000769static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -0500770{
771 mmc->bus_width = width;
772
773 mmc_set_ios(mmc);
774}
775
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000776static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500777{
Stephen Warrenf866a462013-06-11 15:14:01 -0600778 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -0500779 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000780 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -0500781 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +0000782 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
783 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000784 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500785
Thomas Choud52ebf12010-12-24 13:12:21 +0000786#ifdef CONFIG_MMC_SPI_CRC_ON
787 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
788 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
789 cmd.resp_type = MMC_RSP_R1;
790 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000791 err = mmc_send_cmd(mmc, &cmd, NULL);
792
793 if (err)
794 return err;
795 }
796#endif
797
Andy Fleming272cc702008-10-30 16:41:01 -0500798 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000799 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
800 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -0500801 cmd.resp_type = MMC_RSP_R2;
802 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500803
804 err = mmc_send_cmd(mmc, &cmd, NULL);
805
806 if (err)
807 return err;
808
809 memcpy(mmc->cid, cmd.response, 16);
810
811 /*
812 * For MMC cards, set the Relative Address.
813 * For SD cards, get the Relatvie Address.
814 * This also puts the cards into Standby State
815 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000816 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
817 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
818 cmd.cmdarg = mmc->rca << 16;
819 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -0500820
Thomas Choud52ebf12010-12-24 13:12:21 +0000821 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500822
Thomas Choud52ebf12010-12-24 13:12:21 +0000823 if (err)
824 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500825
Thomas Choud52ebf12010-12-24 13:12:21 +0000826 if (IS_SD(mmc))
827 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
828 }
Andy Fleming272cc702008-10-30 16:41:01 -0500829
830 /* Get the Card-Specific Data */
831 cmd.cmdidx = MMC_CMD_SEND_CSD;
832 cmd.resp_type = MMC_RSP_R2;
833 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500834
835 err = mmc_send_cmd(mmc, &cmd, NULL);
836
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000837 /* Waiting for the ready status */
838 mmc_send_status(mmc, timeout);
839
Andy Fleming272cc702008-10-30 16:41:01 -0500840 if (err)
841 return err;
842
Rabin Vincent998be3d2009-04-05 13:30:56 +0530843 mmc->csd[0] = cmd.response[0];
844 mmc->csd[1] = cmd.response[1];
845 mmc->csd[2] = cmd.response[2];
846 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -0500847
848 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530849 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500850
851 switch (version) {
852 case 0:
853 mmc->version = MMC_VERSION_1_2;
854 break;
855 case 1:
856 mmc->version = MMC_VERSION_1_4;
857 break;
858 case 2:
859 mmc->version = MMC_VERSION_2_2;
860 break;
861 case 3:
862 mmc->version = MMC_VERSION_3;
863 break;
864 case 4:
865 mmc->version = MMC_VERSION_4;
866 break;
867 default:
868 mmc->version = MMC_VERSION_1_2;
869 break;
870 }
871 }
872
873 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530874 freq = fbase[(cmd.response[0] & 0x7)];
875 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -0500876
877 mmc->tran_speed = freq * mult;
878
Markus Niebelab711882013-12-16 13:40:46 +0100879 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +0530880 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500881
882 if (IS_SD(mmc))
883 mmc->write_bl_len = mmc->read_bl_len;
884 else
Rabin Vincent998be3d2009-04-05 13:30:56 +0530885 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500886
887 if (mmc->high_capacity) {
888 csize = (mmc->csd[1] & 0x3f) << 16
889 | (mmc->csd[2] & 0xffff0000) >> 16;
890 cmult = 8;
891 } else {
892 csize = (mmc->csd[1] & 0x3ff) << 2
893 | (mmc->csd[2] & 0xc0000000) >> 30;
894 cmult = (mmc->csd[2] & 0x00038000) >> 15;
895 }
896
Stephen Warrenf866a462013-06-11 15:14:01 -0600897 mmc->capacity_user = (csize + 1) << (cmult + 2);
898 mmc->capacity_user *= mmc->read_bl_len;
899 mmc->capacity_boot = 0;
900 mmc->capacity_rpmb = 0;
901 for (i = 0; i < 4; i++)
902 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500903
Simon Glass8bfa1952013-04-03 08:54:30 +0000904 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
905 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500906
Simon Glass8bfa1952013-04-03 08:54:30 +0000907 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
908 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500909
Markus Niebelab711882013-12-16 13:40:46 +0100910 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
911 cmd.cmdidx = MMC_CMD_SET_DSR;
912 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
913 cmd.resp_type = MMC_RSP_NONE;
914 if (mmc_send_cmd(mmc, &cmd, NULL))
915 printf("MMC: SET_DSR failed\n");
916 }
917
Andy Fleming272cc702008-10-30 16:41:01 -0500918 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000919 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
920 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +0000921 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000922 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +0000923 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500924
Thomas Choud52ebf12010-12-24 13:12:21 +0000925 if (err)
926 return err;
927 }
Andy Fleming272cc702008-10-30 16:41:01 -0500928
Lei Wene6f99a52011-06-22 17:03:31 +0000929 /*
930 * For SD, its erase group is always one sector
931 */
932 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +0000933 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530934 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
935 /* check ext_csd version and capacity */
936 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000937 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000938 /*
939 * According to the JEDEC Standard, the value of
940 * ext_csd's capacity is valid if the value is more
941 * than 2GB
942 */
Lei Wen0560db12011-10-03 20:35:10 +0000943 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
944 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
945 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
946 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +0000947 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +0000948 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -0600949 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530950 }
Lei Wenbc897b12011-05-02 16:26:26 +0000951
Jaehoon Chung64f4a612013-01-29 19:31:16 +0000952 switch (ext_csd[EXT_CSD_REV]) {
953 case 1:
954 mmc->version = MMC_VERSION_4_1;
955 break;
956 case 2:
957 mmc->version = MMC_VERSION_4_2;
958 break;
959 case 3:
960 mmc->version = MMC_VERSION_4_3;
961 break;
962 case 5:
963 mmc->version = MMC_VERSION_4_41;
964 break;
965 case 6:
966 mmc->version = MMC_VERSION_4_5;
967 break;
968 }
969
Lei Wene6f99a52011-06-22 17:03:31 +0000970 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +0200971 * Host needs to enable ERASE_GRP_DEF bit if device is
972 * partitioned. This bit will be lost every time after a reset
973 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +0000974 */
Oliver Metz1937e5a2013-10-01 20:32:07 +0200975 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
976 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
977 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
978 EXT_CSD_ERASE_GROUP_DEF, 1);
979
980 if (err)
981 return err;
982
983 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +0000984 mmc->erase_grp_size =
Simon Glass8bfa1952013-04-03 08:54:30 +0000985 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
986 MMC_MAX_BLOCK_LEN * 1024;
987 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +0200988 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +0000989 int erase_gsz, erase_gmul;
990 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
991 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
992 mmc->erase_grp_size = (erase_gsz + 1)
993 * (erase_gmul + 1);
994 }
995
Lei Wenbc897b12011-05-02 16:26:26 +0000996 /* store the partition info of emmc */
Stephen Warren8948ea82012-07-30 10:55:43 +0000997 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
998 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen0560db12011-10-03 20:35:10 +0000999 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrenf866a462013-06-11 15:14:01 -06001000
1001 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1002
1003 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1004
1005 for (i = 0; i < 4; i++) {
1006 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1007 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1008 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1009 mmc->capacity_gp[i] *=
1010 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1011 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1012 }
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301013 }
1014
Stephen Warrenf866a462013-06-11 15:14:01 -06001015 err = mmc_set_capacity(mmc, mmc->part_num);
1016 if (err)
1017 return err;
1018
Andy Fleming272cc702008-10-30 16:41:01 -05001019 if (IS_SD(mmc))
1020 err = sd_change_freq(mmc);
1021 else
1022 err = mmc_change_freq(mmc);
1023
1024 if (err)
1025 return err;
1026
1027 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001028 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001029
1030 if (IS_SD(mmc)) {
1031 if (mmc->card_caps & MMC_MODE_4BIT) {
1032 cmd.cmdidx = MMC_CMD_APP_CMD;
1033 cmd.resp_type = MMC_RSP_R1;
1034 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001035
1036 err = mmc_send_cmd(mmc, &cmd, NULL);
1037 if (err)
1038 return err;
1039
1040 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1041 cmd.resp_type = MMC_RSP_R1;
1042 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001043 err = mmc_send_cmd(mmc, &cmd, NULL);
1044 if (err)
1045 return err;
1046
1047 mmc_set_bus_width(mmc, 4);
1048 }
1049
1050 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001051 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001052 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001053 mmc->tran_speed = 25000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001054 } else {
Andy Fleming7798f6d2012-10-31 19:02:38 +00001055 int idx;
1056
1057 /* An array of possible bus widths in order of preference */
1058 static unsigned ext_csd_bits[] = {
1059 EXT_CSD_BUS_WIDTH_8,
1060 EXT_CSD_BUS_WIDTH_4,
1061 EXT_CSD_BUS_WIDTH_1,
1062 };
1063
1064 /* An array to map CSD bus widths to host cap bits */
1065 static unsigned ext_to_hostcaps[] = {
1066 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1067 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1068 };
1069
1070 /* An array to map chosen bus width to an integer */
1071 static unsigned widths[] = {
1072 8, 4, 1,
1073 };
1074
1075 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1076 unsigned int extw = ext_csd_bits[idx];
1077
1078 /*
1079 * Check to make sure the controller supports
1080 * this bus width, if it's more than 1
1081 */
1082 if (extw != EXT_CSD_BUS_WIDTH_1 &&
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001083 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Fleming7798f6d2012-10-31 19:02:38 +00001084 continue;
1085
Andy Fleming272cc702008-10-30 16:41:01 -05001086 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001087 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001088
1089 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001090 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001091
Andy Fleming7798f6d2012-10-31 19:02:38 +00001092 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001093
Lei Wen41378942011-10-03 20:35:11 +00001094 err = mmc_send_ext_csd(mmc, test_csd);
1095 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1096 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1097 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1098 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1099 && ext_csd[EXT_CSD_REV] \
1100 == test_csd[EXT_CSD_REV]
1101 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1102 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1103 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1104 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Fleming272cc702008-10-30 16:41:01 -05001105
Andy Fleming7798f6d2012-10-31 19:02:38 +00001106 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen41378942011-10-03 20:35:11 +00001107 break;
1108 }
Andy Fleming272cc702008-10-30 16:41:01 -05001109 }
1110
1111 if (mmc->card_caps & MMC_MODE_HS) {
1112 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001113 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001114 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001115 mmc->tran_speed = 26000000;
1116 }
Andy Fleming272cc702008-10-30 16:41:01 -05001117 }
1118
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001119 mmc_set_clock(mmc, mmc->tran_speed);
1120
Andy Fleming272cc702008-10-30 16:41:01 -05001121 /* fill in device description */
1122 mmc->block_dev.lun = 0;
1123 mmc->block_dev.type = 0;
1124 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001125 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301126 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001127#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001128 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1129 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1130 (mmc->cid[3] >> 16) & 0xffff);
1131 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1132 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1133 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1134 (mmc->cid[2] >> 24) & 0xff);
1135 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1136 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001137#else
1138 mmc->block_dev.vendor[0] = 0;
1139 mmc->block_dev.product[0] = 0;
1140 mmc->block_dev.revision[0] = 0;
1141#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001142#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001143 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001144#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001145
1146 return 0;
1147}
1148
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001149static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001150{
1151 struct mmc_cmd cmd;
1152 int err;
1153
1154 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1155 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001156 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001157 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001158
1159 err = mmc_send_cmd(mmc, &cmd, NULL);
1160
1161 if (err)
1162 return err;
1163
Rabin Vincent998be3d2009-04-05 13:30:56 +05301164 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001165 return UNUSABLE_ERR;
1166 else
1167 mmc->version = SD_VERSION_2;
1168
1169 return 0;
1170}
1171
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001172/* not used any more */
1173int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001174{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001175#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1176 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1177#endif
1178 return -1;
1179}
1180
1181struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1182{
1183 struct mmc *mmc;
1184
1185 /* quick validation */
1186 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1187 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1188 return NULL;
1189
1190 mmc = calloc(1, sizeof(*mmc));
1191 if (mmc == NULL)
1192 return NULL;
1193
1194 mmc->cfg = cfg;
1195 mmc->priv = priv;
1196
1197 /* the following chunk was mmc_register() */
1198
Markus Niebelab711882013-12-16 13:40:46 +01001199 /* Setup dsr related values */
1200 mmc->dsr_imp = 0;
1201 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001202 /* Setup the universal parts of the block interface just once */
1203 mmc->block_dev.if_type = IF_TYPE_MMC;
1204 mmc->block_dev.dev = cur_dev_num++;
1205 mmc->block_dev.removable = 1;
1206 mmc->block_dev.block_read = mmc_bread;
1207 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001208 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001209
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001210 /* setup initial part type */
1211 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001212
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001213 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001214
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001215 list_add_tail(&mmc->link, &mmc_devices);
1216
1217 return mmc;
1218}
1219
1220void mmc_destroy(struct mmc *mmc)
1221{
1222 /* only freeing memory for now */
1223 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001224}
1225
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001226#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001227block_dev_desc_t *mmc_get_dev(int dev)
1228{
1229 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001230 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001231 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001232
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001233 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001234}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001235#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001236
Che-Liang Chioue9550442012-11-28 15:21:13 +00001237int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001238{
Macpaul Linafd59322011-11-14 23:35:39 +00001239 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001240
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001241 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001242 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001243 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001244#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001245 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001246#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001247 return NO_CARD_ERR;
1248 }
1249
Lei Wenbc897b12011-05-02 16:26:26 +00001250 if (mmc->has_init)
1251 return 0;
1252
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001253 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001254 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001255
1256 if (err)
1257 return err;
1258
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001259 mmc_set_bus_width(mmc, 1);
1260 mmc_set_clock(mmc, 1);
1261
Andy Fleming272cc702008-10-30 16:41:01 -05001262 /* Reset the Card */
1263 err = mmc_go_idle(mmc);
1264
1265 if (err)
1266 return err;
1267
Lei Wenbc897b12011-05-02 16:26:26 +00001268 /* The internal partition reset to user partition(0) at every CMD0*/
1269 mmc->part_num = 0;
1270
Andy Fleming272cc702008-10-30 16:41:01 -05001271 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001272 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001273
Andy Fleming272cc702008-10-30 16:41:01 -05001274 /* Now try to get the SD card's operating condition */
1275 err = sd_send_op_cond(mmc);
1276
1277 /* If the command timed out, we check for an MMC card */
1278 if (err == TIMEOUT) {
1279 err = mmc_send_op_cond(mmc);
1280
Che-Liang Chioue9550442012-11-28 15:21:13 +00001281 if (err && err != IN_PROGRESS) {
Paul Burton56196822013-09-04 16:12:25 +01001282#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001283 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001284#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001285 return UNUSABLE_ERR;
1286 }
1287 }
1288
Che-Liang Chioue9550442012-11-28 15:21:13 +00001289 if (err == IN_PROGRESS)
1290 mmc->init_in_progress = 1;
1291
1292 return err;
1293}
1294
1295static int mmc_complete_init(struct mmc *mmc)
1296{
1297 int err = 0;
1298
1299 if (mmc->op_cond_pending)
1300 err = mmc_complete_op_cond(mmc);
1301
1302 if (!err)
1303 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001304 if (err)
1305 mmc->has_init = 0;
1306 else
1307 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001308 mmc->init_in_progress = 0;
1309 return err;
1310}
1311
1312int mmc_init(struct mmc *mmc)
1313{
1314 int err = IN_PROGRESS;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001315 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001316
1317 if (mmc->has_init)
1318 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001319
1320 start = get_timer(0);
1321
Che-Liang Chioue9550442012-11-28 15:21:13 +00001322 if (!mmc->init_in_progress)
1323 err = mmc_start_init(mmc);
1324
1325 if (!err || err == IN_PROGRESS)
1326 err = mmc_complete_init(mmc);
1327 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001328 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001329}
1330
Markus Niebelab711882013-12-16 13:40:46 +01001331int mmc_set_dsr(struct mmc *mmc, u16 val)
1332{
1333 mmc->dsr = val;
1334 return 0;
1335}
1336
Andy Fleming272cc702008-10-30 16:41:01 -05001337/*
1338 * CPU and board-specific MMC initializations. Aliased function
1339 * signals caller to move on
1340 */
1341static int __def_mmc_init(bd_t *bis)
1342{
1343 return -1;
1344}
1345
Peter Tyserf9a109b2009-04-20 11:08:46 -05001346int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1347int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Fleming272cc702008-10-30 16:41:01 -05001348
Paul Burton56196822013-09-04 16:12:25 +01001349#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1350
Andy Fleming272cc702008-10-30 16:41:01 -05001351void print_mmc_devices(char separator)
1352{
1353 struct mmc *m;
1354 struct list_head *entry;
1355
1356 list_for_each(entry, &mmc_devices) {
1357 m = list_entry(entry, struct mmc, link);
1358
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001359 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Fleming272cc702008-10-30 16:41:01 -05001360
1361 if (entry->next != &mmc_devices)
1362 printf("%c ", separator);
1363 }
1364
1365 printf("\n");
1366}
1367
Paul Burton56196822013-09-04 16:12:25 +01001368#else
1369void print_mmc_devices(char separator) { }
1370#endif
1371
Lei Wenea6ebe22011-05-02 16:26:25 +00001372int get_mmc_num(void)
1373{
1374 return cur_dev_num;
1375}
1376
Che-Liang Chioue9550442012-11-28 15:21:13 +00001377void mmc_set_preinit(struct mmc *mmc, int preinit)
1378{
1379 mmc->preinit = preinit;
1380}
1381
1382static void do_preinit(void)
1383{
1384 struct mmc *m;
1385 struct list_head *entry;
1386
1387 list_for_each(entry, &mmc_devices) {
1388 m = list_entry(entry, struct mmc, link);
1389
1390 if (m->preinit)
1391 mmc_start_init(m);
1392 }
1393}
1394
1395
Andy Fleming272cc702008-10-30 16:41:01 -05001396int mmc_initialize(bd_t *bis)
1397{
1398 INIT_LIST_HEAD (&mmc_devices);
1399 cur_dev_num = 0;
1400
1401 if (board_mmc_init(bis) < 0)
1402 cpu_mmc_init(bis);
1403
Ying Zhangbb0dc102013-08-16 15:16:11 +08001404#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001405 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001406#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001407
Che-Liang Chioue9550442012-11-28 15:21:13 +00001408 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001409 return 0;
1410}
Amar3690d6d2013-04-27 11:42:58 +05301411
1412#ifdef CONFIG_SUPPORT_EMMC_BOOT
1413/*
1414 * This function changes the size of boot partition and the size of rpmb
1415 * partition present on EMMC devices.
1416 *
1417 * Input Parameters:
1418 * struct *mmc: pointer for the mmc device strcuture
1419 * bootsize: size of boot partition
1420 * rpmbsize: size of rpmb partition
1421 *
1422 * Returns 0 on success.
1423 */
1424
1425int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1426 unsigned long rpmbsize)
1427{
1428 int err;
1429 struct mmc_cmd cmd;
1430
1431 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1432 cmd.cmdidx = MMC_CMD_RES_MAN;
1433 cmd.resp_type = MMC_RSP_R1b;
1434 cmd.cmdarg = MMC_CMD62_ARG1;
1435
1436 err = mmc_send_cmd(mmc, &cmd, NULL);
1437 if (err) {
1438 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1439 return err;
1440 }
1441
1442 /* Boot partition changing mode */
1443 cmd.cmdidx = MMC_CMD_RES_MAN;
1444 cmd.resp_type = MMC_RSP_R1b;
1445 cmd.cmdarg = MMC_CMD62_ARG2;
1446
1447 err = mmc_send_cmd(mmc, &cmd, NULL);
1448 if (err) {
1449 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1450 return err;
1451 }
1452 /* boot partition size is multiple of 128KB */
1453 bootsize = (bootsize * 1024) / 128;
1454
1455 /* Arg: boot partition size */
1456 cmd.cmdidx = MMC_CMD_RES_MAN;
1457 cmd.resp_type = MMC_RSP_R1b;
1458 cmd.cmdarg = bootsize;
1459
1460 err = mmc_send_cmd(mmc, &cmd, NULL);
1461 if (err) {
1462 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1463 return err;
1464 }
1465 /* RPMB partition size is multiple of 128KB */
1466 rpmbsize = (rpmbsize * 1024) / 128;
1467 /* Arg: RPMB partition size */
1468 cmd.cmdidx = MMC_CMD_RES_MAN;
1469 cmd.resp_type = MMC_RSP_R1b;
1470 cmd.cmdarg = rpmbsize;
1471
1472 err = mmc_send_cmd(mmc, &cmd, NULL);
1473 if (err) {
1474 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1475 return err;
1476 }
1477 return 0;
1478}
1479
1480/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001481 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1482 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1483 * and BOOT_MODE.
1484 *
1485 * Returns 0 on success.
1486 */
1487int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1488{
1489 int err;
1490
1491 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1492 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1493 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1494 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1495
1496 if (err)
1497 return err;
1498 return 0;
1499}
1500
1501/*
Tom Rini792970b2014-02-05 10:24:21 -05001502 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1503 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1504 * PARTITION_ACCESS.
1505 *
1506 * Returns 0 on success.
1507 */
1508int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1509{
1510 int err;
1511
1512 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1513 EXT_CSD_BOOT_ACK(ack) |
1514 EXT_CSD_BOOT_PART_NUM(part_num) |
1515 EXT_CSD_PARTITION_ACCESS(access));
1516
1517 if (err)
1518 return err;
1519 return 0;
1520}
Tom Rini33ace362014-02-07 14:15:20 -05001521
1522/*
1523 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1524 * for enable. Note that this is a write-once field for non-zero values.
1525 *
1526 * Returns 0 on success.
1527 */
1528int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1529{
1530 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1531 enable);
1532}
Amar3690d6d2013-04-27 11:42:58 +05301533#endif