blob: 08187d5f3ead245d7327fe3522758d32fad1bec2 [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 }
153
154 return 0;
155}
156
Paul Burton8d30cc92013-09-09 15:30:26 +0100157int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500158{
159 struct mmc_cmd cmd;
160
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900161 if (mmc->card_caps & MMC_MODE_DDR_52MHz)
162 return 0;
163
Andy Flemingad347bb2008-10-30 16:41:01 -0500164 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
165 cmd.resp_type = MMC_RSP_R1;
166 cmd.cmdarg = len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500167
168 return mmc_send_cmd(mmc, &cmd, NULL);
169}
170
171struct mmc *find_mmc_device(int dev_num)
172{
173 struct mmc *m;
174 struct list_head *entry;
175
176 list_for_each(entry, &mmc_devices) {
177 m = list_entry(entry, struct mmc, link);
178
179 if (m->block_dev.dev == dev_num)
180 return m;
181 }
182
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100183#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -0500184 printf("MMC Device %d not found\n", dev_num);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100185#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500186
187 return NULL;
188}
189
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200190static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000191 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500192{
193 struct mmc_cmd cmd;
194 struct mmc_data data;
195
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700196 if (blkcnt > 1)
197 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
198 else
199 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500200
201 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700202 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500203 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700204 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500205
206 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500207
208 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700209 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500210 data.blocksize = mmc->read_bl_len;
211 data.flags = MMC_DATA_READ;
212
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700213 if (mmc_send_cmd(mmc, &cmd, &data))
214 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500215
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700216 if (blkcnt > 1) {
217 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
218 cmd.cmdarg = 0;
219 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700220 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100221#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700222 printf("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100223#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700224 return 0;
225 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500226 }
227
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700228 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500229}
230
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200231static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Flemingad347bb2008-10-30 16:41:01 -0500232{
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700233 lbaint_t cur, blocks_todo = blkcnt;
234
235 if (blkcnt == 0)
236 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500237
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700238 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500239 if (!mmc)
240 return 0;
241
Lei Wene1cc9c82010-09-13 22:07:27 +0800242 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100243#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200244 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800245 start + blkcnt, mmc->block_dev.lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100246#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800247 return 0;
248 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500249
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700250 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Flemingad347bb2008-10-30 16:41:01 -0500251 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500252
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700253 do {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200254 cur = (blocks_todo > mmc->cfg->b_max) ?
255 mmc->cfg->b_max : blocks_todo;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700256 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
257 return 0;
258 blocks_todo -= cur;
259 start += cur;
260 dst += cur * mmc->read_bl_len;
261 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500262
263 return blkcnt;
264}
265
Kim Phillips87ea3892012-10-29 13:34:43 +0000266static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500267{
268 struct mmc_cmd cmd;
269 int err;
270
271 udelay(1000);
272
273 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
274 cmd.cmdarg = 0;
275 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500276
277 err = mmc_send_cmd(mmc, &cmd, NULL);
278
279 if (err)
280 return err;
281
282 udelay(2000);
283
284 return 0;
285}
286
Kim Phillips87ea3892012-10-29 13:34:43 +0000287static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500288{
289 int timeout = 1000;
290 int err;
291 struct mmc_cmd cmd;
292
293 do {
294 cmd.cmdidx = MMC_CMD_APP_CMD;
295 cmd.resp_type = MMC_RSP_R1;
296 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500297
298 err = mmc_send_cmd(mmc, &cmd, NULL);
299
300 if (err)
301 return err;
302
303 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
304 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100305
306 /*
307 * Most cards do not answer if some reserved bits
308 * in the ocr are set. However, Some controller
309 * can set bit 7 (reserved for low voltages), but
310 * how to manage low voltages SD card is not yet
311 * specified.
312 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000313 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200314 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500315
316 if (mmc->version == SD_VERSION_2)
317 cmd.cmdarg |= OCR_HCS;
318
319 err = mmc_send_cmd(mmc, &cmd, NULL);
320
321 if (err)
322 return err;
323
324 udelay(1000);
325 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
326
327 if (timeout <= 0)
328 return UNUSABLE_ERR;
329
330 if (mmc->version != SD_VERSION_2)
331 mmc->version = SD_VERSION_1_0;
332
Thomas Chou1254c3d2010-12-24 13:12:21 +0000333 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
334 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
335 cmd.resp_type = MMC_RSP_R3;
336 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000337
338 err = mmc_send_cmd(mmc, &cmd, NULL);
339
340 if (err)
341 return err;
342 }
343
Rabin Vincentb6eed942009-04-05 13:30:56 +0530344 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500345
346 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
347 mmc->rca = 0;
348
349 return 0;
350}
351
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000352/* We pass in the cmd since otherwise the init seems to fail */
353static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
354 int use_arg)
Andy Flemingad347bb2008-10-30 16:41:01 -0500355{
Andy Flemingad347bb2008-10-30 16:41:01 -0500356 int err;
357
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000358 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
359 cmd->resp_type = MMC_RSP_R3;
360 cmd->cmdarg = 0;
361 if (use_arg && !mmc_host_is_spi(mmc)) {
362 cmd->cmdarg =
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200363 (mmc->cfg->voltages &
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000364 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
365 (mmc->op_cond_response & OCR_ACCESS_MODE);
366
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200367 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000368 cmd->cmdarg |= OCR_HCS;
369 }
370 err = mmc_send_cmd(mmc, cmd, NULL);
371 if (err)
372 return err;
373 mmc->op_cond_response = cmd->response[0];
374 return 0;
375}
376
377int mmc_send_op_cond(struct mmc *mmc)
378{
379 struct mmc_cmd cmd;
380 int err, i;
381
Andy Flemingad347bb2008-10-30 16:41:01 -0500382 /* Some cards seem to need this */
383 mmc_go_idle(mmc);
384
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000385 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000386 mmc->op_cond_pending = 1;
387 for (i = 0; i < 2; i++) {
388 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
389 if (err)
390 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200391
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000392 /* exit if not busy (flag seems to be inverted) */
393 if (mmc->op_cond_response & OCR_BUSY)
394 return 0;
395 }
396 return IN_PROGRESS;
397}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200398
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000399int mmc_complete_op_cond(struct mmc *mmc)
400{
401 struct mmc_cmd cmd;
402 int timeout = 1000;
403 uint start;
404 int err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200405
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000406 mmc->op_cond_pending = 0;
407 start = get_timer(0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500408 do {
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000409 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
Andy Flemingad347bb2008-10-30 16:41:01 -0500410 if (err)
411 return err;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000412 if (get_timer(start) > timeout)
413 return UNUSABLE_ERR;
414 udelay(100);
415 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Flemingad347bb2008-10-30 16:41:01 -0500416
Thomas Chou1254c3d2010-12-24 13:12:21 +0000417 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
418 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
419 cmd.resp_type = MMC_RSP_R3;
420 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000421
422 err = mmc_send_cmd(mmc, &cmd, NULL);
423
424 if (err)
425 return err;
426 }
427
Andy Flemingad347bb2008-10-30 16:41:01 -0500428 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincentb6eed942009-04-05 13:30:56 +0530429 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500430
431 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700432 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500433
434 return 0;
435}
436
437
Kim Phillips87ea3892012-10-29 13:34:43 +0000438static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500439{
440 struct mmc_cmd cmd;
441 struct mmc_data data;
442 int err;
443
444 /* Get the Card Status Register */
445 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
446 cmd.resp_type = MMC_RSP_R1;
447 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500448
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000449 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500450 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000451 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500452 data.flags = MMC_DATA_READ;
453
454 err = mmc_send_cmd(mmc, &cmd, &data);
455
456 return err;
457}
458
459
Kim Phillips87ea3892012-10-29 13:34:43 +0000460static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500461{
462 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000463 int timeout = 1000;
464 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500465
466 cmd.cmdidx = MMC_CMD_SWITCH;
467 cmd.resp_type = MMC_RSP_R1b;
468 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000469 (index << 16) |
470 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500471
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000472 ret = mmc_send_cmd(mmc, &cmd, NULL);
473
474 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000475 if (!ret)
476 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000477
478 return ret;
479
Andy Flemingad347bb2008-10-30 16:41:01 -0500480}
481
Kim Phillips87ea3892012-10-29 13:34:43 +0000482static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500483{
Simon Glassa09c2b72013-04-03 08:54:30 +0000484 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500485 char cardtype;
486 int err;
487
488 mmc->card_caps = 0;
489
Thomas Chou1254c3d2010-12-24 13:12:21 +0000490 if (mmc_host_is_spi(mmc))
491 return 0;
492
Andy Flemingad347bb2008-10-30 16:41:01 -0500493 /* Only version 4 supports high-speed */
494 if (mmc->version < MMC_VERSION_4)
495 return 0;
496
Andy Flemingad347bb2008-10-30 16:41:01 -0500497 err = mmc_send_ext_csd(mmc, ext_csd);
498
499 if (err)
500 return err;
501
Lei Wen217467f2011-10-03 20:35:10 +0000502 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500503
504 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
505
506 if (err)
507 return err;
508
509 /* Now check to see that it worked */
510 err = mmc_send_ext_csd(mmc, ext_csd);
511
512 if (err)
513 return err;
514
515 /* No high-speed support */
Lei Wen217467f2011-10-03 20:35:10 +0000516 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500517 return 0;
518
519 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900520 if (cardtype & EXT_CSD_CARD_TYPE_52) {
521 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
522 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Flemingad347bb2008-10-30 16:41:01 -0500523 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900524 } else {
Andy Flemingad347bb2008-10-30 16:41:01 -0500525 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900526 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500527
528 return 0;
529}
530
Stephen Warrene315ae82013-06-11 15:14:01 -0600531static int mmc_set_capacity(struct mmc *mmc, int part_num)
532{
533 switch (part_num) {
534 case 0:
535 mmc->capacity = mmc->capacity_user;
536 break;
537 case 1:
538 case 2:
539 mmc->capacity = mmc->capacity_boot;
540 break;
541 case 3:
542 mmc->capacity = mmc->capacity_rpmb;
543 break;
544 case 4:
545 case 5:
546 case 6:
547 case 7:
548 mmc->capacity = mmc->capacity_gp[part_num - 4];
549 break;
550 default:
551 return -1;
552 }
553
554 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
555
556 return 0;
557}
558
Lei Wen31b99802011-05-02 16:26:26 +0000559int mmc_switch_part(int dev_num, unsigned int part_num)
560{
561 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrene315ae82013-06-11 15:14:01 -0600562 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000563
564 if (!mmc)
565 return -1;
566
Stephen Warrene315ae82013-06-11 15:14:01 -0600567 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
568 (mmc->part_config & ~PART_ACCESS_MASK)
569 | (part_num & PART_ACCESS_MASK));
570 if (ret)
571 return ret;
572
573 return mmc_set_capacity(mmc, part_num);
Lei Wen31b99802011-05-02 16:26:26 +0000574}
575
Thierry Redingb9c8b772012-01-02 01:15:37 +0000576int mmc_getcd(struct mmc *mmc)
577{
578 int cd;
579
580 cd = board_mmc_getcd(mmc);
581
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000582 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200583 if (mmc->cfg->ops->getcd)
584 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000585 else
586 cd = 1;
587 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000588
589 return cd;
590}
591
Kim Phillips87ea3892012-10-29 13:34:43 +0000592static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -0500593{
594 struct mmc_cmd cmd;
595 struct mmc_data data;
596
597 /* Switch the frequency */
598 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
599 cmd.resp_type = MMC_RSP_R1;
600 cmd.cmdarg = (mode << 31) | 0xffffff;
601 cmd.cmdarg &= ~(0xf << (group * 4));
602 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -0500603
604 data.dest = (char *)resp;
605 data.blocksize = 64;
606 data.blocks = 1;
607 data.flags = MMC_DATA_READ;
608
609 return mmc_send_cmd(mmc, &cmd, &data);
610}
611
612
Kim Phillips87ea3892012-10-29 13:34:43 +0000613static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500614{
615 int err;
616 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000617 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
618 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500619 struct mmc_data data;
620 int timeout;
621
622 mmc->card_caps = 0;
623
Thomas Chou1254c3d2010-12-24 13:12:21 +0000624 if (mmc_host_is_spi(mmc))
625 return 0;
626
Andy Flemingad347bb2008-10-30 16:41:01 -0500627 /* Read the SCR to find out if this card supports higher speeds */
628 cmd.cmdidx = MMC_CMD_APP_CMD;
629 cmd.resp_type = MMC_RSP_R1;
630 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500631
632 err = mmc_send_cmd(mmc, &cmd, NULL);
633
634 if (err)
635 return err;
636
637 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
638 cmd.resp_type = MMC_RSP_R1;
639 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500640
641 timeout = 3;
642
643retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000644 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -0500645 data.blocksize = 8;
646 data.blocks = 1;
647 data.flags = MMC_DATA_READ;
648
649 err = mmc_send_cmd(mmc, &cmd, &data);
650
651 if (err) {
652 if (timeout--)
653 goto retry_scr;
654
655 return err;
656 }
657
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300658 mmc->scr[0] = __be32_to_cpu(scr[0]);
659 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500660
661 switch ((mmc->scr[0] >> 24) & 0xf) {
662 case 0:
663 mmc->version = SD_VERSION_1_0;
664 break;
665 case 1:
666 mmc->version = SD_VERSION_1_10;
667 break;
668 case 2:
669 mmc->version = SD_VERSION_2;
Jaehoon Chungd552bd12013-01-29 22:58:16 +0000670 if ((mmc->scr[0] >> 15) & 0x1)
671 mmc->version = SD_VERSION_3;
Andy Flemingad347bb2008-10-30 16:41:01 -0500672 break;
673 default:
674 mmc->version = SD_VERSION_1_0;
675 break;
676 }
677
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530678 if (mmc->scr[0] & SD_DATA_4BIT)
679 mmc->card_caps |= MMC_MODE_4BIT;
680
Andy Flemingad347bb2008-10-30 16:41:01 -0500681 /* Version 1.0 doesn't support switching */
682 if (mmc->version == SD_VERSION_1_0)
683 return 0;
684
685 timeout = 4;
686 while (timeout--) {
687 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +0000688 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500689
690 if (err)
691 return err;
692
693 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300694 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500695 break;
696 }
697
Andy Flemingad347bb2008-10-30 16:41:01 -0500698 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300699 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500700 return 0;
701
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000702 /*
703 * If the host doesn't support SD_HIGHSPEED, do not switch card to
704 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
705 * This can avoid furthur problem when the card runs in different
706 * mode between the host.
707 */
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200708 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
709 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000710 return 0;
711
Anton staaf9b00f0d2011-10-03 13:54:59 +0000712 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500713
714 if (err)
715 return err;
716
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300717 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500718 mmc->card_caps |= MMC_MODE_HS;
719
720 return 0;
721}
722
723/* frequency bases */
724/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000725static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500726 10000,
727 100000,
728 1000000,
729 10000000,
730};
731
732/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
733 * to platforms without floating point.
734 */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000735static const int multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500736 0, /* reserved */
737 10,
738 12,
739 13,
740 15,
741 20,
742 25,
743 30,
744 35,
745 40,
746 45,
747 50,
748 55,
749 60,
750 70,
751 80,
752};
753
Kim Phillips87ea3892012-10-29 13:34:43 +0000754static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500755{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200756 if (mmc->cfg->ops->set_ios)
757 mmc->cfg->ops->set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -0500758}
759
760void mmc_set_clock(struct mmc *mmc, uint clock)
761{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200762 if (clock > mmc->cfg->f_max)
763 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -0500764
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200765 if (clock < mmc->cfg->f_min)
766 clock = mmc->cfg->f_min;
Andy Flemingad347bb2008-10-30 16:41:01 -0500767
768 mmc->clock = clock;
769
770 mmc_set_ios(mmc);
771}
772
Kim Phillips87ea3892012-10-29 13:34:43 +0000773static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -0500774{
775 mmc->bus_width = width;
776
777 mmc_set_ios(mmc);
778}
779
Kim Phillips87ea3892012-10-29 13:34:43 +0000780static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500781{
Stephen Warrene315ae82013-06-11 15:14:01 -0600782 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -0500783 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000784 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -0500785 struct mmc_cmd cmd;
Simon Glassa09c2b72013-04-03 08:54:30 +0000786 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
787 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000788 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500789
Thomas Chou1254c3d2010-12-24 13:12:21 +0000790#ifdef CONFIG_MMC_SPI_CRC_ON
791 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
792 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
793 cmd.resp_type = MMC_RSP_R1;
794 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000795 err = mmc_send_cmd(mmc, &cmd, NULL);
796
797 if (err)
798 return err;
799 }
800#endif
801
Andy Flemingad347bb2008-10-30 16:41:01 -0500802 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000803 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
804 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -0500805 cmd.resp_type = MMC_RSP_R2;
806 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500807
808 err = mmc_send_cmd(mmc, &cmd, NULL);
809
810 if (err)
811 return err;
812
813 memcpy(mmc->cid, cmd.response, 16);
814
815 /*
816 * For MMC cards, set the Relative Address.
817 * For SD cards, get the Relatvie Address.
818 * This also puts the cards into Standby State
819 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000820 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
821 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
822 cmd.cmdarg = mmc->rca << 16;
823 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -0500824
Thomas Chou1254c3d2010-12-24 13:12:21 +0000825 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500826
Thomas Chou1254c3d2010-12-24 13:12:21 +0000827 if (err)
828 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500829
Thomas Chou1254c3d2010-12-24 13:12:21 +0000830 if (IS_SD(mmc))
831 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
832 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500833
834 /* Get the Card-Specific Data */
835 cmd.cmdidx = MMC_CMD_SEND_CSD;
836 cmd.resp_type = MMC_RSP_R2;
837 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500838
839 err = mmc_send_cmd(mmc, &cmd, NULL);
840
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000841 /* Waiting for the ready status */
842 mmc_send_status(mmc, timeout);
843
Andy Flemingad347bb2008-10-30 16:41:01 -0500844 if (err)
845 return err;
846
Rabin Vincentb6eed942009-04-05 13:30:56 +0530847 mmc->csd[0] = cmd.response[0];
848 mmc->csd[1] = cmd.response[1];
849 mmc->csd[2] = cmd.response[2];
850 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -0500851
852 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530853 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500854
855 switch (version) {
856 case 0:
857 mmc->version = MMC_VERSION_1_2;
858 break;
859 case 1:
860 mmc->version = MMC_VERSION_1_4;
861 break;
862 case 2:
863 mmc->version = MMC_VERSION_2_2;
864 break;
865 case 3:
866 mmc->version = MMC_VERSION_3;
867 break;
868 case 4:
869 mmc->version = MMC_VERSION_4;
870 break;
871 default:
872 mmc->version = MMC_VERSION_1_2;
873 break;
874 }
875 }
876
877 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530878 freq = fbase[(cmd.response[0] & 0x7)];
879 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -0500880
881 mmc->tran_speed = freq * mult;
882
Markus Niebel03951412013-12-16 13:40:46 +0100883 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +0530884 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500885
886 if (IS_SD(mmc))
887 mmc->write_bl_len = mmc->read_bl_len;
888 else
Rabin Vincentb6eed942009-04-05 13:30:56 +0530889 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500890
891 if (mmc->high_capacity) {
892 csize = (mmc->csd[1] & 0x3f) << 16
893 | (mmc->csd[2] & 0xffff0000) >> 16;
894 cmult = 8;
895 } else {
896 csize = (mmc->csd[1] & 0x3ff) << 2
897 | (mmc->csd[2] & 0xc0000000) >> 30;
898 cmult = (mmc->csd[2] & 0x00038000) >> 15;
899 }
900
Stephen Warrene315ae82013-06-11 15:14:01 -0600901 mmc->capacity_user = (csize + 1) << (cmult + 2);
902 mmc->capacity_user *= mmc->read_bl_len;
903 mmc->capacity_boot = 0;
904 mmc->capacity_rpmb = 0;
905 for (i = 0; i < 4; i++)
906 mmc->capacity_gp[i] = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500907
Simon Glassa09c2b72013-04-03 08:54:30 +0000908 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
909 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500910
Simon Glassa09c2b72013-04-03 08:54:30 +0000911 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
912 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500913
Markus Niebel03951412013-12-16 13:40:46 +0100914 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
915 cmd.cmdidx = MMC_CMD_SET_DSR;
916 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
917 cmd.resp_type = MMC_RSP_NONE;
918 if (mmc_send_cmd(mmc, &cmd, NULL))
919 printf("MMC: SET_DSR failed\n");
920 }
921
Andy Flemingad347bb2008-10-30 16:41:01 -0500922 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000923 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
924 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +0000925 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000926 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000927 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500928
Thomas Chou1254c3d2010-12-24 13:12:21 +0000929 if (err)
930 return err;
931 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500932
Lei Wenea526762011-06-22 17:03:31 +0000933 /*
934 * For SD, its erase group is always one sector
935 */
936 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +0000937 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530938 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
939 /* check ext_csd version and capacity */
940 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillips87ea3892012-10-29 13:34:43 +0000941 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000942 /*
943 * According to the JEDEC Standard, the value of
944 * ext_csd's capacity is valid if the value is more
945 * than 2GB
946 */
Lei Wen217467f2011-10-03 20:35:10 +0000947 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
948 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
949 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
950 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glassa09c2b72013-04-03 08:54:30 +0000951 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +0000952 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -0600953 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530954 }
Lei Wen31b99802011-05-02 16:26:26 +0000955
Jaehoon Chung6108ef62013-01-29 19:31:16 +0000956 switch (ext_csd[EXT_CSD_REV]) {
957 case 1:
958 mmc->version = MMC_VERSION_4_1;
959 break;
960 case 2:
961 mmc->version = MMC_VERSION_4_2;
962 break;
963 case 3:
964 mmc->version = MMC_VERSION_4_3;
965 break;
966 case 5:
967 mmc->version = MMC_VERSION_4_41;
968 break;
969 case 6:
970 mmc->version = MMC_VERSION_4_5;
971 break;
972 }
973
Lei Wenea526762011-06-22 17:03:31 +0000974 /*
Oliver Metzb3f14092013-10-01 20:32:07 +0200975 * Host needs to enable ERASE_GRP_DEF bit if device is
976 * partitioned. This bit will be lost every time after a reset
977 * or power off. This will affect erase size.
Lei Wenea526762011-06-22 17:03:31 +0000978 */
Oliver Metzb3f14092013-10-01 20:32:07 +0200979 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
980 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
981 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
982 EXT_CSD_ERASE_GROUP_DEF, 1);
983
984 if (err)
985 return err;
986
987 /* Read out group size from ext_csd */
Lei Wen217467f2011-10-03 20:35:10 +0000988 mmc->erase_grp_size =
Simon Glassa09c2b72013-04-03 08:54:30 +0000989 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
990 MMC_MAX_BLOCK_LEN * 1024;
991 } else {
Oliver Metzb3f14092013-10-01 20:32:07 +0200992 /* Calculate the group size from the csd value. */
Lei Wenea526762011-06-22 17:03:31 +0000993 int erase_gsz, erase_gmul;
994 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
995 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
996 mmc->erase_grp_size = (erase_gsz + 1)
997 * (erase_gmul + 1);
998 }
999
Lei Wen31b99802011-05-02 16:26:26 +00001000 /* store the partition info of emmc */
Stephen Warren009784c2012-07-30 10:55:43 +00001001 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1002 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen217467f2011-10-03 20:35:10 +00001003 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrene315ae82013-06-11 15:14:01 -06001004
1005 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1006
1007 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1008
1009 for (i = 0; i < 4; i++) {
1010 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1011 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1012 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1013 mmc->capacity_gp[i] *=
1014 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1015 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1016 }
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301017 }
1018
Stephen Warrene315ae82013-06-11 15:14:01 -06001019 err = mmc_set_capacity(mmc, mmc->part_num);
1020 if (err)
1021 return err;
1022
Andy Flemingad347bb2008-10-30 16:41:01 -05001023 if (IS_SD(mmc))
1024 err = sd_change_freq(mmc);
1025 else
1026 err = mmc_change_freq(mmc);
1027
1028 if (err)
1029 return err;
1030
1031 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001032 mmc->card_caps &= mmc->cfg->host_caps;
Andy Flemingad347bb2008-10-30 16:41:01 -05001033
1034 if (IS_SD(mmc)) {
1035 if (mmc->card_caps & MMC_MODE_4BIT) {
1036 cmd.cmdidx = MMC_CMD_APP_CMD;
1037 cmd.resp_type = MMC_RSP_R1;
1038 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001039
1040 err = mmc_send_cmd(mmc, &cmd, NULL);
1041 if (err)
1042 return err;
1043
1044 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1045 cmd.resp_type = MMC_RSP_R1;
1046 cmd.cmdarg = 2;
Andy Flemingad347bb2008-10-30 16:41:01 -05001047 err = mmc_send_cmd(mmc, &cmd, NULL);
1048 if (err)
1049 return err;
1050
1051 mmc_set_bus_width(mmc, 4);
1052 }
1053
1054 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001055 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001056 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001057 mmc->tran_speed = 25000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001058 } else {
Andy Flemingeb766ad2012-10-31 19:02:38 +00001059 int idx;
1060
1061 /* An array of possible bus widths in order of preference */
1062 static unsigned ext_csd_bits[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001063 EXT_CSD_DDR_BUS_WIDTH_8,
1064 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001065 EXT_CSD_BUS_WIDTH_8,
1066 EXT_CSD_BUS_WIDTH_4,
1067 EXT_CSD_BUS_WIDTH_1,
1068 };
1069
1070 /* An array to map CSD bus widths to host cap bits */
1071 static unsigned ext_to_hostcaps[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001072 [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
1073 [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001074 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1075 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1076 };
1077
1078 /* An array to map chosen bus width to an integer */
1079 static unsigned widths[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001080 8, 4, 8, 4, 1,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001081 };
1082
1083 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1084 unsigned int extw = ext_csd_bits[idx];
1085
1086 /*
1087 * Check to make sure the controller supports
1088 * this bus width, if it's more than 1
1089 */
1090 if (extw != EXT_CSD_BUS_WIDTH_1 &&
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001091 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Flemingeb766ad2012-10-31 19:02:38 +00001092 continue;
1093
Andy Flemingad347bb2008-10-30 16:41:01 -05001094 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001095 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001096
1097 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001098 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001099
Andy Flemingeb766ad2012-10-31 19:02:38 +00001100 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001101
Lei Wen4f5a6a52011-10-03 20:35:11 +00001102 err = mmc_send_ext_csd(mmc, test_csd);
1103 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1104 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1105 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1106 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1107 && ext_csd[EXT_CSD_REV] \
1108 == test_csd[EXT_CSD_REV]
1109 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1110 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1111 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1112 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Flemingad347bb2008-10-30 16:41:01 -05001113
Andy Flemingeb766ad2012-10-31 19:02:38 +00001114 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen4f5a6a52011-10-03 20:35:11 +00001115 break;
1116 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001117 }
1118
1119 if (mmc->card_caps & MMC_MODE_HS) {
1120 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001121 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001122 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001123 mmc->tran_speed = 26000000;
1124 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001125 }
1126
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001127 mmc_set_clock(mmc, mmc->tran_speed);
1128
Andy Flemingad347bb2008-10-30 16:41:01 -05001129 /* fill in device description */
1130 mmc->block_dev.lun = 0;
1131 mmc->block_dev.type = 0;
1132 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich2eec2ab2013-04-09 21:11:56 +00001133 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent69d4e2c2009-04-05 13:30:54 +05301134 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001135#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Hutt7367ec22012-10-20 17:15:59 +00001136 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1137 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1138 (mmc->cid[3] >> 16) & 0xffff);
1139 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1140 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1141 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1142 (mmc->cid[2] >> 24) & 0xff);
1143 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1144 (mmc->cid[2] >> 16) & 0xf);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001145#else
1146 mmc->block_dev.vendor[0] = 0;
1147 mmc->block_dev.product[0] = 0;
1148 mmc->block_dev.revision[0] = 0;
1149#endif
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001150#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001151 init_part(&mmc->block_dev);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001152#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001153
1154 return 0;
1155}
1156
Kim Phillips87ea3892012-10-29 13:34:43 +00001157static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001158{
1159 struct mmc_cmd cmd;
1160 int err;
1161
1162 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1163 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001164 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05001165 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001166
1167 err = mmc_send_cmd(mmc, &cmd, NULL);
1168
1169 if (err)
1170 return err;
1171
Rabin Vincentb6eed942009-04-05 13:30:56 +05301172 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-10-30 16:41:01 -05001173 return UNUSABLE_ERR;
1174 else
1175 mmc->version = SD_VERSION_2;
1176
1177 return 0;
1178}
1179
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001180/* not used any more */
1181int __deprecated mmc_register(struct mmc *mmc)
1182{
1183#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1184 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1185#endif
1186 return -1;
1187}
1188
1189struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
Andy Flemingad347bb2008-10-30 16:41:01 -05001190{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001191 struct mmc *mmc;
1192
1193 /* quick validation */
1194 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1195 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1196 return NULL;
1197
1198 mmc = calloc(1, sizeof(*mmc));
1199 if (mmc == NULL)
1200 return NULL;
1201
1202 mmc->cfg = cfg;
1203 mmc->priv = priv;
1204
1205 /* the following chunk was mmc_register() */
1206
Markus Niebel03951412013-12-16 13:40:46 +01001207 /* Setup dsr related values */
1208 mmc->dsr_imp = 0;
1209 mmc->dsr = 0xffffffff;
Andy Flemingad347bb2008-10-30 16:41:01 -05001210 /* Setup the universal parts of the block interface just once */
1211 mmc->block_dev.if_type = IF_TYPE_MMC;
1212 mmc->block_dev.dev = cur_dev_num++;
1213 mmc->block_dev.removable = 1;
1214 mmc->block_dev.block_read = mmc_bread;
1215 mmc->block_dev.block_write = mmc_bwrite;
Lei Wenea526762011-06-22 17:03:31 +00001216 mmc->block_dev.block_erase = mmc_berase;
Andy Flemingad347bb2008-10-30 16:41:01 -05001217
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001218 /* setup initial part type */
1219 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Flemingad347bb2008-10-30 16:41:01 -05001220
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001221 INIT_LIST_HEAD(&mmc->link);
Andy Flemingad347bb2008-10-30 16:41:01 -05001222
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001223 list_add_tail(&mmc->link, &mmc_devices);
1224
1225 return mmc;
1226}
1227
1228void mmc_destroy(struct mmc *mmc)
1229{
1230 /* only freeing memory for now */
1231 free(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001232}
1233
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001234#ifdef CONFIG_PARTITIONS
Andy Flemingad347bb2008-10-30 16:41:01 -05001235block_dev_desc_t *mmc_get_dev(int dev)
1236{
1237 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6ce8aed2012-08-10 08:59:12 +00001238 if (!mmc || mmc_init(mmc))
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001239 return NULL;
Andy Flemingad347bb2008-10-30 16:41:01 -05001240
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001241 return &mmc->block_dev;
Andy Flemingad347bb2008-10-30 16:41:01 -05001242}
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001243#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001244
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001245int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001246{
Macpaul Lin028bde12011-11-14 23:35:39 +00001247 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001248
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001249 /* we pretend there's no card when init is NULL */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001250 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Redingb9c8b772012-01-02 01:15:37 +00001251 mmc->has_init = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001252#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001253 printf("MMC: no card present\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001254#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +00001255 return NO_CARD_ERR;
1256 }
1257
Lei Wen31b99802011-05-02 16:26:26 +00001258 if (mmc->has_init)
1259 return 0;
1260
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001261 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001262 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001263
1264 if (err)
1265 return err;
1266
Ilya Yanok8459aab2009-06-29 17:53:16 +04001267 mmc_set_bus_width(mmc, 1);
1268 mmc_set_clock(mmc, 1);
1269
Andy Flemingad347bb2008-10-30 16:41:01 -05001270 /* Reset the Card */
1271 err = mmc_go_idle(mmc);
1272
1273 if (err)
1274 return err;
1275
Lei Wen31b99802011-05-02 16:26:26 +00001276 /* The internal partition reset to user partition(0) at every CMD0*/
1277 mmc->part_num = 0;
1278
Andy Flemingad347bb2008-10-30 16:41:01 -05001279 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001280 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001281
Andy Flemingad347bb2008-10-30 16:41:01 -05001282 /* Now try to get the SD card's operating condition */
1283 err = sd_send_op_cond(mmc);
1284
1285 /* If the command timed out, we check for an MMC card */
1286 if (err == TIMEOUT) {
1287 err = mmc_send_op_cond(mmc);
1288
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001289 if (err && err != IN_PROGRESS) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001290#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001291 printf("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001292#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001293 return UNUSABLE_ERR;
1294 }
1295 }
1296
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001297 if (err == IN_PROGRESS)
1298 mmc->init_in_progress = 1;
1299
1300 return err;
1301}
1302
1303static int mmc_complete_init(struct mmc *mmc)
1304{
1305 int err = 0;
1306
1307 if (mmc->op_cond_pending)
1308 err = mmc_complete_op_cond(mmc);
1309
1310 if (!err)
1311 err = mmc_startup(mmc);
Lei Wen31b99802011-05-02 16:26:26 +00001312 if (err)
1313 mmc->has_init = 0;
1314 else
1315 mmc->has_init = 1;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001316 mmc->init_in_progress = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001317 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001318}
1319
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001320int mmc_init(struct mmc *mmc)
1321{
1322 int err = IN_PROGRESS;
1323 unsigned start = get_timer(0);
1324
1325 if (mmc->has_init)
1326 return 0;
1327 if (!mmc->init_in_progress)
1328 err = mmc_start_init(mmc);
1329
1330 if (!err || err == IN_PROGRESS)
1331 err = mmc_complete_init(mmc);
1332 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
1333 return err;
1334}
1335
Markus Niebel03951412013-12-16 13:40:46 +01001336int mmc_set_dsr(struct mmc *mmc, u16 val)
1337{
1338 mmc->dsr = val;
1339 return 0;
1340}
1341
Andy Flemingad347bb2008-10-30 16:41:01 -05001342/*
1343 * CPU and board-specific MMC initializations. Aliased function
1344 * signals caller to move on
1345 */
1346static int __def_mmc_init(bd_t *bis)
1347{
1348 return -1;
1349}
1350
Peter Tyser21d2cd22009-04-20 11:08:46 -05001351int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1352int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Flemingad347bb2008-10-30 16:41:01 -05001353
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001354#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1355
Andy Flemingad347bb2008-10-30 16:41:01 -05001356void print_mmc_devices(char separator)
1357{
1358 struct mmc *m;
1359 struct list_head *entry;
1360
1361 list_for_each(entry, &mmc_devices) {
1362 m = list_entry(entry, struct mmc, link);
1363
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001364 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Flemingad347bb2008-10-30 16:41:01 -05001365
1366 if (entry->next != &mmc_devices)
1367 printf("%c ", separator);
1368 }
1369
1370 printf("\n");
1371}
1372
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001373#else
1374void print_mmc_devices(char separator) { }
1375#endif
1376
Lei Wend430d7c2011-05-02 16:26:25 +00001377int get_mmc_num(void)
1378{
1379 return cur_dev_num;
1380}
1381
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001382void mmc_set_preinit(struct mmc *mmc, int preinit)
1383{
1384 mmc->preinit = preinit;
1385}
1386
1387static void do_preinit(void)
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
1395 if (m->preinit)
1396 mmc_start_init(m);
1397 }
1398}
1399
1400
Andy Flemingad347bb2008-10-30 16:41:01 -05001401int mmc_initialize(bd_t *bis)
1402{
1403 INIT_LIST_HEAD (&mmc_devices);
1404 cur_dev_num = 0;
1405
1406 if (board_mmc_init(bis) < 0)
1407 cpu_mmc_init(bis);
1408
Ying Zhang9ff70262013-08-16 15:16:11 +08001409#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05001410 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08001411#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001412
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001413 do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001414 return 0;
1415}
Amar1104e9b2013-04-27 11:42:58 +05301416
1417#ifdef CONFIG_SUPPORT_EMMC_BOOT
1418/*
1419 * This function changes the size of boot partition and the size of rpmb
1420 * partition present on EMMC devices.
1421 *
1422 * Input Parameters:
1423 * struct *mmc: pointer for the mmc device strcuture
1424 * bootsize: size of boot partition
1425 * rpmbsize: size of rpmb partition
1426 *
1427 * Returns 0 on success.
1428 */
1429
1430int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1431 unsigned long rpmbsize)
1432{
1433 int err;
1434 struct mmc_cmd cmd;
1435
1436 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1437 cmd.cmdidx = MMC_CMD_RES_MAN;
1438 cmd.resp_type = MMC_RSP_R1b;
1439 cmd.cmdarg = MMC_CMD62_ARG1;
1440
1441 err = mmc_send_cmd(mmc, &cmd, NULL);
1442 if (err) {
1443 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1444 return err;
1445 }
1446
1447 /* Boot partition changing mode */
1448 cmd.cmdidx = MMC_CMD_RES_MAN;
1449 cmd.resp_type = MMC_RSP_R1b;
1450 cmd.cmdarg = MMC_CMD62_ARG2;
1451
1452 err = mmc_send_cmd(mmc, &cmd, NULL);
1453 if (err) {
1454 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1455 return err;
1456 }
1457 /* boot partition size is multiple of 128KB */
1458 bootsize = (bootsize * 1024) / 128;
1459
1460 /* Arg: boot partition size */
1461 cmd.cmdidx = MMC_CMD_RES_MAN;
1462 cmd.resp_type = MMC_RSP_R1b;
1463 cmd.cmdarg = bootsize;
1464
1465 err = mmc_send_cmd(mmc, &cmd, NULL);
1466 if (err) {
1467 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1468 return err;
1469 }
1470 /* RPMB partition size is multiple of 128KB */
1471 rpmbsize = (rpmbsize * 1024) / 128;
1472 /* Arg: RPMB partition size */
1473 cmd.cmdidx = MMC_CMD_RES_MAN;
1474 cmd.resp_type = MMC_RSP_R1b;
1475 cmd.cmdarg = rpmbsize;
1476
1477 err = mmc_send_cmd(mmc, &cmd, NULL);
1478 if (err) {
1479 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1480 return err;
1481 }
1482 return 0;
1483}
1484
1485/*
Tom Rini4cf854c2014-02-05 10:24:22 -05001486 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1487 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1488 * and BOOT_MODE.
1489 *
1490 * Returns 0 on success.
1491 */
1492int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1493{
1494 int err;
1495
1496 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1497 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1498 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1499 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1500
1501 if (err)
1502 return err;
1503 return 0;
1504}
1505
1506/*
Tom Rinif8c6f792014-02-05 10:24:21 -05001507 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1508 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1509 * PARTITION_ACCESS.
1510 *
1511 * Returns 0 on success.
1512 */
1513int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1514{
1515 int err;
1516
1517 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1518 EXT_CSD_BOOT_ACK(ack) |
1519 EXT_CSD_BOOT_PART_NUM(part_num) |
1520 EXT_CSD_PARTITION_ACCESS(access));
1521
1522 if (err)
1523 return err;
1524 return 0;
1525}
Tom Rini35a3ea12014-02-07 14:15:20 -05001526
1527/*
1528 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1529 * for enable. Note that this is a write-once field for non-zero values.
1530 *
1531 * Returns 0 on success.
1532 */
1533int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1534{
1535 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1536 enable);
1537}
Amar1104e9b2013-04-27 11:42:58 +05301538#endif