blob: 0c9ae5d9cdb421755e32af59321bdbc3a9776bd7 [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 }
153
154 return 0;
155}
156
Paul Burtonda61fa52013-09-09 15:30:26 +0100157int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500158{
159 struct mmc_cmd cmd;
160
161 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
162 cmd.resp_type = MMC_RSP_R1;
163 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500164
165 return mmc_send_cmd(mmc, &cmd, NULL);
166}
167
168struct mmc *find_mmc_device(int dev_num)
169{
170 struct mmc *m;
171 struct list_head *entry;
172
173 list_for_each(entry, &mmc_devices) {
174 m = list_entry(entry, struct mmc, link);
175
176 if (m->block_dev.dev == dev_num)
177 return m;
178 }
179
Paul Burton56196822013-09-04 16:12:25 +0100180#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -0500181 printf("MMC Device %d not found\n", dev_num);
Paul Burton56196822013-09-04 16:12:25 +0100182#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500183
184 return NULL;
185}
186
Sascha Silbeff8fef52013-06-14 13:07:25 +0200187static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000188 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500189{
190 struct mmc_cmd cmd;
191 struct mmc_data data;
192
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700193 if (blkcnt > 1)
194 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
195 else
196 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500197
198 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700199 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500200 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700201 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500202
203 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500204
205 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700206 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500207 data.blocksize = mmc->read_bl_len;
208 data.flags = MMC_DATA_READ;
209
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700210 if (mmc_send_cmd(mmc, &cmd, &data))
211 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500212
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700213 if (blkcnt > 1) {
214 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
215 cmd.cmdarg = 0;
216 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700217 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100218#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700219 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100220#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700221 return 0;
222 }
Andy Fleming272cc702008-10-30 16:41:01 -0500223 }
224
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700225 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500226}
227
Sascha Silbeff8fef52013-06-14 13:07:25 +0200228static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500229{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700230 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500231
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700232 if (blkcnt == 0)
233 return 0;
234
235 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500236 if (!mmc)
237 return 0;
238
Lei Wend2bf29e2010-09-13 22:07:27 +0800239 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton56196822013-09-04 16:12:25 +0100240#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200241 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800242 start + blkcnt, mmc->block_dev.lba);
Paul Burton56196822013-09-04 16:12:25 +0100243#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800244 return 0;
245 }
Andy Fleming272cc702008-10-30 16:41:01 -0500246
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700247 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500248 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500249
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700250 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200251 cur = (blocks_todo > mmc->cfg->b_max) ?
252 mmc->cfg->b_max : blocks_todo;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700253 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
254 return 0;
255 blocks_todo -= cur;
256 start += cur;
257 dst += cur * mmc->read_bl_len;
258 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500259
260 return blkcnt;
261}
262
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000263static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500264{
265 struct mmc_cmd cmd;
266 int err;
267
268 udelay(1000);
269
270 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
271 cmd.cmdarg = 0;
272 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500273
274 err = mmc_send_cmd(mmc, &cmd, NULL);
275
276 if (err)
277 return err;
278
279 udelay(2000);
280
281 return 0;
282}
283
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000284static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500285{
286 int timeout = 1000;
287 int err;
288 struct mmc_cmd cmd;
289
290 do {
291 cmd.cmdidx = MMC_CMD_APP_CMD;
292 cmd.resp_type = MMC_RSP_R1;
293 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500294
295 err = mmc_send_cmd(mmc, &cmd, NULL);
296
297 if (err)
298 return err;
299
300 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
301 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100302
303 /*
304 * Most cards do not answer if some reserved bits
305 * in the ocr are set. However, Some controller
306 * can set bit 7 (reserved for low voltages), but
307 * how to manage low voltages SD card is not yet
308 * specified.
309 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000310 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200311 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500312
313 if (mmc->version == SD_VERSION_2)
314 cmd.cmdarg |= OCR_HCS;
315
316 err = mmc_send_cmd(mmc, &cmd, NULL);
317
318 if (err)
319 return err;
320
321 udelay(1000);
322 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
323
324 if (timeout <= 0)
325 return UNUSABLE_ERR;
326
327 if (mmc->version != SD_VERSION_2)
328 mmc->version = SD_VERSION_1_0;
329
Thomas Choud52ebf12010-12-24 13:12:21 +0000330 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
331 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
332 cmd.resp_type = MMC_RSP_R3;
333 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000334
335 err = mmc_send_cmd(mmc, &cmd, NULL);
336
337 if (err)
338 return err;
339 }
340
Rabin Vincent998be3d2009-04-05 13:30:56 +0530341 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500342
343 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
344 mmc->rca = 0;
345
346 return 0;
347}
348
Che-Liang Chioue9550442012-11-28 15:21:13 +0000349/* We pass in the cmd since otherwise the init seems to fail */
350static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
351 int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500352{
Andy Fleming272cc702008-10-30 16:41:01 -0500353 int err;
354
Che-Liang Chioue9550442012-11-28 15:21:13 +0000355 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
356 cmd->resp_type = MMC_RSP_R3;
357 cmd->cmdarg = 0;
358 if (use_arg && !mmc_host_is_spi(mmc)) {
359 cmd->cmdarg =
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200360 (mmc->cfg->voltages &
Che-Liang Chioue9550442012-11-28 15:21:13 +0000361 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
362 (mmc->op_cond_response & OCR_ACCESS_MODE);
363
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200364 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000365 cmd->cmdarg |= OCR_HCS;
366 }
367 err = mmc_send_cmd(mmc, cmd, NULL);
368 if (err)
369 return err;
370 mmc->op_cond_response = cmd->response[0];
371 return 0;
372}
373
374int mmc_send_op_cond(struct mmc *mmc)
375{
376 struct mmc_cmd cmd;
377 int err, i;
378
Andy Fleming272cc702008-10-30 16:41:01 -0500379 /* Some cards seem to need this */
380 mmc_go_idle(mmc);
381
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000382 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000383 mmc->op_cond_pending = 1;
384 for (i = 0; i < 2; i++) {
385 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500386 if (err)
387 return err;
388
Che-Liang Chioue9550442012-11-28 15:21:13 +0000389 /* exit if not busy (flag seems to be inverted) */
390 if (mmc->op_cond_response & OCR_BUSY)
391 return 0;
392 }
393 return IN_PROGRESS;
394}
Andy Fleming272cc702008-10-30 16:41:01 -0500395
Che-Liang Chioue9550442012-11-28 15:21:13 +0000396int mmc_complete_op_cond(struct mmc *mmc)
397{
398 struct mmc_cmd cmd;
399 int timeout = 1000;
400 uint start;
401 int err;
402
403 mmc->op_cond_pending = 0;
404 start = get_timer(0);
405 do {
406 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
407 if (err)
408 return err;
409 if (get_timer(start) > timeout)
410 return UNUSABLE_ERR;
411 udelay(100);
412 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Fleming272cc702008-10-30 16:41:01 -0500413
Thomas Choud52ebf12010-12-24 13:12:21 +0000414 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
415 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
416 cmd.resp_type = MMC_RSP_R3;
417 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000418
419 err = mmc_send_cmd(mmc, &cmd, NULL);
420
421 if (err)
422 return err;
423 }
424
Andy Fleming272cc702008-10-30 16:41:01 -0500425 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincent998be3d2009-04-05 13:30:56 +0530426 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500427
428 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700429 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500430
431 return 0;
432}
433
434
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000435static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500436{
437 struct mmc_cmd cmd;
438 struct mmc_data data;
439 int err;
440
441 /* Get the Card Status Register */
442 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
443 cmd.resp_type = MMC_RSP_R1;
444 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500445
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000446 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500447 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000448 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500449 data.flags = MMC_DATA_READ;
450
451 err = mmc_send_cmd(mmc, &cmd, &data);
452
453 return err;
454}
455
456
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000457static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500458{
459 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000460 int timeout = 1000;
461 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500462
463 cmd.cmdidx = MMC_CMD_SWITCH;
464 cmd.resp_type = MMC_RSP_R1b;
465 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000466 (index << 16) |
467 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500468
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000469 ret = mmc_send_cmd(mmc, &cmd, NULL);
470
471 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000472 if (!ret)
473 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000474
475 return ret;
476
Andy Fleming272cc702008-10-30 16:41:01 -0500477}
478
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000479static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500480{
Simon Glass8bfa1952013-04-03 08:54:30 +0000481 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500482 char cardtype;
483 int err;
484
485 mmc->card_caps = 0;
486
Thomas Choud52ebf12010-12-24 13:12:21 +0000487 if (mmc_host_is_spi(mmc))
488 return 0;
489
Andy Fleming272cc702008-10-30 16:41:01 -0500490 /* Only version 4 supports high-speed */
491 if (mmc->version < MMC_VERSION_4)
492 return 0;
493
Andy Fleming272cc702008-10-30 16:41:01 -0500494 err = mmc_send_ext_csd(mmc, ext_csd);
495
496 if (err)
497 return err;
498
Lei Wen0560db12011-10-03 20:35:10 +0000499 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500500
501 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
502
503 if (err)
504 return err;
505
506 /* Now check to see that it worked */
507 err = mmc_send_ext_csd(mmc, ext_csd);
508
509 if (err)
510 return err;
511
512 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000513 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500514 return 0;
515
516 /* High Speed is set, there are two types: 52MHz and 26MHz */
517 if (cardtype & MMC_HS_52MHZ)
518 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
519 else
520 mmc->card_caps |= MMC_MODE_HS;
521
522 return 0;
523}
524
Stephen Warrenf866a462013-06-11 15:14:01 -0600525static int mmc_set_capacity(struct mmc *mmc, int part_num)
526{
527 switch (part_num) {
528 case 0:
529 mmc->capacity = mmc->capacity_user;
530 break;
531 case 1:
532 case 2:
533 mmc->capacity = mmc->capacity_boot;
534 break;
535 case 3:
536 mmc->capacity = mmc->capacity_rpmb;
537 break;
538 case 4:
539 case 5:
540 case 6:
541 case 7:
542 mmc->capacity = mmc->capacity_gp[part_num - 4];
543 break;
544 default:
545 return -1;
546 }
547
548 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
549
550 return 0;
551}
552
Lei Wenbc897b12011-05-02 16:26:26 +0000553int mmc_switch_part(int dev_num, unsigned int part_num)
554{
555 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600556 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000557
558 if (!mmc)
559 return -1;
560
Stephen Warrenf866a462013-06-11 15:14:01 -0600561 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
562 (mmc->part_config & ~PART_ACCESS_MASK)
563 | (part_num & PART_ACCESS_MASK));
564 if (ret)
565 return ret;
566
567 return mmc_set_capacity(mmc, part_num);
Lei Wenbc897b12011-05-02 16:26:26 +0000568}
569
Thierry Reding48972d92012-01-02 01:15:37 +0000570int mmc_getcd(struct mmc *mmc)
571{
572 int cd;
573
574 cd = board_mmc_getcd(mmc);
575
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000576 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200577 if (mmc->cfg->ops->getcd)
578 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000579 else
580 cd = 1;
581 }
Thierry Reding48972d92012-01-02 01:15:37 +0000582
583 return cd;
584}
585
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000586static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500587{
588 struct mmc_cmd cmd;
589 struct mmc_data data;
590
591 /* Switch the frequency */
592 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
593 cmd.resp_type = MMC_RSP_R1;
594 cmd.cmdarg = (mode << 31) | 0xffffff;
595 cmd.cmdarg &= ~(0xf << (group * 4));
596 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500597
598 data.dest = (char *)resp;
599 data.blocksize = 64;
600 data.blocks = 1;
601 data.flags = MMC_DATA_READ;
602
603 return mmc_send_cmd(mmc, &cmd, &data);
604}
605
606
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000607static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500608{
609 int err;
610 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000611 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
612 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500613 struct mmc_data data;
614 int timeout;
615
616 mmc->card_caps = 0;
617
Thomas Choud52ebf12010-12-24 13:12:21 +0000618 if (mmc_host_is_spi(mmc))
619 return 0;
620
Andy Fleming272cc702008-10-30 16:41:01 -0500621 /* Read the SCR to find out if this card supports higher speeds */
622 cmd.cmdidx = MMC_CMD_APP_CMD;
623 cmd.resp_type = MMC_RSP_R1;
624 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500625
626 err = mmc_send_cmd(mmc, &cmd, NULL);
627
628 if (err)
629 return err;
630
631 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
632 cmd.resp_type = MMC_RSP_R1;
633 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500634
635 timeout = 3;
636
637retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000638 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500639 data.blocksize = 8;
640 data.blocks = 1;
641 data.flags = MMC_DATA_READ;
642
643 err = mmc_send_cmd(mmc, &cmd, &data);
644
645 if (err) {
646 if (timeout--)
647 goto retry_scr;
648
649 return err;
650 }
651
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300652 mmc->scr[0] = __be32_to_cpu(scr[0]);
653 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500654
655 switch ((mmc->scr[0] >> 24) & 0xf) {
656 case 0:
657 mmc->version = SD_VERSION_1_0;
658 break;
659 case 1:
660 mmc->version = SD_VERSION_1_10;
661 break;
662 case 2:
663 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000664 if ((mmc->scr[0] >> 15) & 0x1)
665 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500666 break;
667 default:
668 mmc->version = SD_VERSION_1_0;
669 break;
670 }
671
Alagu Sankarb44c7082010-05-12 15:08:24 +0530672 if (mmc->scr[0] & SD_DATA_4BIT)
673 mmc->card_caps |= MMC_MODE_4BIT;
674
Andy Fleming272cc702008-10-30 16:41:01 -0500675 /* Version 1.0 doesn't support switching */
676 if (mmc->version == SD_VERSION_1_0)
677 return 0;
678
679 timeout = 4;
680 while (timeout--) {
681 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000682 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500683
684 if (err)
685 return err;
686
687 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300688 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500689 break;
690 }
691
Andy Fleming272cc702008-10-30 16:41:01 -0500692 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300693 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500694 return 0;
695
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000696 /*
697 * If the host doesn't support SD_HIGHSPEED, do not switch card to
698 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
699 * This can avoid furthur problem when the card runs in different
700 * mode between the host.
701 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200702 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
703 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000704 return 0;
705
Anton staaff781dd32011-10-03 13:54:59 +0000706 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500707
708 if (err)
709 return err;
710
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300711 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500712 mmc->card_caps |= MMC_MODE_HS;
713
714 return 0;
715}
716
717/* frequency bases */
718/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000719static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500720 10000,
721 100000,
722 1000000,
723 10000000,
724};
725
726/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
727 * to platforms without floating point.
728 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000729static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500730 0, /* reserved */
731 10,
732 12,
733 13,
734 15,
735 20,
736 25,
737 30,
738 35,
739 40,
740 45,
741 50,
742 55,
743 60,
744 70,
745 80,
746};
747
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000748static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500749{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200750 if (mmc->cfg->ops->set_ios)
751 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500752}
753
754void mmc_set_clock(struct mmc *mmc, uint clock)
755{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200756 if (clock > mmc->cfg->f_max)
757 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500758
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200759 if (clock < mmc->cfg->f_min)
760 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -0500761
762 mmc->clock = clock;
763
764 mmc_set_ios(mmc);
765}
766
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000767static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -0500768{
769 mmc->bus_width = width;
770
771 mmc_set_ios(mmc);
772}
773
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000774static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500775{
Stephen Warrenf866a462013-06-11 15:14:01 -0600776 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -0500777 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000778 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -0500779 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +0000780 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
781 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000782 int timeout = 1000;
Andy Fleming272cc702008-10-30 16:41:01 -0500783
Thomas Choud52ebf12010-12-24 13:12:21 +0000784#ifdef CONFIG_MMC_SPI_CRC_ON
785 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
786 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
787 cmd.resp_type = MMC_RSP_R1;
788 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000789 err = mmc_send_cmd(mmc, &cmd, NULL);
790
791 if (err)
792 return err;
793 }
794#endif
795
Andy Fleming272cc702008-10-30 16:41:01 -0500796 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000797 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
798 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -0500799 cmd.resp_type = MMC_RSP_R2;
800 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500801
802 err = mmc_send_cmd(mmc, &cmd, NULL);
803
804 if (err)
805 return err;
806
807 memcpy(mmc->cid, cmd.response, 16);
808
809 /*
810 * For MMC cards, set the Relative Address.
811 * For SD cards, get the Relatvie Address.
812 * This also puts the cards into Standby State
813 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000814 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
815 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
816 cmd.cmdarg = mmc->rca << 16;
817 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -0500818
Thomas Choud52ebf12010-12-24 13:12:21 +0000819 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500820
Thomas Choud52ebf12010-12-24 13:12:21 +0000821 if (err)
822 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500823
Thomas Choud52ebf12010-12-24 13:12:21 +0000824 if (IS_SD(mmc))
825 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
826 }
Andy Fleming272cc702008-10-30 16:41:01 -0500827
828 /* Get the Card-Specific Data */
829 cmd.cmdidx = MMC_CMD_SEND_CSD;
830 cmd.resp_type = MMC_RSP_R2;
831 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500832
833 err = mmc_send_cmd(mmc, &cmd, NULL);
834
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000835 /* Waiting for the ready status */
836 mmc_send_status(mmc, timeout);
837
Andy Fleming272cc702008-10-30 16:41:01 -0500838 if (err)
839 return err;
840
Rabin Vincent998be3d2009-04-05 13:30:56 +0530841 mmc->csd[0] = cmd.response[0];
842 mmc->csd[1] = cmd.response[1];
843 mmc->csd[2] = cmd.response[2];
844 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -0500845
846 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530847 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500848
849 switch (version) {
850 case 0:
851 mmc->version = MMC_VERSION_1_2;
852 break;
853 case 1:
854 mmc->version = MMC_VERSION_1_4;
855 break;
856 case 2:
857 mmc->version = MMC_VERSION_2_2;
858 break;
859 case 3:
860 mmc->version = MMC_VERSION_3;
861 break;
862 case 4:
863 mmc->version = MMC_VERSION_4;
864 break;
865 default:
866 mmc->version = MMC_VERSION_1_2;
867 break;
868 }
869 }
870
871 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +0530872 freq = fbase[(cmd.response[0] & 0x7)];
873 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -0500874
875 mmc->tran_speed = freq * mult;
876
Markus Niebelab711882013-12-16 13:40:46 +0100877 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +0530878 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500879
880 if (IS_SD(mmc))
881 mmc->write_bl_len = mmc->read_bl_len;
882 else
Rabin Vincent998be3d2009-04-05 13:30:56 +0530883 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -0500884
885 if (mmc->high_capacity) {
886 csize = (mmc->csd[1] & 0x3f) << 16
887 | (mmc->csd[2] & 0xffff0000) >> 16;
888 cmult = 8;
889 } else {
890 csize = (mmc->csd[1] & 0x3ff) << 2
891 | (mmc->csd[2] & 0xc0000000) >> 30;
892 cmult = (mmc->csd[2] & 0x00038000) >> 15;
893 }
894
Stephen Warrenf866a462013-06-11 15:14:01 -0600895 mmc->capacity_user = (csize + 1) << (cmult + 2);
896 mmc->capacity_user *= mmc->read_bl_len;
897 mmc->capacity_boot = 0;
898 mmc->capacity_rpmb = 0;
899 for (i = 0; i < 4; i++)
900 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500901
Simon Glass8bfa1952013-04-03 08:54:30 +0000902 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
903 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500904
Simon Glass8bfa1952013-04-03 08:54:30 +0000905 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
906 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500907
Markus Niebelab711882013-12-16 13:40:46 +0100908 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
909 cmd.cmdidx = MMC_CMD_SET_DSR;
910 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
911 cmd.resp_type = MMC_RSP_NONE;
912 if (mmc_send_cmd(mmc, &cmd, NULL))
913 printf("MMC: SET_DSR failed\n");
914 }
915
Andy Fleming272cc702008-10-30 16:41:01 -0500916 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +0000917 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
918 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +0000919 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +0000920 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +0000921 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -0500922
Thomas Choud52ebf12010-12-24 13:12:21 +0000923 if (err)
924 return err;
925 }
Andy Fleming272cc702008-10-30 16:41:01 -0500926
Lei Wene6f99a52011-06-22 17:03:31 +0000927 /*
928 * For SD, its erase group is always one sector
929 */
930 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +0000931 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530932 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
933 /* check ext_csd version and capacity */
934 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000935 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +0000936 /*
937 * According to the JEDEC Standard, the value of
938 * ext_csd's capacity is valid if the value is more
939 * than 2GB
940 */
Lei Wen0560db12011-10-03 20:35:10 +0000941 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
942 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
943 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
944 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +0000945 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +0000946 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -0600947 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +0530948 }
Lei Wenbc897b12011-05-02 16:26:26 +0000949
Jaehoon Chung64f4a612013-01-29 19:31:16 +0000950 switch (ext_csd[EXT_CSD_REV]) {
951 case 1:
952 mmc->version = MMC_VERSION_4_1;
953 break;
954 case 2:
955 mmc->version = MMC_VERSION_4_2;
956 break;
957 case 3:
958 mmc->version = MMC_VERSION_4_3;
959 break;
960 case 5:
961 mmc->version = MMC_VERSION_4_41;
962 break;
963 case 6:
964 mmc->version = MMC_VERSION_4_5;
965 break;
966 }
967
Lei Wene6f99a52011-06-22 17:03:31 +0000968 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +0200969 * Host needs to enable ERASE_GRP_DEF bit if device is
970 * partitioned. This bit will be lost every time after a reset
971 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +0000972 */
Oliver Metz1937e5a2013-10-01 20:32:07 +0200973 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
974 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
975 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
976 EXT_CSD_ERASE_GROUP_DEF, 1);
977
978 if (err)
979 return err;
980
981 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +0000982 mmc->erase_grp_size =
Simon Glass8bfa1952013-04-03 08:54:30 +0000983 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
984 MMC_MAX_BLOCK_LEN * 1024;
985 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +0200986 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +0000987 int erase_gsz, erase_gmul;
988 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
989 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
990 mmc->erase_grp_size = (erase_gsz + 1)
991 * (erase_gmul + 1);
992 }
993
Lei Wenbc897b12011-05-02 16:26:26 +0000994 /* store the partition info of emmc */
Stephen Warren8948ea82012-07-30 10:55:43 +0000995 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
996 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen0560db12011-10-03 20:35:10 +0000997 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrenf866a462013-06-11 15:14:01 -0600998
999 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1000
1001 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1002
1003 for (i = 0; i < 4; i++) {
1004 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1005 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1006 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1007 mmc->capacity_gp[i] *=
1008 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1009 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1010 }
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301011 }
1012
Stephen Warrenf866a462013-06-11 15:14:01 -06001013 err = mmc_set_capacity(mmc, mmc->part_num);
1014 if (err)
1015 return err;
1016
Andy Fleming272cc702008-10-30 16:41:01 -05001017 if (IS_SD(mmc))
1018 err = sd_change_freq(mmc);
1019 else
1020 err = mmc_change_freq(mmc);
1021
1022 if (err)
1023 return err;
1024
1025 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001026 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001027
1028 if (IS_SD(mmc)) {
1029 if (mmc->card_caps & MMC_MODE_4BIT) {
1030 cmd.cmdidx = MMC_CMD_APP_CMD;
1031 cmd.resp_type = MMC_RSP_R1;
1032 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001033
1034 err = mmc_send_cmd(mmc, &cmd, NULL);
1035 if (err)
1036 return err;
1037
1038 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1039 cmd.resp_type = MMC_RSP_R1;
1040 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001041 err = mmc_send_cmd(mmc, &cmd, NULL);
1042 if (err)
1043 return err;
1044
1045 mmc_set_bus_width(mmc, 4);
1046 }
1047
1048 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001049 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001050 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001051 mmc->tran_speed = 25000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001052 } else {
Andy Fleming7798f6d2012-10-31 19:02:38 +00001053 int idx;
1054
1055 /* An array of possible bus widths in order of preference */
1056 static unsigned ext_csd_bits[] = {
1057 EXT_CSD_BUS_WIDTH_8,
1058 EXT_CSD_BUS_WIDTH_4,
1059 EXT_CSD_BUS_WIDTH_1,
1060 };
1061
1062 /* An array to map CSD bus widths to host cap bits */
1063 static unsigned ext_to_hostcaps[] = {
1064 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1065 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1066 };
1067
1068 /* An array to map chosen bus width to an integer */
1069 static unsigned widths[] = {
1070 8, 4, 1,
1071 };
1072
1073 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1074 unsigned int extw = ext_csd_bits[idx];
1075
1076 /*
1077 * Check to make sure the controller supports
1078 * this bus width, if it's more than 1
1079 */
1080 if (extw != EXT_CSD_BUS_WIDTH_1 &&
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001081 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Fleming7798f6d2012-10-31 19:02:38 +00001082 continue;
1083
Andy Fleming272cc702008-10-30 16:41:01 -05001084 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001085 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001086
1087 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001088 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001089
Andy Fleming7798f6d2012-10-31 19:02:38 +00001090 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001091
Lei Wen41378942011-10-03 20:35:11 +00001092 err = mmc_send_ext_csd(mmc, test_csd);
1093 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1094 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1095 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1096 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1097 && ext_csd[EXT_CSD_REV] \
1098 == test_csd[EXT_CSD_REV]
1099 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1100 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1101 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1102 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Fleming272cc702008-10-30 16:41:01 -05001103
Andy Fleming7798f6d2012-10-31 19:02:38 +00001104 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen41378942011-10-03 20:35:11 +00001105 break;
1106 }
Andy Fleming272cc702008-10-30 16:41:01 -05001107 }
1108
1109 if (mmc->card_caps & MMC_MODE_HS) {
1110 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001111 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001112 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001113 mmc->tran_speed = 26000000;
1114 }
Andy Fleming272cc702008-10-30 16:41:01 -05001115 }
1116
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001117 mmc_set_clock(mmc, mmc->tran_speed);
1118
Andy Fleming272cc702008-10-30 16:41:01 -05001119 /* fill in device description */
1120 mmc->block_dev.lun = 0;
1121 mmc->block_dev.type = 0;
1122 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001123 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301124 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001125#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001126 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1127 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1128 (mmc->cid[3] >> 16) & 0xffff);
1129 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1130 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1131 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1132 (mmc->cid[2] >> 24) & 0xff);
1133 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1134 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001135#else
1136 mmc->block_dev.vendor[0] = 0;
1137 mmc->block_dev.product[0] = 0;
1138 mmc->block_dev.revision[0] = 0;
1139#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001140#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001141 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001142#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001143
1144 return 0;
1145}
1146
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001147static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001148{
1149 struct mmc_cmd cmd;
1150 int err;
1151
1152 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1153 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001154 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001155 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001156
1157 err = mmc_send_cmd(mmc, &cmd, NULL);
1158
1159 if (err)
1160 return err;
1161
Rabin Vincent998be3d2009-04-05 13:30:56 +05301162 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001163 return UNUSABLE_ERR;
1164 else
1165 mmc->version = SD_VERSION_2;
1166
1167 return 0;
1168}
1169
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001170/* not used any more */
1171int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001172{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001173#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1174 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1175#endif
1176 return -1;
1177}
1178
1179struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1180{
1181 struct mmc *mmc;
1182
1183 /* quick validation */
1184 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1185 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1186 return NULL;
1187
1188 mmc = calloc(1, sizeof(*mmc));
1189 if (mmc == NULL)
1190 return NULL;
1191
1192 mmc->cfg = cfg;
1193 mmc->priv = priv;
1194
1195 /* the following chunk was mmc_register() */
1196
Markus Niebelab711882013-12-16 13:40:46 +01001197 /* Setup dsr related values */
1198 mmc->dsr_imp = 0;
1199 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001200 /* Setup the universal parts of the block interface just once */
1201 mmc->block_dev.if_type = IF_TYPE_MMC;
1202 mmc->block_dev.dev = cur_dev_num++;
1203 mmc->block_dev.removable = 1;
1204 mmc->block_dev.block_read = mmc_bread;
1205 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001206 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001207
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001208 /* setup initial part type */
1209 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001210
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001211 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001212
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001213 list_add_tail(&mmc->link, &mmc_devices);
1214
1215 return mmc;
1216}
1217
1218void mmc_destroy(struct mmc *mmc)
1219{
1220 /* only freeing memory for now */
1221 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001222}
1223
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001224#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001225block_dev_desc_t *mmc_get_dev(int dev)
1226{
1227 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001228 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001229 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001230
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001231 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001232}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001233#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001234
Che-Liang Chioue9550442012-11-28 15:21:13 +00001235int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001236{
Macpaul Linafd59322011-11-14 23:35:39 +00001237 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001238
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001239 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001240 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001241 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001242#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001243 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001244#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001245 return NO_CARD_ERR;
1246 }
1247
Lei Wenbc897b12011-05-02 16:26:26 +00001248 if (mmc->has_init)
1249 return 0;
1250
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001251 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001252 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001253
1254 if (err)
1255 return err;
1256
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001257 mmc_set_bus_width(mmc, 1);
1258 mmc_set_clock(mmc, 1);
1259
Andy Fleming272cc702008-10-30 16:41:01 -05001260 /* Reset the Card */
1261 err = mmc_go_idle(mmc);
1262
1263 if (err)
1264 return err;
1265
Lei Wenbc897b12011-05-02 16:26:26 +00001266 /* The internal partition reset to user partition(0) at every CMD0*/
1267 mmc->part_num = 0;
1268
Andy Fleming272cc702008-10-30 16:41:01 -05001269 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001270 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001271
Andy Fleming272cc702008-10-30 16:41:01 -05001272 /* Now try to get the SD card's operating condition */
1273 err = sd_send_op_cond(mmc);
1274
1275 /* If the command timed out, we check for an MMC card */
1276 if (err == TIMEOUT) {
1277 err = mmc_send_op_cond(mmc);
1278
Che-Liang Chioue9550442012-11-28 15:21:13 +00001279 if (err && err != IN_PROGRESS) {
Paul Burton56196822013-09-04 16:12:25 +01001280#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001281 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001282#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001283 return UNUSABLE_ERR;
1284 }
1285 }
1286
Che-Liang Chioue9550442012-11-28 15:21:13 +00001287 if (err == IN_PROGRESS)
1288 mmc->init_in_progress = 1;
1289
1290 return err;
1291}
1292
1293static int mmc_complete_init(struct mmc *mmc)
1294{
1295 int err = 0;
1296
1297 if (mmc->op_cond_pending)
1298 err = mmc_complete_op_cond(mmc);
1299
1300 if (!err)
1301 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001302 if (err)
1303 mmc->has_init = 0;
1304 else
1305 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001306 mmc->init_in_progress = 0;
1307 return err;
1308}
1309
1310int mmc_init(struct mmc *mmc)
1311{
1312 int err = IN_PROGRESS;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001313 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001314
1315 if (mmc->has_init)
1316 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001317
1318 start = get_timer(0);
1319
Che-Liang Chioue9550442012-11-28 15:21:13 +00001320 if (!mmc->init_in_progress)
1321 err = mmc_start_init(mmc);
1322
1323 if (!err || err == IN_PROGRESS)
1324 err = mmc_complete_init(mmc);
1325 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001326 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001327}
1328
Markus Niebelab711882013-12-16 13:40:46 +01001329int mmc_set_dsr(struct mmc *mmc, u16 val)
1330{
1331 mmc->dsr = val;
1332 return 0;
1333}
1334
Andy Fleming272cc702008-10-30 16:41:01 -05001335/*
1336 * CPU and board-specific MMC initializations. Aliased function
1337 * signals caller to move on
1338 */
1339static int __def_mmc_init(bd_t *bis)
1340{
1341 return -1;
1342}
1343
Peter Tyserf9a109b2009-04-20 11:08:46 -05001344int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1345int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Fleming272cc702008-10-30 16:41:01 -05001346
Paul Burton56196822013-09-04 16:12:25 +01001347#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1348
Andy Fleming272cc702008-10-30 16:41:01 -05001349void print_mmc_devices(char separator)
1350{
1351 struct mmc *m;
1352 struct list_head *entry;
1353
1354 list_for_each(entry, &mmc_devices) {
1355 m = list_entry(entry, struct mmc, link);
1356
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001357 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Fleming272cc702008-10-30 16:41:01 -05001358
1359 if (entry->next != &mmc_devices)
1360 printf("%c ", separator);
1361 }
1362
1363 printf("\n");
1364}
1365
Paul Burton56196822013-09-04 16:12:25 +01001366#else
1367void print_mmc_devices(char separator) { }
1368#endif
1369
Lei Wenea6ebe22011-05-02 16:26:25 +00001370int get_mmc_num(void)
1371{
1372 return cur_dev_num;
1373}
1374
Che-Liang Chioue9550442012-11-28 15:21:13 +00001375void mmc_set_preinit(struct mmc *mmc, int preinit)
1376{
1377 mmc->preinit = preinit;
1378}
1379
1380static void do_preinit(void)
1381{
1382 struct mmc *m;
1383 struct list_head *entry;
1384
1385 list_for_each(entry, &mmc_devices) {
1386 m = list_entry(entry, struct mmc, link);
1387
1388 if (m->preinit)
1389 mmc_start_init(m);
1390 }
1391}
1392
1393
Andy Fleming272cc702008-10-30 16:41:01 -05001394int mmc_initialize(bd_t *bis)
1395{
1396 INIT_LIST_HEAD (&mmc_devices);
1397 cur_dev_num = 0;
1398
1399 if (board_mmc_init(bis) < 0)
1400 cpu_mmc_init(bis);
1401
Ying Zhangbb0dc102013-08-16 15:16:11 +08001402#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001403 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001404#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001405
Che-Liang Chioue9550442012-11-28 15:21:13 +00001406 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001407 return 0;
1408}
Amar3690d6d2013-04-27 11:42:58 +05301409
1410#ifdef CONFIG_SUPPORT_EMMC_BOOT
1411/*
1412 * This function changes the size of boot partition and the size of rpmb
1413 * partition present on EMMC devices.
1414 *
1415 * Input Parameters:
1416 * struct *mmc: pointer for the mmc device strcuture
1417 * bootsize: size of boot partition
1418 * rpmbsize: size of rpmb partition
1419 *
1420 * Returns 0 on success.
1421 */
1422
1423int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1424 unsigned long rpmbsize)
1425{
1426 int err;
1427 struct mmc_cmd cmd;
1428
1429 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1430 cmd.cmdidx = MMC_CMD_RES_MAN;
1431 cmd.resp_type = MMC_RSP_R1b;
1432 cmd.cmdarg = MMC_CMD62_ARG1;
1433
1434 err = mmc_send_cmd(mmc, &cmd, NULL);
1435 if (err) {
1436 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1437 return err;
1438 }
1439
1440 /* Boot partition changing mode */
1441 cmd.cmdidx = MMC_CMD_RES_MAN;
1442 cmd.resp_type = MMC_RSP_R1b;
1443 cmd.cmdarg = MMC_CMD62_ARG2;
1444
1445 err = mmc_send_cmd(mmc, &cmd, NULL);
1446 if (err) {
1447 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1448 return err;
1449 }
1450 /* boot partition size is multiple of 128KB */
1451 bootsize = (bootsize * 1024) / 128;
1452
1453 /* Arg: boot partition size */
1454 cmd.cmdidx = MMC_CMD_RES_MAN;
1455 cmd.resp_type = MMC_RSP_R1b;
1456 cmd.cmdarg = bootsize;
1457
1458 err = mmc_send_cmd(mmc, &cmd, NULL);
1459 if (err) {
1460 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1461 return err;
1462 }
1463 /* RPMB partition size is multiple of 128KB */
1464 rpmbsize = (rpmbsize * 1024) / 128;
1465 /* Arg: RPMB partition size */
1466 cmd.cmdidx = MMC_CMD_RES_MAN;
1467 cmd.resp_type = MMC_RSP_R1b;
1468 cmd.cmdarg = rpmbsize;
1469
1470 err = mmc_send_cmd(mmc, &cmd, NULL);
1471 if (err) {
1472 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1473 return err;
1474 }
1475 return 0;
1476}
1477
1478/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001479 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1480 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1481 * and BOOT_MODE.
1482 *
1483 * Returns 0 on success.
1484 */
1485int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1486{
1487 int err;
1488
1489 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1490 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1491 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1492 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1493
1494 if (err)
1495 return err;
1496 return 0;
1497}
1498
1499/*
Tom Rini792970b2014-02-05 10:24:21 -05001500 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1501 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1502 * PARTITION_ACCESS.
1503 *
1504 * Returns 0 on success.
1505 */
1506int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1507{
1508 int err;
1509
1510 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1511 EXT_CSD_BOOT_ACK(ack) |
1512 EXT_CSD_BOOT_PART_NUM(part_num) |
1513 EXT_CSD_PARTITION_ACCESS(access));
1514
1515 if (err)
1516 return err;
1517 return 0;
1518}
Tom Rini33ace362014-02-07 14:15:20 -05001519
1520/*
1521 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1522 * for enable. Note that this is a write-once field for non-zero values.
1523 *
1524 * Returns 0 on success.
1525 */
1526int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1527{
1528 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1529 enable);
1530}
Amar3690d6d2013-04-27 11:42:58 +05301531#endif