blob: 0312da91af7736db2ee2845cbfea7cfbdb115dd0 [file] [log] [blame]
Andy Fleming272cc702008-10-30 16:41:01 -05001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Based vaguely on the Linux code
6 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Andy Fleming272cc702008-10-30 16:41:01 -05008 */
9
10#include <config.h>
11#include <common.h>
12#include <command.h>
Sjoerd Simons8e3332e2015-08-30 16:55:45 -060013#include <dm.h>
14#include <dm/device-internal.h>
Stephen Warrend4622df2014-05-23 12:47:06 -060015#include <errno.h>
Andy Fleming272cc702008-10-30 16:41:01 -050016#include <mmc.h>
17#include <part.h>
18#include <malloc.h>
Simon Glasscf92e052015-09-02 17:24:58 -060019#include <memalign.h>
Andy Fleming272cc702008-10-30 16:41:01 -050020#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053021#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010022#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050023
Peng Fan3697e592016-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 Glass8ca51e52016-06-12 23:30:22 -060032#ifndef CONFIG_DM_MMC_OPS
Jeroen Hofstee750121c2014-07-12 21:24:08 +020033__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-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 Korsgaardd4e1da42013-03-21 04:00:03 +000044 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020045 if (mmc->cfg->ops->getwp)
46 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000047 else
48 wp = 0;
49 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000050
51 return wp;
52}
53
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020054__weak int board_mmc_getcd(struct mmc *mmc)
55{
Stefano Babic11fdade2010-02-05 15:04:43 +010056 return -1;
57}
Simon Glass8ca51e52016-06-12 23:30:22 -060058#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010059
Marek Vasut8635ff92012-03-15 18:41:35 +000060#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060061void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
62{
63 printf("CMD_SEND:%d\n", cmd->cmdidx);
64 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
65}
66
67void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
68{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000069 int i;
70 u8 *ptr;
71
Bin Meng7863ce52016-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 Recalcati5db2fe32011-03-11 02:01:14 +000096 printf("\n");
Bin Meng7863ce52016-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 Meng53e8e402016-03-17 21:53:13 -0700115 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000116 }
Simon Glassc0c76eb2016-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 Recalcati5db2fe32011-03-11 02:01:14 +0000126#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600127
Simon Glass8ca51e52016-06-12 23:30:22 -0600128#ifndef CONFIG_DM_MMC_OPS
Simon Glassc0c76eb2016-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 Vasut8635ff92012-03-15 18:41:35 +0000137 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500138}
Simon Glass8ca51e52016-06-12 23:30:22 -0600139#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500140
Paul Burtonda61fa52013-09-09 15:30:26 +0100141int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000142{
143 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000144 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000145
146 cmd.cmdidx = MMC_CMD_SEND_STATUS;
147 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200148 if (!mmc_host_is_spi(mmc))
149 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000150
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500151 while (1) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000152 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-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 Burton56196822013-09-04 16:12:25 +0100159#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000160 printf("Status Error: 0x%08X\n",
161 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100162#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900163 return -ECOMM;
Jan Kloetzked617c422012-02-05 22:29:12 +0000164 }
165 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000166 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000167
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500168 if (timeout-- <= 0)
169 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000170
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500171 udelay(1000);
172 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000173
Simon Glassc0c76eb2016-06-12 23:30:20 -0600174 mmc_trace_state(mmc, &cmd);
Jongman Heo5b0c9422012-06-03 21:32:13 +0000175 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100176#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000177 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100178#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900179 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000180 }
181
182 return 0;
183}
184
Paul Burtonda61fa52013-09-09 15:30:26 +0100185int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500186{
187 struct mmc_cmd cmd;
188
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600189 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900190 return 0;
191
Andy Fleming272cc702008-10-30 16:41:01 -0500192 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
193 cmd.resp_type = MMC_RSP_R1;
194 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500195
196 return mmc_send_cmd(mmc, &cmd, NULL);
197}
198
Sascha Silbeff8fef52013-06-14 13:07:25 +0200199static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000200 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500201{
202 struct mmc_cmd cmd;
203 struct mmc_data data;
204
Alagu Sankar4a1a06b2010-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 Fleming272cc702008-10-30 16:41:01 -0500209
210 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700211 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500212 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700213 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500214
215 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500216
217 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700218 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500219 data.blocksize = mmc->read_bl_len;
220 data.flags = MMC_DATA_READ;
221
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700222 if (mmc_send_cmd(mmc, &cmd, &data))
223 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500224
Alagu Sankar4a1a06b2010-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 Sankar4a1a06b2010-10-25 07:23:56 -0700229 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100230#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700231 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100232#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700233 return 0;
234 }
Andy Fleming272cc702008-10-30 16:41:01 -0500235 }
236
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700237 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500238}
239
Simon Glass33fb2112016-05-01 13:52:41 -0600240#ifdef CONFIG_BLK
Simon Glass7dba0b92016-06-12 23:30:15 -0600241ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600242#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600243ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
244 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600245#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500246{
Simon Glass33fb2112016-05-01 13:52:41 -0600247#ifdef CONFIG_BLK
248 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
249#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700250 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700251 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700252 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500253
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700254 if (blkcnt == 0)
255 return 0;
256
257 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500258 if (!mmc)
259 return 0;
260
Simon Glass69f45cd2016-05-01 13:52:29 -0600261 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
Stephen Warren873cc1d2015-12-07 11:38:49 -0700262 if (err < 0)
263 return 0;
264
Simon Glassc40fdca2016-05-01 13:52:35 -0600265 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100266#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200267 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glassc40fdca2016-05-01 13:52:35 -0600268 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100269#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800270 return 0;
271 }
Andy Fleming272cc702008-10-30 16:41:01 -0500272
Simon Glass11692992015-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 Fleming272cc702008-10-30 16:41:01 -0500275 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600276 }
Andy Fleming272cc702008-10-30 16:41:01 -0500277
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700278 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200279 cur = (blocks_todo > mmc->cfg->b_max) ?
280 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-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 Sankar4a1a06b2010-10-25 07:23:56 -0700283 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600284 }
Alagu Sankar4a1a06b2010-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 Fleming272cc702008-10-30 16:41:01 -0500289
290 return blkcnt;
291}
292
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000293static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-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 Fleming272cc702008-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 Phillipsfdbb8732012-10-29 13:34:43 +0000314static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500315{
316 int timeout = 1000;
317 int err;
318 struct mmc_cmd cmd;
319
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500320 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500321 cmd.cmdidx = MMC_CMD_APP_CMD;
322 cmd.resp_type = MMC_RSP_R1;
323 cmd.cmdarg = 0;
Andy Fleming272cc702008-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 Babic250de122010-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 Choud52ebf12010-12-24 13:12:21 +0000340 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200341 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-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 Gabbasov1677eef2015-03-19 07:44:06 -0500351 if (cmd.response[0] & OCR_BUSY)
352 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500353
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500354 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900355 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500356
357 udelay(1000);
358 }
Andy Fleming272cc702008-10-30 16:41:01 -0500359
360 if (mmc->version != SD_VERSION_2)
361 mmc->version = SD_VERSION_1_0;
362
Thomas Choud52ebf12010-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 Choud52ebf12010-12-24 13:12:21 +0000367
368 err = mmc_send_cmd(mmc, &cmd, NULL);
369
370 if (err)
371 return err;
372 }
373
Rabin Vincent998be3d2009-04-05 13:30:56 +0530374 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-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 Gabbasov5289b532015-03-19 07:44:04 -0500382static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500383{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500384 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500385 int err;
386
Andrew Gabbasov5289b532015-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 Herring5a203972015-03-23 17:56:59 -0500390 if (use_arg && !mmc_host_is_spi(mmc))
391 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200392 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500393 (mmc->ocr & OCR_VOLTAGE_MASK)) |
394 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000395
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500396 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000397 if (err)
398 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500399 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000400 return 0;
401}
402
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200403static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000404{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000405 int err, i;
406
Andy Fleming272cc702008-10-30 16:41:01 -0500407 /* Some cards seem to need this */
408 mmc_go_idle(mmc);
409
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000410 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000411 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500412 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500413 if (err)
414 return err;
415
Che-Liang Chioue9550442012-11-28 15:21:13 +0000416 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500417 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500418 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000419 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500420 mmc->op_cond_pending = 1;
421 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000422}
Andy Fleming272cc702008-10-30 16:41:01 -0500423
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200424static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000425{
426 struct mmc_cmd cmd;
427 int timeout = 1000;
428 uint start;
429 int err;
430
431 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500432 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lud188b112016-08-02 15:33:18 +0800433 /* Some cards seem to need this */
434 mmc_go_idle(mmc);
435
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500436 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500437 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500438 err = mmc_send_op_cond_iter(mmc, 1);
439 if (err)
440 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500441 if (mmc->ocr & OCR_BUSY)
442 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500443 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900444 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500445 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500446 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500447 }
Andy Fleming272cc702008-10-30 16:41:01 -0500448
Thomas Choud52ebf12010-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 Choud52ebf12010-12-24 13:12:21 +0000453
454 err = mmc_send_cmd(mmc, &cmd, NULL);
455
456 if (err)
457 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500458
459 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000460 }
461
Andy Fleming272cc702008-10-30 16:41:01 -0500462 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500463
464 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700465 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500466
467 return 0;
468}
469
470
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000471static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-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 Fleming272cc702008-10-30 16:41:01 -0500481
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000482 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500483 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000484 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-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 Glassc40704f2016-06-12 23:30:18 -0600492int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500493{
494 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000495 int timeout = 1000;
496 int ret;
Andy Fleming272cc702008-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 Recalcati5d4fc8d2011-03-11 02:01:12 +0000501 (index << 16) |
502 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500503
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000504 ret = mmc_send_cmd(mmc, &cmd, NULL);
505
506 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000507 if (!ret)
508 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000509
510 return ret;
511
Andy Fleming272cc702008-10-30 16:41:01 -0500512}
513
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000514static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500515{
Simon Glass8bfa1952013-04-03 08:54:30 +0000516 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500517 char cardtype;
518 int err;
519
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600520 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500521
Thomas Choud52ebf12010-12-24 13:12:21 +0000522 if (mmc_host_is_spi(mmc))
523 return 0;
524
Andy Fleming272cc702008-10-30 16:41:01 -0500525 /* Only version 4 supports high-speed */
526 if (mmc->version < MMC_VERSION_4)
527 return 0;
528
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600529 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
530
Andy Fleming272cc702008-10-30 16:41:01 -0500531 err = mmc_send_ext_csd(mmc, ext_csd);
532
533 if (err)
534 return err;
535
Lei Wen0560db12011-10-03 20:35:10 +0000536 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-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 Schochera5e27b42016-06-07 08:31:21 +0200541 return err;
Andy Fleming272cc702008-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 Wen0560db12011-10-03 20:35:10 +0000550 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500551 return 0;
552
553 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900554 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600555 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900556 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500557 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900558 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500559 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900560 }
Andy Fleming272cc702008-10-30 16:41:01 -0500561
562 return 0;
563}
564
Stephen Warrenf866a462013-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 Glassc40fdca2016-05-01 13:52:35 -0600588 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600589
590 return 0;
591}
592
Simon Glass7dba0b92016-06-12 23:30:15 -0600593int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000594{
Stephen Warrenf866a462013-06-11 15:14:01 -0600595 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000596
Stephen Warrenf866a462013-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));
Stephen Warrenf866a462013-06-11 15:14:01 -0600600
Peter Bigot6dc93e72014-09-02 18:31:23 -0500601 /*
602 * Set the capacity if the switch succeeded or was intended
603 * to return to representing the raw device.
604 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700605 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500606 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600607 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700608 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500609
610 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000611}
612
Diego Santa Cruzac9da0e2014-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 Cruz8dda5b0e2014-12-23 10:50:31 +0100623 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-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 Cruz8dda5b0e2014-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 Cruzac9da0e2014-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 Cruz8dda5b0e2014-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 Cruzac9da0e2014-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 Glass8ca51e52016-06-12 23:30:22 -0600807#ifndef CONFIG_DM_MMC_OPS
Thierry Reding48972d92012-01-02 01:15:37 +0000808int mmc_getcd(struct mmc *mmc)
809{
810 int cd;
811
812 cd = board_mmc_getcd(mmc);
813
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000814 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200815 if (mmc->cfg->ops->getcd)
816 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000817 else
818 cd = 1;
819 }
Thierry Reding48972d92012-01-02 01:15:37 +0000820
821 return cd;
822}
Simon Glass8ca51e52016-06-12 23:30:22 -0600823#endif
Thierry Reding48972d92012-01-02 01:15:37 +0000824
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000825static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-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 Fleming272cc702008-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 Phillipsfdbb8732012-10-29 13:34:43 +0000846static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500847{
848 int err;
849 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000850 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
851 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500852 struct mmc_data data;
853 int timeout;
854
855 mmc->card_caps = 0;
856
Thomas Choud52ebf12010-12-24 13:12:21 +0000857 if (mmc_host_is_spi(mmc))
858 return 0;
859
Andy Fleming272cc702008-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 Fleming272cc702008-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 Fleming272cc702008-10-30 16:41:01 -0500873
874 timeout = 3;
875
876retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000877 data.dest = (char *)scr;
Andy Fleming272cc702008-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 Kharuzhy4e3d89b2009-05-07 00:43:30 +0300891 mmc->scr[0] = __be32_to_cpu(scr[0]);
892 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500893
894 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-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 Fleming272cc702008-10-30 16:41:01 -0500909 }
910
Alagu Sankarb44c7082010-05-12 15:08:24 +0530911 if (mmc->scr[0] & SD_DATA_4BIT)
912 mmc->card_caps |= MMC_MODE_4BIT;
913
Andy Fleming272cc702008-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 staaff781dd32011-10-03 13:54:59 +0000921 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500922
923 if (err)
924 return err;
925
926 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300927 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500928 break;
929 }
930
Andy Fleming272cc702008-10-30 16:41:01 -0500931 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300932 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500933 return 0;
934
Macpaul Lin2c3fbf42011-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 Antoniou93bfd612014-03-11 19:34:20 +0200941 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
942 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000943 return 0;
944
Anton staaff781dd32011-10-03 13:54:59 +0000945 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500946
947 if (err)
948 return err;
949
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300950 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500951 mmc->card_caps |= MMC_MODE_HS;
952
953 return 0;
954}
955
Peng Fan3697e592016-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 Fleming272cc702008-10-30 16:41:01 -05001012/* frequency bases */
1013/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001014static const int fbase[] = {
Andy Fleming272cc702008-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 Glass61fe0762016-05-14 14:02:57 -06001024static const u8 multipliers[] = {
Andy Fleming272cc702008-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 Glass8ca51e52016-06-12 23:30:22 -06001043#ifndef CONFIG_DM_MMC_OPS
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001044static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001045{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001046 if (mmc->cfg->ops->set_ios)
1047 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001048}
Simon Glass8ca51e52016-06-12 23:30:22 -06001049#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001050
1051void mmc_set_clock(struct mmc *mmc, uint clock)
1052{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001053 if (clock > mmc->cfg->f_max)
1054 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001055
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001056 if (clock < mmc->cfg->f_min)
1057 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001058
1059 mmc->clock = clock;
1060
1061 mmc_set_ios(mmc);
1062}
1063
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001064static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001065{
1066 mmc->bus_width = width;
1067
1068 mmc_set_ios(mmc);
1069}
1070
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001071static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001072{
Stephen Warrenf866a462013-06-11 15:14:01 -06001073 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001074 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001075 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001076 struct mmc_cmd cmd;
Simon Glass8bfa1952013-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 Recalcati5d4fc8d2011-03-11 02:01:12 +00001079 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001080 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001081 bool part_completed;
Simon Glassc40fdca2016-05-01 13:52:35 -06001082 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05001083
Thomas Choud52ebf12010-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 Choud52ebf12010-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 Fleming272cc702008-10-30 16:41:01 -05001096 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-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 Fleming272cc702008-10-30 16:41:01 -05001099 cmd.resp_type = MMC_RSP_R2;
1100 cmd.cmdarg = 0;
Andy Fleming272cc702008-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 Choud52ebf12010-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 Fleming272cc702008-10-30 16:41:01 -05001118
Thomas Choud52ebf12010-12-24 13:12:21 +00001119 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001120
Thomas Choud52ebf12010-12-24 13:12:21 +00001121 if (err)
1122 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001123
Thomas Choud52ebf12010-12-24 13:12:21 +00001124 if (IS_SD(mmc))
1125 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1126 }
Andy Fleming272cc702008-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 Fleming272cc702008-10-30 16:41:01 -05001132
1133 err = mmc_send_cmd(mmc, &cmd, NULL);
1134
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001135 /* Waiting for the ready status */
1136 mmc_send_status(mmc, timeout);
1137
Andy Fleming272cc702008-10-30 16:41:01 -05001138 if (err)
1139 return err;
1140
Rabin Vincent998be3d2009-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 Fleming272cc702008-10-30 16:41:01 -05001145
1146 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301147 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001148
1149 switch (version) {
Bin Meng53e8e402016-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 Fleming272cc702008-10-30 16:41:01 -05001168 }
1169 }
1170
1171 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301172 freq = fbase[(cmd.response[0] & 0x7)];
1173 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001174
1175 mmc->tran_speed = freq * mult;
1176
Markus Niebelab711882013-12-16 13:40:46 +01001177 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301178 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001179
1180 if (IS_SD(mmc))
1181 mmc->write_bl_len = mmc->read_bl_len;
1182 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301183 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-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 Warrenf866a462013-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 Fleming272cc702008-10-30 16:41:01 -05001201
Simon Glass8bfa1952013-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 Fleming272cc702008-10-30 16:41:01 -05001204
Simon Glass8bfa1952013-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 Fleming272cc702008-10-30 16:41:01 -05001207
Markus Niebelab711882013-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 Fleming272cc702008-10-30 16:41:01 -05001216 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-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 Bhargavfe8f7062011-10-05 03:13:23 +00001219 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001220 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001221 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001222
Thomas Choud52ebf12010-12-24 13:12:21 +00001223 if (err)
1224 return err;
1225 }
Andy Fleming272cc702008-10-30 16:41:01 -05001226
Lei Wene6f99a52011-06-22 17:03:31 +00001227 /*
1228 * For SD, its erase group is always one sector
1229 */
1230 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001231 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-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 Cruz9cf199e2014-12-23 10:50:28 +01001235 if (err)
1236 return err;
1237 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-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 Wen0560db12011-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 Glass8bfa1952013-04-03 08:54:30 +00001247 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001248 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001249 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301250 }
Lei Wenbc897b12011-05-02 16:26:26 +00001251
Jaehoon Chung64f4a612013-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 Niebeledab7232014-11-18 15:13:53 +01001268 case 7:
1269 mmc->version = MMC_VERSION_5_0;
1270 break;
Stefan Wahren1a3619c2016-06-16 17:54:06 +00001271 case 8:
1272 mmc->version = MMC_VERSION_5_1;
1273 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001274 }
1275
Diego Santa Cruz8a0cf492014-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 Cruz0c453bb2014-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 Cruz8a0cf492014-12-23 10:50:27 +01001289 if (part_completed &&
1290 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-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 Cruz8a0cf492014-12-23 10:50:27 +01001299 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001300 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-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 Cruz0c453bb2014-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 Cruzf8e89d62014-12-23 10:50:21 +01001309 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001310 }
1311
Diego Santa Cruz8a0cf492014-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 Cruza7f852b2014-12-23 10:50:22 +01001328
Lei Wene6f99a52011-06-22 17:03:31 +00001329 /*
Oliver Metz1937e5a2013-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 Wene6f99a52011-06-22 17:03:31 +00001333 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001334 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001335 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001336 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001337 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1338 has_parts = true;
1339 if (has_parts) {
Oliver Metz1937e5a2013-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 Petermaier021a8052014-08-08 09:47:22 +02001345 else
1346 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001347 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001348
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001349 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001350 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001351 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001352 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-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 Cruz8a0cf492014-12-23 10:50:27 +01001358 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-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 Glass8bfa1952013-04-03 08:54:30 +00001366 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001367 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-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 Cruz037dc0a2014-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 Cruz9e41a002014-12-23 10:50:33 +01001378
1379 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301380 }
1381
Simon Glassc40fdca2016-05-01 13:52:35 -06001382 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06001383 if (err)
1384 return err;
1385
Andy Fleming272cc702008-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 Antoniou93bfd612014-03-11 19:34:20 +02001395 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-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 Fleming272cc702008-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 Fleming272cc702008-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 Fan3697e592016-09-01 11:13:38 +08001417 err = sd_read_ssr(mmc);
1418 if (err)
1419 return err;
1420
Andy Fleming272cc702008-10-30 16:41:01 -05001421 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001422 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001423 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001424 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001425 } else if (mmc->version >= MMC_VERSION_4) {
1426 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-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 Chungd22e3d42014-05-16 13:59:54 +09001431 EXT_CSD_DDR_BUS_WIDTH_8,
1432 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-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 Gabbasov786e8f82014-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 Fleming7798f6d2012-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 Chungd22e3d42014-05-16 13:59:54 +09001450 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-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 Gabbasov786e8f82014-12-01 06:59:09 -06001455 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001456
1457 /*
Andrew Gabbasovbf477072014-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 Gabbasov786e8f82014-12-01 06:59:09 -06001470 * Check to make sure the card and controller support
1471 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001472 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001473 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001474 continue;
1475
Andy Fleming272cc702008-10-30 16:41:01 -05001476 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001477 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001478
1479 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001480 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001481
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001482 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001483 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001484
Lei Wen41378942011-10-03 20:35:11 +00001485 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001486
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001487 if (err)
1488 continue;
1489
1490 /* 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 Wen41378942011-10-03 20:35:11 +00001501 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001502 else
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001503 err = -EBADMSG;
Andy Fleming272cc702008-10-30 16:41:01 -05001504 }
1505
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001506 if (err)
1507 return err;
1508
Andy Fleming272cc702008-10-30 16:41:01 -05001509 if (mmc->card_caps & MMC_MODE_HS) {
1510 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001511 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001512 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001513 mmc->tran_speed = 26000000;
1514 }
Andy Fleming272cc702008-10-30 16:41:01 -05001515 }
1516
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001517 mmc_set_clock(mmc, mmc->tran_speed);
1518
Andrew Gabbasov5af8f452014-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 Fleming272cc702008-10-30 16:41:01 -05001525 /* fill in device description */
Simon Glassc40fdca2016-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 Simonsfc011f62015-12-04 23:27:40 +01001533#if !defined(CONFIG_SPL_BUILD) || \
1534 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1535 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06001536 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00001537 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1538 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001539 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-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 Glassc40fdca2016-05-01 13:52:35 -06001543 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001544 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001545#else
Simon Glassc40fdca2016-05-01 13:52:35 -06001546 bdesc->vendor[0] = 0;
1547 bdesc->product[0] = 0;
1548 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01001549#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001550#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glassc40fdca2016-05-01 13:52:35 -06001551 part_init(bdesc);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001552#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001553
1554 return 0;
1555}
1556
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001557static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-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 Antoniou93bfd612014-03-11 19:34:20 +02001564 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001565 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001566
1567 err = mmc_send_cmd(mmc, &cmd, NULL);
1568
1569 if (err)
1570 return err;
1571
Rabin Vincent998be3d2009-04-05 13:30:56 +05301572 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001573 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05001574 else
1575 mmc->version = SD_VERSION_2;
1576
1577 return 0;
1578}
1579
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001580/* board-specific MMC power initializations. */
1581__weak void board_mmc_power_init(void)
1582{
1583}
1584
Che-Liang Chioue9550442012-11-28 15:21:13 +00001585int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001586{
Simon Glass8ca51e52016-06-12 23:30:22 -06001587 bool no_card;
Macpaul Linafd59322011-11-14 23:35:39 +00001588 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001589
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001590 /* we pretend there's no card when init is NULL */
Simon Glass8ca51e52016-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 Reding48972d92012-01-02 01:15:37 +00001596 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001597#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001598 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001599#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001600 return -ENOMEDIUM;
Thierry Reding48972d92012-01-02 01:15:37 +00001601 }
1602
Lei Wenbc897b12011-05-02 16:26:26 +00001603 if (mmc->has_init)
1604 return 0;
1605
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001606#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1607 mmc_adapter_card_type_ident();
1608#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001609 board_mmc_power_init();
1610
Simon Glass8ca51e52016-06-12 23:30:22 -06001611#ifdef CONFIG_DM_MMC_OPS
1612 /* The device has already been probed ready for use */
1613#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001614 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001615 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001616 if (err)
1617 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06001618#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001619 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001620 mmc_set_bus_width(mmc, 1);
1621 mmc_set_clock(mmc, 1);
1622
Andy Fleming272cc702008-10-30 16:41:01 -05001623 /* Reset the Card */
1624 err = mmc_go_idle(mmc);
1625
1626 if (err)
1627 return err;
1628
Lei Wenbc897b12011-05-02 16:26:26 +00001629 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06001630 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00001631
Andy Fleming272cc702008-10-30 16:41:01 -05001632 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001633 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001634
Andy Fleming272cc702008-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 Chung915ffa52016-07-19 16:33:36 +09001639 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05001640 err = mmc_send_op_cond(mmc);
1641
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001642 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001643#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001644 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001645#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001646 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05001647 }
1648 }
1649
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001650 if (!err)
Che-Liang Chioue9550442012-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 Gabbasovbd47c132015-03-19 07:44:07 -05001660 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-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 Wenbc897b12011-05-02 16:26:26 +00001666 if (err)
1667 mmc->has_init = 0;
1668 else
1669 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001670 return err;
1671}
1672
1673int mmc_init(struct mmc *mmc)
1674{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001675 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001676 unsigned start;
Simon Glass33fb2112016-05-01 13:52:41 -06001677#ifdef CONFIG_DM_MMC
1678 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00001679
Simon Glass33fb2112016-05-01 13:52:41 -06001680 upriv->mmc = mmc;
1681#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001682 if (mmc->has_init)
1683 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001684
1685 start = get_timer(0);
1686
Che-Liang Chioue9550442012-11-28 15:21:13 +00001687 if (!mmc->init_in_progress)
1688 err = mmc_start_init(mmc);
1689
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001690 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001691 err = mmc_complete_init(mmc);
1692 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001693 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001694}
1695
Markus Niebelab711882013-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 Hofsteecee9ab72014-07-10 22:46:28 +02001702/* CPU-specific MMC initializations */
1703__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001704{
1705 return -1;
1706}
1707
Jeroen Hofsteecee9ab72014-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 Fleming272cc702008-10-30 16:41:01 -05001713
Che-Liang Chioue9550442012-11-28 15:21:13 +00001714void mmc_set_preinit(struct mmc *mmc, int preinit)
1715{
1716 mmc->preinit = preinit;
1717}
1718
Sjoerd Simons8e3332e2015-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 Glass4a1db6d2015-12-29 05:22:49 -07001727 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001728 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07001729 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001730
1731 ret = uclass_get(UCLASS_MMC, &uc);
1732 if (ret)
1733 return ret;
1734
Simon Glass4a1db6d2015-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 Simons8e3332e2015-08-30 16:55:45 -06001747 if (ret)
Simon Glass4a1db6d2015-12-29 05:22:49 -07001748 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-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 Chioue9550442012-11-28 15:21:13 +00001762
Andy Fleming272cc702008-10-30 16:41:01 -05001763int mmc_initialize(bd_t *bis)
1764{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001765 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001766 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001767 if (initialized) /* Avoid initializing mmc multiple times */
1768 return 0;
1769 initialized = 1;
1770
Simon Glassc40fdca2016-05-01 13:52:35 -06001771#ifndef CONFIG_BLK
1772 mmc_list_init();
1773#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001774 ret = mmc_probe(bis);
1775 if (ret)
1776 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001777
Ying Zhangbb0dc102013-08-16 15:16:11 +08001778#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001779 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001780#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001781
Simon Glassc40fdca2016-05-01 13:52:35 -06001782 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001783 return 0;
1784}