blob: 55c2c68cdb23218945d0af727632745897278d72 [file] [log] [blame]
Andy Flemingad347bb2008-10-30 16:41:01 -05001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Based vaguely on the Linux code
6 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Andy Flemingad347bb2008-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 Vincent69d4e2c2009-04-05 13:30:54 +053017#include <div64.h>
Paul Burton8d30cc92013-09-09 15:30:26 +010018#include "mmc_private.h"
Andy Flemingad347bb2008-10-30 16:41:01 -050019
20static struct list_head mmc_devices;
21static int cur_dev_num = -1;
22
Nikita Kiryanov020f2612012-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 Korsgaardf7b15102013-03-21 04:00:03 +000034 if (wp < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +020035 if (mmc->cfg->ops->getwp)
36 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +000037 else
38 wp = 0;
39 }
Nikita Kiryanov020f2612012-12-03 02:19:46 +000040
41 return wp;
42}
43
Thierry Redingd7aebf42012-01-02 01:15:36 +000044int __board_mmc_getcd(struct mmc *mmc) {
Stefano Babic6e00edf2010-02-05 15:04:43 +010045 return -1;
46}
47
Thierry Redingd7aebf42012-01-02 01:15:36 +000048int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
Stefano Babic6e00edf2010-02-05 15:04:43 +010049 alias("__board_mmc_getcd")));
50
Paul Burton8d30cc92013-09-09 15:30:26 +010051int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
Andy Flemingad347bb2008-10-30 16:41:01 -050052{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000053 int ret;
Marek Vasutdccb6082012-03-15 18:41:35 +000054
Marek Vasutdccb6082012-03-15 18:41:35 +000055#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati894b1e22011-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 Antoniou2c850462014-03-11 19:34:20 +020061 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati894b1e22011-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 Behmec9cb4a92012-03-08 02:35:34 +000088 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati894b1e22011-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 Recalcati894b1e22011-03-11 02:01:14 +0000103#else
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200104 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000105#endif
Marek Vasutdccb6082012-03-15 18:41:35 +0000106 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500107}
108
Paul Burton8d30cc92013-09-09 15:30:26 +0100109int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000110{
111 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000112 int err, retries = 5;
Raffaele Recalcati01a0dc62011-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 Vasutc4427392011-08-10 09:24:48 +0200119 if (!mmc_host_is_spi(mmc))
120 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000121
122 do {
123 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-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 Burton6a7c5ba2013-09-04 16:12:25 +0100130#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzke31789322012-02-05 22:29:12 +0000131 printf("Status Error: 0x%08X\n",
132 cmd.response[0]);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100133#endif
Jan Kloetzke31789322012-02-05 22:29:12 +0000134 return COMM_ERR;
135 }
136 } else if (--retries < 0)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000137 return err;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000138
139 udelay(1000);
140
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000141 } while (timeout--);
142
Raffaele Recalcati894b1e22011-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 Heo1be00d92012-06-03 21:32:13 +0000147 if (timeout <= 0) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100148#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000149 printf("Timeout waiting card ready\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100150#endif
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000151 return TIMEOUT;
152 }
Andrew Gabbasove80682f2014-04-03 04:34:32 -0500153 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
154 return SWITCH_ERR;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000155
156 return 0;
157}
158
Paul Burton8d30cc92013-09-09 15:30:26 +0100159int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500160{
161 struct mmc_cmd cmd;
162
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900163 if (mmc->card_caps & MMC_MODE_DDR_52MHz)
164 return 0;
165
Andy Flemingad347bb2008-10-30 16:41:01 -0500166 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
167 cmd.resp_type = MMC_RSP_R1;
168 cmd.cmdarg = len;
Andy Flemingad347bb2008-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 Burton6a7c5ba2013-09-04 16:12:25 +0100185#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -0500186 printf("MMC Device %d not found\n", dev_num);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100187#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500188
189 return NULL;
190}
191
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200192static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000193 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500194{
195 struct mmc_cmd cmd;
196 struct mmc_data data;
197
Alagu Sankarc25d1b92010-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 Flemingad347bb2008-10-30 16:41:01 -0500202
203 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700204 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500205 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700206 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500207
208 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500209
210 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700211 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500212 data.blocksize = mmc->read_bl_len;
213 data.flags = MMC_DATA_READ;
214
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700215 if (mmc_send_cmd(mmc, &cmd, &data))
216 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500217
Alagu Sankarc25d1b92010-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 Sankarc25d1b92010-10-25 07:23:56 -0700222 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100223#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700224 printf("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100225#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700226 return 0;
227 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500228 }
229
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700230 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500231}
232
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200233static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Flemingad347bb2008-10-30 16:41:01 -0500234{
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700235 lbaint_t cur, blocks_todo = blkcnt;
236
237 if (blkcnt == 0)
238 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500239
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700240 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500241 if (!mmc)
242 return 0;
243
Lei Wene1cc9c82010-09-13 22:07:27 +0800244 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100245#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200246 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800247 start + blkcnt, mmc->block_dev.lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100248#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800249 return 0;
250 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500251
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700252 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Flemingad347bb2008-10-30 16:41:01 -0500253 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500254
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700255 do {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200256 cur = (blocks_todo > mmc->cfg->b_max) ?
257 mmc->cfg->b_max : blocks_todo;
Alagu Sankarc25d1b92010-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 Flemingad347bb2008-10-30 16:41:01 -0500264
265 return blkcnt;
266}
267
Kim Phillips87ea3892012-10-29 13:34:43 +0000268static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000289static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Babicf8e9a212010-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 Chou1254c3d2010-12-24 13:12:21 +0000315 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200316 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-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 Chou1254c3d2010-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 Chou1254c3d2010-12-24 13:12:21 +0000339
340 err = mmc_send_cmd(mmc, &cmd, NULL);
341
342 if (err)
343 return err;
344 }
345
Rabin Vincentb6eed942009-04-05 13:30:56 +0530346 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-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 Chiou4a2c7d72012-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 Flemingad347bb2008-10-30 16:41:01 -0500357{
Andy Flemingad347bb2008-10-30 16:41:01 -0500358 int err;
359
Che-Liang Chiou4a2c7d72012-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 Antoniou2c850462014-03-11 19:34:20 +0200365 (mmc->cfg->voltages &
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000366 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
367 (mmc->op_cond_response & OCR_ACCESS_MODE);
368
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200369 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chiou4a2c7d72012-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 Flemingad347bb2008-10-30 16:41:01 -0500384 /* Some cards seem to need this */
385 mmc_go_idle(mmc);
386
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000387 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-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);
391 if (err)
392 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200393
Che-Liang Chiou4a2c7d72012-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}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200400
Che-Liang Chiou4a2c7d72012-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;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200407
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000408 mmc->op_cond_pending = 0;
409 start = get_timer(0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500410 do {
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000411 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
Andy Flemingad347bb2008-10-30 16:41:01 -0500412 if (err)
413 return err;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000414 if (get_timer(start) > timeout)
415 return UNUSABLE_ERR;
416 udelay(100);
417 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Flemingad347bb2008-10-30 16:41:01 -0500418
Thomas Chou1254c3d2010-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 Chou1254c3d2010-12-24 13:12:21 +0000423
424 err = mmc_send_cmd(mmc, &cmd, NULL);
425
426 if (err)
427 return err;
428 }
429
Andy Flemingad347bb2008-10-30 16:41:01 -0500430 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincentb6eed942009-04-05 13:30:56 +0530431 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500432
433 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700434 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500435
436 return 0;
437}
438
439
Kim Phillips87ea3892012-10-29 13:34:43 +0000440static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -0500450
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000451 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500452 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000453 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000462static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500463{
464 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000465 int timeout = 1000;
466 int ret;
Andy Flemingad347bb2008-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 Recalcati01a0dc62011-03-11 02:01:12 +0000471 (index << 16) |
472 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500473
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000474 ret = mmc_send_cmd(mmc, &cmd, NULL);
475
476 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000477 if (!ret)
478 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000479
480 return ret;
481
Andy Flemingad347bb2008-10-30 16:41:01 -0500482}
483
Kim Phillips87ea3892012-10-29 13:34:43 +0000484static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500485{
Simon Glassa09c2b72013-04-03 08:54:30 +0000486 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500487 char cardtype;
488 int err;
489
490 mmc->card_caps = 0;
491
Thomas Chou1254c3d2010-12-24 13:12:21 +0000492 if (mmc_host_is_spi(mmc))
493 return 0;
494
Andy Flemingad347bb2008-10-30 16:41:01 -0500495 /* Only version 4 supports high-speed */
496 if (mmc->version < MMC_VERSION_4)
497 return 0;
498
Andy Flemingad347bb2008-10-30 16:41:01 -0500499 err = mmc_send_ext_csd(mmc, ext_csd);
500
501 if (err)
502 return err;
503
Lei Wen217467f2011-10-03 20:35:10 +0000504 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-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 Gabbasove80682f2014-04-03 04:34:32 -0500509 return err == SWITCH_ERR ? 0 : err;
Andy Flemingad347bb2008-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 Wen217467f2011-10-03 20:35:10 +0000518 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500519 return 0;
520
521 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chung38ce30b2014-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 Flemingad347bb2008-10-30 16:41:01 -0500525 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900526 } else {
Andy Flemingad347bb2008-10-30 16:41:01 -0500527 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900528 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500529
530 return 0;
531}
532
Stephen Warrene315ae82013-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 Warren52c44e42014-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 Wen31b99802011-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 Warrene315ae82013-06-11 15:14:01 -0600590 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000591
592 if (!mmc)
593 return -1;
594
Stephen Warrene315ae82013-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 Wen31b99802011-05-02 16:26:26 +0000602}
603
Thierry Redingb9c8b772012-01-02 01:15:37 +0000604int mmc_getcd(struct mmc *mmc)
605{
606 int cd;
607
608 cd = board_mmc_getcd(mmc);
609
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000610 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200611 if (mmc->cfg->ops->getcd)
612 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000613 else
614 cd = 1;
615 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000616
617 return cd;
618}
619
Kim Phillips87ea3892012-10-29 13:34:43 +0000620static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000641static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500642{
643 int err;
644 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000645 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
646 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500647 struct mmc_data data;
648 int timeout;
649
650 mmc->card_caps = 0;
651
Thomas Chou1254c3d2010-12-24 13:12:21 +0000652 if (mmc_host_is_spi(mmc))
653 return 0;
654
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -0500668
669 timeout = 3;
670
671retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000672 data.dest = (char *)scr;
Andy Flemingad347bb2008-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 Kharuzhy6e8edf42009-05-07 00:43:30 +0300686 mmc->scr[0] = __be32_to_cpu(scr[0]);
687 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-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 Chungd552bd12013-01-29 22:58:16 +0000698 if ((mmc->scr[0] >> 15) & 0x1)
699 mmc->version = SD_VERSION_3;
Andy Flemingad347bb2008-10-30 16:41:01 -0500700 break;
701 default:
702 mmc->version = SD_VERSION_1_0;
703 break;
704 }
705
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530706 if (mmc->scr[0] & SD_DATA_4BIT)
707 mmc->card_caps |= MMC_MODE_4BIT;
708
Andy Flemingad347bb2008-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 staaf9b00f0d2011-10-03 13:54:59 +0000716 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500717
718 if (err)
719 return err;
720
721 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300722 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500723 break;
724 }
725
Andy Flemingad347bb2008-10-30 16:41:01 -0500726 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300727 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500728 return 0;
729
Macpaul Lin24e92ec2011-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 Antoniou2c850462014-03-11 19:34:20 +0200736 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
737 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000738 return 0;
739
Anton staaf9b00f0d2011-10-03 13:54:59 +0000740 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500741
742 if (err)
743 return err;
744
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300745 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-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 Frysingerb588caf2010-10-20 01:15:53 +0000753static const int fbase[] = {
Andy Flemingad347bb2008-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 Frysingerb588caf2010-10-20 01:15:53 +0000763static const int multipliers[] = {
Andy Flemingad347bb2008-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 Phillips87ea3892012-10-29 13:34:43 +0000782static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500783{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200784 if (mmc->cfg->ops->set_ios)
785 mmc->cfg->ops->set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -0500786}
787
788void mmc_set_clock(struct mmc *mmc, uint clock)
789{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200790 if (clock > mmc->cfg->f_max)
791 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -0500792
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200793 if (clock < mmc->cfg->f_min)
794 clock = mmc->cfg->f_min;
Andy Flemingad347bb2008-10-30 16:41:01 -0500795
796 mmc->clock = clock;
797
798 mmc_set_ios(mmc);
799}
800
Kim Phillips87ea3892012-10-29 13:34:43 +0000801static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -0500802{
803 mmc->bus_width = width;
804
805 mmc_set_ios(mmc);
806}
807
Kim Phillips87ea3892012-10-29 13:34:43 +0000808static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500809{
Stephen Warrene315ae82013-06-11 15:14:01 -0600810 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -0500811 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000812 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -0500813 struct mmc_cmd cmd;
Simon Glassa09c2b72013-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 Recalcati01a0dc62011-03-11 02:01:12 +0000816 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500817
Thomas Chou1254c3d2010-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 Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500830 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500833 cmd.resp_type = MMC_RSP_R2;
834 cmd.cmdarg = 0;
Andy Flemingad347bb2008-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 Chou1254c3d2010-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 Flemingad347bb2008-10-30 16:41:01 -0500852
Thomas Chou1254c3d2010-12-24 13:12:21 +0000853 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500854
Thomas Chou1254c3d2010-12-24 13:12:21 +0000855 if (err)
856 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500857
Thomas Chou1254c3d2010-12-24 13:12:21 +0000858 if (IS_SD(mmc))
859 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
860 }
Andy Flemingad347bb2008-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 Flemingad347bb2008-10-30 16:41:01 -0500866
867 err = mmc_send_cmd(mmc, &cmd, NULL);
868
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000869 /* Waiting for the ready status */
870 mmc_send_status(mmc, timeout);
871
Andy Flemingad347bb2008-10-30 16:41:01 -0500872 if (err)
873 return err;
874
Rabin Vincentb6eed942009-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 Flemingad347bb2008-10-30 16:41:01 -0500879
880 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530881 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-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 Vincentbdf7a682009-04-05 13:30:55 +0530906 freq = fbase[(cmd.response[0] & 0x7)];
907 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -0500908
909 mmc->tran_speed = freq * mult;
910
Markus Niebel03951412013-12-16 13:40:46 +0100911 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +0530912 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500913
914 if (IS_SD(mmc))
915 mmc->write_bl_len = mmc->read_bl_len;
916 else
Rabin Vincentb6eed942009-04-05 13:30:56 +0530917 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-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 Warrene315ae82013-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 Flemingad347bb2008-10-30 16:41:01 -0500935
Simon Glassa09c2b72013-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 Flemingad347bb2008-10-30 16:41:01 -0500938
Simon Glassa09c2b72013-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 Flemingad347bb2008-10-30 16:41:01 -0500941
Markus Niebel03951412013-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 Flemingad347bb2008-10-30 16:41:01 -0500950 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-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 Bhargav4a32fba2011-10-05 03:13:23 +0000953 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000954 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000955 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500956
Thomas Chou1254c3d2010-12-24 13:12:21 +0000957 if (err)
958 return err;
959 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500960
Lei Wenea526762011-06-22 17:03:31 +0000961 /*
962 * For SD, its erase group is always one sector
963 */
964 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +0000965 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-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 Phillips87ea3892012-10-29 13:34:43 +0000969 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda7d88de52011-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 Wen217467f2011-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 Glassa09c2b72013-04-03 08:54:30 +0000979 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +0000980 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -0600981 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530982 }
Lei Wen31b99802011-05-02 16:26:26 +0000983
Jaehoon Chung6108ef62013-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 Wenea526762011-06-22 17:03:31 +00001002 /*
Oliver Metzb3f14092013-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 Wenea526762011-06-22 17:03:31 +00001006 */
Oliver Metzb3f14092013-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 Wen217467f2011-10-03 20:35:10 +00001016 mmc->erase_grp_size =
Simon Glassa09c2b72013-04-03 08:54:30 +00001017 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
1018 MMC_MAX_BLOCK_LEN * 1024;
1019 } else {
Oliver Metzb3f14092013-10-01 20:32:07 +02001020 /* Calculate the group size from the csd value. */
Lei Wenea526762011-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 Wen31b99802011-05-02 16:26:26 +00001028 /* store the partition info of emmc */
Stephen Warren009784c2012-07-30 10:55:43 +00001029 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1030 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen217467f2011-10-03 20:35:10 +00001031 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrene315ae82013-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 Ghorai232293c2010-09-20 18:29:29 +05301045 }
1046
Stephen Warrene315ae82013-06-11 15:14:01 -06001047 err = mmc_set_capacity(mmc, mmc->part_num);
1048 if (err)
1049 return err;
1050
Andy Flemingad347bb2008-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 Antoniou2c850462014-03-11 19:34:20 +02001060 mmc->card_caps &= mmc->cfg->host_caps;
Andy Flemingad347bb2008-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 Flemingad347bb2008-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 Flemingad347bb2008-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 Chunge1d4c7b2012-03-26 21:16:03 +00001083 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001084 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001085 mmc->tran_speed = 25000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001086 } else {
Andy Flemingeb766ad2012-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 Chung38ce30b2014-05-16 13:59:54 +09001091 EXT_CSD_DDR_BUS_WIDTH_8,
1092 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Flemingeb766ad2012-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 Chung38ce30b2014-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 Flemingeb766ad2012-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 Chung38ce30b2014-05-16 13:59:54 +09001108 8, 4, 8, 4, 1,
Andy Flemingeb766ad2012-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 Antoniou2c850462014-03-11 19:34:20 +02001119 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Flemingeb766ad2012-10-31 19:02:38 +00001120 continue;
1121
Andy Flemingad347bb2008-10-30 16:41:01 -05001122 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001123 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001124
1125 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001126 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001127
Andy Flemingeb766ad2012-10-31 19:02:38 +00001128 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001129
Lei Wen4f5a6a52011-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 Flemingad347bb2008-10-30 16:41:01 -05001141
Andy Flemingeb766ad2012-10-31 19:02:38 +00001142 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen4f5a6a52011-10-03 20:35:11 +00001143 break;
1144 }
Andy Flemingad347bb2008-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 Chunge1d4c7b2012-03-26 21:16:03 +00001149 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001150 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001151 mmc->tran_speed = 26000000;
1152 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001153 }
1154
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001155 mmc_set_clock(mmc, mmc->tran_speed);
1156
Andy Flemingad347bb2008-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 Eich2eec2ab2013-04-09 21:11:56 +00001161 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent69d4e2c2009-04-05 13:30:54 +05301162 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001163#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Hutt7367ec22012-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 Burton6a7c5ba2013-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 Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001178#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001179 init_part(&mmc->block_dev);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001180#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001181
1182 return 0;
1183}
1184
Kim Phillips87ea3892012-10-29 13:34:43 +00001185static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-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 Antoniou2c850462014-03-11 19:34:20 +02001192 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05001193 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001194
1195 err = mmc_send_cmd(mmc, &cmd, NULL);
1196
1197 if (err)
1198 return err;
1199
Rabin Vincentb6eed942009-04-05 13:30:56 +05301200 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-10-30 16:41:01 -05001201 return UNUSABLE_ERR;
1202 else
1203 mmc->version = SD_VERSION_2;
1204
1205 return 0;
1206}
1207
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001208/* not used any more */
1209int __deprecated mmc_register(struct mmc *mmc)
1210{
1211#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)
Andy Flemingad347bb2008-10-30 16:41:01 -05001218{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001219 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 Niebel03951412013-12-16 13:40:46 +01001235 /* Setup dsr related values */
1236 mmc->dsr_imp = 0;
1237 mmc->dsr = 0xffffffff;
Andy Flemingad347bb2008-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 Wenea526762011-06-22 17:03:31 +00001244 mmc->block_dev.block_erase = mmc_berase;
Andy Flemingad347bb2008-10-30 16:41:01 -05001245
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001246 /* setup initial part type */
1247 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Flemingad347bb2008-10-30 16:41:01 -05001248
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001249 INIT_LIST_HEAD(&mmc->link);
Andy Flemingad347bb2008-10-30 16:41:01 -05001250
Pantelis Antoniou2c850462014-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 Flemingad347bb2008-10-30 16:41:01 -05001260}
1261
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001262#ifdef CONFIG_PARTITIONS
Andy Flemingad347bb2008-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ébaudeau6ce8aed2012-08-10 08:59:12 +00001266 if (!mmc || mmc_init(mmc))
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001267 return NULL;
Andy Flemingad347bb2008-10-30 16:41:01 -05001268
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001269 return &mmc->block_dev;
Andy Flemingad347bb2008-10-30 16:41:01 -05001270}
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001271#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001272
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001273int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001274{
Macpaul Lin028bde12011-11-14 23:35:39 +00001275 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001276
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001277 /* we pretend there's no card when init is NULL */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001278 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Redingb9c8b772012-01-02 01:15:37 +00001279 mmc->has_init = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001280#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001281 printf("MMC: no card present\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001282#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +00001283 return NO_CARD_ERR;
1284 }
1285
Lei Wen31b99802011-05-02 16:26:26 +00001286 if (mmc->has_init)
1287 return 0;
1288
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001289 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001290 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001291
1292 if (err)
1293 return err;
1294
Ilya Yanok8459aab2009-06-29 17:53:16 +04001295 mmc_set_bus_width(mmc, 1);
1296 mmc_set_clock(mmc, 1);
1297
Andy Flemingad347bb2008-10-30 16:41:01 -05001298 /* Reset the Card */
1299 err = mmc_go_idle(mmc);
1300
1301 if (err)
1302 return err;
1303
Lei Wen31b99802011-05-02 16:26:26 +00001304 /* The internal partition reset to user partition(0) at every CMD0*/
1305 mmc->part_num = 0;
1306
Andy Flemingad347bb2008-10-30 16:41:01 -05001307 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001308 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001309
Andy Flemingad347bb2008-10-30 16:41:01 -05001310 /* Now try to get the SD card's operating condition */
1311 err = sd_send_op_cond(mmc);
1312
1313 /* If the command timed out, we check for an MMC card */
1314 if (err == TIMEOUT) {
1315 err = mmc_send_op_cond(mmc);
1316
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001317 if (err && err != IN_PROGRESS) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001318#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001319 printf("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001320#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001321 return UNUSABLE_ERR;
1322 }
1323 }
1324
Che-Liang Chiou4a2c7d72012-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 Wen31b99802011-05-02 16:26:26 +00001340 if (err)
1341 mmc->has_init = 0;
1342 else
1343 mmc->has_init = 1;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001344 mmc->init_in_progress = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001345 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001346}
1347
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001348int mmc_init(struct mmc *mmc)
1349{
1350 int err = IN_PROGRESS;
Mateusz Zalegada351782014-04-29 20:15:30 +02001351 unsigned start;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001352
1353 if (mmc->has_init)
1354 return 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001355
1356 start = get_timer(0);
1357
Che-Liang Chiou4a2c7d72012-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));
1364 return err;
1365}
1366
Markus Niebel03951412013-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 Flemingad347bb2008-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 Tyser21d2cd22009-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 Flemingad347bb2008-10-30 16:41:01 -05001384
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001385#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1386
Andy Flemingad347bb2008-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 Antoniou2c850462014-03-11 19:34:20 +02001395 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Flemingad347bb2008-10-30 16:41:01 -05001396
1397 if (entry->next != &mmc_devices)
1398 printf("%c ", separator);
1399 }
1400
1401 printf("\n");
1402}
1403
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001404#else
1405void print_mmc_devices(char separator) { }
1406#endif
1407
Lei Wend430d7c2011-05-02 16:26:25 +00001408int get_mmc_num(void)
1409{
1410 return cur_dev_num;
1411}
1412
Che-Liang Chiou4a2c7d72012-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 Flemingad347bb2008-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 Zhang9ff70262013-08-16 15:16:11 +08001440#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05001441 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08001442#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001443
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001444 do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001445 return 0;
1446}
Amar1104e9b2013-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 Rini4cf854c2014-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 Rinif8c6f792014-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 Rini35a3ea12014-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}
Amar1104e9b2013-04-27 11:42:58 +05301569#endif