blob: afb11b9e7d543fea5f789f13aed3769a290b486c [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>
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -060013#include <dm.h>
14#include <dm/device-internal.h>
Stephen Warrenbf0c7852014-05-23 12:47:06 -060015#include <errno.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050016#include <mmc.h>
17#include <part.h>
18#include <malloc.h>
Simon Glass2dd337a2015-09-02 17:24:58 -060019#include <memalign.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050020#include <linux/list.h>
Rabin Vincent69d4e2c2009-04-05 13:30:54 +053021#include <div64.h>
Paul Burton8d30cc92013-09-09 15:30:26 +010022#include "mmc_private.h"
Andy Flemingad347bb2008-10-30 16:41:01 -050023
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +020024__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanov020f2612012-12-03 02:19:46 +000025{
26 return -1;
27}
28
29int mmc_getwp(struct mmc *mmc)
30{
31 int wp;
32
33 wp = board_mmc_getwp(mmc);
34
Peter Korsgaardf7b15102013-03-21 04:00:03 +000035 if (wp < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +020036 if (mmc->cfg->ops->getwp)
37 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +000038 else
39 wp = 0;
40 }
Nikita Kiryanov020f2612012-12-03 02:19:46 +000041
42 return wp;
43}
44
Jeroen Hofstee47726302014-07-10 22:46:28 +020045__weak int board_mmc_getcd(struct mmc *mmc)
46{
Stefano Babic6e00edf2010-02-05 15:04:43 +010047 return -1;
48}
49
Simon Glassb23d96e2016-06-12 23:30:20 -060050#ifdef CONFIG_MMC_TRACE
51void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
Andy Flemingad347bb2008-10-30 16:41:01 -050052{
Simon Glassb23d96e2016-06-12 23:30:20 -060053 printf("CMD_SEND:%d\n", cmd->cmdidx);
54 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
55}
Marek Vasutdccb6082012-03-15 18:41:35 +000056
Simon Glassb23d96e2016-06-12 23:30:20 -060057void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
58{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000059 int i;
60 u8 *ptr;
61
Bin Meng8d1ad1e2016-03-17 21:53:14 -070062 if (ret) {
63 printf("\t\tRET\t\t\t %d\n", ret);
64 } else {
65 switch (cmd->resp_type) {
66 case MMC_RSP_NONE:
67 printf("\t\tMMC_RSP_NONE\n");
68 break;
69 case MMC_RSP_R1:
70 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
71 cmd->response[0]);
72 break;
73 case MMC_RSP_R1b:
74 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
75 cmd->response[0]);
76 break;
77 case MMC_RSP_R2:
78 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
79 cmd->response[0]);
80 printf("\t\t \t\t 0x%08X \n",
81 cmd->response[1]);
82 printf("\t\t \t\t 0x%08X \n",
83 cmd->response[2]);
84 printf("\t\t \t\t 0x%08X \n",
85 cmd->response[3]);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000086 printf("\n");
Bin Meng8d1ad1e2016-03-17 21:53:14 -070087 printf("\t\t\t\t\tDUMPING DATA\n");
88 for (i = 0; i < 4; i++) {
89 int j;
90 printf("\t\t\t\t\t%03d - ", i*4);
91 ptr = (u8 *)&cmd->response[i];
92 ptr += 3;
93 for (j = 0; j < 4; j++)
94 printf("%02X ", *ptr--);
95 printf("\n");
96 }
97 break;
98 case MMC_RSP_R3:
99 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
100 cmd->response[0]);
101 break;
102 default:
103 printf("\t\tERROR MMC rsp not supported\n");
104 break;
Bin Meng4a4ef872016-03-17 21:53:13 -0700105 }
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000106 }
Simon Glassb23d96e2016-06-12 23:30:20 -0600107}
108
109void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
110{
111 int status;
112
113 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
114 printf("CURR STATE:%d\n", status);
115}
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000116#endif
Simon Glassb23d96e2016-06-12 23:30:20 -0600117
118int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
119{
120 int ret;
121
122 mmmc_trace_before_send(mmc, cmd);
123 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
124 mmmc_trace_after_send(mmc, cmd, ret);
125
Marek Vasutdccb6082012-03-15 18:41:35 +0000126 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500127}
128
Paul Burton8d30cc92013-09-09 15:30:26 +0100129int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000130{
131 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000132 int err, retries = 5;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000133
134 cmd.cmdidx = MMC_CMD_SEND_STATUS;
135 cmd.resp_type = MMC_RSP_R1;
Marek Vasutc4427392011-08-10 09:24:48 +0200136 if (!mmc_host_is_spi(mmc))
137 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000138
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500139 while (1) {
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000140 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-02-05 22:29:12 +0000141 if (!err) {
142 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
143 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
144 MMC_STATE_PRG)
145 break;
146 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100147#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzke31789322012-02-05 22:29:12 +0000148 printf("Status Error: 0x%08X\n",
149 cmd.response[0]);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100150#endif
Jan Kloetzke31789322012-02-05 22:29:12 +0000151 return COMM_ERR;
152 }
153 } else if (--retries < 0)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000154 return err;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000155
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500156 if (timeout-- <= 0)
157 break;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000158
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500159 udelay(1000);
160 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000161
Simon Glassb23d96e2016-06-12 23:30:20 -0600162 mmc_trace_state(mmc, &cmd);
Jongman Heo1be00d92012-06-03 21:32:13 +0000163 if (timeout <= 0) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100164#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000165 printf("Timeout waiting card ready\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100166#endif
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000167 return TIMEOUT;
168 }
169
170 return 0;
171}
172
Paul Burton8d30cc92013-09-09 15:30:26 +0100173int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500174{
175 struct mmc_cmd cmd;
176
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -0600177 if (mmc->ddr_mode)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900178 return 0;
179
Andy Flemingad347bb2008-10-30 16:41:01 -0500180 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
181 cmd.resp_type = MMC_RSP_R1;
182 cmd.cmdarg = len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500183
184 return mmc_send_cmd(mmc, &cmd, NULL);
185}
186
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200187static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000188 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500189{
190 struct mmc_cmd cmd;
191 struct mmc_data data;
192
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700193 if (blkcnt > 1)
194 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
195 else
196 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500197
198 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700199 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500200 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700201 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500202
203 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500204
205 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700206 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500207 data.blocksize = mmc->read_bl_len;
208 data.flags = MMC_DATA_READ;
209
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700210 if (mmc_send_cmd(mmc, &cmd, &data))
211 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500212
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700213 if (blkcnt > 1) {
214 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
215 cmd.cmdarg = 0;
216 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700217 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100218#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700219 printf("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100220#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700221 return 0;
222 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500223 }
224
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700225 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500226}
227
Simon Glass59bc6f22016-05-01 13:52:41 -0600228#ifdef CONFIG_BLK
Simon Glass62e293a2016-06-12 23:30:15 -0600229ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600230#else
Simon Glass62e293a2016-06-12 23:30:15 -0600231ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
232 void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600233#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500234{
Simon Glass59bc6f22016-05-01 13:52:41 -0600235#ifdef CONFIG_BLK
236 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
237#endif
Simon Glass2f26fff2016-02-29 15:25:51 -0700238 int dev_num = block_dev->devnum;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700239 int err;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700240 lbaint_t cur, blocks_todo = blkcnt;
241
242 if (blkcnt == 0)
243 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500244
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700245 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500246 if (!mmc)
247 return 0;
248
Simon Glass11f2bb62016-05-01 13:52:29 -0600249 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700250 if (err < 0)
251 return 0;
252
Simon Glasse5db1152016-05-01 13:52:35 -0600253 if ((start + blkcnt) > block_dev->lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100254#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200255 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glasse5db1152016-05-01 13:52:35 -0600256 start + blkcnt, block_dev->lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100257#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800258 return 0;
259 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500260
Simon Glassa4343c42015-06-23 15:38:50 -0600261 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
262 debug("%s: Failed to set blocklen\n", __func__);
Andy Flemingad347bb2008-10-30 16:41:01 -0500263 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600264 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500265
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700266 do {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200267 cur = (blocks_todo > mmc->cfg->b_max) ?
268 mmc->cfg->b_max : blocks_todo;
Simon Glassa4343c42015-06-23 15:38:50 -0600269 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
270 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700271 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600272 }
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700273 blocks_todo -= cur;
274 start += cur;
275 dst += cur * mmc->read_bl_len;
276 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500277
278 return blkcnt;
279}
280
Kim Phillips87ea3892012-10-29 13:34:43 +0000281static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500282{
283 struct mmc_cmd cmd;
284 int err;
285
286 udelay(1000);
287
288 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
289 cmd.cmdarg = 0;
290 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500291
292 err = mmc_send_cmd(mmc, &cmd, NULL);
293
294 if (err)
295 return err;
296
297 udelay(2000);
298
299 return 0;
300}
301
Kim Phillips87ea3892012-10-29 13:34:43 +0000302static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500303{
304 int timeout = 1000;
305 int err;
306 struct mmc_cmd cmd;
307
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500308 while (1) {
Andy Flemingad347bb2008-10-30 16:41:01 -0500309 cmd.cmdidx = MMC_CMD_APP_CMD;
310 cmd.resp_type = MMC_RSP_R1;
311 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500312
313 err = mmc_send_cmd(mmc, &cmd, NULL);
314
315 if (err)
316 return err;
317
318 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
319 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100320
321 /*
322 * Most cards do not answer if some reserved bits
323 * in the ocr are set. However, Some controller
324 * can set bit 7 (reserved for low voltages), but
325 * how to manage low voltages SD card is not yet
326 * specified.
327 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000328 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200329 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500330
331 if (mmc->version == SD_VERSION_2)
332 cmd.cmdarg |= OCR_HCS;
333
334 err = mmc_send_cmd(mmc, &cmd, NULL);
335
336 if (err)
337 return err;
338
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500339 if (cmd.response[0] & OCR_BUSY)
340 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500341
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500342 if (timeout-- <= 0)
343 return UNUSABLE_ERR;
344
345 udelay(1000);
346 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500347
348 if (mmc->version != SD_VERSION_2)
349 mmc->version = SD_VERSION_1_0;
350
Thomas Chou1254c3d2010-12-24 13:12:21 +0000351 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
352 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
353 cmd.resp_type = MMC_RSP_R3;
354 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000355
356 err = mmc_send_cmd(mmc, &cmd, NULL);
357
358 if (err)
359 return err;
360 }
361
Rabin Vincentb6eed942009-04-05 13:30:56 +0530362 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500363
364 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
365 mmc->rca = 0;
366
367 return 0;
368}
369
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500370static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Flemingad347bb2008-10-30 16:41:01 -0500371{
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500372 struct mmc_cmd cmd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500373 int err;
374
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500375 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
376 cmd.resp_type = MMC_RSP_R3;
377 cmd.cmdarg = 0;
Rob Herring5fd3edd2015-03-23 17:56:59 -0500378 if (use_arg && !mmc_host_is_spi(mmc))
379 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200380 (mmc->cfg->voltages &
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500381 (mmc->ocr & OCR_VOLTAGE_MASK)) |
382 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000383
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500384 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000385 if (err)
386 return err;
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500387 mmc->ocr = cmd.response[0];
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000388 return 0;
389}
390
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200391static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000392{
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000393 int err, i;
394
Andy Flemingad347bb2008-10-30 16:41:01 -0500395 /* Some cards seem to need this */
396 mmc_go_idle(mmc);
397
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000398 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000399 for (i = 0; i < 2; i++) {
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500400 err = mmc_send_op_cond_iter(mmc, i != 0);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000401 if (err)
402 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200403
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000404 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500405 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500406 break;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000407 }
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500408 mmc->op_cond_pending = 1;
409 return 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000410}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200411
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200412static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000413{
414 struct mmc_cmd cmd;
415 int timeout = 1000;
416 uint start;
417 int err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200418
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000419 mmc->op_cond_pending = 0;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500420 if (!(mmc->ocr & OCR_BUSY)) {
421 start = get_timer(0);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500422 while (1) {
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500423 err = mmc_send_op_cond_iter(mmc, 1);
424 if (err)
425 return err;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500426 if (mmc->ocr & OCR_BUSY)
427 break;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500428 if (get_timer(start) > timeout)
429 return UNUSABLE_ERR;
430 udelay(100);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500431 }
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500432 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500433
Thomas Chou1254c3d2010-12-24 13:12:21 +0000434 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
435 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
436 cmd.resp_type = MMC_RSP_R3;
437 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000438
439 err = mmc_send_cmd(mmc, &cmd, NULL);
440
441 if (err)
442 return err;
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500443
444 mmc->ocr = cmd.response[0];
Thomas Chou1254c3d2010-12-24 13:12:21 +0000445 }
446
Andy Flemingad347bb2008-10-30 16:41:01 -0500447 mmc->version = MMC_VERSION_UNKNOWN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500448
449 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700450 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500451
452 return 0;
453}
454
455
Kim Phillips87ea3892012-10-29 13:34:43 +0000456static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500457{
458 struct mmc_cmd cmd;
459 struct mmc_data data;
460 int err;
461
462 /* Get the Card Status Register */
463 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
464 cmd.resp_type = MMC_RSP_R1;
465 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500466
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000467 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500468 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000469 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500470 data.flags = MMC_DATA_READ;
471
472 err = mmc_send_cmd(mmc, &cmd, &data);
473
474 return err;
475}
476
Simon Glass84f9df92016-06-12 23:30:18 -0600477int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500478{
479 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000480 int timeout = 1000;
481 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500482
483 cmd.cmdidx = MMC_CMD_SWITCH;
484 cmd.resp_type = MMC_RSP_R1b;
485 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000486 (index << 16) |
487 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500488
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000489 ret = mmc_send_cmd(mmc, &cmd, NULL);
490
491 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000492 if (!ret)
493 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000494
495 return ret;
496
Andy Flemingad347bb2008-10-30 16:41:01 -0500497}
498
Kim Phillips87ea3892012-10-29 13:34:43 +0000499static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500500{
Simon Glassa09c2b72013-04-03 08:54:30 +0000501 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500502 char cardtype;
503 int err;
504
Andrew Gabbasovccb7b042014-12-25 10:22:25 -0600505 mmc->card_caps = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500506
Thomas Chou1254c3d2010-12-24 13:12:21 +0000507 if (mmc_host_is_spi(mmc))
508 return 0;
509
Andy Flemingad347bb2008-10-30 16:41:01 -0500510 /* Only version 4 supports high-speed */
511 if (mmc->version < MMC_VERSION_4)
512 return 0;
513
Andrew Gabbasovccb7b042014-12-25 10:22:25 -0600514 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
515
Andy Flemingad347bb2008-10-30 16:41:01 -0500516 err = mmc_send_ext_csd(mmc, ext_csd);
517
518 if (err)
519 return err;
520
Lei Wen217467f2011-10-03 20:35:10 +0000521 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500522
523 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
524
525 if (err)
Heiko Schocher9016ab92016-06-07 08:31:21 +0200526 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500527
528 /* Now check to see that it worked */
529 err = mmc_send_ext_csd(mmc, ext_csd);
530
531 if (err)
532 return err;
533
534 /* No high-speed support */
Lei Wen217467f2011-10-03 20:35:10 +0000535 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500536 return 0;
537
538 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900539 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov95a37132014-12-01 06:59:10 -0600540 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900541 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Flemingad347bb2008-10-30 16:41:01 -0500542 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900543 } else {
Andy Flemingad347bb2008-10-30 16:41:01 -0500544 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900545 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500546
547 return 0;
548}
549
Stephen Warrene315ae82013-06-11 15:14:01 -0600550static int mmc_set_capacity(struct mmc *mmc, int part_num)
551{
552 switch (part_num) {
553 case 0:
554 mmc->capacity = mmc->capacity_user;
555 break;
556 case 1:
557 case 2:
558 mmc->capacity = mmc->capacity_boot;
559 break;
560 case 3:
561 mmc->capacity = mmc->capacity_rpmb;
562 break;
563 case 4:
564 case 5:
565 case 6:
566 case 7:
567 mmc->capacity = mmc->capacity_gp[part_num - 4];
568 break;
569 default:
570 return -1;
571 }
572
Simon Glasse5db1152016-05-01 13:52:35 -0600573 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrene315ae82013-06-11 15:14:01 -0600574
575 return 0;
576}
577
Simon Glass62e293a2016-06-12 23:30:15 -0600578int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wen31b99802011-05-02 16:26:26 +0000579{
Stephen Warrene315ae82013-06-11 15:14:01 -0600580 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000581
Stephen Warrene315ae82013-06-11 15:14:01 -0600582 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
583 (mmc->part_config & ~PART_ACCESS_MASK)
584 | (part_num & PART_ACCESS_MASK));
Peter Bigot45fde892014-09-02 18:31:23 -0500585
586 /*
587 * Set the capacity if the switch succeeded or was intended
588 * to return to representing the raw device.
589 */
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700590 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot45fde892014-09-02 18:31:23 -0500591 ret = mmc_set_capacity(mmc, part_num);
Simon Glass984db5d2016-05-01 13:52:37 -0600592 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700593 }
Stephen Warrene315ae82013-06-11 15:14:01 -0600594
Peter Bigot45fde892014-09-02 18:31:23 -0500595 return ret;
Lei Wen31b99802011-05-02 16:26:26 +0000596}
597
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100598int mmc_hwpart_config(struct mmc *mmc,
599 const struct mmc_hwpart_conf *conf,
600 enum mmc_hwpart_conf_mode mode)
601{
602 u8 part_attrs = 0;
603 u32 enh_size_mult;
604 u32 enh_start_addr;
605 u32 gp_size_mult[4];
606 u32 max_enh_size_mult;
607 u32 tot_enh_size_mult = 0;
Diego Santa Cruz80200272014-12-23 10:50:31 +0100608 u8 wr_rel_set;
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100609 int i, pidx, err;
610 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
611
612 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
613 return -EINVAL;
614
615 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
616 printf("eMMC >= 4.4 required for enhanced user data area\n");
617 return -EMEDIUMTYPE;
618 }
619
620 if (!(mmc->part_support & PART_SUPPORT)) {
621 printf("Card does not support partitioning\n");
622 return -EMEDIUMTYPE;
623 }
624
625 if (!mmc->hc_wp_grp_size) {
626 printf("Card does not define HC WP group size\n");
627 return -EMEDIUMTYPE;
628 }
629
630 /* check partition alignment and total enhanced size */
631 if (conf->user.enh_size) {
632 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
633 conf->user.enh_start % mmc->hc_wp_grp_size) {
634 printf("User data enhanced area not HC WP group "
635 "size aligned\n");
636 return -EINVAL;
637 }
638 part_attrs |= EXT_CSD_ENH_USR;
639 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
640 if (mmc->high_capacity) {
641 enh_start_addr = conf->user.enh_start;
642 } else {
643 enh_start_addr = (conf->user.enh_start << 9);
644 }
645 } else {
646 enh_size_mult = 0;
647 enh_start_addr = 0;
648 }
649 tot_enh_size_mult += enh_size_mult;
650
651 for (pidx = 0; pidx < 4; pidx++) {
652 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
653 printf("GP%i partition not HC WP group size "
654 "aligned\n", pidx+1);
655 return -EINVAL;
656 }
657 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
658 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
659 part_attrs |= EXT_CSD_ENH_GP(pidx);
660 tot_enh_size_mult += gp_size_mult[pidx];
661 }
662 }
663
664 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
665 printf("Card does not support enhanced attribute\n");
666 return -EMEDIUMTYPE;
667 }
668
669 err = mmc_send_ext_csd(mmc, ext_csd);
670 if (err)
671 return err;
672
673 max_enh_size_mult =
674 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
675 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
676 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
677 if (tot_enh_size_mult > max_enh_size_mult) {
678 printf("Total enhanced size exceeds maximum (%u > %u)\n",
679 tot_enh_size_mult, max_enh_size_mult);
680 return -EMEDIUMTYPE;
681 }
682
Diego Santa Cruz80200272014-12-23 10:50:31 +0100683 /* The default value of EXT_CSD_WR_REL_SET is device
684 * dependent, the values can only be changed if the
685 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
686 * changed only once and before partitioning is completed. */
687 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
688 if (conf->user.wr_rel_change) {
689 if (conf->user.wr_rel_set)
690 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
691 else
692 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
693 }
694 for (pidx = 0; pidx < 4; pidx++) {
695 if (conf->gp_part[pidx].wr_rel_change) {
696 if (conf->gp_part[pidx].wr_rel_set)
697 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
698 else
699 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
700 }
701 }
702
703 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
704 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
705 puts("Card does not support host controlled partition write "
706 "reliability settings\n");
707 return -EMEDIUMTYPE;
708 }
709
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100710 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
711 EXT_CSD_PARTITION_SETTING_COMPLETED) {
712 printf("Card already partitioned\n");
713 return -EPERM;
714 }
715
716 if (mode == MMC_HWPART_CONF_CHECK)
717 return 0;
718
719 /* Partitioning requires high-capacity size definitions */
720 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
721 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
722 EXT_CSD_ERASE_GROUP_DEF, 1);
723
724 if (err)
725 return err;
726
727 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
728
729 /* update erase group size to be high-capacity */
730 mmc->erase_grp_size =
731 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
732
733 }
734
735 /* all OK, write the configuration */
736 for (i = 0; i < 4; i++) {
737 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
738 EXT_CSD_ENH_START_ADDR+i,
739 (enh_start_addr >> (i*8)) & 0xFF);
740 if (err)
741 return err;
742 }
743 for (i = 0; i < 3; i++) {
744 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
745 EXT_CSD_ENH_SIZE_MULT+i,
746 (enh_size_mult >> (i*8)) & 0xFF);
747 if (err)
748 return err;
749 }
750 for (pidx = 0; pidx < 4; pidx++) {
751 for (i = 0; i < 3; i++) {
752 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
753 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
754 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
755 if (err)
756 return err;
757 }
758 }
759 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
760 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
761 if (err)
762 return err;
763
764 if (mode == MMC_HWPART_CONF_SET)
765 return 0;
766
Diego Santa Cruz80200272014-12-23 10:50:31 +0100767 /* The WR_REL_SET is a write-once register but shall be
768 * written before setting PART_SETTING_COMPLETED. As it is
769 * write-once we can only write it when completing the
770 * partitioning. */
771 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
772 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
773 EXT_CSD_WR_REL_SET, wr_rel_set);
774 if (err)
775 return err;
776 }
777
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100778 /* Setting PART_SETTING_COMPLETED confirms the partition
779 * configuration but it only becomes effective after power
780 * cycle, so we do not adjust the partition related settings
781 * in the mmc struct. */
782
783 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
784 EXT_CSD_PARTITION_SETTING,
785 EXT_CSD_PARTITION_SETTING_COMPLETED);
786 if (err)
787 return err;
788
789 return 0;
790}
791
Thierry Redingb9c8b772012-01-02 01:15:37 +0000792int mmc_getcd(struct mmc *mmc)
793{
794 int cd;
795
796 cd = board_mmc_getcd(mmc);
797
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000798 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200799 if (mmc->cfg->ops->getcd)
800 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000801 else
802 cd = 1;
803 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000804
805 return cd;
806}
807
Kim Phillips87ea3892012-10-29 13:34:43 +0000808static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -0500809{
810 struct mmc_cmd cmd;
811 struct mmc_data data;
812
813 /* Switch the frequency */
814 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
815 cmd.resp_type = MMC_RSP_R1;
816 cmd.cmdarg = (mode << 31) | 0xffffff;
817 cmd.cmdarg &= ~(0xf << (group * 4));
818 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -0500819
820 data.dest = (char *)resp;
821 data.blocksize = 64;
822 data.blocks = 1;
823 data.flags = MMC_DATA_READ;
824
825 return mmc_send_cmd(mmc, &cmd, &data);
826}
827
828
Kim Phillips87ea3892012-10-29 13:34:43 +0000829static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500830{
831 int err;
832 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000833 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
834 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500835 struct mmc_data data;
836 int timeout;
837
838 mmc->card_caps = 0;
839
Thomas Chou1254c3d2010-12-24 13:12:21 +0000840 if (mmc_host_is_spi(mmc))
841 return 0;
842
Andy Flemingad347bb2008-10-30 16:41:01 -0500843 /* Read the SCR to find out if this card supports higher speeds */
844 cmd.cmdidx = MMC_CMD_APP_CMD;
845 cmd.resp_type = MMC_RSP_R1;
846 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500847
848 err = mmc_send_cmd(mmc, &cmd, NULL);
849
850 if (err)
851 return err;
852
853 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
854 cmd.resp_type = MMC_RSP_R1;
855 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500856
857 timeout = 3;
858
859retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000860 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -0500861 data.blocksize = 8;
862 data.blocks = 1;
863 data.flags = MMC_DATA_READ;
864
865 err = mmc_send_cmd(mmc, &cmd, &data);
866
867 if (err) {
868 if (timeout--)
869 goto retry_scr;
870
871 return err;
872 }
873
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300874 mmc->scr[0] = __be32_to_cpu(scr[0]);
875 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500876
877 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng4a4ef872016-03-17 21:53:13 -0700878 case 0:
879 mmc->version = SD_VERSION_1_0;
880 break;
881 case 1:
882 mmc->version = SD_VERSION_1_10;
883 break;
884 case 2:
885 mmc->version = SD_VERSION_2;
886 if ((mmc->scr[0] >> 15) & 0x1)
887 mmc->version = SD_VERSION_3;
888 break;
889 default:
890 mmc->version = SD_VERSION_1_0;
891 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500892 }
893
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530894 if (mmc->scr[0] & SD_DATA_4BIT)
895 mmc->card_caps |= MMC_MODE_4BIT;
896
Andy Flemingad347bb2008-10-30 16:41:01 -0500897 /* Version 1.0 doesn't support switching */
898 if (mmc->version == SD_VERSION_1_0)
899 return 0;
900
901 timeout = 4;
902 while (timeout--) {
903 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +0000904 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500905
906 if (err)
907 return err;
908
909 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300910 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500911 break;
912 }
913
Andy Flemingad347bb2008-10-30 16:41:01 -0500914 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300915 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500916 return 0;
917
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000918 /*
919 * If the host doesn't support SD_HIGHSPEED, do not switch card to
920 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
921 * This can avoid furthur problem when the card runs in different
922 * mode between the host.
923 */
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200924 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
925 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000926 return 0;
927
Anton staaf9b00f0d2011-10-03 13:54:59 +0000928 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500929
930 if (err)
931 return err;
932
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300933 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500934 mmc->card_caps |= MMC_MODE_HS;
935
936 return 0;
937}
938
939/* frequency bases */
940/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000941static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500942 10000,
943 100000,
944 1000000,
945 10000000,
946};
947
948/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
949 * to platforms without floating point.
950 */
Simon Glass03317cc2016-05-14 14:02:57 -0600951static const u8 multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500952 0, /* reserved */
953 10,
954 12,
955 13,
956 15,
957 20,
958 25,
959 30,
960 35,
961 40,
962 45,
963 50,
964 55,
965 60,
966 70,
967 80,
968};
969
Kim Phillips87ea3892012-10-29 13:34:43 +0000970static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500971{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200972 if (mmc->cfg->ops->set_ios)
973 mmc->cfg->ops->set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -0500974}
975
976void mmc_set_clock(struct mmc *mmc, uint clock)
977{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200978 if (clock > mmc->cfg->f_max)
979 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -0500980
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200981 if (clock < mmc->cfg->f_min)
982 clock = mmc->cfg->f_min;
Andy Flemingad347bb2008-10-30 16:41:01 -0500983
984 mmc->clock = clock;
985
986 mmc_set_ios(mmc);
987}
988
Kim Phillips87ea3892012-10-29 13:34:43 +0000989static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -0500990{
991 mmc->bus_width = width;
992
993 mmc_set_ios(mmc);
994}
995
Kim Phillips87ea3892012-10-29 13:34:43 +0000996static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500997{
Stephen Warrene315ae82013-06-11 15:14:01 -0600998 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -0500999 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001000 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -05001001 struct mmc_cmd cmd;
Simon Glassa09c2b72013-04-03 08:54:30 +00001002 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1003 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001004 int timeout = 1000;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001005 bool has_parts = false;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001006 bool part_completed;
Simon Glasse5db1152016-05-01 13:52:35 -06001007 struct blk_desc *bdesc;
Andy Flemingad347bb2008-10-30 16:41:01 -05001008
Thomas Chou1254c3d2010-12-24 13:12:21 +00001009#ifdef CONFIG_MMC_SPI_CRC_ON
1010 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1011 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1012 cmd.resp_type = MMC_RSP_R1;
1013 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001014 err = mmc_send_cmd(mmc, &cmd, NULL);
1015
1016 if (err)
1017 return err;
1018 }
1019#endif
1020
Andy Flemingad347bb2008-10-30 16:41:01 -05001021 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001022 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1023 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -05001024 cmd.resp_type = MMC_RSP_R2;
1025 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001026
1027 err = mmc_send_cmd(mmc, &cmd, NULL);
1028
1029 if (err)
1030 return err;
1031
1032 memcpy(mmc->cid, cmd.response, 16);
1033
1034 /*
1035 * For MMC cards, set the Relative Address.
1036 * For SD cards, get the Relatvie Address.
1037 * This also puts the cards into Standby State
1038 */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001039 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1040 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1041 cmd.cmdarg = mmc->rca << 16;
1042 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -05001043
Thomas Chou1254c3d2010-12-24 13:12:21 +00001044 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001045
Thomas Chou1254c3d2010-12-24 13:12:21 +00001046 if (err)
1047 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001048
Thomas Chou1254c3d2010-12-24 13:12:21 +00001049 if (IS_SD(mmc))
1050 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1051 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001052
1053 /* Get the Card-Specific Data */
1054 cmd.cmdidx = MMC_CMD_SEND_CSD;
1055 cmd.resp_type = MMC_RSP_R2;
1056 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001057
1058 err = mmc_send_cmd(mmc, &cmd, NULL);
1059
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001060 /* Waiting for the ready status */
1061 mmc_send_status(mmc, timeout);
1062
Andy Flemingad347bb2008-10-30 16:41:01 -05001063 if (err)
1064 return err;
1065
Rabin Vincentb6eed942009-04-05 13:30:56 +05301066 mmc->csd[0] = cmd.response[0];
1067 mmc->csd[1] = cmd.response[1];
1068 mmc->csd[2] = cmd.response[2];
1069 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -05001070
1071 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301072 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -05001073
1074 switch (version) {
Bin Meng4a4ef872016-03-17 21:53:13 -07001075 case 0:
1076 mmc->version = MMC_VERSION_1_2;
1077 break;
1078 case 1:
1079 mmc->version = MMC_VERSION_1_4;
1080 break;
1081 case 2:
1082 mmc->version = MMC_VERSION_2_2;
1083 break;
1084 case 3:
1085 mmc->version = MMC_VERSION_3;
1086 break;
1087 case 4:
1088 mmc->version = MMC_VERSION_4;
1089 break;
1090 default:
1091 mmc->version = MMC_VERSION_1_2;
1092 break;
Andy Flemingad347bb2008-10-30 16:41:01 -05001093 }
1094 }
1095
1096 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301097 freq = fbase[(cmd.response[0] & 0x7)];
1098 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -05001099
1100 mmc->tran_speed = freq * mult;
1101
Markus Niebel03951412013-12-16 13:40:46 +01001102 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +05301103 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001104
1105 if (IS_SD(mmc))
1106 mmc->write_bl_len = mmc->read_bl_len;
1107 else
Rabin Vincentb6eed942009-04-05 13:30:56 +05301108 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001109
1110 if (mmc->high_capacity) {
1111 csize = (mmc->csd[1] & 0x3f) << 16
1112 | (mmc->csd[2] & 0xffff0000) >> 16;
1113 cmult = 8;
1114 } else {
1115 csize = (mmc->csd[1] & 0x3ff) << 2
1116 | (mmc->csd[2] & 0xc0000000) >> 30;
1117 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1118 }
1119
Stephen Warrene315ae82013-06-11 15:14:01 -06001120 mmc->capacity_user = (csize + 1) << (cmult + 2);
1121 mmc->capacity_user *= mmc->read_bl_len;
1122 mmc->capacity_boot = 0;
1123 mmc->capacity_rpmb = 0;
1124 for (i = 0; i < 4; i++)
1125 mmc->capacity_gp[i] = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001126
Simon Glassa09c2b72013-04-03 08:54:30 +00001127 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1128 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001129
Simon Glassa09c2b72013-04-03 08:54:30 +00001130 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1131 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001132
Markus Niebel03951412013-12-16 13:40:46 +01001133 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1134 cmd.cmdidx = MMC_CMD_SET_DSR;
1135 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1136 cmd.resp_type = MMC_RSP_NONE;
1137 if (mmc_send_cmd(mmc, &cmd, NULL))
1138 printf("MMC: SET_DSR failed\n");
1139 }
1140
Andy Flemingad347bb2008-10-30 16:41:01 -05001141 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001142 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1143 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +00001144 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001145 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001146 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001147
Thomas Chou1254c3d2010-12-24 13:12:21 +00001148 if (err)
1149 return err;
1150 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001151
Lei Wenea526762011-06-22 17:03:31 +00001152 /*
1153 * For SD, its erase group is always one sector
1154 */
1155 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +00001156 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301157 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1158 /* check ext_csd version and capacity */
1159 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruzca25e062014-12-23 10:50:28 +01001160 if (err)
1161 return err;
1162 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001163 /*
1164 * According to the JEDEC Standard, the value of
1165 * ext_csd's capacity is valid if the value is more
1166 * than 2GB
1167 */
Lei Wen217467f2011-10-03 20:35:10 +00001168 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1169 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1170 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1171 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glassa09c2b72013-04-03 08:54:30 +00001172 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +00001173 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -06001174 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301175 }
Lei Wen31b99802011-05-02 16:26:26 +00001176
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001177 switch (ext_csd[EXT_CSD_REV]) {
1178 case 1:
1179 mmc->version = MMC_VERSION_4_1;
1180 break;
1181 case 2:
1182 mmc->version = MMC_VERSION_4_2;
1183 break;
1184 case 3:
1185 mmc->version = MMC_VERSION_4_3;
1186 break;
1187 case 5:
1188 mmc->version = MMC_VERSION_4_41;
1189 break;
1190 case 6:
1191 mmc->version = MMC_VERSION_4_5;
1192 break;
Markus Niebel32f53b62014-11-18 15:13:53 +01001193 case 7:
1194 mmc->version = MMC_VERSION_5_0;
1195 break;
Stefan Wahren1243cd82016-06-16 17:54:06 +00001196 case 8:
1197 mmc->version = MMC_VERSION_5_1;
1198 break;
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001199 }
1200
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001201 /* The partition data may be non-zero but it is only
1202 * effective if PARTITION_SETTING_COMPLETED is set in
1203 * EXT_CSD, so ignore any data if this bit is not set,
1204 * except for enabling the high-capacity group size
1205 * definition (see below). */
1206 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1207 EXT_CSD_PARTITION_SETTING_COMPLETED);
1208
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001209 /* store the partition info of emmc */
1210 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1211 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1212 ext_csd[EXT_CSD_BOOT_MULT])
1213 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001214 if (part_completed &&
1215 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001216 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1217
1218 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1219
1220 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1221
1222 for (i = 0; i < 4; i++) {
1223 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001224 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001225 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001226 if (mult)
1227 has_parts = true;
1228 if (!part_completed)
1229 continue;
1230 mmc->capacity_gp[i] = mult;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001231 mmc->capacity_gp[i] *=
1232 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1233 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruze5a2a3a2014-12-23 10:50:21 +01001234 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001235 }
1236
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001237 if (part_completed) {
1238 mmc->enh_user_size =
1239 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1240 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1241 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1242 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1243 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1244 mmc->enh_user_size <<= 19;
1245 mmc->enh_user_start =
1246 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1247 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1248 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1249 ext_csd[EXT_CSD_ENH_START_ADDR];
1250 if (mmc->high_capacity)
1251 mmc->enh_user_start <<= 9;
1252 }
Diego Santa Cruz3b62d842014-12-23 10:50:22 +01001253
Lei Wenea526762011-06-22 17:03:31 +00001254 /*
Oliver Metzb3f14092013-10-01 20:32:07 +02001255 * Host needs to enable ERASE_GRP_DEF bit if device is
1256 * partitioned. This bit will be lost every time after a reset
1257 * or power off. This will affect erase size.
Lei Wenea526762011-06-22 17:03:31 +00001258 */
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001259 if (part_completed)
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001260 has_parts = true;
Oliver Metzb3f14092013-10-01 20:32:07 +02001261 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001262 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1263 has_parts = true;
1264 if (has_parts) {
Oliver Metzb3f14092013-10-01 20:32:07 +02001265 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1266 EXT_CSD_ERASE_GROUP_DEF, 1);
1267
1268 if (err)
1269 return err;
Hannes Petermaier15e874d2014-08-08 09:47:22 +02001270 else
1271 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001272 }
Oliver Metzb3f14092013-10-01 20:32:07 +02001273
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001274 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metzb3f14092013-10-01 20:32:07 +02001275 /* Read out group size from ext_csd */
Lei Wen217467f2011-10-03 20:35:10 +00001276 mmc->erase_grp_size =
Diego Santa Cruz747f6fa2014-12-23 10:50:24 +01001277 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebel6d398922014-11-18 15:11:42 +01001278 /*
1279 * if high capacity and partition setting completed
1280 * SEC_COUNT is valid even if it is smaller than 2 GiB
1281 * JEDEC Standard JESD84-B45, 6.2.4
1282 */
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001283 if (mmc->high_capacity && part_completed) {
Markus Niebel6d398922014-11-18 15:11:42 +01001284 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1285 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1286 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1287 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1288 capacity *= MMC_MAX_BLOCK_LEN;
1289 mmc->capacity_user = capacity;
1290 }
Simon Glassa09c2b72013-04-03 08:54:30 +00001291 } else {
Oliver Metzb3f14092013-10-01 20:32:07 +02001292 /* Calculate the group size from the csd value. */
Lei Wenea526762011-06-22 17:03:31 +00001293 int erase_gsz, erase_gmul;
1294 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1295 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1296 mmc->erase_grp_size = (erase_gsz + 1)
1297 * (erase_gmul + 1);
1298 }
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001299
1300 mmc->hc_wp_grp_size = 1024
1301 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1302 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz37a50b92014-12-23 10:50:33 +01001303
1304 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301305 }
1306
Simon Glasse5db1152016-05-01 13:52:35 -06001307 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrene315ae82013-06-11 15:14:01 -06001308 if (err)
1309 return err;
1310
Andy Flemingad347bb2008-10-30 16:41:01 -05001311 if (IS_SD(mmc))
1312 err = sd_change_freq(mmc);
1313 else
1314 err = mmc_change_freq(mmc);
1315
1316 if (err)
1317 return err;
1318
1319 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001320 mmc->card_caps &= mmc->cfg->host_caps;
Andy Flemingad347bb2008-10-30 16:41:01 -05001321
1322 if (IS_SD(mmc)) {
1323 if (mmc->card_caps & MMC_MODE_4BIT) {
1324 cmd.cmdidx = MMC_CMD_APP_CMD;
1325 cmd.resp_type = MMC_RSP_R1;
1326 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001327
1328 err = mmc_send_cmd(mmc, &cmd, NULL);
1329 if (err)
1330 return err;
1331
1332 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1333 cmd.resp_type = MMC_RSP_R1;
1334 cmd.cmdarg = 2;
Andy Flemingad347bb2008-10-30 16:41:01 -05001335 err = mmc_send_cmd(mmc, &cmd, NULL);
1336 if (err)
1337 return err;
1338
1339 mmc_set_bus_width(mmc, 4);
1340 }
1341
1342 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001343 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001344 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001345 mmc->tran_speed = 25000000;
Andrew Gabbasovccb7b042014-12-25 10:22:25 -06001346 } else if (mmc->version >= MMC_VERSION_4) {
1347 /* Only version 4 of MMC supports wider bus widths */
Andy Flemingeb766ad2012-10-31 19:02:38 +00001348 int idx;
1349
1350 /* An array of possible bus widths in order of preference */
1351 static unsigned ext_csd_bits[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001352 EXT_CSD_DDR_BUS_WIDTH_8,
1353 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001354 EXT_CSD_BUS_WIDTH_8,
1355 EXT_CSD_BUS_WIDTH_4,
1356 EXT_CSD_BUS_WIDTH_1,
1357 };
1358
1359 /* An array to map CSD bus widths to host cap bits */
1360 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001361 [EXT_CSD_DDR_BUS_WIDTH_4] =
1362 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1363 [EXT_CSD_DDR_BUS_WIDTH_8] =
1364 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001365 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1366 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1367 };
1368
1369 /* An array to map chosen bus width to an integer */
1370 static unsigned widths[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001371 8, 4, 8, 4, 1,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001372 };
1373
1374 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1375 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001376 unsigned int caps = ext_to_hostcaps[extw];
Andy Flemingeb766ad2012-10-31 19:02:38 +00001377
1378 /*
Andrew Gabbasovc1b2cf02014-12-25 10:22:24 -06001379 * If the bus width is still not changed,
1380 * don't try to set the default again.
1381 * Otherwise, recover from switch attempts
1382 * by switching to 1-bit bus width.
1383 */
1384 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1385 mmc->bus_width == 1) {
1386 err = 0;
1387 break;
1388 }
1389
1390 /*
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001391 * Check to make sure the card and controller support
1392 * these capabilities
Andy Flemingeb766ad2012-10-31 19:02:38 +00001393 */
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001394 if ((mmc->card_caps & caps) != caps)
Andy Flemingeb766ad2012-10-31 19:02:38 +00001395 continue;
1396
Andy Flemingad347bb2008-10-30 16:41:01 -05001397 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001398 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001399
1400 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001401 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001402
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001403 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Flemingeb766ad2012-10-31 19:02:38 +00001404 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001405
Lei Wen4f5a6a52011-10-03 20:35:11 +00001406 err = mmc_send_ext_csd(mmc, test_csd);
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001407
1408 if (err)
1409 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001410
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001411 /* Only compare read only fields */
1412 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1413 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1414 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1415 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1416 ext_csd[EXT_CSD_REV]
1417 == test_csd[EXT_CSD_REV] &&
1418 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1419 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1420 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1421 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001422 break;
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001423 else
1424 err = SWITCH_ERR;
Andy Flemingad347bb2008-10-30 16:41:01 -05001425 }
1426
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001427 if (err)
1428 return err;
1429
Andy Flemingad347bb2008-10-30 16:41:01 -05001430 if (mmc->card_caps & MMC_MODE_HS) {
1431 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001432 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001433 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001434 mmc->tran_speed = 26000000;
1435 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001436 }
1437
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001438 mmc_set_clock(mmc, mmc->tran_speed);
1439
Andrew Gabbasov532663b2014-12-01 06:59:11 -06001440 /* Fix the block length for DDR mode */
1441 if (mmc->ddr_mode) {
1442 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1443 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1444 }
1445
Andy Flemingad347bb2008-10-30 16:41:01 -05001446 /* fill in device description */
Simon Glasse5db1152016-05-01 13:52:35 -06001447 bdesc = mmc_get_blk_desc(mmc);
1448 bdesc->lun = 0;
1449 bdesc->hwpart = 0;
1450 bdesc->type = 0;
1451 bdesc->blksz = mmc->read_bl_len;
1452 bdesc->log2blksz = LOG2(bdesc->blksz);
1453 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsd67754f2015-12-04 23:27:40 +01001454#if !defined(CONFIG_SPL_BUILD) || \
1455 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1456 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glasse5db1152016-05-01 13:52:35 -06001457 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Hutt7367ec22012-10-20 17:15:59 +00001458 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1459 (mmc->cid[3] >> 16) & 0xffff);
Simon Glasse5db1152016-05-01 13:52:35 -06001460 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Hutt7367ec22012-10-20 17:15:59 +00001461 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1462 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1463 (mmc->cid[2] >> 24) & 0xff);
Simon Glasse5db1152016-05-01 13:52:35 -06001464 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Hutt7367ec22012-10-20 17:15:59 +00001465 (mmc->cid[2] >> 16) & 0xf);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001466#else
Simon Glasse5db1152016-05-01 13:52:35 -06001467 bdesc->vendor[0] = 0;
1468 bdesc->product[0] = 0;
1469 bdesc->revision[0] = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001470#endif
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001471#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glasse5db1152016-05-01 13:52:35 -06001472 part_init(bdesc);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001473#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001474
1475 return 0;
1476}
1477
Kim Phillips87ea3892012-10-29 13:34:43 +00001478static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001479{
1480 struct mmc_cmd cmd;
1481 int err;
1482
1483 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1484 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001485 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05001486 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001487
1488 err = mmc_send_cmd(mmc, &cmd, NULL);
1489
1490 if (err)
1491 return err;
1492
Rabin Vincentb6eed942009-04-05 13:30:56 +05301493 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-10-30 16:41:01 -05001494 return UNUSABLE_ERR;
1495 else
1496 mmc->version = SD_VERSION_2;
1497
1498 return 0;
1499}
1500
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01001501/* board-specific MMC power initializations. */
1502__weak void board_mmc_power_init(void)
1503{
1504}
1505
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001506int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001507{
Macpaul Lin028bde12011-11-14 23:35:39 +00001508 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001509
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001510 /* we pretend there's no card when init is NULL */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001511 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Redingb9c8b772012-01-02 01:15:37 +00001512 mmc->has_init = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001513#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001514 printf("MMC: no card present\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001515#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +00001516 return NO_CARD_ERR;
1517 }
1518
Lei Wen31b99802011-05-02 16:26:26 +00001519 if (mmc->has_init)
1520 return 0;
1521
Yangbo Lub124f8a2015-04-22 13:57:00 +08001522#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1523 mmc_adapter_card_type_ident();
1524#endif
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01001525 board_mmc_power_init();
1526
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001527 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001528 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001529
1530 if (err)
1531 return err;
1532
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001533 mmc->ddr_mode = 0;
Ilya Yanok8459aab2009-06-29 17:53:16 +04001534 mmc_set_bus_width(mmc, 1);
1535 mmc_set_clock(mmc, 1);
1536
Andy Flemingad347bb2008-10-30 16:41:01 -05001537 /* Reset the Card */
1538 err = mmc_go_idle(mmc);
1539
1540 if (err)
1541 return err;
1542
Lei Wen31b99802011-05-02 16:26:26 +00001543 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glasse5db1152016-05-01 13:52:35 -06001544 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001545
Andy Flemingad347bb2008-10-30 16:41:01 -05001546 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001547 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001548
Andy Flemingad347bb2008-10-30 16:41:01 -05001549 /* Now try to get the SD card's operating condition */
1550 err = sd_send_op_cond(mmc);
1551
1552 /* If the command timed out, we check for an MMC card */
1553 if (err == TIMEOUT) {
1554 err = mmc_send_op_cond(mmc);
1555
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001556 if (err) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001557#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001558 printf("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001559#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001560 return UNUSABLE_ERR;
1561 }
1562 }
1563
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001564 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001565 mmc->init_in_progress = 1;
1566
1567 return err;
1568}
1569
1570static int mmc_complete_init(struct mmc *mmc)
1571{
1572 int err = 0;
1573
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001574 mmc->init_in_progress = 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001575 if (mmc->op_cond_pending)
1576 err = mmc_complete_op_cond(mmc);
1577
1578 if (!err)
1579 err = mmc_startup(mmc);
Lei Wen31b99802011-05-02 16:26:26 +00001580 if (err)
1581 mmc->has_init = 0;
1582 else
1583 mmc->has_init = 1;
1584 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001585}
1586
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001587int mmc_init(struct mmc *mmc)
1588{
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001589 int err = 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001590 unsigned start;
Simon Glass59bc6f22016-05-01 13:52:41 -06001591#ifdef CONFIG_DM_MMC
1592 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001593
Simon Glass59bc6f22016-05-01 13:52:41 -06001594 upriv->mmc = mmc;
1595#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001596 if (mmc->has_init)
1597 return 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001598
1599 start = get_timer(0);
1600
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001601 if (!mmc->init_in_progress)
1602 err = mmc_start_init(mmc);
1603
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001604 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001605 err = mmc_complete_init(mmc);
1606 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
1607 return err;
1608}
1609
Markus Niebel03951412013-12-16 13:40:46 +01001610int mmc_set_dsr(struct mmc *mmc, u16 val)
1611{
1612 mmc->dsr = val;
1613 return 0;
1614}
1615
Jeroen Hofstee47726302014-07-10 22:46:28 +02001616/* CPU-specific MMC initializations */
1617__weak int cpu_mmc_init(bd_t *bis)
Andy Flemingad347bb2008-10-30 16:41:01 -05001618{
1619 return -1;
1620}
1621
Jeroen Hofstee47726302014-07-10 22:46:28 +02001622/* board-specific MMC initializations. */
1623__weak int board_mmc_init(bd_t *bis)
1624{
1625 return -1;
1626}
Andy Flemingad347bb2008-10-30 16:41:01 -05001627
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001628void mmc_set_preinit(struct mmc *mmc, int preinit)
1629{
1630 mmc->preinit = preinit;
1631}
1632
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001633#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
1634static int mmc_probe(bd_t *bis)
1635{
1636 return 0;
1637}
1638#elif defined(CONFIG_DM_MMC)
1639static int mmc_probe(bd_t *bis)
1640{
Simon Glass547cb342015-12-29 05:22:49 -07001641 int ret, i;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001642 struct uclass *uc;
Simon Glass547cb342015-12-29 05:22:49 -07001643 struct udevice *dev;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001644
1645 ret = uclass_get(UCLASS_MMC, &uc);
1646 if (ret)
1647 return ret;
1648
Simon Glass547cb342015-12-29 05:22:49 -07001649 /*
1650 * Try to add them in sequence order. Really with driver model we
1651 * should allow holes, but the current MMC list does not allow that.
1652 * So if we request 0, 1, 3 we will get 0, 1, 2.
1653 */
1654 for (i = 0; ; i++) {
1655 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
1656 if (ret == -ENODEV)
1657 break;
1658 }
1659 uclass_foreach_dev(dev, uc) {
1660 ret = device_probe(dev);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001661 if (ret)
Simon Glass547cb342015-12-29 05:22:49 -07001662 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001663 }
1664
1665 return 0;
1666}
1667#else
1668static int mmc_probe(bd_t *bis)
1669{
1670 if (board_mmc_init(bis) < 0)
1671 cpu_mmc_init(bis);
1672
1673 return 0;
1674}
1675#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001676
Andy Flemingad347bb2008-10-30 16:41:01 -05001677int mmc_initialize(bd_t *bis)
1678{
Daniel Kochmański13df57b2015-05-29 16:55:43 +02001679 static int initialized = 0;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001680 int ret;
Daniel Kochmański13df57b2015-05-29 16:55:43 +02001681 if (initialized) /* Avoid initializing mmc multiple times */
1682 return 0;
1683 initialized = 1;
1684
Simon Glasse5db1152016-05-01 13:52:35 -06001685#ifndef CONFIG_BLK
1686 mmc_list_init();
1687#endif
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001688 ret = mmc_probe(bis);
1689 if (ret)
1690 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -05001691
Ying Zhang9ff70262013-08-16 15:16:11 +08001692#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05001693 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08001694#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001695
Simon Glasse5db1152016-05-01 13:52:35 -06001696 mmc_do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001697 return 0;
1698}