blob: 55c2c68cdb23218945d0af727632745897278d72 [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
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900163 if (mmc->card_caps & MMC_MODE_DDR_52MHz)
164 return 0;
165
Andy Fleming272cc702008-10-30 16:41:01 -0500166 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
167 cmd.resp_type = MMC_RSP_R1;
168 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500169
170 return mmc_send_cmd(mmc, &cmd, NULL);
171}
172
173struct mmc *find_mmc_device(int dev_num)
174{
175 struct mmc *m;
176 struct list_head *entry;
177
178 list_for_each(entry, &mmc_devices) {
179 m = list_entry(entry, struct mmc, link);
180
181 if (m->block_dev.dev == dev_num)
182 return m;
183 }
184
Paul Burton56196822013-09-04 16:12:25 +0100185#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -0500186 printf("MMC Device %d not found\n", dev_num);
Paul Burton56196822013-09-04 16:12:25 +0100187#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500188
189 return NULL;
190}
191
Sascha Silbeff8fef52013-06-14 13:07:25 +0200192static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000193 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500194{
195 struct mmc_cmd cmd;
196 struct mmc_data data;
197
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700198 if (blkcnt > 1)
199 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
200 else
201 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500202
203 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700204 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500205 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700206 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500207
208 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500209
210 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700211 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500212 data.blocksize = mmc->read_bl_len;
213 data.flags = MMC_DATA_READ;
214
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700215 if (mmc_send_cmd(mmc, &cmd, &data))
216 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500217
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700218 if (blkcnt > 1) {
219 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
220 cmd.cmdarg = 0;
221 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700222 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100223#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700224 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100225#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700226 return 0;
227 }
Andy Fleming272cc702008-10-30 16:41:01 -0500228 }
229
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700230 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500231}
232
Sascha Silbeff8fef52013-06-14 13:07:25 +0200233static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500234{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700235 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500236
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700237 if (blkcnt == 0)
238 return 0;
239
240 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500241 if (!mmc)
242 return 0;
243
Lei Wend2bf29e2010-09-13 22:07:27 +0800244 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton56196822013-09-04 16:12:25 +0100245#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200246 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800247 start + blkcnt, mmc->block_dev.lba);
Paul Burton56196822013-09-04 16:12:25 +0100248#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800249 return 0;
250 }
Andy Fleming272cc702008-10-30 16:41:01 -0500251
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700252 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500253 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500254
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700255 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200256 cur = (blocks_todo > mmc->cfg->b_max) ?
257 mmc->cfg->b_max : blocks_todo;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700258 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
259 return 0;
260 blocks_todo -= cur;
261 start += cur;
262 dst += cur * mmc->read_bl_len;
263 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500264
265 return blkcnt;
266}
267
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000268static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500269{
270 struct mmc_cmd cmd;
271 int err;
272
273 udelay(1000);
274
275 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
276 cmd.cmdarg = 0;
277 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500278
279 err = mmc_send_cmd(mmc, &cmd, NULL);
280
281 if (err)
282 return err;
283
284 udelay(2000);
285
286 return 0;
287}
288
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000289static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500290{
291 int timeout = 1000;
292 int err;
293 struct mmc_cmd cmd;
294
295 do {
296 cmd.cmdidx = MMC_CMD_APP_CMD;
297 cmd.resp_type = MMC_RSP_R1;
298 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500299
300 err = mmc_send_cmd(mmc, &cmd, NULL);
301
302 if (err)
303 return err;
304
305 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
306 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100307
308 /*
309 * Most cards do not answer if some reserved bits
310 * in the ocr are set. However, Some controller
311 * can set bit 7 (reserved for low voltages), but
312 * how to manage low voltages SD card is not yet
313 * specified.
314 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000315 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200316 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500317
318 if (mmc->version == SD_VERSION_2)
319 cmd.cmdarg |= OCR_HCS;
320
321 err = mmc_send_cmd(mmc, &cmd, NULL);
322
323 if (err)
324 return err;
325
326 udelay(1000);
327 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
328
329 if (timeout <= 0)
330 return UNUSABLE_ERR;
331
332 if (mmc->version != SD_VERSION_2)
333 mmc->version = SD_VERSION_1_0;
334
Thomas Choud52ebf12010-12-24 13:12:21 +0000335 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
336 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
337 cmd.resp_type = MMC_RSP_R3;
338 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000339
340 err = mmc_send_cmd(mmc, &cmd, NULL);
341
342 if (err)
343 return err;
344 }
345
Rabin Vincent998be3d2009-04-05 13:30:56 +0530346 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500347
348 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
349 mmc->rca = 0;
350
351 return 0;
352}
353
Che-Liang Chioue9550442012-11-28 15:21:13 +0000354/* We pass in the cmd since otherwise the init seems to fail */
355static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
356 int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500357{
Andy Fleming272cc702008-10-30 16:41:01 -0500358 int err;
359
Che-Liang Chioue9550442012-11-28 15:21:13 +0000360 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
361 cmd->resp_type = MMC_RSP_R3;
362 cmd->cmdarg = 0;
363 if (use_arg && !mmc_host_is_spi(mmc)) {
364 cmd->cmdarg =
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200365 (mmc->cfg->voltages &
Che-Liang Chioue9550442012-11-28 15:21:13 +0000366 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
367 (mmc->op_cond_response & OCR_ACCESS_MODE);
368
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200369 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000370 cmd->cmdarg |= OCR_HCS;
371 }
372 err = mmc_send_cmd(mmc, cmd, NULL);
373 if (err)
374 return err;
375 mmc->op_cond_response = cmd->response[0];
376 return 0;
377}
378
379int mmc_send_op_cond(struct mmc *mmc)
380{
381 struct mmc_cmd cmd;
382 int err, i;
383
Andy Fleming272cc702008-10-30 16:41:01 -0500384 /* Some cards seem to need this */
385 mmc_go_idle(mmc);
386
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000387 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000388 mmc->op_cond_pending = 1;
389 for (i = 0; i < 2; i++) {
390 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500391 if (err)
392 return err;
393
Che-Liang Chioue9550442012-11-28 15:21:13 +0000394 /* exit if not busy (flag seems to be inverted) */
395 if (mmc->op_cond_response & OCR_BUSY)
396 return 0;
397 }
398 return IN_PROGRESS;
399}
Andy Fleming272cc702008-10-30 16:41:01 -0500400
Che-Liang Chioue9550442012-11-28 15:21:13 +0000401int mmc_complete_op_cond(struct mmc *mmc)
402{
403 struct mmc_cmd cmd;
404 int timeout = 1000;
405 uint start;
406 int err;
407
408 mmc->op_cond_pending = 0;
409 start = get_timer(0);
410 do {
411 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
412 if (err)
413 return err;
414 if (get_timer(start) > timeout)
415 return UNUSABLE_ERR;
416 udelay(100);
417 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Fleming272cc702008-10-30 16:41:01 -0500418
Thomas Choud52ebf12010-12-24 13:12:21 +0000419 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
420 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
421 cmd.resp_type = MMC_RSP_R3;
422 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000423
424 err = mmc_send_cmd(mmc, &cmd, NULL);
425
426 if (err)
427 return err;
428 }
429
Andy Fleming272cc702008-10-30 16:41:01 -0500430 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincent998be3d2009-04-05 13:30:56 +0530431 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500432
433 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700434 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500435
436 return 0;
437}
438
439
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000440static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500441{
442 struct mmc_cmd cmd;
443 struct mmc_data data;
444 int err;
445
446 /* Get the Card Status Register */
447 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
448 cmd.resp_type = MMC_RSP_R1;
449 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500450
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000451 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500452 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000453 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500454 data.flags = MMC_DATA_READ;
455
456 err = mmc_send_cmd(mmc, &cmd, &data);
457
458 return err;
459}
460
461
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000462static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500463{
464 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000465 int timeout = 1000;
466 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500467
468 cmd.cmdidx = MMC_CMD_SWITCH;
469 cmd.resp_type = MMC_RSP_R1b;
470 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000471 (index << 16) |
472 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500473
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000474 ret = mmc_send_cmd(mmc, &cmd, NULL);
475
476 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000477 if (!ret)
478 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000479
480 return ret;
481
Andy Fleming272cc702008-10-30 16:41:01 -0500482}
483
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000484static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500485{
Simon Glass8bfa1952013-04-03 08:54:30 +0000486 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500487 char cardtype;
488 int err;
489
490 mmc->card_caps = 0;
491
Thomas Choud52ebf12010-12-24 13:12:21 +0000492 if (mmc_host_is_spi(mmc))
493 return 0;
494
Andy Fleming272cc702008-10-30 16:41:01 -0500495 /* Only version 4 supports high-speed */
496 if (mmc->version < MMC_VERSION_4)
497 return 0;
498
Andy Fleming272cc702008-10-30 16:41:01 -0500499 err = mmc_send_ext_csd(mmc, ext_csd);
500
501 if (err)
502 return err;
503
Lei Wen0560db12011-10-03 20:35:10 +0000504 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500505
506 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
507
508 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500509 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500510
511 /* Now check to see that it worked */
512 err = mmc_send_ext_csd(mmc, ext_csd);
513
514 if (err)
515 return err;
516
517 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000518 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500519 return 0;
520
521 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900522 if (cardtype & EXT_CSD_CARD_TYPE_52) {
523 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
524 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500525 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900526 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500527 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900528 }
Andy Fleming272cc702008-10-30 16:41:01 -0500529
530 return 0;
531}
532
Stephen Warrenf866a462013-06-11 15:14:01 -0600533static int mmc_set_capacity(struct mmc *mmc, int part_num)
534{
535 switch (part_num) {
536 case 0:
537 mmc->capacity = mmc->capacity_user;
538 break;
539 case 1:
540 case 2:
541 mmc->capacity = mmc->capacity_boot;
542 break;
543 case 3:
544 mmc->capacity = mmc->capacity_rpmb;
545 break;
546 case 4:
547 case 5:
548 case 6:
549 case 7:
550 mmc->capacity = mmc->capacity_gp[part_num - 4];
551 break;
552 default:
553 return -1;
554 }
555
556 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
557
558 return 0;
559}
560
Stephen Warrend2356282014-05-07 12:19:02 -0600561int mmc_select_hwpart(int dev_num, int hwpart)
562{
563 struct mmc *mmc = find_mmc_device(dev_num);
564 int ret;
565
566 if (!mmc)
567 return -1;
568
569 if (mmc->part_num == hwpart)
570 return 0;
571
572 if (mmc->part_config == MMCPART_NOAVAILABLE) {
573 printf("Card doesn't support part_switch\n");
574 return -1;
575 }
576
577 ret = mmc_switch_part(dev_num, hwpart);
578 if (ret)
579 return -1;
580
581 mmc->part_num = hwpart;
582
583 return 0;
584}
585
586
Lei Wenbc897b12011-05-02 16:26:26 +0000587int mmc_switch_part(int dev_num, unsigned int part_num)
588{
589 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600590 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000591
592 if (!mmc)
593 return -1;
594
Stephen Warrenf866a462013-06-11 15:14:01 -0600595 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
596 (mmc->part_config & ~PART_ACCESS_MASK)
597 | (part_num & PART_ACCESS_MASK));
598 if (ret)
599 return ret;
600
601 return mmc_set_capacity(mmc, part_num);
Lei Wenbc897b12011-05-02 16:26:26 +0000602}
603
Thierry Reding48972d92012-01-02 01:15:37 +0000604int mmc_getcd(struct mmc *mmc)
605{
606 int cd;
607
608 cd = board_mmc_getcd(mmc);
609
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000610 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200611 if (mmc->cfg->ops->getcd)
612 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000613 else
614 cd = 1;
615 }
Thierry Reding48972d92012-01-02 01:15:37 +0000616
617 return cd;
618}
619
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000620static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500621{
622 struct mmc_cmd cmd;
623 struct mmc_data data;
624
625 /* Switch the frequency */
626 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
627 cmd.resp_type = MMC_RSP_R1;
628 cmd.cmdarg = (mode << 31) | 0xffffff;
629 cmd.cmdarg &= ~(0xf << (group * 4));
630 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500631
632 data.dest = (char *)resp;
633 data.blocksize = 64;
634 data.blocks = 1;
635 data.flags = MMC_DATA_READ;
636
637 return mmc_send_cmd(mmc, &cmd, &data);
638}
639
640
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000641static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500642{
643 int err;
644 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000645 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
646 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500647 struct mmc_data data;
648 int timeout;
649
650 mmc->card_caps = 0;
651
Thomas Choud52ebf12010-12-24 13:12:21 +0000652 if (mmc_host_is_spi(mmc))
653 return 0;
654
Andy Fleming272cc702008-10-30 16:41:01 -0500655 /* Read the SCR to find out if this card supports higher speeds */
656 cmd.cmdidx = MMC_CMD_APP_CMD;
657 cmd.resp_type = MMC_RSP_R1;
658 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500659
660 err = mmc_send_cmd(mmc, &cmd, NULL);
661
662 if (err)
663 return err;
664
665 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
666 cmd.resp_type = MMC_RSP_R1;
667 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500668
669 timeout = 3;
670
671retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000672 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500673 data.blocksize = 8;
674 data.blocks = 1;
675 data.flags = MMC_DATA_READ;
676
677 err = mmc_send_cmd(mmc, &cmd, &data);
678
679 if (err) {
680 if (timeout--)
681 goto retry_scr;
682
683 return err;
684 }
685
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300686 mmc->scr[0] = __be32_to_cpu(scr[0]);
687 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500688
689 switch ((mmc->scr[0] >> 24) & 0xf) {
690 case 0:
691 mmc->version = SD_VERSION_1_0;
692 break;
693 case 1:
694 mmc->version = SD_VERSION_1_10;
695 break;
696 case 2:
697 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000698 if ((mmc->scr[0] >> 15) & 0x1)
699 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500700 break;
701 default:
702 mmc->version = SD_VERSION_1_0;
703 break;
704 }
705
Alagu Sankarb44c7082010-05-12 15:08:24 +0530706 if (mmc->scr[0] & SD_DATA_4BIT)
707 mmc->card_caps |= MMC_MODE_4BIT;
708
Andy Fleming272cc702008-10-30 16:41:01 -0500709 /* Version 1.0 doesn't support switching */
710 if (mmc->version == SD_VERSION_1_0)
711 return 0;
712
713 timeout = 4;
714 while (timeout--) {
715 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000716 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500717
718 if (err)
719 return err;
720
721 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300722 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500723 break;
724 }
725
Andy Fleming272cc702008-10-30 16:41:01 -0500726 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300727 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500728 return 0;
729
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000730 /*
731 * If the host doesn't support SD_HIGHSPEED, do not switch card to
732 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
733 * This can avoid furthur problem when the card runs in different
734 * mode between the host.
735 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200736 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
737 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000738 return 0;
739
Anton staaff781dd32011-10-03 13:54:59 +0000740 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500741
742 if (err)
743 return err;
744
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300745 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500746 mmc->card_caps |= MMC_MODE_HS;
747
748 return 0;
749}
750
751/* frequency bases */
752/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000753static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500754 10000,
755 100000,
756 1000000,
757 10000000,
758};
759
760/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
761 * to platforms without floating point.
762 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000763static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500764 0, /* reserved */
765 10,
766 12,
767 13,
768 15,
769 20,
770 25,
771 30,
772 35,
773 40,
774 45,
775 50,
776 55,
777 60,
778 70,
779 80,
780};
781
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000782static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500783{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200784 if (mmc->cfg->ops->set_ios)
785 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500786}
787
788void mmc_set_clock(struct mmc *mmc, uint clock)
789{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200790 if (clock > mmc->cfg->f_max)
791 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500792
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200793 if (clock < mmc->cfg->f_min)
794 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -0500795
796 mmc->clock = clock;
797
798 mmc_set_ios(mmc);
799}
800
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000801static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -0500802{
803 mmc->bus_width = width;
804
805 mmc_set_ios(mmc);
806}
807
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000808static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500809{
Stephen Warrenf866a462013-06-11 15:14:01 -0600810 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -0500811 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000812 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -0500813 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +0000814 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
815 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000816 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500817
Thomas Choud52ebf12010-12-24 13:12:21 +0000818#ifdef CONFIG_MMC_SPI_CRC_ON
819 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
820 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
821 cmd.resp_type = MMC_RSP_R1;
822 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000823 err = mmc_send_cmd(mmc, &cmd, NULL);
824
825 if (err)
826 return err;
827 }
828#endif
829
Andy Fleming272cc702008-10-30 16:41:01 -0500830 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000831 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
832 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -0500833 cmd.resp_type = MMC_RSP_R2;
834 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500835
836 err = mmc_send_cmd(mmc, &cmd, NULL);
837
838 if (err)
839 return err;
840
841 memcpy(mmc->cid, cmd.response, 16);
842
843 /*
844 * For MMC cards, set the Relative Address.
845 * For SD cards, get the Relatvie Address.
846 * This also puts the cards into Standby State
847 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000848 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
849 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
850 cmd.cmdarg = mmc->rca << 16;
851 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -0500852
Thomas Choud52ebf12010-12-24 13:12:21 +0000853 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500854
Thomas Choud52ebf12010-12-24 13:12:21 +0000855 if (err)
856 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500857
Thomas Choud52ebf12010-12-24 13:12:21 +0000858 if (IS_SD(mmc))
859 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
860 }
Andy Fleming272cc702008-10-30 16:41:01 -0500861
862 /* Get the Card-Specific Data */
863 cmd.cmdidx = MMC_CMD_SEND_CSD;
864 cmd.resp_type = MMC_RSP_R2;
865 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500866
867 err = mmc_send_cmd(mmc, &cmd, NULL);
868
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000869 /* Waiting for the ready status */
870 mmc_send_status(mmc, timeout);
871
Andy Fleming272cc702008-10-30 16:41:01 -0500872 if (err)
873 return err;
874
Rabin Vincent998be3d2009-04-05 13:30:56 +0530875 mmc->csd[0] = cmd.response[0];
876 mmc->csd[1] = cmd.response[1];
877 mmc->csd[2] = cmd.response[2];
878 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -0500879
880 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530881 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500882
883 switch (version) {
884 case 0:
885 mmc->version = MMC_VERSION_1_2;
886 break;
887 case 1:
888 mmc->version = MMC_VERSION_1_4;
889 break;
890 case 2:
891 mmc->version = MMC_VERSION_2_2;
892 break;
893 case 3:
894 mmc->version = MMC_VERSION_3;
895 break;
896 case 4:
897 mmc->version = MMC_VERSION_4;
898 break;
899 default:
900 mmc->version = MMC_VERSION_1_2;
901 break;
902 }
903 }
904
905 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530906 freq = fbase[(cmd.response[0] & 0x7)];
907 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -0500908
909 mmc->tran_speed = freq * mult;
910
Markus Niebelab711882013-12-16 13:40:46 +0100911 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +0530912 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500913
914 if (IS_SD(mmc))
915 mmc->write_bl_len = mmc->read_bl_len;
916 else
Rabin Vincent998be3d2009-04-05 13:30:56 +0530917 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500918
919 if (mmc->high_capacity) {
920 csize = (mmc->csd[1] & 0x3f) << 16
921 | (mmc->csd[2] & 0xffff0000) >> 16;
922 cmult = 8;
923 } else {
924 csize = (mmc->csd[1] & 0x3ff) << 2
925 | (mmc->csd[2] & 0xc0000000) >> 30;
926 cmult = (mmc->csd[2] & 0x00038000) >> 15;
927 }
928
Stephen Warrenf866a462013-06-11 15:14:01 -0600929 mmc->capacity_user = (csize + 1) << (cmult + 2);
930 mmc->capacity_user *= mmc->read_bl_len;
931 mmc->capacity_boot = 0;
932 mmc->capacity_rpmb = 0;
933 for (i = 0; i < 4; i++)
934 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500935
Simon Glass8bfa1952013-04-03 08:54:30 +0000936 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
937 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500938
Simon Glass8bfa1952013-04-03 08:54:30 +0000939 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
940 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500941
Markus Niebelab711882013-12-16 13:40:46 +0100942 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
943 cmd.cmdidx = MMC_CMD_SET_DSR;
944 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
945 cmd.resp_type = MMC_RSP_NONE;
946 if (mmc_send_cmd(mmc, &cmd, NULL))
947 printf("MMC: SET_DSR failed\n");
948 }
949
Andy Fleming272cc702008-10-30 16:41:01 -0500950 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000951 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
952 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +0000953 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000954 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +0000955 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500956
Thomas Choud52ebf12010-12-24 13:12:21 +0000957 if (err)
958 return err;
959 }
Andy Fleming272cc702008-10-30 16:41:01 -0500960
Lei Wene6f99a52011-06-22 17:03:31 +0000961 /*
962 * For SD, its erase group is always one sector
963 */
964 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +0000965 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530966 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
967 /* check ext_csd version and capacity */
968 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000969 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000970 /*
971 * According to the JEDEC Standard, the value of
972 * ext_csd's capacity is valid if the value is more
973 * than 2GB
974 */
Lei Wen0560db12011-10-03 20:35:10 +0000975 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
976 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
977 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
978 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +0000979 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +0000980 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -0600981 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530982 }
Lei Wenbc897b12011-05-02 16:26:26 +0000983
Jaehoon Chung64f4a612013-01-29 19:31:16 +0000984 switch (ext_csd[EXT_CSD_REV]) {
985 case 1:
986 mmc->version = MMC_VERSION_4_1;
987 break;
988 case 2:
989 mmc->version = MMC_VERSION_4_2;
990 break;
991 case 3:
992 mmc->version = MMC_VERSION_4_3;
993 break;
994 case 5:
995 mmc->version = MMC_VERSION_4_41;
996 break;
997 case 6:
998 mmc->version = MMC_VERSION_4_5;
999 break;
1000 }
1001
Lei Wene6f99a52011-06-22 17:03:31 +00001002 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001003 * Host needs to enable ERASE_GRP_DEF bit if device is
1004 * partitioned. This bit will be lost every time after a reset
1005 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001006 */
Oliver Metz1937e5a2013-10-01 20:32:07 +02001007 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
1008 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
1009 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1010 EXT_CSD_ERASE_GROUP_DEF, 1);
1011
1012 if (err)
1013 return err;
1014
1015 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001016 mmc->erase_grp_size =
Simon Glass8bfa1952013-04-03 08:54:30 +00001017 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
1018 MMC_MAX_BLOCK_LEN * 1024;
1019 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001020 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001021 int erase_gsz, erase_gmul;
1022 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1023 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1024 mmc->erase_grp_size = (erase_gsz + 1)
1025 * (erase_gmul + 1);
1026 }
1027
Lei Wenbc897b12011-05-02 16:26:26 +00001028 /* store the partition info of emmc */
Stephen Warren8948ea82012-07-30 10:55:43 +00001029 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1030 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen0560db12011-10-03 20:35:10 +00001031 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrenf866a462013-06-11 15:14:01 -06001032
1033 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1034
1035 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1036
1037 for (i = 0; i < 4; i++) {
1038 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1039 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1040 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1041 mmc->capacity_gp[i] *=
1042 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1043 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1044 }
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301045 }
1046
Stephen Warrenf866a462013-06-11 15:14:01 -06001047 err = mmc_set_capacity(mmc, mmc->part_num);
1048 if (err)
1049 return err;
1050
Andy Fleming272cc702008-10-30 16:41:01 -05001051 if (IS_SD(mmc))
1052 err = sd_change_freq(mmc);
1053 else
1054 err = mmc_change_freq(mmc);
1055
1056 if (err)
1057 return err;
1058
1059 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001060 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001061
1062 if (IS_SD(mmc)) {
1063 if (mmc->card_caps & MMC_MODE_4BIT) {
1064 cmd.cmdidx = MMC_CMD_APP_CMD;
1065 cmd.resp_type = MMC_RSP_R1;
1066 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001067
1068 err = mmc_send_cmd(mmc, &cmd, NULL);
1069 if (err)
1070 return err;
1071
1072 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1073 cmd.resp_type = MMC_RSP_R1;
1074 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001075 err = mmc_send_cmd(mmc, &cmd, NULL);
1076 if (err)
1077 return err;
1078
1079 mmc_set_bus_width(mmc, 4);
1080 }
1081
1082 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001083 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001084 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001085 mmc->tran_speed = 25000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001086 } else {
Andy Fleming7798f6d2012-10-31 19:02:38 +00001087 int idx;
1088
1089 /* An array of possible bus widths in order of preference */
1090 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001091 EXT_CSD_DDR_BUS_WIDTH_8,
1092 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001093 EXT_CSD_BUS_WIDTH_8,
1094 EXT_CSD_BUS_WIDTH_4,
1095 EXT_CSD_BUS_WIDTH_1,
1096 };
1097
1098 /* An array to map CSD bus widths to host cap bits */
1099 static unsigned ext_to_hostcaps[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001100 [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
1101 [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001102 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1103 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1104 };
1105
1106 /* An array to map chosen bus width to an integer */
1107 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001108 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001109 };
1110
1111 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1112 unsigned int extw = ext_csd_bits[idx];
1113
1114 /*
1115 * Check to make sure the controller supports
1116 * this bus width, if it's more than 1
1117 */
1118 if (extw != EXT_CSD_BUS_WIDTH_1 &&
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001119 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Fleming7798f6d2012-10-31 19:02:38 +00001120 continue;
1121
Andy Fleming272cc702008-10-30 16:41:01 -05001122 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001123 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001124
1125 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001126 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001127
Andy Fleming7798f6d2012-10-31 19:02:38 +00001128 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001129
Lei Wen41378942011-10-03 20:35:11 +00001130 err = mmc_send_ext_csd(mmc, test_csd);
1131 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1132 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1133 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1134 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1135 && ext_csd[EXT_CSD_REV] \
1136 == test_csd[EXT_CSD_REV]
1137 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1138 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1139 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1140 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Fleming272cc702008-10-30 16:41:01 -05001141
Andy Fleming7798f6d2012-10-31 19:02:38 +00001142 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen41378942011-10-03 20:35:11 +00001143 break;
1144 }
Andy Fleming272cc702008-10-30 16:41:01 -05001145 }
1146
1147 if (mmc->card_caps & MMC_MODE_HS) {
1148 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001149 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001150 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001151 mmc->tran_speed = 26000000;
1152 }
Andy Fleming272cc702008-10-30 16:41:01 -05001153 }
1154
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001155 mmc_set_clock(mmc, mmc->tran_speed);
1156
Andy Fleming272cc702008-10-30 16:41:01 -05001157 /* fill in device description */
1158 mmc->block_dev.lun = 0;
1159 mmc->block_dev.type = 0;
1160 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001161 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301162 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001163#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001164 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1165 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1166 (mmc->cid[3] >> 16) & 0xffff);
1167 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1168 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1169 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1170 (mmc->cid[2] >> 24) & 0xff);
1171 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1172 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001173#else
1174 mmc->block_dev.vendor[0] = 0;
1175 mmc->block_dev.product[0] = 0;
1176 mmc->block_dev.revision[0] = 0;
1177#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001178#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001179 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001180#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001181
1182 return 0;
1183}
1184
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001185static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001186{
1187 struct mmc_cmd cmd;
1188 int err;
1189
1190 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1191 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001192 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001193 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001194
1195 err = mmc_send_cmd(mmc, &cmd, NULL);
1196
1197 if (err)
1198 return err;
1199
Rabin Vincent998be3d2009-04-05 13:30:56 +05301200 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001201 return UNUSABLE_ERR;
1202 else
1203 mmc->version = SD_VERSION_2;
1204
1205 return 0;
1206}
1207
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001208/* not used any more */
1209int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001210{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001211#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1212 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1213#endif
1214 return -1;
1215}
1216
1217struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1218{
1219 struct mmc *mmc;
1220
1221 /* quick validation */
1222 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1223 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1224 return NULL;
1225
1226 mmc = calloc(1, sizeof(*mmc));
1227 if (mmc == NULL)
1228 return NULL;
1229
1230 mmc->cfg = cfg;
1231 mmc->priv = priv;
1232
1233 /* the following chunk was mmc_register() */
1234
Markus Niebelab711882013-12-16 13:40:46 +01001235 /* Setup dsr related values */
1236 mmc->dsr_imp = 0;
1237 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001238 /* Setup the universal parts of the block interface just once */
1239 mmc->block_dev.if_type = IF_TYPE_MMC;
1240 mmc->block_dev.dev = cur_dev_num++;
1241 mmc->block_dev.removable = 1;
1242 mmc->block_dev.block_read = mmc_bread;
1243 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001244 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001245
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001246 /* setup initial part type */
1247 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001248
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001249 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001250
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001251 list_add_tail(&mmc->link, &mmc_devices);
1252
1253 return mmc;
1254}
1255
1256void mmc_destroy(struct mmc *mmc)
1257{
1258 /* only freeing memory for now */
1259 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001260}
1261
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001262#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001263block_dev_desc_t *mmc_get_dev(int dev)
1264{
1265 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001266 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001267 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001268
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001269 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001270}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001271#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001272
Che-Liang Chioue9550442012-11-28 15:21:13 +00001273int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001274{
Macpaul Linafd59322011-11-14 23:35:39 +00001275 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001276
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001277 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001278 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001279 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001280#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001281 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001282#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001283 return NO_CARD_ERR;
1284 }
1285
Lei Wenbc897b12011-05-02 16:26:26 +00001286 if (mmc->has_init)
1287 return 0;
1288
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001289 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001290 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001291
1292 if (err)
1293 return err;
1294
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001295 mmc_set_bus_width(mmc, 1);
1296 mmc_set_clock(mmc, 1);
1297
Andy Fleming272cc702008-10-30 16:41:01 -05001298 /* Reset the Card */
1299 err = mmc_go_idle(mmc);
1300
1301 if (err)
1302 return err;
1303
Lei Wenbc897b12011-05-02 16:26:26 +00001304 /* The internal partition reset to user partition(0) at every CMD0*/
1305 mmc->part_num = 0;
1306
Andy Fleming272cc702008-10-30 16:41:01 -05001307 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001308 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001309
Andy Fleming272cc702008-10-30 16:41:01 -05001310 /* Now try to get the SD card's operating condition */
1311 err = sd_send_op_cond(mmc);
1312
1313 /* If the command timed out, we check for an MMC card */
1314 if (err == TIMEOUT) {
1315 err = mmc_send_op_cond(mmc);
1316
Che-Liang Chioue9550442012-11-28 15:21:13 +00001317 if (err && err != IN_PROGRESS) {
Paul Burton56196822013-09-04 16:12:25 +01001318#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001319 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001320#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001321 return UNUSABLE_ERR;
1322 }
1323 }
1324
Che-Liang Chioue9550442012-11-28 15:21:13 +00001325 if (err == IN_PROGRESS)
1326 mmc->init_in_progress = 1;
1327
1328 return err;
1329}
1330
1331static int mmc_complete_init(struct mmc *mmc)
1332{
1333 int err = 0;
1334
1335 if (mmc->op_cond_pending)
1336 err = mmc_complete_op_cond(mmc);
1337
1338 if (!err)
1339 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001340 if (err)
1341 mmc->has_init = 0;
1342 else
1343 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001344 mmc->init_in_progress = 0;
1345 return err;
1346}
1347
1348int mmc_init(struct mmc *mmc)
1349{
1350 int err = IN_PROGRESS;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001351 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001352
1353 if (mmc->has_init)
1354 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001355
1356 start = get_timer(0);
1357
Che-Liang Chioue9550442012-11-28 15:21:13 +00001358 if (!mmc->init_in_progress)
1359 err = mmc_start_init(mmc);
1360
1361 if (!err || err == IN_PROGRESS)
1362 err = mmc_complete_init(mmc);
1363 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001364 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001365}
1366
Markus Niebelab711882013-12-16 13:40:46 +01001367int mmc_set_dsr(struct mmc *mmc, u16 val)
1368{
1369 mmc->dsr = val;
1370 return 0;
1371}
1372
Andy Fleming272cc702008-10-30 16:41:01 -05001373/*
1374 * CPU and board-specific MMC initializations. Aliased function
1375 * signals caller to move on
1376 */
1377static int __def_mmc_init(bd_t *bis)
1378{
1379 return -1;
1380}
1381
Peter Tyserf9a109b2009-04-20 11:08:46 -05001382int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1383int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Fleming272cc702008-10-30 16:41:01 -05001384
Paul Burton56196822013-09-04 16:12:25 +01001385#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1386
Andy Fleming272cc702008-10-30 16:41:01 -05001387void print_mmc_devices(char separator)
1388{
1389 struct mmc *m;
1390 struct list_head *entry;
1391
1392 list_for_each(entry, &mmc_devices) {
1393 m = list_entry(entry, struct mmc, link);
1394
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001395 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Fleming272cc702008-10-30 16:41:01 -05001396
1397 if (entry->next != &mmc_devices)
1398 printf("%c ", separator);
1399 }
1400
1401 printf("\n");
1402}
1403
Paul Burton56196822013-09-04 16:12:25 +01001404#else
1405void print_mmc_devices(char separator) { }
1406#endif
1407
Lei Wenea6ebe22011-05-02 16:26:25 +00001408int get_mmc_num(void)
1409{
1410 return cur_dev_num;
1411}
1412
Che-Liang Chioue9550442012-11-28 15:21:13 +00001413void mmc_set_preinit(struct mmc *mmc, int preinit)
1414{
1415 mmc->preinit = preinit;
1416}
1417
1418static void do_preinit(void)
1419{
1420 struct mmc *m;
1421 struct list_head *entry;
1422
1423 list_for_each(entry, &mmc_devices) {
1424 m = list_entry(entry, struct mmc, link);
1425
1426 if (m->preinit)
1427 mmc_start_init(m);
1428 }
1429}
1430
1431
Andy Fleming272cc702008-10-30 16:41:01 -05001432int mmc_initialize(bd_t *bis)
1433{
1434 INIT_LIST_HEAD (&mmc_devices);
1435 cur_dev_num = 0;
1436
1437 if (board_mmc_init(bis) < 0)
1438 cpu_mmc_init(bis);
1439
Ying Zhangbb0dc102013-08-16 15:16:11 +08001440#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001441 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001442#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001443
Che-Liang Chioue9550442012-11-28 15:21:13 +00001444 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001445 return 0;
1446}
Amar3690d6d2013-04-27 11:42:58 +05301447
1448#ifdef CONFIG_SUPPORT_EMMC_BOOT
1449/*
1450 * This function changes the size of boot partition and the size of rpmb
1451 * partition present on EMMC devices.
1452 *
1453 * Input Parameters:
1454 * struct *mmc: pointer for the mmc device strcuture
1455 * bootsize: size of boot partition
1456 * rpmbsize: size of rpmb partition
1457 *
1458 * Returns 0 on success.
1459 */
1460
1461int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1462 unsigned long rpmbsize)
1463{
1464 int err;
1465 struct mmc_cmd cmd;
1466
1467 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1468 cmd.cmdidx = MMC_CMD_RES_MAN;
1469 cmd.resp_type = MMC_RSP_R1b;
1470 cmd.cmdarg = MMC_CMD62_ARG1;
1471
1472 err = mmc_send_cmd(mmc, &cmd, NULL);
1473 if (err) {
1474 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1475 return err;
1476 }
1477
1478 /* Boot partition changing mode */
1479 cmd.cmdidx = MMC_CMD_RES_MAN;
1480 cmd.resp_type = MMC_RSP_R1b;
1481 cmd.cmdarg = MMC_CMD62_ARG2;
1482
1483 err = mmc_send_cmd(mmc, &cmd, NULL);
1484 if (err) {
1485 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1486 return err;
1487 }
1488 /* boot partition size is multiple of 128KB */
1489 bootsize = (bootsize * 1024) / 128;
1490
1491 /* Arg: boot partition size */
1492 cmd.cmdidx = MMC_CMD_RES_MAN;
1493 cmd.resp_type = MMC_RSP_R1b;
1494 cmd.cmdarg = bootsize;
1495
1496 err = mmc_send_cmd(mmc, &cmd, NULL);
1497 if (err) {
1498 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1499 return err;
1500 }
1501 /* RPMB partition size is multiple of 128KB */
1502 rpmbsize = (rpmbsize * 1024) / 128;
1503 /* Arg: RPMB partition size */
1504 cmd.cmdidx = MMC_CMD_RES_MAN;
1505 cmd.resp_type = MMC_RSP_R1b;
1506 cmd.cmdarg = rpmbsize;
1507
1508 err = mmc_send_cmd(mmc, &cmd, NULL);
1509 if (err) {
1510 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1511 return err;
1512 }
1513 return 0;
1514}
1515
1516/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001517 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1518 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1519 * and BOOT_MODE.
1520 *
1521 * Returns 0 on success.
1522 */
1523int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1524{
1525 int err;
1526
1527 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1528 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1529 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1530 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1531
1532 if (err)
1533 return err;
1534 return 0;
1535}
1536
1537/*
Tom Rini792970b2014-02-05 10:24:21 -05001538 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1539 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1540 * PARTITION_ACCESS.
1541 *
1542 * Returns 0 on success.
1543 */
1544int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1545{
1546 int err;
1547
1548 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1549 EXT_CSD_BOOT_ACK(ack) |
1550 EXT_CSD_BOOT_PART_NUM(part_num) |
1551 EXT_CSD_PARTITION_ACCESS(access));
1552
1553 if (err)
1554 return err;
1555 return 0;
1556}
Tom Rini33ace362014-02-07 14:15:20 -05001557
1558/*
1559 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1560 * for enable. Note that this is a write-once field for non-zero values.
1561 *
1562 * Returns 0 on success.
1563 */
1564int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1565{
1566 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1567 enable);
1568}
Amar3690d6d2013-04-27 11:42:58 +05301569#endif