blob: 0312da91af7736db2ee2845cbfea7cfbdb115dd0 [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
Peng Fanb3fcf1e2016-09-01 11:13:38 +080024static const unsigned int sd_au_size[] = {
25 0, SZ_16K / 512, SZ_32K / 512,
26 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
27 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
28 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
29 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512,
30};
31
Simon Glass394dfc02016-06-12 23:30:22 -060032#ifndef CONFIG_DM_MMC_OPS
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +020033__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanov020f2612012-12-03 02:19:46 +000034{
35 return -1;
36}
37
38int mmc_getwp(struct mmc *mmc)
39{
40 int wp;
41
42 wp = board_mmc_getwp(mmc);
43
Peter Korsgaardf7b15102013-03-21 04:00:03 +000044 if (wp < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +020045 if (mmc->cfg->ops->getwp)
46 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +000047 else
48 wp = 0;
49 }
Nikita Kiryanov020f2612012-12-03 02:19:46 +000050
51 return wp;
52}
53
Jeroen Hofstee47726302014-07-10 22:46:28 +020054__weak int board_mmc_getcd(struct mmc *mmc)
55{
Stefano Babic6e00edf2010-02-05 15:04:43 +010056 return -1;
57}
Simon Glass394dfc02016-06-12 23:30:22 -060058#endif
Stefano Babic6e00edf2010-02-05 15:04:43 +010059
Simon Glassb23d96e2016-06-12 23:30:20 -060060#ifdef CONFIG_MMC_TRACE
61void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
Andy Flemingad347bb2008-10-30 16:41:01 -050062{
Simon Glassb23d96e2016-06-12 23:30:20 -060063 printf("CMD_SEND:%d\n", cmd->cmdidx);
64 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
65}
Marek Vasutdccb6082012-03-15 18:41:35 +000066
Simon Glassb23d96e2016-06-12 23:30:20 -060067void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
68{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000069 int i;
70 u8 *ptr;
71
Bin Meng8d1ad1e2016-03-17 21:53:14 -070072 if (ret) {
73 printf("\t\tRET\t\t\t %d\n", ret);
74 } else {
75 switch (cmd->resp_type) {
76 case MMC_RSP_NONE:
77 printf("\t\tMMC_RSP_NONE\n");
78 break;
79 case MMC_RSP_R1:
80 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
81 cmd->response[0]);
82 break;
83 case MMC_RSP_R1b:
84 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
85 cmd->response[0]);
86 break;
87 case MMC_RSP_R2:
88 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
89 cmd->response[0]);
90 printf("\t\t \t\t 0x%08X \n",
91 cmd->response[1]);
92 printf("\t\t \t\t 0x%08X \n",
93 cmd->response[2]);
94 printf("\t\t \t\t 0x%08X \n",
95 cmd->response[3]);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000096 printf("\n");
Bin Meng8d1ad1e2016-03-17 21:53:14 -070097 printf("\t\t\t\t\tDUMPING DATA\n");
98 for (i = 0; i < 4; i++) {
99 int j;
100 printf("\t\t\t\t\t%03d - ", i*4);
101 ptr = (u8 *)&cmd->response[i];
102 ptr += 3;
103 for (j = 0; j < 4; j++)
104 printf("%02X ", *ptr--);
105 printf("\n");
106 }
107 break;
108 case MMC_RSP_R3:
109 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
110 cmd->response[0]);
111 break;
112 default:
113 printf("\t\tERROR MMC rsp not supported\n");
114 break;
Bin Meng4a4ef872016-03-17 21:53:13 -0700115 }
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000116 }
Simon Glassb23d96e2016-06-12 23:30:20 -0600117}
118
119void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
120{
121 int status;
122
123 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
124 printf("CURR STATE:%d\n", status);
125}
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000126#endif
Simon Glassb23d96e2016-06-12 23:30:20 -0600127
Simon Glass394dfc02016-06-12 23:30:22 -0600128#ifndef CONFIG_DM_MMC_OPS
Simon Glassb23d96e2016-06-12 23:30:20 -0600129int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
130{
131 int ret;
132
133 mmmc_trace_before_send(mmc, cmd);
134 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
135 mmmc_trace_after_send(mmc, cmd, ret);
136
Marek Vasutdccb6082012-03-15 18:41:35 +0000137 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500138}
Simon Glass394dfc02016-06-12 23:30:22 -0600139#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500140
Paul Burton8d30cc92013-09-09 15:30:26 +0100141int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000142{
143 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000144 int err, retries = 5;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000145
146 cmd.cmdidx = MMC_CMD_SEND_STATUS;
147 cmd.resp_type = MMC_RSP_R1;
Marek Vasutc4427392011-08-10 09:24:48 +0200148 if (!mmc_host_is_spi(mmc))
149 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000150
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500151 while (1) {
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000152 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-02-05 22:29:12 +0000153 if (!err) {
154 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
155 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
156 MMC_STATE_PRG)
157 break;
158 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100159#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzke31789322012-02-05 22:29:12 +0000160 printf("Status Error: 0x%08X\n",
161 cmd.response[0]);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100162#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +0900163 return -ECOMM;
Jan Kloetzke31789322012-02-05 22:29:12 +0000164 }
165 } else if (--retries < 0)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000166 return err;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000167
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500168 if (timeout-- <= 0)
169 break;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000170
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500171 udelay(1000);
172 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000173
Simon Glassb23d96e2016-06-12 23:30:20 -0600174 mmc_trace_state(mmc, &cmd);
Jongman Heo1be00d92012-06-03 21:32:13 +0000175 if (timeout <= 0) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100176#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000177 printf("Timeout waiting card ready\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100178#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +0900179 return -ETIMEDOUT;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000180 }
181
182 return 0;
183}
184
Paul Burton8d30cc92013-09-09 15:30:26 +0100185int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500186{
187 struct mmc_cmd cmd;
188
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -0600189 if (mmc->ddr_mode)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900190 return 0;
191
Andy Flemingad347bb2008-10-30 16:41:01 -0500192 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
193 cmd.resp_type = MMC_RSP_R1;
194 cmd.cmdarg = len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500195
196 return mmc_send_cmd(mmc, &cmd, NULL);
197}
198
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200199static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000200 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500201{
202 struct mmc_cmd cmd;
203 struct mmc_data data;
204
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700205 if (blkcnt > 1)
206 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
207 else
208 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500209
210 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700211 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500212 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700213 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500214
215 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500216
217 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700218 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500219 data.blocksize = mmc->read_bl_len;
220 data.flags = MMC_DATA_READ;
221
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700222 if (mmc_send_cmd(mmc, &cmd, &data))
223 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500224
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700225 if (blkcnt > 1) {
226 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
227 cmd.cmdarg = 0;
228 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700229 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100230#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700231 printf("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100232#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700233 return 0;
234 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500235 }
236
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700237 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500238}
239
Simon Glass59bc6f22016-05-01 13:52:41 -0600240#ifdef CONFIG_BLK
Simon Glass62e293a2016-06-12 23:30:15 -0600241ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600242#else
Simon Glass62e293a2016-06-12 23:30:15 -0600243ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
244 void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600245#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500246{
Simon Glass59bc6f22016-05-01 13:52:41 -0600247#ifdef CONFIG_BLK
248 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
249#endif
Simon Glass2f26fff2016-02-29 15:25:51 -0700250 int dev_num = block_dev->devnum;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700251 int err;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700252 lbaint_t cur, blocks_todo = blkcnt;
253
254 if (blkcnt == 0)
255 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500256
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700257 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500258 if (!mmc)
259 return 0;
260
Simon Glass11f2bb62016-05-01 13:52:29 -0600261 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700262 if (err < 0)
263 return 0;
264
Simon Glasse5db1152016-05-01 13:52:35 -0600265 if ((start + blkcnt) > block_dev->lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100266#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200267 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glasse5db1152016-05-01 13:52:35 -0600268 start + blkcnt, block_dev->lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100269#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800270 return 0;
271 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500272
Simon Glassa4343c42015-06-23 15:38:50 -0600273 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
274 debug("%s: Failed to set blocklen\n", __func__);
Andy Flemingad347bb2008-10-30 16:41:01 -0500275 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600276 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500277
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700278 do {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200279 cur = (blocks_todo > mmc->cfg->b_max) ?
280 mmc->cfg->b_max : blocks_todo;
Simon Glassa4343c42015-06-23 15:38:50 -0600281 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
282 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700283 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600284 }
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700285 blocks_todo -= cur;
286 start += cur;
287 dst += cur * mmc->read_bl_len;
288 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500289
290 return blkcnt;
291}
292
Kim Phillips87ea3892012-10-29 13:34:43 +0000293static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500294{
295 struct mmc_cmd cmd;
296 int err;
297
298 udelay(1000);
299
300 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
301 cmd.cmdarg = 0;
302 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500303
304 err = mmc_send_cmd(mmc, &cmd, NULL);
305
306 if (err)
307 return err;
308
309 udelay(2000);
310
311 return 0;
312}
313
Kim Phillips87ea3892012-10-29 13:34:43 +0000314static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500315{
316 int timeout = 1000;
317 int err;
318 struct mmc_cmd cmd;
319
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500320 while (1) {
Andy Flemingad347bb2008-10-30 16:41:01 -0500321 cmd.cmdidx = MMC_CMD_APP_CMD;
322 cmd.resp_type = MMC_RSP_R1;
323 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500324
325 err = mmc_send_cmd(mmc, &cmd, NULL);
326
327 if (err)
328 return err;
329
330 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
331 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100332
333 /*
334 * Most cards do not answer if some reserved bits
335 * in the ocr are set. However, Some controller
336 * can set bit 7 (reserved for low voltages), but
337 * how to manage low voltages SD card is not yet
338 * specified.
339 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000340 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200341 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500342
343 if (mmc->version == SD_VERSION_2)
344 cmd.cmdarg |= OCR_HCS;
345
346 err = mmc_send_cmd(mmc, &cmd, NULL);
347
348 if (err)
349 return err;
350
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500351 if (cmd.response[0] & OCR_BUSY)
352 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500353
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500354 if (timeout-- <= 0)
Jaehoon Chung7825d202016-07-19 16:33:36 +0900355 return -EOPNOTSUPP;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500356
357 udelay(1000);
358 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500359
360 if (mmc->version != SD_VERSION_2)
361 mmc->version = SD_VERSION_1_0;
362
Thomas Chou1254c3d2010-12-24 13:12:21 +0000363 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
364 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
365 cmd.resp_type = MMC_RSP_R3;
366 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000367
368 err = mmc_send_cmd(mmc, &cmd, NULL);
369
370 if (err)
371 return err;
372 }
373
Rabin Vincentb6eed942009-04-05 13:30:56 +0530374 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500375
376 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
377 mmc->rca = 0;
378
379 return 0;
380}
381
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500382static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Flemingad347bb2008-10-30 16:41:01 -0500383{
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500384 struct mmc_cmd cmd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500385 int err;
386
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500387 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
388 cmd.resp_type = MMC_RSP_R3;
389 cmd.cmdarg = 0;
Rob Herring5fd3edd2015-03-23 17:56:59 -0500390 if (use_arg && !mmc_host_is_spi(mmc))
391 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200392 (mmc->cfg->voltages &
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500393 (mmc->ocr & OCR_VOLTAGE_MASK)) |
394 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000395
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500396 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000397 if (err)
398 return err;
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500399 mmc->ocr = cmd.response[0];
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000400 return 0;
401}
402
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200403static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000404{
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000405 int err, i;
406
Andy Flemingad347bb2008-10-30 16:41:01 -0500407 /* Some cards seem to need this */
408 mmc_go_idle(mmc);
409
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000410 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000411 for (i = 0; i < 2; i++) {
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500412 err = mmc_send_op_cond_iter(mmc, i != 0);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000413 if (err)
414 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200415
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000416 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500417 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500418 break;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000419 }
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500420 mmc->op_cond_pending = 1;
421 return 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000422}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200423
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200424static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000425{
426 struct mmc_cmd cmd;
427 int timeout = 1000;
428 uint start;
429 int err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200430
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000431 mmc->op_cond_pending = 0;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500432 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lu9c720612016-08-02 15:33:18 +0800433 /* Some cards seem to need this */
434 mmc_go_idle(mmc);
435
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500436 start = get_timer(0);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500437 while (1) {
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500438 err = mmc_send_op_cond_iter(mmc, 1);
439 if (err)
440 return err;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500441 if (mmc->ocr & OCR_BUSY)
442 break;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500443 if (get_timer(start) > timeout)
Jaehoon Chung7825d202016-07-19 16:33:36 +0900444 return -EOPNOTSUPP;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500445 udelay(100);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500446 }
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500447 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500448
Thomas Chou1254c3d2010-12-24 13:12:21 +0000449 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
450 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
451 cmd.resp_type = MMC_RSP_R3;
452 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000453
454 err = mmc_send_cmd(mmc, &cmd, NULL);
455
456 if (err)
457 return err;
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500458
459 mmc->ocr = cmd.response[0];
Thomas Chou1254c3d2010-12-24 13:12:21 +0000460 }
461
Andy Flemingad347bb2008-10-30 16:41:01 -0500462 mmc->version = MMC_VERSION_UNKNOWN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500463
464 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700465 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500466
467 return 0;
468}
469
470
Kim Phillips87ea3892012-10-29 13:34:43 +0000471static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500472{
473 struct mmc_cmd cmd;
474 struct mmc_data data;
475 int err;
476
477 /* Get the Card Status Register */
478 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
479 cmd.resp_type = MMC_RSP_R1;
480 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500481
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000482 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500483 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000484 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500485 data.flags = MMC_DATA_READ;
486
487 err = mmc_send_cmd(mmc, &cmd, &data);
488
489 return err;
490}
491
Simon Glass84f9df92016-06-12 23:30:18 -0600492int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500493{
494 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000495 int timeout = 1000;
496 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500497
498 cmd.cmdidx = MMC_CMD_SWITCH;
499 cmd.resp_type = MMC_RSP_R1b;
500 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000501 (index << 16) |
502 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500503
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000504 ret = mmc_send_cmd(mmc, &cmd, NULL);
505
506 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000507 if (!ret)
508 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000509
510 return ret;
511
Andy Flemingad347bb2008-10-30 16:41:01 -0500512}
513
Kim Phillips87ea3892012-10-29 13:34:43 +0000514static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500515{
Simon Glassa09c2b72013-04-03 08:54:30 +0000516 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500517 char cardtype;
518 int err;
519
Andrew Gabbasovccb7b042014-12-25 10:22:25 -0600520 mmc->card_caps = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500521
Thomas Chou1254c3d2010-12-24 13:12:21 +0000522 if (mmc_host_is_spi(mmc))
523 return 0;
524
Andy Flemingad347bb2008-10-30 16:41:01 -0500525 /* Only version 4 supports high-speed */
526 if (mmc->version < MMC_VERSION_4)
527 return 0;
528
Andrew Gabbasovccb7b042014-12-25 10:22:25 -0600529 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
530
Andy Flemingad347bb2008-10-30 16:41:01 -0500531 err = mmc_send_ext_csd(mmc, ext_csd);
532
533 if (err)
534 return err;
535
Lei Wen217467f2011-10-03 20:35:10 +0000536 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500537
538 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
539
540 if (err)
Heiko Schocher9016ab92016-06-07 08:31:21 +0200541 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500542
543 /* Now check to see that it worked */
544 err = mmc_send_ext_csd(mmc, ext_csd);
545
546 if (err)
547 return err;
548
549 /* No high-speed support */
Lei Wen217467f2011-10-03 20:35:10 +0000550 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500551 return 0;
552
553 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900554 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov95a37132014-12-01 06:59:10 -0600555 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900556 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Flemingad347bb2008-10-30 16:41:01 -0500557 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900558 } else {
Andy Flemingad347bb2008-10-30 16:41:01 -0500559 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900560 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500561
562 return 0;
563}
564
Stephen Warrene315ae82013-06-11 15:14:01 -0600565static int mmc_set_capacity(struct mmc *mmc, int part_num)
566{
567 switch (part_num) {
568 case 0:
569 mmc->capacity = mmc->capacity_user;
570 break;
571 case 1:
572 case 2:
573 mmc->capacity = mmc->capacity_boot;
574 break;
575 case 3:
576 mmc->capacity = mmc->capacity_rpmb;
577 break;
578 case 4:
579 case 5:
580 case 6:
581 case 7:
582 mmc->capacity = mmc->capacity_gp[part_num - 4];
583 break;
584 default:
585 return -1;
586 }
587
Simon Glasse5db1152016-05-01 13:52:35 -0600588 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrene315ae82013-06-11 15:14:01 -0600589
590 return 0;
591}
592
Simon Glass62e293a2016-06-12 23:30:15 -0600593int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wen31b99802011-05-02 16:26:26 +0000594{
Stephen Warrene315ae82013-06-11 15:14:01 -0600595 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000596
Stephen Warrene315ae82013-06-11 15:14:01 -0600597 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
598 (mmc->part_config & ~PART_ACCESS_MASK)
599 | (part_num & PART_ACCESS_MASK));
Peter Bigot45fde892014-09-02 18:31:23 -0500600
601 /*
602 * Set the capacity if the switch succeeded or was intended
603 * to return to representing the raw device.
604 */
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700605 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot45fde892014-09-02 18:31:23 -0500606 ret = mmc_set_capacity(mmc, part_num);
Simon Glass984db5d2016-05-01 13:52:37 -0600607 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700608 }
Stephen Warrene315ae82013-06-11 15:14:01 -0600609
Peter Bigot45fde892014-09-02 18:31:23 -0500610 return ret;
Lei Wen31b99802011-05-02 16:26:26 +0000611}
612
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100613int mmc_hwpart_config(struct mmc *mmc,
614 const struct mmc_hwpart_conf *conf,
615 enum mmc_hwpart_conf_mode mode)
616{
617 u8 part_attrs = 0;
618 u32 enh_size_mult;
619 u32 enh_start_addr;
620 u32 gp_size_mult[4];
621 u32 max_enh_size_mult;
622 u32 tot_enh_size_mult = 0;
Diego Santa Cruz80200272014-12-23 10:50:31 +0100623 u8 wr_rel_set;
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100624 int i, pidx, err;
625 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
626
627 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
628 return -EINVAL;
629
630 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
631 printf("eMMC >= 4.4 required for enhanced user data area\n");
632 return -EMEDIUMTYPE;
633 }
634
635 if (!(mmc->part_support & PART_SUPPORT)) {
636 printf("Card does not support partitioning\n");
637 return -EMEDIUMTYPE;
638 }
639
640 if (!mmc->hc_wp_grp_size) {
641 printf("Card does not define HC WP group size\n");
642 return -EMEDIUMTYPE;
643 }
644
645 /* check partition alignment and total enhanced size */
646 if (conf->user.enh_size) {
647 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
648 conf->user.enh_start % mmc->hc_wp_grp_size) {
649 printf("User data enhanced area not HC WP group "
650 "size aligned\n");
651 return -EINVAL;
652 }
653 part_attrs |= EXT_CSD_ENH_USR;
654 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
655 if (mmc->high_capacity) {
656 enh_start_addr = conf->user.enh_start;
657 } else {
658 enh_start_addr = (conf->user.enh_start << 9);
659 }
660 } else {
661 enh_size_mult = 0;
662 enh_start_addr = 0;
663 }
664 tot_enh_size_mult += enh_size_mult;
665
666 for (pidx = 0; pidx < 4; pidx++) {
667 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
668 printf("GP%i partition not HC WP group size "
669 "aligned\n", pidx+1);
670 return -EINVAL;
671 }
672 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
673 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
674 part_attrs |= EXT_CSD_ENH_GP(pidx);
675 tot_enh_size_mult += gp_size_mult[pidx];
676 }
677 }
678
679 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
680 printf("Card does not support enhanced attribute\n");
681 return -EMEDIUMTYPE;
682 }
683
684 err = mmc_send_ext_csd(mmc, ext_csd);
685 if (err)
686 return err;
687
688 max_enh_size_mult =
689 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
690 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
691 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
692 if (tot_enh_size_mult > max_enh_size_mult) {
693 printf("Total enhanced size exceeds maximum (%u > %u)\n",
694 tot_enh_size_mult, max_enh_size_mult);
695 return -EMEDIUMTYPE;
696 }
697
Diego Santa Cruz80200272014-12-23 10:50:31 +0100698 /* The default value of EXT_CSD_WR_REL_SET is device
699 * dependent, the values can only be changed if the
700 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
701 * changed only once and before partitioning is completed. */
702 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
703 if (conf->user.wr_rel_change) {
704 if (conf->user.wr_rel_set)
705 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
706 else
707 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
708 }
709 for (pidx = 0; pidx < 4; pidx++) {
710 if (conf->gp_part[pidx].wr_rel_change) {
711 if (conf->gp_part[pidx].wr_rel_set)
712 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
713 else
714 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
715 }
716 }
717
718 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
719 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
720 puts("Card does not support host controlled partition write "
721 "reliability settings\n");
722 return -EMEDIUMTYPE;
723 }
724
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100725 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
726 EXT_CSD_PARTITION_SETTING_COMPLETED) {
727 printf("Card already partitioned\n");
728 return -EPERM;
729 }
730
731 if (mode == MMC_HWPART_CONF_CHECK)
732 return 0;
733
734 /* Partitioning requires high-capacity size definitions */
735 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
736 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
737 EXT_CSD_ERASE_GROUP_DEF, 1);
738
739 if (err)
740 return err;
741
742 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
743
744 /* update erase group size to be high-capacity */
745 mmc->erase_grp_size =
746 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
747
748 }
749
750 /* all OK, write the configuration */
751 for (i = 0; i < 4; i++) {
752 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
753 EXT_CSD_ENH_START_ADDR+i,
754 (enh_start_addr >> (i*8)) & 0xFF);
755 if (err)
756 return err;
757 }
758 for (i = 0; i < 3; i++) {
759 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
760 EXT_CSD_ENH_SIZE_MULT+i,
761 (enh_size_mult >> (i*8)) & 0xFF);
762 if (err)
763 return err;
764 }
765 for (pidx = 0; pidx < 4; pidx++) {
766 for (i = 0; i < 3; i++) {
767 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
768 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
769 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
770 if (err)
771 return err;
772 }
773 }
774 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
775 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
776 if (err)
777 return err;
778
779 if (mode == MMC_HWPART_CONF_SET)
780 return 0;
781
Diego Santa Cruz80200272014-12-23 10:50:31 +0100782 /* The WR_REL_SET is a write-once register but shall be
783 * written before setting PART_SETTING_COMPLETED. As it is
784 * write-once we can only write it when completing the
785 * partitioning. */
786 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
787 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
788 EXT_CSD_WR_REL_SET, wr_rel_set);
789 if (err)
790 return err;
791 }
792
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100793 /* Setting PART_SETTING_COMPLETED confirms the partition
794 * configuration but it only becomes effective after power
795 * cycle, so we do not adjust the partition related settings
796 * in the mmc struct. */
797
798 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
799 EXT_CSD_PARTITION_SETTING,
800 EXT_CSD_PARTITION_SETTING_COMPLETED);
801 if (err)
802 return err;
803
804 return 0;
805}
806
Simon Glass394dfc02016-06-12 23:30:22 -0600807#ifndef CONFIG_DM_MMC_OPS
Thierry Redingb9c8b772012-01-02 01:15:37 +0000808int mmc_getcd(struct mmc *mmc)
809{
810 int cd;
811
812 cd = board_mmc_getcd(mmc);
813
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000814 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200815 if (mmc->cfg->ops->getcd)
816 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000817 else
818 cd = 1;
819 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000820
821 return cd;
822}
Simon Glass394dfc02016-06-12 23:30:22 -0600823#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +0000824
Kim Phillips87ea3892012-10-29 13:34:43 +0000825static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -0500826{
827 struct mmc_cmd cmd;
828 struct mmc_data data;
829
830 /* Switch the frequency */
831 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
832 cmd.resp_type = MMC_RSP_R1;
833 cmd.cmdarg = (mode << 31) | 0xffffff;
834 cmd.cmdarg &= ~(0xf << (group * 4));
835 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -0500836
837 data.dest = (char *)resp;
838 data.blocksize = 64;
839 data.blocks = 1;
840 data.flags = MMC_DATA_READ;
841
842 return mmc_send_cmd(mmc, &cmd, &data);
843}
844
845
Kim Phillips87ea3892012-10-29 13:34:43 +0000846static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500847{
848 int err;
849 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000850 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
851 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500852 struct mmc_data data;
853 int timeout;
854
855 mmc->card_caps = 0;
856
Thomas Chou1254c3d2010-12-24 13:12:21 +0000857 if (mmc_host_is_spi(mmc))
858 return 0;
859
Andy Flemingad347bb2008-10-30 16:41:01 -0500860 /* Read the SCR to find out if this card supports higher speeds */
861 cmd.cmdidx = MMC_CMD_APP_CMD;
862 cmd.resp_type = MMC_RSP_R1;
863 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500864
865 err = mmc_send_cmd(mmc, &cmd, NULL);
866
867 if (err)
868 return err;
869
870 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
871 cmd.resp_type = MMC_RSP_R1;
872 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500873
874 timeout = 3;
875
876retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000877 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -0500878 data.blocksize = 8;
879 data.blocks = 1;
880 data.flags = MMC_DATA_READ;
881
882 err = mmc_send_cmd(mmc, &cmd, &data);
883
884 if (err) {
885 if (timeout--)
886 goto retry_scr;
887
888 return err;
889 }
890
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300891 mmc->scr[0] = __be32_to_cpu(scr[0]);
892 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500893
894 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng4a4ef872016-03-17 21:53:13 -0700895 case 0:
896 mmc->version = SD_VERSION_1_0;
897 break;
898 case 1:
899 mmc->version = SD_VERSION_1_10;
900 break;
901 case 2:
902 mmc->version = SD_VERSION_2;
903 if ((mmc->scr[0] >> 15) & 0x1)
904 mmc->version = SD_VERSION_3;
905 break;
906 default:
907 mmc->version = SD_VERSION_1_0;
908 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500909 }
910
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530911 if (mmc->scr[0] & SD_DATA_4BIT)
912 mmc->card_caps |= MMC_MODE_4BIT;
913
Andy Flemingad347bb2008-10-30 16:41:01 -0500914 /* Version 1.0 doesn't support switching */
915 if (mmc->version == SD_VERSION_1_0)
916 return 0;
917
918 timeout = 4;
919 while (timeout--) {
920 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +0000921 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500922
923 if (err)
924 return err;
925
926 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300927 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500928 break;
929 }
930
Andy Flemingad347bb2008-10-30 16:41:01 -0500931 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300932 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500933 return 0;
934
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000935 /*
936 * If the host doesn't support SD_HIGHSPEED, do not switch card to
937 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
938 * This can avoid furthur problem when the card runs in different
939 * mode between the host.
940 */
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200941 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
942 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000943 return 0;
944
Anton staaf9b00f0d2011-10-03 13:54:59 +0000945 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500946
947 if (err)
948 return err;
949
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300950 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500951 mmc->card_caps |= MMC_MODE_HS;
952
953 return 0;
954}
955
Peng Fanb3fcf1e2016-09-01 11:13:38 +0800956static int sd_read_ssr(struct mmc *mmc)
957{
958 int err, i;
959 struct mmc_cmd cmd;
960 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
961 struct mmc_data data;
962 int timeout = 3;
963 unsigned int au, eo, et, es;
964
965 cmd.cmdidx = MMC_CMD_APP_CMD;
966 cmd.resp_type = MMC_RSP_R1;
967 cmd.cmdarg = mmc->rca << 16;
968
969 err = mmc_send_cmd(mmc, &cmd, NULL);
970 if (err)
971 return err;
972
973 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
974 cmd.resp_type = MMC_RSP_R1;
975 cmd.cmdarg = 0;
976
977retry_ssr:
978 data.dest = (char *)ssr;
979 data.blocksize = 64;
980 data.blocks = 1;
981 data.flags = MMC_DATA_READ;
982
983 err = mmc_send_cmd(mmc, &cmd, &data);
984 if (err) {
985 if (timeout--)
986 goto retry_ssr;
987
988 return err;
989 }
990
991 for (i = 0; i < 16; i++)
992 ssr[i] = be32_to_cpu(ssr[i]);
993
994 au = (ssr[2] >> 12) & 0xF;
995 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
996 mmc->ssr.au = sd_au_size[au];
997 es = (ssr[3] >> 24) & 0xFF;
998 es |= (ssr[2] & 0xFF) << 8;
999 et = (ssr[3] >> 18) & 0x3F;
1000 if (es && et) {
1001 eo = (ssr[3] >> 16) & 0x3;
1002 mmc->ssr.erase_timeout = (et * 1000) / es;
1003 mmc->ssr.erase_offset = eo * 1000;
1004 }
1005 } else {
1006 debug("Invalid Allocation Unit Size.\n");
1007 }
1008
1009 return 0;
1010}
1011
Andy Flemingad347bb2008-10-30 16:41:01 -05001012/* frequency bases */
1013/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +00001014static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -05001015 10000,
1016 100000,
1017 1000000,
1018 10000000,
1019};
1020
1021/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1022 * to platforms without floating point.
1023 */
Simon Glass03317cc2016-05-14 14:02:57 -06001024static const u8 multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -05001025 0, /* reserved */
1026 10,
1027 12,
1028 13,
1029 15,
1030 20,
1031 25,
1032 30,
1033 35,
1034 40,
1035 45,
1036 50,
1037 55,
1038 60,
1039 70,
1040 80,
1041};
1042
Simon Glass394dfc02016-06-12 23:30:22 -06001043#ifndef CONFIG_DM_MMC_OPS
Kim Phillips87ea3892012-10-29 13:34:43 +00001044static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001045{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001046 if (mmc->cfg->ops->set_ios)
1047 mmc->cfg->ops->set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001048}
Simon Glass394dfc02016-06-12 23:30:22 -06001049#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001050
1051void mmc_set_clock(struct mmc *mmc, uint clock)
1052{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001053 if (clock > mmc->cfg->f_max)
1054 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -05001055
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001056 if (clock < mmc->cfg->f_min)
1057 clock = mmc->cfg->f_min;
Andy Flemingad347bb2008-10-30 16:41:01 -05001058
1059 mmc->clock = clock;
1060
1061 mmc_set_ios(mmc);
1062}
1063
Kim Phillips87ea3892012-10-29 13:34:43 +00001064static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -05001065{
1066 mmc->bus_width = width;
1067
1068 mmc_set_ios(mmc);
1069}
1070
Kim Phillips87ea3892012-10-29 13:34:43 +00001071static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001072{
Stephen Warrene315ae82013-06-11 15:14:01 -06001073 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -05001074 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001075 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -05001076 struct mmc_cmd cmd;
Simon Glassa09c2b72013-04-03 08:54:30 +00001077 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1078 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001079 int timeout = 1000;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001080 bool has_parts = false;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001081 bool part_completed;
Simon Glasse5db1152016-05-01 13:52:35 -06001082 struct blk_desc *bdesc;
Andy Flemingad347bb2008-10-30 16:41:01 -05001083
Thomas Chou1254c3d2010-12-24 13:12:21 +00001084#ifdef CONFIG_MMC_SPI_CRC_ON
1085 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1086 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1087 cmd.resp_type = MMC_RSP_R1;
1088 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001089 err = mmc_send_cmd(mmc, &cmd, NULL);
1090
1091 if (err)
1092 return err;
1093 }
1094#endif
1095
Andy Flemingad347bb2008-10-30 16:41:01 -05001096 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001097 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1098 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -05001099 cmd.resp_type = MMC_RSP_R2;
1100 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001101
1102 err = mmc_send_cmd(mmc, &cmd, NULL);
1103
1104 if (err)
1105 return err;
1106
1107 memcpy(mmc->cid, cmd.response, 16);
1108
1109 /*
1110 * For MMC cards, set the Relative Address.
1111 * For SD cards, get the Relatvie Address.
1112 * This also puts the cards into Standby State
1113 */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001114 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1115 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1116 cmd.cmdarg = mmc->rca << 16;
1117 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -05001118
Thomas Chou1254c3d2010-12-24 13:12:21 +00001119 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001120
Thomas Chou1254c3d2010-12-24 13:12:21 +00001121 if (err)
1122 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001123
Thomas Chou1254c3d2010-12-24 13:12:21 +00001124 if (IS_SD(mmc))
1125 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1126 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001127
1128 /* Get the Card-Specific Data */
1129 cmd.cmdidx = MMC_CMD_SEND_CSD;
1130 cmd.resp_type = MMC_RSP_R2;
1131 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001132
1133 err = mmc_send_cmd(mmc, &cmd, NULL);
1134
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001135 /* Waiting for the ready status */
1136 mmc_send_status(mmc, timeout);
1137
Andy Flemingad347bb2008-10-30 16:41:01 -05001138 if (err)
1139 return err;
1140
Rabin Vincentb6eed942009-04-05 13:30:56 +05301141 mmc->csd[0] = cmd.response[0];
1142 mmc->csd[1] = cmd.response[1];
1143 mmc->csd[2] = cmd.response[2];
1144 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -05001145
1146 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301147 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -05001148
1149 switch (version) {
Bin Meng4a4ef872016-03-17 21:53:13 -07001150 case 0:
1151 mmc->version = MMC_VERSION_1_2;
1152 break;
1153 case 1:
1154 mmc->version = MMC_VERSION_1_4;
1155 break;
1156 case 2:
1157 mmc->version = MMC_VERSION_2_2;
1158 break;
1159 case 3:
1160 mmc->version = MMC_VERSION_3;
1161 break;
1162 case 4:
1163 mmc->version = MMC_VERSION_4;
1164 break;
1165 default:
1166 mmc->version = MMC_VERSION_1_2;
1167 break;
Andy Flemingad347bb2008-10-30 16:41:01 -05001168 }
1169 }
1170
1171 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301172 freq = fbase[(cmd.response[0] & 0x7)];
1173 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -05001174
1175 mmc->tran_speed = freq * mult;
1176
Markus Niebel03951412013-12-16 13:40:46 +01001177 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +05301178 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001179
1180 if (IS_SD(mmc))
1181 mmc->write_bl_len = mmc->read_bl_len;
1182 else
Rabin Vincentb6eed942009-04-05 13:30:56 +05301183 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001184
1185 if (mmc->high_capacity) {
1186 csize = (mmc->csd[1] & 0x3f) << 16
1187 | (mmc->csd[2] & 0xffff0000) >> 16;
1188 cmult = 8;
1189 } else {
1190 csize = (mmc->csd[1] & 0x3ff) << 2
1191 | (mmc->csd[2] & 0xc0000000) >> 30;
1192 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1193 }
1194
Stephen Warrene315ae82013-06-11 15:14:01 -06001195 mmc->capacity_user = (csize + 1) << (cmult + 2);
1196 mmc->capacity_user *= mmc->read_bl_len;
1197 mmc->capacity_boot = 0;
1198 mmc->capacity_rpmb = 0;
1199 for (i = 0; i < 4; i++)
1200 mmc->capacity_gp[i] = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001201
Simon Glassa09c2b72013-04-03 08:54:30 +00001202 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1203 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001204
Simon Glassa09c2b72013-04-03 08:54:30 +00001205 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1206 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001207
Markus Niebel03951412013-12-16 13:40:46 +01001208 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1209 cmd.cmdidx = MMC_CMD_SET_DSR;
1210 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1211 cmd.resp_type = MMC_RSP_NONE;
1212 if (mmc_send_cmd(mmc, &cmd, NULL))
1213 printf("MMC: SET_DSR failed\n");
1214 }
1215
Andy Flemingad347bb2008-10-30 16:41:01 -05001216 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001217 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1218 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +00001219 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001220 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001221 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001222
Thomas Chou1254c3d2010-12-24 13:12:21 +00001223 if (err)
1224 return err;
1225 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001226
Lei Wenea526762011-06-22 17:03:31 +00001227 /*
1228 * For SD, its erase group is always one sector
1229 */
1230 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +00001231 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301232 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1233 /* check ext_csd version and capacity */
1234 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruzca25e062014-12-23 10:50:28 +01001235 if (err)
1236 return err;
1237 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001238 /*
1239 * According to the JEDEC Standard, the value of
1240 * ext_csd's capacity is valid if the value is more
1241 * than 2GB
1242 */
Lei Wen217467f2011-10-03 20:35:10 +00001243 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1244 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1245 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1246 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glassa09c2b72013-04-03 08:54:30 +00001247 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +00001248 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -06001249 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301250 }
Lei Wen31b99802011-05-02 16:26:26 +00001251
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001252 switch (ext_csd[EXT_CSD_REV]) {
1253 case 1:
1254 mmc->version = MMC_VERSION_4_1;
1255 break;
1256 case 2:
1257 mmc->version = MMC_VERSION_4_2;
1258 break;
1259 case 3:
1260 mmc->version = MMC_VERSION_4_3;
1261 break;
1262 case 5:
1263 mmc->version = MMC_VERSION_4_41;
1264 break;
1265 case 6:
1266 mmc->version = MMC_VERSION_4_5;
1267 break;
Markus Niebel32f53b62014-11-18 15:13:53 +01001268 case 7:
1269 mmc->version = MMC_VERSION_5_0;
1270 break;
Stefan Wahren1243cd82016-06-16 17:54:06 +00001271 case 8:
1272 mmc->version = MMC_VERSION_5_1;
1273 break;
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001274 }
1275
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001276 /* The partition data may be non-zero but it is only
1277 * effective if PARTITION_SETTING_COMPLETED is set in
1278 * EXT_CSD, so ignore any data if this bit is not set,
1279 * except for enabling the high-capacity group size
1280 * definition (see below). */
1281 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1282 EXT_CSD_PARTITION_SETTING_COMPLETED);
1283
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001284 /* store the partition info of emmc */
1285 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1286 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1287 ext_csd[EXT_CSD_BOOT_MULT])
1288 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001289 if (part_completed &&
1290 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001291 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1292
1293 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1294
1295 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1296
1297 for (i = 0; i < 4; i++) {
1298 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001299 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001300 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001301 if (mult)
1302 has_parts = true;
1303 if (!part_completed)
1304 continue;
1305 mmc->capacity_gp[i] = mult;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001306 mmc->capacity_gp[i] *=
1307 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1308 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruze5a2a3a2014-12-23 10:50:21 +01001309 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001310 }
1311
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001312 if (part_completed) {
1313 mmc->enh_user_size =
1314 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1315 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1316 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1317 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1318 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1319 mmc->enh_user_size <<= 19;
1320 mmc->enh_user_start =
1321 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1322 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1323 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1324 ext_csd[EXT_CSD_ENH_START_ADDR];
1325 if (mmc->high_capacity)
1326 mmc->enh_user_start <<= 9;
1327 }
Diego Santa Cruz3b62d842014-12-23 10:50:22 +01001328
Lei Wenea526762011-06-22 17:03:31 +00001329 /*
Oliver Metzb3f14092013-10-01 20:32:07 +02001330 * Host needs to enable ERASE_GRP_DEF bit if device is
1331 * partitioned. This bit will be lost every time after a reset
1332 * or power off. This will affect erase size.
Lei Wenea526762011-06-22 17:03:31 +00001333 */
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001334 if (part_completed)
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001335 has_parts = true;
Oliver Metzb3f14092013-10-01 20:32:07 +02001336 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001337 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1338 has_parts = true;
1339 if (has_parts) {
Oliver Metzb3f14092013-10-01 20:32:07 +02001340 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1341 EXT_CSD_ERASE_GROUP_DEF, 1);
1342
1343 if (err)
1344 return err;
Hannes Petermaier15e874d2014-08-08 09:47:22 +02001345 else
1346 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001347 }
Oliver Metzb3f14092013-10-01 20:32:07 +02001348
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001349 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metzb3f14092013-10-01 20:32:07 +02001350 /* Read out group size from ext_csd */
Lei Wen217467f2011-10-03 20:35:10 +00001351 mmc->erase_grp_size =
Diego Santa Cruz747f6fa2014-12-23 10:50:24 +01001352 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebel6d398922014-11-18 15:11:42 +01001353 /*
1354 * if high capacity and partition setting completed
1355 * SEC_COUNT is valid even if it is smaller than 2 GiB
1356 * JEDEC Standard JESD84-B45, 6.2.4
1357 */
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001358 if (mmc->high_capacity && part_completed) {
Markus Niebel6d398922014-11-18 15:11:42 +01001359 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1360 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1361 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1362 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1363 capacity *= MMC_MAX_BLOCK_LEN;
1364 mmc->capacity_user = capacity;
1365 }
Simon Glassa09c2b72013-04-03 08:54:30 +00001366 } else {
Oliver Metzb3f14092013-10-01 20:32:07 +02001367 /* Calculate the group size from the csd value. */
Lei Wenea526762011-06-22 17:03:31 +00001368 int erase_gsz, erase_gmul;
1369 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1370 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1371 mmc->erase_grp_size = (erase_gsz + 1)
1372 * (erase_gmul + 1);
1373 }
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001374
1375 mmc->hc_wp_grp_size = 1024
1376 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1377 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz37a50b92014-12-23 10:50:33 +01001378
1379 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301380 }
1381
Simon Glasse5db1152016-05-01 13:52:35 -06001382 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrene315ae82013-06-11 15:14:01 -06001383 if (err)
1384 return err;
1385
Andy Flemingad347bb2008-10-30 16:41:01 -05001386 if (IS_SD(mmc))
1387 err = sd_change_freq(mmc);
1388 else
1389 err = mmc_change_freq(mmc);
1390
1391 if (err)
1392 return err;
1393
1394 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001395 mmc->card_caps &= mmc->cfg->host_caps;
Andy Flemingad347bb2008-10-30 16:41:01 -05001396
1397 if (IS_SD(mmc)) {
1398 if (mmc->card_caps & MMC_MODE_4BIT) {
1399 cmd.cmdidx = MMC_CMD_APP_CMD;
1400 cmd.resp_type = MMC_RSP_R1;
1401 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001402
1403 err = mmc_send_cmd(mmc, &cmd, NULL);
1404 if (err)
1405 return err;
1406
1407 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1408 cmd.resp_type = MMC_RSP_R1;
1409 cmd.cmdarg = 2;
Andy Flemingad347bb2008-10-30 16:41:01 -05001410 err = mmc_send_cmd(mmc, &cmd, NULL);
1411 if (err)
1412 return err;
1413
1414 mmc_set_bus_width(mmc, 4);
1415 }
1416
Peng Fanb3fcf1e2016-09-01 11:13:38 +08001417 err = sd_read_ssr(mmc);
1418 if (err)
1419 return err;
1420
Andy Flemingad347bb2008-10-30 16:41:01 -05001421 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001422 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001423 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001424 mmc->tran_speed = 25000000;
Andrew Gabbasovccb7b042014-12-25 10:22:25 -06001425 } else if (mmc->version >= MMC_VERSION_4) {
1426 /* Only version 4 of MMC supports wider bus widths */
Andy Flemingeb766ad2012-10-31 19:02:38 +00001427 int idx;
1428
1429 /* An array of possible bus widths in order of preference */
1430 static unsigned ext_csd_bits[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001431 EXT_CSD_DDR_BUS_WIDTH_8,
1432 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001433 EXT_CSD_BUS_WIDTH_8,
1434 EXT_CSD_BUS_WIDTH_4,
1435 EXT_CSD_BUS_WIDTH_1,
1436 };
1437
1438 /* An array to map CSD bus widths to host cap bits */
1439 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001440 [EXT_CSD_DDR_BUS_WIDTH_4] =
1441 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1442 [EXT_CSD_DDR_BUS_WIDTH_8] =
1443 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001444 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1445 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1446 };
1447
1448 /* An array to map chosen bus width to an integer */
1449 static unsigned widths[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001450 8, 4, 8, 4, 1,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001451 };
1452
1453 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1454 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001455 unsigned int caps = ext_to_hostcaps[extw];
Andy Flemingeb766ad2012-10-31 19:02:38 +00001456
1457 /*
Andrew Gabbasovc1b2cf02014-12-25 10:22:24 -06001458 * If the bus width is still not changed,
1459 * don't try to set the default again.
1460 * Otherwise, recover from switch attempts
1461 * by switching to 1-bit bus width.
1462 */
1463 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1464 mmc->bus_width == 1) {
1465 err = 0;
1466 break;
1467 }
1468
1469 /*
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001470 * Check to make sure the card and controller support
1471 * these capabilities
Andy Flemingeb766ad2012-10-31 19:02:38 +00001472 */
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001473 if ((mmc->card_caps & caps) != caps)
Andy Flemingeb766ad2012-10-31 19:02:38 +00001474 continue;
1475
Andy Flemingad347bb2008-10-30 16:41:01 -05001476 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001477 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001478
1479 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001480 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001481
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001482 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Flemingeb766ad2012-10-31 19:02:38 +00001483 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001484
Lei Wen4f5a6a52011-10-03 20:35:11 +00001485 err = mmc_send_ext_csd(mmc, test_csd);
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001486
1487 if (err)
1488 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001489
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001490 /* Only compare read only fields */
1491 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1492 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1493 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1494 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1495 ext_csd[EXT_CSD_REV]
1496 == test_csd[EXT_CSD_REV] &&
1497 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1498 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1499 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1500 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001501 break;
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001502 else
Jaehoon Chung7825d202016-07-19 16:33:36 +09001503 err = -EBADMSG;
Andy Flemingad347bb2008-10-30 16:41:01 -05001504 }
1505
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001506 if (err)
1507 return err;
1508
Andy Flemingad347bb2008-10-30 16:41:01 -05001509 if (mmc->card_caps & MMC_MODE_HS) {
1510 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001511 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001512 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001513 mmc->tran_speed = 26000000;
1514 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001515 }
1516
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001517 mmc_set_clock(mmc, mmc->tran_speed);
1518
Andrew Gabbasov532663b2014-12-01 06:59:11 -06001519 /* Fix the block length for DDR mode */
1520 if (mmc->ddr_mode) {
1521 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1522 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1523 }
1524
Andy Flemingad347bb2008-10-30 16:41:01 -05001525 /* fill in device description */
Simon Glasse5db1152016-05-01 13:52:35 -06001526 bdesc = mmc_get_blk_desc(mmc);
1527 bdesc->lun = 0;
1528 bdesc->hwpart = 0;
1529 bdesc->type = 0;
1530 bdesc->blksz = mmc->read_bl_len;
1531 bdesc->log2blksz = LOG2(bdesc->blksz);
1532 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsd67754f2015-12-04 23:27:40 +01001533#if !defined(CONFIG_SPL_BUILD) || \
1534 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1535 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glasse5db1152016-05-01 13:52:35 -06001536 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Hutt7367ec22012-10-20 17:15:59 +00001537 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1538 (mmc->cid[3] >> 16) & 0xffff);
Simon Glasse5db1152016-05-01 13:52:35 -06001539 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Hutt7367ec22012-10-20 17:15:59 +00001540 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1541 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1542 (mmc->cid[2] >> 24) & 0xff);
Simon Glasse5db1152016-05-01 13:52:35 -06001543 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Hutt7367ec22012-10-20 17:15:59 +00001544 (mmc->cid[2] >> 16) & 0xf);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001545#else
Simon Glasse5db1152016-05-01 13:52:35 -06001546 bdesc->vendor[0] = 0;
1547 bdesc->product[0] = 0;
1548 bdesc->revision[0] = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001549#endif
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001550#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glasse5db1152016-05-01 13:52:35 -06001551 part_init(bdesc);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001552#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001553
1554 return 0;
1555}
1556
Kim Phillips87ea3892012-10-29 13:34:43 +00001557static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001558{
1559 struct mmc_cmd cmd;
1560 int err;
1561
1562 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1563 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001564 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05001565 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001566
1567 err = mmc_send_cmd(mmc, &cmd, NULL);
1568
1569 if (err)
1570 return err;
1571
Rabin Vincentb6eed942009-04-05 13:30:56 +05301572 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung7825d202016-07-19 16:33:36 +09001573 return -EOPNOTSUPP;
Andy Flemingad347bb2008-10-30 16:41:01 -05001574 else
1575 mmc->version = SD_VERSION_2;
1576
1577 return 0;
1578}
1579
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01001580/* board-specific MMC power initializations. */
1581__weak void board_mmc_power_init(void)
1582{
1583}
1584
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001585int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001586{
Simon Glass394dfc02016-06-12 23:30:22 -06001587 bool no_card;
Macpaul Lin028bde12011-11-14 23:35:39 +00001588 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001589
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001590 /* we pretend there's no card when init is NULL */
Simon Glass394dfc02016-06-12 23:30:22 -06001591 no_card = mmc_getcd(mmc) == 0;
1592#ifndef CONFIG_DM_MMC_OPS
1593 no_card = no_card || (mmc->cfg->ops->init == NULL);
1594#endif
1595 if (no_card) {
Thierry Redingb9c8b772012-01-02 01:15:37 +00001596 mmc->has_init = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001597#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001598 printf("MMC: no card present\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001599#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +09001600 return -ENOMEDIUM;
Thierry Redingb9c8b772012-01-02 01:15:37 +00001601 }
1602
Lei Wen31b99802011-05-02 16:26:26 +00001603 if (mmc->has_init)
1604 return 0;
1605
Yangbo Lub124f8a2015-04-22 13:57:00 +08001606#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1607 mmc_adapter_card_type_ident();
1608#endif
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01001609 board_mmc_power_init();
1610
Simon Glass394dfc02016-06-12 23:30:22 -06001611#ifdef CONFIG_DM_MMC_OPS
1612 /* The device has already been probed ready for use */
1613#else
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001614 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001615 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001616 if (err)
1617 return err;
Simon Glass394dfc02016-06-12 23:30:22 -06001618#endif
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001619 mmc->ddr_mode = 0;
Ilya Yanok8459aab2009-06-29 17:53:16 +04001620 mmc_set_bus_width(mmc, 1);
1621 mmc_set_clock(mmc, 1);
1622
Andy Flemingad347bb2008-10-30 16:41:01 -05001623 /* Reset the Card */
1624 err = mmc_go_idle(mmc);
1625
1626 if (err)
1627 return err;
1628
Lei Wen31b99802011-05-02 16:26:26 +00001629 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glasse5db1152016-05-01 13:52:35 -06001630 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001631
Andy Flemingad347bb2008-10-30 16:41:01 -05001632 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001633 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001634
Andy Flemingad347bb2008-10-30 16:41:01 -05001635 /* Now try to get the SD card's operating condition */
1636 err = sd_send_op_cond(mmc);
1637
1638 /* If the command timed out, we check for an MMC card */
Jaehoon Chung7825d202016-07-19 16:33:36 +09001639 if (err == -ETIMEDOUT) {
Andy Flemingad347bb2008-10-30 16:41:01 -05001640 err = mmc_send_op_cond(mmc);
1641
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001642 if (err) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001643#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001644 printf("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001645#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +09001646 return -EOPNOTSUPP;
Andy Flemingad347bb2008-10-30 16:41:01 -05001647 }
1648 }
1649
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001650 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001651 mmc->init_in_progress = 1;
1652
1653 return err;
1654}
1655
1656static int mmc_complete_init(struct mmc *mmc)
1657{
1658 int err = 0;
1659
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001660 mmc->init_in_progress = 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001661 if (mmc->op_cond_pending)
1662 err = mmc_complete_op_cond(mmc);
1663
1664 if (!err)
1665 err = mmc_startup(mmc);
Lei Wen31b99802011-05-02 16:26:26 +00001666 if (err)
1667 mmc->has_init = 0;
1668 else
1669 mmc->has_init = 1;
1670 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001671}
1672
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001673int mmc_init(struct mmc *mmc)
1674{
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001675 int err = 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001676 unsigned start;
Simon Glass59bc6f22016-05-01 13:52:41 -06001677#ifdef CONFIG_DM_MMC
1678 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001679
Simon Glass59bc6f22016-05-01 13:52:41 -06001680 upriv->mmc = mmc;
1681#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001682 if (mmc->has_init)
1683 return 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001684
1685 start = get_timer(0);
1686
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001687 if (!mmc->init_in_progress)
1688 err = mmc_start_init(mmc);
1689
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001690 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001691 err = mmc_complete_init(mmc);
1692 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
1693 return err;
1694}
1695
Markus Niebel03951412013-12-16 13:40:46 +01001696int mmc_set_dsr(struct mmc *mmc, u16 val)
1697{
1698 mmc->dsr = val;
1699 return 0;
1700}
1701
Jeroen Hofstee47726302014-07-10 22:46:28 +02001702/* CPU-specific MMC initializations */
1703__weak int cpu_mmc_init(bd_t *bis)
Andy Flemingad347bb2008-10-30 16:41:01 -05001704{
1705 return -1;
1706}
1707
Jeroen Hofstee47726302014-07-10 22:46:28 +02001708/* board-specific MMC initializations. */
1709__weak int board_mmc_init(bd_t *bis)
1710{
1711 return -1;
1712}
Andy Flemingad347bb2008-10-30 16:41:01 -05001713
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001714void mmc_set_preinit(struct mmc *mmc, int preinit)
1715{
1716 mmc->preinit = preinit;
1717}
1718
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001719#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
1720static int mmc_probe(bd_t *bis)
1721{
1722 return 0;
1723}
1724#elif defined(CONFIG_DM_MMC)
1725static int mmc_probe(bd_t *bis)
1726{
Simon Glass547cb342015-12-29 05:22:49 -07001727 int ret, i;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001728 struct uclass *uc;
Simon Glass547cb342015-12-29 05:22:49 -07001729 struct udevice *dev;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001730
1731 ret = uclass_get(UCLASS_MMC, &uc);
1732 if (ret)
1733 return ret;
1734
Simon Glass547cb342015-12-29 05:22:49 -07001735 /*
1736 * Try to add them in sequence order. Really with driver model we
1737 * should allow holes, but the current MMC list does not allow that.
1738 * So if we request 0, 1, 3 we will get 0, 1, 2.
1739 */
1740 for (i = 0; ; i++) {
1741 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
1742 if (ret == -ENODEV)
1743 break;
1744 }
1745 uclass_foreach_dev(dev, uc) {
1746 ret = device_probe(dev);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001747 if (ret)
Simon Glass547cb342015-12-29 05:22:49 -07001748 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001749 }
1750
1751 return 0;
1752}
1753#else
1754static int mmc_probe(bd_t *bis)
1755{
1756 if (board_mmc_init(bis) < 0)
1757 cpu_mmc_init(bis);
1758
1759 return 0;
1760}
1761#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001762
Andy Flemingad347bb2008-10-30 16:41:01 -05001763int mmc_initialize(bd_t *bis)
1764{
Daniel Kochmański13df57b2015-05-29 16:55:43 +02001765 static int initialized = 0;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001766 int ret;
Daniel Kochmański13df57b2015-05-29 16:55:43 +02001767 if (initialized) /* Avoid initializing mmc multiple times */
1768 return 0;
1769 initialized = 1;
1770
Simon Glasse5db1152016-05-01 13:52:35 -06001771#ifndef CONFIG_BLK
1772 mmc_list_init();
1773#endif
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001774 ret = mmc_probe(bis);
1775 if (ret)
1776 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -05001777
Ying Zhang9ff70262013-08-16 15:16:11 +08001778#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05001779 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08001780#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001781
Simon Glasse5db1152016-05-01 13:52:35 -06001782 mmc_do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001783 return 0;
1784}