blob: 8b53ead98f802ccc60906f43fbad039aa7852f98 [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
Stephen Warrend2356282014-05-07 12:19:02 -0600555int mmc_select_hwpart(int dev_num, int hwpart)
556{
557 struct mmc *mmc = find_mmc_device(dev_num);
558 int ret;
559
560 if (!mmc)
561 return -1;
562
563 if (mmc->part_num == hwpart)
564 return 0;
565
566 if (mmc->part_config == MMCPART_NOAVAILABLE) {
567 printf("Card doesn't support part_switch\n");
568 return -1;
569 }
570
571 ret = mmc_switch_part(dev_num, hwpart);
572 if (ret)
573 return -1;
574
575 mmc->part_num = hwpart;
576
577 return 0;
578}
579
580
Lei Wenbc897b12011-05-02 16:26:26 +0000581int mmc_switch_part(int dev_num, unsigned int part_num)
582{
583 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600584 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000585
586 if (!mmc)
587 return -1;
588
Stephen Warrenf866a462013-06-11 15:14:01 -0600589 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
590 (mmc->part_config & ~PART_ACCESS_MASK)
591 | (part_num & PART_ACCESS_MASK));
592 if (ret)
593 return ret;
594
595 return mmc_set_capacity(mmc, part_num);
Lei Wenbc897b12011-05-02 16:26:26 +0000596}
597
Thierry Reding48972d92012-01-02 01:15:37 +0000598int mmc_getcd(struct mmc *mmc)
599{
600 int cd;
601
602 cd = board_mmc_getcd(mmc);
603
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000604 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200605 if (mmc->cfg->ops->getcd)
606 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000607 else
608 cd = 1;
609 }
Thierry Reding48972d92012-01-02 01:15:37 +0000610
611 return cd;
612}
613
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000614static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500615{
616 struct mmc_cmd cmd;
617 struct mmc_data data;
618
619 /* Switch the frequency */
620 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
621 cmd.resp_type = MMC_RSP_R1;
622 cmd.cmdarg = (mode << 31) | 0xffffff;
623 cmd.cmdarg &= ~(0xf << (group * 4));
624 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500625
626 data.dest = (char *)resp;
627 data.blocksize = 64;
628 data.blocks = 1;
629 data.flags = MMC_DATA_READ;
630
631 return mmc_send_cmd(mmc, &cmd, &data);
632}
633
634
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000635static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500636{
637 int err;
638 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000639 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
640 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500641 struct mmc_data data;
642 int timeout;
643
644 mmc->card_caps = 0;
645
Thomas Choud52ebf12010-12-24 13:12:21 +0000646 if (mmc_host_is_spi(mmc))
647 return 0;
648
Andy Fleming272cc702008-10-30 16:41:01 -0500649 /* Read the SCR to find out if this card supports higher speeds */
650 cmd.cmdidx = MMC_CMD_APP_CMD;
651 cmd.resp_type = MMC_RSP_R1;
652 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500653
654 err = mmc_send_cmd(mmc, &cmd, NULL);
655
656 if (err)
657 return err;
658
659 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
660 cmd.resp_type = MMC_RSP_R1;
661 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500662
663 timeout = 3;
664
665retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000666 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500667 data.blocksize = 8;
668 data.blocks = 1;
669 data.flags = MMC_DATA_READ;
670
671 err = mmc_send_cmd(mmc, &cmd, &data);
672
673 if (err) {
674 if (timeout--)
675 goto retry_scr;
676
677 return err;
678 }
679
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300680 mmc->scr[0] = __be32_to_cpu(scr[0]);
681 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500682
683 switch ((mmc->scr[0] >> 24) & 0xf) {
684 case 0:
685 mmc->version = SD_VERSION_1_0;
686 break;
687 case 1:
688 mmc->version = SD_VERSION_1_10;
689 break;
690 case 2:
691 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000692 if ((mmc->scr[0] >> 15) & 0x1)
693 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500694 break;
695 default:
696 mmc->version = SD_VERSION_1_0;
697 break;
698 }
699
Alagu Sankarb44c7082010-05-12 15:08:24 +0530700 if (mmc->scr[0] & SD_DATA_4BIT)
701 mmc->card_caps |= MMC_MODE_4BIT;
702
Andy Fleming272cc702008-10-30 16:41:01 -0500703 /* Version 1.0 doesn't support switching */
704 if (mmc->version == SD_VERSION_1_0)
705 return 0;
706
707 timeout = 4;
708 while (timeout--) {
709 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000710 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500711
712 if (err)
713 return err;
714
715 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300716 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500717 break;
718 }
719
Andy Fleming272cc702008-10-30 16:41:01 -0500720 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300721 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500722 return 0;
723
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000724 /*
725 * If the host doesn't support SD_HIGHSPEED, do not switch card to
726 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
727 * This can avoid furthur problem when the card runs in different
728 * mode between the host.
729 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200730 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
731 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000732 return 0;
733
Anton staaff781dd32011-10-03 13:54:59 +0000734 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500735
736 if (err)
737 return err;
738
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300739 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500740 mmc->card_caps |= MMC_MODE_HS;
741
742 return 0;
743}
744
745/* frequency bases */
746/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000747static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500748 10000,
749 100000,
750 1000000,
751 10000000,
752};
753
754/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
755 * to platforms without floating point.
756 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000757static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500758 0, /* reserved */
759 10,
760 12,
761 13,
762 15,
763 20,
764 25,
765 30,
766 35,
767 40,
768 45,
769 50,
770 55,
771 60,
772 70,
773 80,
774};
775
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000776static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500777{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200778 if (mmc->cfg->ops->set_ios)
779 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500780}
781
782void mmc_set_clock(struct mmc *mmc, uint clock)
783{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200784 if (clock > mmc->cfg->f_max)
785 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500786
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200787 if (clock < mmc->cfg->f_min)
788 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -0500789
790 mmc->clock = clock;
791
792 mmc_set_ios(mmc);
793}
794
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000795static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -0500796{
797 mmc->bus_width = width;
798
799 mmc_set_ios(mmc);
800}
801
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000802static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500803{
Stephen Warrenf866a462013-06-11 15:14:01 -0600804 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -0500805 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000806 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -0500807 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +0000808 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
809 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000810 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500811
Thomas Choud52ebf12010-12-24 13:12:21 +0000812#ifdef CONFIG_MMC_SPI_CRC_ON
813 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
814 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
815 cmd.resp_type = MMC_RSP_R1;
816 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000817 err = mmc_send_cmd(mmc, &cmd, NULL);
818
819 if (err)
820 return err;
821 }
822#endif
823
Andy Fleming272cc702008-10-30 16:41:01 -0500824 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000825 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
826 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -0500827 cmd.resp_type = MMC_RSP_R2;
828 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500829
830 err = mmc_send_cmd(mmc, &cmd, NULL);
831
832 if (err)
833 return err;
834
835 memcpy(mmc->cid, cmd.response, 16);
836
837 /*
838 * For MMC cards, set the Relative Address.
839 * For SD cards, get the Relatvie Address.
840 * This also puts the cards into Standby State
841 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000842 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
843 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
844 cmd.cmdarg = mmc->rca << 16;
845 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -0500846
Thomas Choud52ebf12010-12-24 13:12:21 +0000847 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500848
Thomas Choud52ebf12010-12-24 13:12:21 +0000849 if (err)
850 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500851
Thomas Choud52ebf12010-12-24 13:12:21 +0000852 if (IS_SD(mmc))
853 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
854 }
Andy Fleming272cc702008-10-30 16:41:01 -0500855
856 /* Get the Card-Specific Data */
857 cmd.cmdidx = MMC_CMD_SEND_CSD;
858 cmd.resp_type = MMC_RSP_R2;
859 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500860
861 err = mmc_send_cmd(mmc, &cmd, NULL);
862
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000863 /* Waiting for the ready status */
864 mmc_send_status(mmc, timeout);
865
Andy Fleming272cc702008-10-30 16:41:01 -0500866 if (err)
867 return err;
868
Rabin Vincent998be3d2009-04-05 13:30:56 +0530869 mmc->csd[0] = cmd.response[0];
870 mmc->csd[1] = cmd.response[1];
871 mmc->csd[2] = cmd.response[2];
872 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -0500873
874 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530875 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500876
877 switch (version) {
878 case 0:
879 mmc->version = MMC_VERSION_1_2;
880 break;
881 case 1:
882 mmc->version = MMC_VERSION_1_4;
883 break;
884 case 2:
885 mmc->version = MMC_VERSION_2_2;
886 break;
887 case 3:
888 mmc->version = MMC_VERSION_3;
889 break;
890 case 4:
891 mmc->version = MMC_VERSION_4;
892 break;
893 default:
894 mmc->version = MMC_VERSION_1_2;
895 break;
896 }
897 }
898
899 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530900 freq = fbase[(cmd.response[0] & 0x7)];
901 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -0500902
903 mmc->tran_speed = freq * mult;
904
Markus Niebelab711882013-12-16 13:40:46 +0100905 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +0530906 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500907
908 if (IS_SD(mmc))
909 mmc->write_bl_len = mmc->read_bl_len;
910 else
Rabin Vincent998be3d2009-04-05 13:30:56 +0530911 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500912
913 if (mmc->high_capacity) {
914 csize = (mmc->csd[1] & 0x3f) << 16
915 | (mmc->csd[2] & 0xffff0000) >> 16;
916 cmult = 8;
917 } else {
918 csize = (mmc->csd[1] & 0x3ff) << 2
919 | (mmc->csd[2] & 0xc0000000) >> 30;
920 cmult = (mmc->csd[2] & 0x00038000) >> 15;
921 }
922
Stephen Warrenf866a462013-06-11 15:14:01 -0600923 mmc->capacity_user = (csize + 1) << (cmult + 2);
924 mmc->capacity_user *= mmc->read_bl_len;
925 mmc->capacity_boot = 0;
926 mmc->capacity_rpmb = 0;
927 for (i = 0; i < 4; i++)
928 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500929
Simon Glass8bfa1952013-04-03 08:54:30 +0000930 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
931 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500932
Simon Glass8bfa1952013-04-03 08:54:30 +0000933 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
934 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500935
Markus Niebelab711882013-12-16 13:40:46 +0100936 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
937 cmd.cmdidx = MMC_CMD_SET_DSR;
938 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
939 cmd.resp_type = MMC_RSP_NONE;
940 if (mmc_send_cmd(mmc, &cmd, NULL))
941 printf("MMC: SET_DSR failed\n");
942 }
943
Andy Fleming272cc702008-10-30 16:41:01 -0500944 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000945 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
946 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +0000947 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000948 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +0000949 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500950
Thomas Choud52ebf12010-12-24 13:12:21 +0000951 if (err)
952 return err;
953 }
Andy Fleming272cc702008-10-30 16:41:01 -0500954
Lei Wene6f99a52011-06-22 17:03:31 +0000955 /*
956 * For SD, its erase group is always one sector
957 */
958 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +0000959 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530960 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
961 /* check ext_csd version and capacity */
962 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000963 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000964 /*
965 * According to the JEDEC Standard, the value of
966 * ext_csd's capacity is valid if the value is more
967 * than 2GB
968 */
Lei Wen0560db12011-10-03 20:35:10 +0000969 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
970 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
971 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
972 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +0000973 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +0000974 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -0600975 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530976 }
Lei Wenbc897b12011-05-02 16:26:26 +0000977
Jaehoon Chung64f4a612013-01-29 19:31:16 +0000978 switch (ext_csd[EXT_CSD_REV]) {
979 case 1:
980 mmc->version = MMC_VERSION_4_1;
981 break;
982 case 2:
983 mmc->version = MMC_VERSION_4_2;
984 break;
985 case 3:
986 mmc->version = MMC_VERSION_4_3;
987 break;
988 case 5:
989 mmc->version = MMC_VERSION_4_41;
990 break;
991 case 6:
992 mmc->version = MMC_VERSION_4_5;
993 break;
994 }
995
Lei Wene6f99a52011-06-22 17:03:31 +0000996 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +0200997 * Host needs to enable ERASE_GRP_DEF bit if device is
998 * partitioned. This bit will be lost every time after a reset
999 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001000 */
Oliver Metz1937e5a2013-10-01 20:32:07 +02001001 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
1002 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
1003 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1004 EXT_CSD_ERASE_GROUP_DEF, 1);
1005
1006 if (err)
1007 return err;
1008
1009 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001010 mmc->erase_grp_size =
Simon Glass8bfa1952013-04-03 08:54:30 +00001011 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
1012 MMC_MAX_BLOCK_LEN * 1024;
1013 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001014 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001015 int erase_gsz, erase_gmul;
1016 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1017 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1018 mmc->erase_grp_size = (erase_gsz + 1)
1019 * (erase_gmul + 1);
1020 }
1021
Lei Wenbc897b12011-05-02 16:26:26 +00001022 /* store the partition info of emmc */
Stephen Warren8948ea82012-07-30 10:55:43 +00001023 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1024 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen0560db12011-10-03 20:35:10 +00001025 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrenf866a462013-06-11 15:14:01 -06001026
1027 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1028
1029 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1030
1031 for (i = 0; i < 4; i++) {
1032 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1033 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1034 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1035 mmc->capacity_gp[i] *=
1036 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1037 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1038 }
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301039 }
1040
Stephen Warrenf866a462013-06-11 15:14:01 -06001041 err = mmc_set_capacity(mmc, mmc->part_num);
1042 if (err)
1043 return err;
1044
Andy Fleming272cc702008-10-30 16:41:01 -05001045 if (IS_SD(mmc))
1046 err = sd_change_freq(mmc);
1047 else
1048 err = mmc_change_freq(mmc);
1049
1050 if (err)
1051 return err;
1052
1053 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001054 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001055
1056 if (IS_SD(mmc)) {
1057 if (mmc->card_caps & MMC_MODE_4BIT) {
1058 cmd.cmdidx = MMC_CMD_APP_CMD;
1059 cmd.resp_type = MMC_RSP_R1;
1060 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001061
1062 err = mmc_send_cmd(mmc, &cmd, NULL);
1063 if (err)
1064 return err;
1065
1066 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1067 cmd.resp_type = MMC_RSP_R1;
1068 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001069 err = mmc_send_cmd(mmc, &cmd, NULL);
1070 if (err)
1071 return err;
1072
1073 mmc_set_bus_width(mmc, 4);
1074 }
1075
1076 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001077 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001078 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001079 mmc->tran_speed = 25000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001080 } else {
Andy Fleming7798f6d2012-10-31 19:02:38 +00001081 int idx;
1082
1083 /* An array of possible bus widths in order of preference */
1084 static unsigned ext_csd_bits[] = {
1085 EXT_CSD_BUS_WIDTH_8,
1086 EXT_CSD_BUS_WIDTH_4,
1087 EXT_CSD_BUS_WIDTH_1,
1088 };
1089
1090 /* An array to map CSD bus widths to host cap bits */
1091 static unsigned ext_to_hostcaps[] = {
1092 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1093 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1094 };
1095
1096 /* An array to map chosen bus width to an integer */
1097 static unsigned widths[] = {
1098 8, 4, 1,
1099 };
1100
1101 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1102 unsigned int extw = ext_csd_bits[idx];
1103
1104 /*
1105 * Check to make sure the controller supports
1106 * this bus width, if it's more than 1
1107 */
1108 if (extw != EXT_CSD_BUS_WIDTH_1 &&
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001109 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Fleming7798f6d2012-10-31 19:02:38 +00001110 continue;
1111
Andy Fleming272cc702008-10-30 16:41:01 -05001112 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001113 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001114
1115 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001116 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001117
Andy Fleming7798f6d2012-10-31 19:02:38 +00001118 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001119
Lei Wen41378942011-10-03 20:35:11 +00001120 err = mmc_send_ext_csd(mmc, test_csd);
1121 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1122 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1123 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1124 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1125 && ext_csd[EXT_CSD_REV] \
1126 == test_csd[EXT_CSD_REV]
1127 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1128 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1129 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1130 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Fleming272cc702008-10-30 16:41:01 -05001131
Andy Fleming7798f6d2012-10-31 19:02:38 +00001132 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen41378942011-10-03 20:35:11 +00001133 break;
1134 }
Andy Fleming272cc702008-10-30 16:41:01 -05001135 }
1136
1137 if (mmc->card_caps & MMC_MODE_HS) {
1138 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001139 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001140 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001141 mmc->tran_speed = 26000000;
1142 }
Andy Fleming272cc702008-10-30 16:41:01 -05001143 }
1144
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001145 mmc_set_clock(mmc, mmc->tran_speed);
1146
Andy Fleming272cc702008-10-30 16:41:01 -05001147 /* fill in device description */
1148 mmc->block_dev.lun = 0;
1149 mmc->block_dev.type = 0;
1150 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001151 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301152 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001153#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001154 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1155 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1156 (mmc->cid[3] >> 16) & 0xffff);
1157 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1158 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1159 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1160 (mmc->cid[2] >> 24) & 0xff);
1161 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1162 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001163#else
1164 mmc->block_dev.vendor[0] = 0;
1165 mmc->block_dev.product[0] = 0;
1166 mmc->block_dev.revision[0] = 0;
1167#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001168#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001169 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001170#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001171
1172 return 0;
1173}
1174
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001175static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001176{
1177 struct mmc_cmd cmd;
1178 int err;
1179
1180 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1181 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001182 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001183 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001184
1185 err = mmc_send_cmd(mmc, &cmd, NULL);
1186
1187 if (err)
1188 return err;
1189
Rabin Vincent998be3d2009-04-05 13:30:56 +05301190 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001191 return UNUSABLE_ERR;
1192 else
1193 mmc->version = SD_VERSION_2;
1194
1195 return 0;
1196}
1197
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001198/* not used any more */
1199int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001200{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001201#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1202 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1203#endif
1204 return -1;
1205}
1206
1207struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1208{
1209 struct mmc *mmc;
1210
1211 /* quick validation */
1212 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1213 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1214 return NULL;
1215
1216 mmc = calloc(1, sizeof(*mmc));
1217 if (mmc == NULL)
1218 return NULL;
1219
1220 mmc->cfg = cfg;
1221 mmc->priv = priv;
1222
1223 /* the following chunk was mmc_register() */
1224
Markus Niebelab711882013-12-16 13:40:46 +01001225 /* Setup dsr related values */
1226 mmc->dsr_imp = 0;
1227 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001228 /* Setup the universal parts of the block interface just once */
1229 mmc->block_dev.if_type = IF_TYPE_MMC;
1230 mmc->block_dev.dev = cur_dev_num++;
1231 mmc->block_dev.removable = 1;
1232 mmc->block_dev.block_read = mmc_bread;
1233 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001234 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001235
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001236 /* setup initial part type */
1237 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001238
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001239 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001240
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001241 list_add_tail(&mmc->link, &mmc_devices);
1242
1243 return mmc;
1244}
1245
1246void mmc_destroy(struct mmc *mmc)
1247{
1248 /* only freeing memory for now */
1249 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001250}
1251
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001252#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001253block_dev_desc_t *mmc_get_dev(int dev)
1254{
1255 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001256 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001257 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001258
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001259 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001260}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001261#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001262
Che-Liang Chioue9550442012-11-28 15:21:13 +00001263int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001264{
Macpaul Linafd59322011-11-14 23:35:39 +00001265 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001266
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001267 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001268 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001269 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001270#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001271 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001272#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001273 return NO_CARD_ERR;
1274 }
1275
Lei Wenbc897b12011-05-02 16:26:26 +00001276 if (mmc->has_init)
1277 return 0;
1278
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001279 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001280 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001281
1282 if (err)
1283 return err;
1284
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001285 mmc_set_bus_width(mmc, 1);
1286 mmc_set_clock(mmc, 1);
1287
Andy Fleming272cc702008-10-30 16:41:01 -05001288 /* Reset the Card */
1289 err = mmc_go_idle(mmc);
1290
1291 if (err)
1292 return err;
1293
Lei Wenbc897b12011-05-02 16:26:26 +00001294 /* The internal partition reset to user partition(0) at every CMD0*/
1295 mmc->part_num = 0;
1296
Andy Fleming272cc702008-10-30 16:41:01 -05001297 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001298 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001299
Andy Fleming272cc702008-10-30 16:41:01 -05001300 /* Now try to get the SD card's operating condition */
1301 err = sd_send_op_cond(mmc);
1302
1303 /* If the command timed out, we check for an MMC card */
1304 if (err == TIMEOUT) {
1305 err = mmc_send_op_cond(mmc);
1306
Che-Liang Chioue9550442012-11-28 15:21:13 +00001307 if (err && err != IN_PROGRESS) {
Paul Burton56196822013-09-04 16:12:25 +01001308#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001309 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001310#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001311 return UNUSABLE_ERR;
1312 }
1313 }
1314
Che-Liang Chioue9550442012-11-28 15:21:13 +00001315 if (err == IN_PROGRESS)
1316 mmc->init_in_progress = 1;
1317
1318 return err;
1319}
1320
1321static int mmc_complete_init(struct mmc *mmc)
1322{
1323 int err = 0;
1324
1325 if (mmc->op_cond_pending)
1326 err = mmc_complete_op_cond(mmc);
1327
1328 if (!err)
1329 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001330 if (err)
1331 mmc->has_init = 0;
1332 else
1333 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001334 mmc->init_in_progress = 0;
1335 return err;
1336}
1337
1338int mmc_init(struct mmc *mmc)
1339{
1340 int err = IN_PROGRESS;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001341 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001342
1343 if (mmc->has_init)
1344 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001345
1346 start = get_timer(0);
1347
Che-Liang Chioue9550442012-11-28 15:21:13 +00001348 if (!mmc->init_in_progress)
1349 err = mmc_start_init(mmc);
1350
1351 if (!err || err == IN_PROGRESS)
1352 err = mmc_complete_init(mmc);
1353 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001354 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001355}
1356
Markus Niebelab711882013-12-16 13:40:46 +01001357int mmc_set_dsr(struct mmc *mmc, u16 val)
1358{
1359 mmc->dsr = val;
1360 return 0;
1361}
1362
Andy Fleming272cc702008-10-30 16:41:01 -05001363/*
1364 * CPU and board-specific MMC initializations. Aliased function
1365 * signals caller to move on
1366 */
1367static int __def_mmc_init(bd_t *bis)
1368{
1369 return -1;
1370}
1371
Peter Tyserf9a109b2009-04-20 11:08:46 -05001372int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1373int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Fleming272cc702008-10-30 16:41:01 -05001374
Paul Burton56196822013-09-04 16:12:25 +01001375#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1376
Andy Fleming272cc702008-10-30 16:41:01 -05001377void print_mmc_devices(char separator)
1378{
1379 struct mmc *m;
1380 struct list_head *entry;
1381
1382 list_for_each(entry, &mmc_devices) {
1383 m = list_entry(entry, struct mmc, link);
1384
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001385 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Fleming272cc702008-10-30 16:41:01 -05001386
1387 if (entry->next != &mmc_devices)
1388 printf("%c ", separator);
1389 }
1390
1391 printf("\n");
1392}
1393
Paul Burton56196822013-09-04 16:12:25 +01001394#else
1395void print_mmc_devices(char separator) { }
1396#endif
1397
Lei Wenea6ebe22011-05-02 16:26:25 +00001398int get_mmc_num(void)
1399{
1400 return cur_dev_num;
1401}
1402
Che-Liang Chioue9550442012-11-28 15:21:13 +00001403void mmc_set_preinit(struct mmc *mmc, int preinit)
1404{
1405 mmc->preinit = preinit;
1406}
1407
1408static void do_preinit(void)
1409{
1410 struct mmc *m;
1411 struct list_head *entry;
1412
1413 list_for_each(entry, &mmc_devices) {
1414 m = list_entry(entry, struct mmc, link);
1415
1416 if (m->preinit)
1417 mmc_start_init(m);
1418 }
1419}
1420
1421
Andy Fleming272cc702008-10-30 16:41:01 -05001422int mmc_initialize(bd_t *bis)
1423{
1424 INIT_LIST_HEAD (&mmc_devices);
1425 cur_dev_num = 0;
1426
1427 if (board_mmc_init(bis) < 0)
1428 cpu_mmc_init(bis);
1429
Ying Zhangbb0dc102013-08-16 15:16:11 +08001430#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001431 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001432#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001433
Che-Liang Chioue9550442012-11-28 15:21:13 +00001434 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001435 return 0;
1436}
Amar3690d6d2013-04-27 11:42:58 +05301437
1438#ifdef CONFIG_SUPPORT_EMMC_BOOT
1439/*
1440 * This function changes the size of boot partition and the size of rpmb
1441 * partition present on EMMC devices.
1442 *
1443 * Input Parameters:
1444 * struct *mmc: pointer for the mmc device strcuture
1445 * bootsize: size of boot partition
1446 * rpmbsize: size of rpmb partition
1447 *
1448 * Returns 0 on success.
1449 */
1450
1451int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1452 unsigned long rpmbsize)
1453{
1454 int err;
1455 struct mmc_cmd cmd;
1456
1457 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1458 cmd.cmdidx = MMC_CMD_RES_MAN;
1459 cmd.resp_type = MMC_RSP_R1b;
1460 cmd.cmdarg = MMC_CMD62_ARG1;
1461
1462 err = mmc_send_cmd(mmc, &cmd, NULL);
1463 if (err) {
1464 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1465 return err;
1466 }
1467
1468 /* Boot partition changing mode */
1469 cmd.cmdidx = MMC_CMD_RES_MAN;
1470 cmd.resp_type = MMC_RSP_R1b;
1471 cmd.cmdarg = MMC_CMD62_ARG2;
1472
1473 err = mmc_send_cmd(mmc, &cmd, NULL);
1474 if (err) {
1475 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1476 return err;
1477 }
1478 /* boot partition size is multiple of 128KB */
1479 bootsize = (bootsize * 1024) / 128;
1480
1481 /* Arg: boot partition size */
1482 cmd.cmdidx = MMC_CMD_RES_MAN;
1483 cmd.resp_type = MMC_RSP_R1b;
1484 cmd.cmdarg = bootsize;
1485
1486 err = mmc_send_cmd(mmc, &cmd, NULL);
1487 if (err) {
1488 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1489 return err;
1490 }
1491 /* RPMB partition size is multiple of 128KB */
1492 rpmbsize = (rpmbsize * 1024) / 128;
1493 /* Arg: RPMB partition size */
1494 cmd.cmdidx = MMC_CMD_RES_MAN;
1495 cmd.resp_type = MMC_RSP_R1b;
1496 cmd.cmdarg = rpmbsize;
1497
1498 err = mmc_send_cmd(mmc, &cmd, NULL);
1499 if (err) {
1500 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1501 return err;
1502 }
1503 return 0;
1504}
1505
1506/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001507 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1508 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1509 * and BOOT_MODE.
1510 *
1511 * Returns 0 on success.
1512 */
1513int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1514{
1515 int err;
1516
1517 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1518 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1519 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1520 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1521
1522 if (err)
1523 return err;
1524 return 0;
1525}
1526
1527/*
Tom Rini792970b2014-02-05 10:24:21 -05001528 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1529 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1530 * PARTITION_ACCESS.
1531 *
1532 * Returns 0 on success.
1533 */
1534int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1535{
1536 int err;
1537
1538 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1539 EXT_CSD_BOOT_ACK(ack) |
1540 EXT_CSD_BOOT_PART_NUM(part_num) |
1541 EXT_CSD_PARTITION_ACCESS(access));
1542
1543 if (err)
1544 return err;
1545 return 0;
1546}
Tom Rini33ace362014-02-07 14:15:20 -05001547
1548/*
1549 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1550 * for enable. Note that this is a write-once field for non-zero values.
1551 *
1552 * Returns 0 on success.
1553 */
1554int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1555{
1556 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1557 enable);
1558}
Amar3690d6d2013-04-27 11:42:58 +05301559#endif