blob: 3daa74882265ef356453b0ba086f4bc3c2f519c7 [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
Simon Glass8ca51e52016-06-12 23:30:22 -060024#ifndef CONFIG_DM_MMC_OPS
Jeroen Hofstee750121c2014-07-12 21:24:08 +020025__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000026{
27 return -1;
28}
29
30int mmc_getwp(struct mmc *mmc)
31{
32 int wp;
33
34 wp = board_mmc_getwp(mmc);
35
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000036 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020037 if (mmc->cfg->ops->getwp)
38 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000039 else
40 wp = 0;
41 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000042
43 return wp;
44}
45
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020046__weak int board_mmc_getcd(struct mmc *mmc)
47{
Stefano Babic11fdade2010-02-05 15:04:43 +010048 return -1;
49}
Simon Glass8ca51e52016-06-12 23:30:22 -060050#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010051
Marek Vasut8635ff92012-03-15 18:41:35 +000052#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060053void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
54{
55 printf("CMD_SEND:%d\n", cmd->cmdidx);
56 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
57}
58
59void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
60{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000061 int i;
62 u8 *ptr;
63
Bin Meng7863ce52016-03-17 21:53:14 -070064 if (ret) {
65 printf("\t\tRET\t\t\t %d\n", ret);
66 } else {
67 switch (cmd->resp_type) {
68 case MMC_RSP_NONE:
69 printf("\t\tMMC_RSP_NONE\n");
70 break;
71 case MMC_RSP_R1:
72 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
73 cmd->response[0]);
74 break;
75 case MMC_RSP_R1b:
76 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
77 cmd->response[0]);
78 break;
79 case MMC_RSP_R2:
80 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
81 cmd->response[0]);
82 printf("\t\t \t\t 0x%08X \n",
83 cmd->response[1]);
84 printf("\t\t \t\t 0x%08X \n",
85 cmd->response[2]);
86 printf("\t\t \t\t 0x%08X \n",
87 cmd->response[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000088 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -070089 printf("\t\t\t\t\tDUMPING DATA\n");
90 for (i = 0; i < 4; i++) {
91 int j;
92 printf("\t\t\t\t\t%03d - ", i*4);
93 ptr = (u8 *)&cmd->response[i];
94 ptr += 3;
95 for (j = 0; j < 4; j++)
96 printf("%02X ", *ptr--);
97 printf("\n");
98 }
99 break;
100 case MMC_RSP_R3:
101 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
102 cmd->response[0]);
103 break;
104 default:
105 printf("\t\tERROR MMC rsp not supported\n");
106 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700107 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000108 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600109}
110
111void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
112{
113 int status;
114
115 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
116 printf("CURR STATE:%d\n", status);
117}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000118#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600119
Simon Glass8ca51e52016-06-12 23:30:22 -0600120#ifndef CONFIG_DM_MMC_OPS
Simon Glassc0c76eb2016-06-12 23:30:20 -0600121int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
122{
123 int ret;
124
125 mmmc_trace_before_send(mmc, cmd);
126 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
127 mmmc_trace_after_send(mmc, cmd, ret);
128
Marek Vasut8635ff92012-03-15 18:41:35 +0000129 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500130}
Simon Glass8ca51e52016-06-12 23:30:22 -0600131#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500132
Paul Burtonda61fa52013-09-09 15:30:26 +0100133int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000134{
135 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000136 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000137
138 cmd.cmdidx = MMC_CMD_SEND_STATUS;
139 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200140 if (!mmc_host_is_spi(mmc))
141 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000142
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500143 while (1) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000144 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000145 if (!err) {
146 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
147 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
148 MMC_STATE_PRG)
149 break;
150 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton56196822013-09-04 16:12:25 +0100151#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000152 printf("Status Error: 0x%08X\n",
153 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100154#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900155 return -ECOMM;
Jan Kloetzked617c422012-02-05 22:29:12 +0000156 }
157 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000158 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000159
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500160 if (timeout-- <= 0)
161 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000162
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500163 udelay(1000);
164 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000165
Simon Glassc0c76eb2016-06-12 23:30:20 -0600166 mmc_trace_state(mmc, &cmd);
Jongman Heo5b0c9422012-06-03 21:32:13 +0000167 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100168#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000169 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100170#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900171 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000172 }
173
174 return 0;
175}
176
Paul Burtonda61fa52013-09-09 15:30:26 +0100177int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500178{
179 struct mmc_cmd cmd;
180
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600181 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900182 return 0;
183
Andy Fleming272cc702008-10-30 16:41:01 -0500184 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
185 cmd.resp_type = MMC_RSP_R1;
186 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500187
188 return mmc_send_cmd(mmc, &cmd, NULL);
189}
190
Sascha Silbeff8fef52013-06-14 13:07:25 +0200191static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000192 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500193{
194 struct mmc_cmd cmd;
195 struct mmc_data data;
196
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700197 if (blkcnt > 1)
198 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
199 else
200 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500201
202 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700203 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500204 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700205 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500206
207 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500208
209 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700210 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500211 data.blocksize = mmc->read_bl_len;
212 data.flags = MMC_DATA_READ;
213
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700214 if (mmc_send_cmd(mmc, &cmd, &data))
215 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500216
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700217 if (blkcnt > 1) {
218 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
219 cmd.cmdarg = 0;
220 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700221 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100222#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700223 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100224#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700225 return 0;
226 }
Andy Fleming272cc702008-10-30 16:41:01 -0500227 }
228
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700229 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500230}
231
Simon Glass33fb2112016-05-01 13:52:41 -0600232#ifdef CONFIG_BLK
Simon Glass7dba0b92016-06-12 23:30:15 -0600233ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600234#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600235ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
236 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600237#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500238{
Simon Glass33fb2112016-05-01 13:52:41 -0600239#ifdef CONFIG_BLK
240 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
241#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700242 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700243 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700244 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500245
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700246 if (blkcnt == 0)
247 return 0;
248
249 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500250 if (!mmc)
251 return 0;
252
Simon Glass69f45cd2016-05-01 13:52:29 -0600253 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
Stephen Warren873cc1d2015-12-07 11:38:49 -0700254 if (err < 0)
255 return 0;
256
Simon Glassc40fdca2016-05-01 13:52:35 -0600257 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100258#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200259 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glassc40fdca2016-05-01 13:52:35 -0600260 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100261#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800262 return 0;
263 }
Andy Fleming272cc702008-10-30 16:41:01 -0500264
Simon Glass11692992015-06-23 15:38:50 -0600265 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
266 debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500267 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600268 }
Andy Fleming272cc702008-10-30 16:41:01 -0500269
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700270 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200271 cur = (blocks_todo > mmc->cfg->b_max) ?
272 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600273 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
274 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700275 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600276 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700277 blocks_todo -= cur;
278 start += cur;
279 dst += cur * mmc->read_bl_len;
280 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500281
282 return blkcnt;
283}
284
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000285static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500286{
287 struct mmc_cmd cmd;
288 int err;
289
290 udelay(1000);
291
292 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
293 cmd.cmdarg = 0;
294 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500295
296 err = mmc_send_cmd(mmc, &cmd, NULL);
297
298 if (err)
299 return err;
300
301 udelay(2000);
302
303 return 0;
304}
305
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000306static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500307{
308 int timeout = 1000;
309 int err;
310 struct mmc_cmd cmd;
311
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500312 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500313 cmd.cmdidx = MMC_CMD_APP_CMD;
314 cmd.resp_type = MMC_RSP_R1;
315 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500316
317 err = mmc_send_cmd(mmc, &cmd, NULL);
318
319 if (err)
320 return err;
321
322 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
323 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100324
325 /*
326 * Most cards do not answer if some reserved bits
327 * in the ocr are set. However, Some controller
328 * can set bit 7 (reserved for low voltages), but
329 * how to manage low voltages SD card is not yet
330 * specified.
331 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000332 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200333 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500334
335 if (mmc->version == SD_VERSION_2)
336 cmd.cmdarg |= OCR_HCS;
337
338 err = mmc_send_cmd(mmc, &cmd, NULL);
339
340 if (err)
341 return err;
342
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500343 if (cmd.response[0] & OCR_BUSY)
344 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500345
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500346 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900347 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500348
349 udelay(1000);
350 }
Andy Fleming272cc702008-10-30 16:41:01 -0500351
352 if (mmc->version != SD_VERSION_2)
353 mmc->version = SD_VERSION_1_0;
354
Thomas Choud52ebf12010-12-24 13:12:21 +0000355 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
356 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
357 cmd.resp_type = MMC_RSP_R3;
358 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000359
360 err = mmc_send_cmd(mmc, &cmd, NULL);
361
362 if (err)
363 return err;
364 }
365
Rabin Vincent998be3d2009-04-05 13:30:56 +0530366 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500367
368 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
369 mmc->rca = 0;
370
371 return 0;
372}
373
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500374static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500375{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500376 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500377 int err;
378
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500379 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
380 cmd.resp_type = MMC_RSP_R3;
381 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500382 if (use_arg && !mmc_host_is_spi(mmc))
383 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200384 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500385 (mmc->ocr & OCR_VOLTAGE_MASK)) |
386 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000387
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500388 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000389 if (err)
390 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500391 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000392 return 0;
393}
394
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200395static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000396{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000397 int err, i;
398
Andy Fleming272cc702008-10-30 16:41:01 -0500399 /* Some cards seem to need this */
400 mmc_go_idle(mmc);
401
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000402 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000403 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500404 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500405 if (err)
406 return err;
407
Che-Liang Chioue9550442012-11-28 15:21:13 +0000408 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500409 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500410 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000411 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500412 mmc->op_cond_pending = 1;
413 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000414}
Andy Fleming272cc702008-10-30 16:41:01 -0500415
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200416static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000417{
418 struct mmc_cmd cmd;
419 int timeout = 1000;
420 uint start;
421 int err;
422
423 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500424 if (!(mmc->ocr & OCR_BUSY)) {
425 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500426 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500427 err = mmc_send_op_cond_iter(mmc, 1);
428 if (err)
429 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500430 if (mmc->ocr & OCR_BUSY)
431 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500432 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900433 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500434 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500435 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500436 }
Andy Fleming272cc702008-10-30 16:41:01 -0500437
Thomas Choud52ebf12010-12-24 13:12:21 +0000438 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
439 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
440 cmd.resp_type = MMC_RSP_R3;
441 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000442
443 err = mmc_send_cmd(mmc, &cmd, NULL);
444
445 if (err)
446 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500447
448 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000449 }
450
Andy Fleming272cc702008-10-30 16:41:01 -0500451 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500452
453 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700454 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500455
456 return 0;
457}
458
459
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000460static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500461{
462 struct mmc_cmd cmd;
463 struct mmc_data data;
464 int err;
465
466 /* Get the Card Status Register */
467 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
468 cmd.resp_type = MMC_RSP_R1;
469 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500470
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000471 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500472 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000473 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500474 data.flags = MMC_DATA_READ;
475
476 err = mmc_send_cmd(mmc, &cmd, &data);
477
478 return err;
479}
480
Simon Glassc40704f2016-06-12 23:30:18 -0600481int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500482{
483 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000484 int timeout = 1000;
485 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500486
487 cmd.cmdidx = MMC_CMD_SWITCH;
488 cmd.resp_type = MMC_RSP_R1b;
489 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000490 (index << 16) |
491 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500492
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000493 ret = mmc_send_cmd(mmc, &cmd, NULL);
494
495 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000496 if (!ret)
497 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000498
499 return ret;
500
Andy Fleming272cc702008-10-30 16:41:01 -0500501}
502
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000503static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500504{
Simon Glass8bfa1952013-04-03 08:54:30 +0000505 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500506 char cardtype;
507 int err;
508
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600509 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500510
Thomas Choud52ebf12010-12-24 13:12:21 +0000511 if (mmc_host_is_spi(mmc))
512 return 0;
513
Andy Fleming272cc702008-10-30 16:41:01 -0500514 /* Only version 4 supports high-speed */
515 if (mmc->version < MMC_VERSION_4)
516 return 0;
517
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600518 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
519
Andy Fleming272cc702008-10-30 16:41:01 -0500520 err = mmc_send_ext_csd(mmc, ext_csd);
521
522 if (err)
523 return err;
524
Lei Wen0560db12011-10-03 20:35:10 +0000525 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500526
527 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
528
529 if (err)
Heiko Schochera5e27b42016-06-07 08:31:21 +0200530 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500531
532 /* Now check to see that it worked */
533 err = mmc_send_ext_csd(mmc, ext_csd);
534
535 if (err)
536 return err;
537
538 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000539 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500540 return 0;
541
542 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900543 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600544 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900545 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500546 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900547 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500548 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900549 }
Andy Fleming272cc702008-10-30 16:41:01 -0500550
551 return 0;
552}
553
Stephen Warrenf866a462013-06-11 15:14:01 -0600554static int mmc_set_capacity(struct mmc *mmc, int part_num)
555{
556 switch (part_num) {
557 case 0:
558 mmc->capacity = mmc->capacity_user;
559 break;
560 case 1:
561 case 2:
562 mmc->capacity = mmc->capacity_boot;
563 break;
564 case 3:
565 mmc->capacity = mmc->capacity_rpmb;
566 break;
567 case 4:
568 case 5:
569 case 6:
570 case 7:
571 mmc->capacity = mmc->capacity_gp[part_num - 4];
572 break;
573 default:
574 return -1;
575 }
576
Simon Glassc40fdca2016-05-01 13:52:35 -0600577 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600578
579 return 0;
580}
581
Simon Glass7dba0b92016-06-12 23:30:15 -0600582int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000583{
Stephen Warrenf866a462013-06-11 15:14:01 -0600584 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000585
Stephen Warrenf866a462013-06-11 15:14:01 -0600586 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
587 (mmc->part_config & ~PART_ACCESS_MASK)
588 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600589
Peter Bigot6dc93e72014-09-02 18:31:23 -0500590 /*
591 * Set the capacity if the switch succeeded or was intended
592 * to return to representing the raw device.
593 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700594 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500595 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600596 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700597 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500598
599 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000600}
601
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100602int mmc_hwpart_config(struct mmc *mmc,
603 const struct mmc_hwpart_conf *conf,
604 enum mmc_hwpart_conf_mode mode)
605{
606 u8 part_attrs = 0;
607 u32 enh_size_mult;
608 u32 enh_start_addr;
609 u32 gp_size_mult[4];
610 u32 max_enh_size_mult;
611 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100612 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100613 int i, pidx, err;
614 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
615
616 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
617 return -EINVAL;
618
619 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
620 printf("eMMC >= 4.4 required for enhanced user data area\n");
621 return -EMEDIUMTYPE;
622 }
623
624 if (!(mmc->part_support & PART_SUPPORT)) {
625 printf("Card does not support partitioning\n");
626 return -EMEDIUMTYPE;
627 }
628
629 if (!mmc->hc_wp_grp_size) {
630 printf("Card does not define HC WP group size\n");
631 return -EMEDIUMTYPE;
632 }
633
634 /* check partition alignment and total enhanced size */
635 if (conf->user.enh_size) {
636 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
637 conf->user.enh_start % mmc->hc_wp_grp_size) {
638 printf("User data enhanced area not HC WP group "
639 "size aligned\n");
640 return -EINVAL;
641 }
642 part_attrs |= EXT_CSD_ENH_USR;
643 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
644 if (mmc->high_capacity) {
645 enh_start_addr = conf->user.enh_start;
646 } else {
647 enh_start_addr = (conf->user.enh_start << 9);
648 }
649 } else {
650 enh_size_mult = 0;
651 enh_start_addr = 0;
652 }
653 tot_enh_size_mult += enh_size_mult;
654
655 for (pidx = 0; pidx < 4; pidx++) {
656 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
657 printf("GP%i partition not HC WP group size "
658 "aligned\n", pidx+1);
659 return -EINVAL;
660 }
661 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
662 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
663 part_attrs |= EXT_CSD_ENH_GP(pidx);
664 tot_enh_size_mult += gp_size_mult[pidx];
665 }
666 }
667
668 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
669 printf("Card does not support enhanced attribute\n");
670 return -EMEDIUMTYPE;
671 }
672
673 err = mmc_send_ext_csd(mmc, ext_csd);
674 if (err)
675 return err;
676
677 max_enh_size_mult =
678 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
679 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
680 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
681 if (tot_enh_size_mult > max_enh_size_mult) {
682 printf("Total enhanced size exceeds maximum (%u > %u)\n",
683 tot_enh_size_mult, max_enh_size_mult);
684 return -EMEDIUMTYPE;
685 }
686
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100687 /* The default value of EXT_CSD_WR_REL_SET is device
688 * dependent, the values can only be changed if the
689 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
690 * changed only once and before partitioning is completed. */
691 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
692 if (conf->user.wr_rel_change) {
693 if (conf->user.wr_rel_set)
694 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
695 else
696 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
697 }
698 for (pidx = 0; pidx < 4; pidx++) {
699 if (conf->gp_part[pidx].wr_rel_change) {
700 if (conf->gp_part[pidx].wr_rel_set)
701 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
702 else
703 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
704 }
705 }
706
707 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
708 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
709 puts("Card does not support host controlled partition write "
710 "reliability settings\n");
711 return -EMEDIUMTYPE;
712 }
713
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100714 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
715 EXT_CSD_PARTITION_SETTING_COMPLETED) {
716 printf("Card already partitioned\n");
717 return -EPERM;
718 }
719
720 if (mode == MMC_HWPART_CONF_CHECK)
721 return 0;
722
723 /* Partitioning requires high-capacity size definitions */
724 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
725 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
726 EXT_CSD_ERASE_GROUP_DEF, 1);
727
728 if (err)
729 return err;
730
731 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
732
733 /* update erase group size to be high-capacity */
734 mmc->erase_grp_size =
735 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
736
737 }
738
739 /* all OK, write the configuration */
740 for (i = 0; i < 4; i++) {
741 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
742 EXT_CSD_ENH_START_ADDR+i,
743 (enh_start_addr >> (i*8)) & 0xFF);
744 if (err)
745 return err;
746 }
747 for (i = 0; i < 3; i++) {
748 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
749 EXT_CSD_ENH_SIZE_MULT+i,
750 (enh_size_mult >> (i*8)) & 0xFF);
751 if (err)
752 return err;
753 }
754 for (pidx = 0; pidx < 4; pidx++) {
755 for (i = 0; i < 3; i++) {
756 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
757 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
758 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
759 if (err)
760 return err;
761 }
762 }
763 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
764 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
765 if (err)
766 return err;
767
768 if (mode == MMC_HWPART_CONF_SET)
769 return 0;
770
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100771 /* The WR_REL_SET is a write-once register but shall be
772 * written before setting PART_SETTING_COMPLETED. As it is
773 * write-once we can only write it when completing the
774 * partitioning. */
775 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
776 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
777 EXT_CSD_WR_REL_SET, wr_rel_set);
778 if (err)
779 return err;
780 }
781
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100782 /* Setting PART_SETTING_COMPLETED confirms the partition
783 * configuration but it only becomes effective after power
784 * cycle, so we do not adjust the partition related settings
785 * in the mmc struct. */
786
787 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
788 EXT_CSD_PARTITION_SETTING,
789 EXT_CSD_PARTITION_SETTING_COMPLETED);
790 if (err)
791 return err;
792
793 return 0;
794}
795
Simon Glass8ca51e52016-06-12 23:30:22 -0600796#ifndef CONFIG_DM_MMC_OPS
Thierry Reding48972d92012-01-02 01:15:37 +0000797int mmc_getcd(struct mmc *mmc)
798{
799 int cd;
800
801 cd = board_mmc_getcd(mmc);
802
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000803 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200804 if (mmc->cfg->ops->getcd)
805 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000806 else
807 cd = 1;
808 }
Thierry Reding48972d92012-01-02 01:15:37 +0000809
810 return cd;
811}
Simon Glass8ca51e52016-06-12 23:30:22 -0600812#endif
Thierry Reding48972d92012-01-02 01:15:37 +0000813
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000814static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500815{
816 struct mmc_cmd cmd;
817 struct mmc_data data;
818
819 /* Switch the frequency */
820 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
821 cmd.resp_type = MMC_RSP_R1;
822 cmd.cmdarg = (mode << 31) | 0xffffff;
823 cmd.cmdarg &= ~(0xf << (group * 4));
824 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500825
826 data.dest = (char *)resp;
827 data.blocksize = 64;
828 data.blocks = 1;
829 data.flags = MMC_DATA_READ;
830
831 return mmc_send_cmd(mmc, &cmd, &data);
832}
833
834
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000835static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500836{
837 int err;
838 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000839 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
840 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500841 struct mmc_data data;
842 int timeout;
843
844 mmc->card_caps = 0;
845
Thomas Choud52ebf12010-12-24 13:12:21 +0000846 if (mmc_host_is_spi(mmc))
847 return 0;
848
Andy Fleming272cc702008-10-30 16:41:01 -0500849 /* Read the SCR to find out if this card supports higher speeds */
850 cmd.cmdidx = MMC_CMD_APP_CMD;
851 cmd.resp_type = MMC_RSP_R1;
852 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500853
854 err = mmc_send_cmd(mmc, &cmd, NULL);
855
856 if (err)
857 return err;
858
859 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
860 cmd.resp_type = MMC_RSP_R1;
861 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500862
863 timeout = 3;
864
865retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000866 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500867 data.blocksize = 8;
868 data.blocks = 1;
869 data.flags = MMC_DATA_READ;
870
871 err = mmc_send_cmd(mmc, &cmd, &data);
872
873 if (err) {
874 if (timeout--)
875 goto retry_scr;
876
877 return err;
878 }
879
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300880 mmc->scr[0] = __be32_to_cpu(scr[0]);
881 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500882
883 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -0700884 case 0:
885 mmc->version = SD_VERSION_1_0;
886 break;
887 case 1:
888 mmc->version = SD_VERSION_1_10;
889 break;
890 case 2:
891 mmc->version = SD_VERSION_2;
892 if ((mmc->scr[0] >> 15) & 0x1)
893 mmc->version = SD_VERSION_3;
894 break;
895 default:
896 mmc->version = SD_VERSION_1_0;
897 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500898 }
899
Alagu Sankarb44c7082010-05-12 15:08:24 +0530900 if (mmc->scr[0] & SD_DATA_4BIT)
901 mmc->card_caps |= MMC_MODE_4BIT;
902
Andy Fleming272cc702008-10-30 16:41:01 -0500903 /* Version 1.0 doesn't support switching */
904 if (mmc->version == SD_VERSION_1_0)
905 return 0;
906
907 timeout = 4;
908 while (timeout--) {
909 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000910 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500911
912 if (err)
913 return err;
914
915 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300916 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500917 break;
918 }
919
Andy Fleming272cc702008-10-30 16:41:01 -0500920 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300921 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500922 return 0;
923
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000924 /*
925 * If the host doesn't support SD_HIGHSPEED, do not switch card to
926 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
927 * This can avoid furthur problem when the card runs in different
928 * mode between the host.
929 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200930 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
931 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000932 return 0;
933
Anton staaff781dd32011-10-03 13:54:59 +0000934 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500935
936 if (err)
937 return err;
938
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300939 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500940 mmc->card_caps |= MMC_MODE_HS;
941
942 return 0;
943}
944
945/* frequency bases */
946/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000947static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500948 10000,
949 100000,
950 1000000,
951 10000000,
952};
953
954/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
955 * to platforms without floating point.
956 */
Simon Glass61fe0762016-05-14 14:02:57 -0600957static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500958 0, /* reserved */
959 10,
960 12,
961 13,
962 15,
963 20,
964 25,
965 30,
966 35,
967 40,
968 45,
969 50,
970 55,
971 60,
972 70,
973 80,
974};
975
Simon Glass8ca51e52016-06-12 23:30:22 -0600976#ifndef CONFIG_DM_MMC_OPS
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000977static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500978{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200979 if (mmc->cfg->ops->set_ios)
980 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500981}
Simon Glass8ca51e52016-06-12 23:30:22 -0600982#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500983
984void mmc_set_clock(struct mmc *mmc, uint clock)
985{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200986 if (clock > mmc->cfg->f_max)
987 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500988
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200989 if (clock < mmc->cfg->f_min)
990 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -0500991
992 mmc->clock = clock;
993
994 mmc_set_ios(mmc);
995}
996
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000997static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -0500998{
999 mmc->bus_width = width;
1000
1001 mmc_set_ios(mmc);
1002}
1003
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001004static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001005{
Stephen Warrenf866a462013-06-11 15:14:01 -06001006 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001007 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001008 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001009 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001010 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1011 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001012 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001013 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001014 bool part_completed;
Simon Glassc40fdca2016-05-01 13:52:35 -06001015 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05001016
Thomas Choud52ebf12010-12-24 13:12:21 +00001017#ifdef CONFIG_MMC_SPI_CRC_ON
1018 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1019 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1020 cmd.resp_type = MMC_RSP_R1;
1021 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001022 err = mmc_send_cmd(mmc, &cmd, NULL);
1023
1024 if (err)
1025 return err;
1026 }
1027#endif
1028
Andy Fleming272cc702008-10-30 16:41:01 -05001029 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001030 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1031 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001032 cmd.resp_type = MMC_RSP_R2;
1033 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001034
1035 err = mmc_send_cmd(mmc, &cmd, NULL);
1036
1037 if (err)
1038 return err;
1039
1040 memcpy(mmc->cid, cmd.response, 16);
1041
1042 /*
1043 * For MMC cards, set the Relative Address.
1044 * For SD cards, get the Relatvie Address.
1045 * This also puts the cards into Standby State
1046 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001047 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1048 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1049 cmd.cmdarg = mmc->rca << 16;
1050 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001051
Thomas Choud52ebf12010-12-24 13:12:21 +00001052 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001053
Thomas Choud52ebf12010-12-24 13:12:21 +00001054 if (err)
1055 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001056
Thomas Choud52ebf12010-12-24 13:12:21 +00001057 if (IS_SD(mmc))
1058 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1059 }
Andy Fleming272cc702008-10-30 16:41:01 -05001060
1061 /* Get the Card-Specific Data */
1062 cmd.cmdidx = MMC_CMD_SEND_CSD;
1063 cmd.resp_type = MMC_RSP_R2;
1064 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001065
1066 err = mmc_send_cmd(mmc, &cmd, NULL);
1067
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001068 /* Waiting for the ready status */
1069 mmc_send_status(mmc, timeout);
1070
Andy Fleming272cc702008-10-30 16:41:01 -05001071 if (err)
1072 return err;
1073
Rabin Vincent998be3d2009-04-05 13:30:56 +05301074 mmc->csd[0] = cmd.response[0];
1075 mmc->csd[1] = cmd.response[1];
1076 mmc->csd[2] = cmd.response[2];
1077 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001078
1079 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301080 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001081
1082 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07001083 case 0:
1084 mmc->version = MMC_VERSION_1_2;
1085 break;
1086 case 1:
1087 mmc->version = MMC_VERSION_1_4;
1088 break;
1089 case 2:
1090 mmc->version = MMC_VERSION_2_2;
1091 break;
1092 case 3:
1093 mmc->version = MMC_VERSION_3;
1094 break;
1095 case 4:
1096 mmc->version = MMC_VERSION_4;
1097 break;
1098 default:
1099 mmc->version = MMC_VERSION_1_2;
1100 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001101 }
1102 }
1103
1104 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301105 freq = fbase[(cmd.response[0] & 0x7)];
1106 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001107
1108 mmc->tran_speed = freq * mult;
1109
Markus Niebelab711882013-12-16 13:40:46 +01001110 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301111 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001112
1113 if (IS_SD(mmc))
1114 mmc->write_bl_len = mmc->read_bl_len;
1115 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301116 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001117
1118 if (mmc->high_capacity) {
1119 csize = (mmc->csd[1] & 0x3f) << 16
1120 | (mmc->csd[2] & 0xffff0000) >> 16;
1121 cmult = 8;
1122 } else {
1123 csize = (mmc->csd[1] & 0x3ff) << 2
1124 | (mmc->csd[2] & 0xc0000000) >> 30;
1125 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1126 }
1127
Stephen Warrenf866a462013-06-11 15:14:01 -06001128 mmc->capacity_user = (csize + 1) << (cmult + 2);
1129 mmc->capacity_user *= mmc->read_bl_len;
1130 mmc->capacity_boot = 0;
1131 mmc->capacity_rpmb = 0;
1132 for (i = 0; i < 4; i++)
1133 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001134
Simon Glass8bfa1952013-04-03 08:54:30 +00001135 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1136 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001137
Simon Glass8bfa1952013-04-03 08:54:30 +00001138 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1139 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001140
Markus Niebelab711882013-12-16 13:40:46 +01001141 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1142 cmd.cmdidx = MMC_CMD_SET_DSR;
1143 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1144 cmd.resp_type = MMC_RSP_NONE;
1145 if (mmc_send_cmd(mmc, &cmd, NULL))
1146 printf("MMC: SET_DSR failed\n");
1147 }
1148
Andy Fleming272cc702008-10-30 16:41:01 -05001149 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001150 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1151 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001152 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001153 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001154 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001155
Thomas Choud52ebf12010-12-24 13:12:21 +00001156 if (err)
1157 return err;
1158 }
Andy Fleming272cc702008-10-30 16:41:01 -05001159
Lei Wene6f99a52011-06-22 17:03:31 +00001160 /*
1161 * For SD, its erase group is always one sector
1162 */
1163 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001164 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301165 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1166 /* check ext_csd version and capacity */
1167 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001168 if (err)
1169 return err;
1170 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001171 /*
1172 * According to the JEDEC Standard, the value of
1173 * ext_csd's capacity is valid if the value is more
1174 * than 2GB
1175 */
Lei Wen0560db12011-10-03 20:35:10 +00001176 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1177 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1178 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1179 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001180 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001181 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001182 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301183 }
Lei Wenbc897b12011-05-02 16:26:26 +00001184
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001185 switch (ext_csd[EXT_CSD_REV]) {
1186 case 1:
1187 mmc->version = MMC_VERSION_4_1;
1188 break;
1189 case 2:
1190 mmc->version = MMC_VERSION_4_2;
1191 break;
1192 case 3:
1193 mmc->version = MMC_VERSION_4_3;
1194 break;
1195 case 5:
1196 mmc->version = MMC_VERSION_4_41;
1197 break;
1198 case 6:
1199 mmc->version = MMC_VERSION_4_5;
1200 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001201 case 7:
1202 mmc->version = MMC_VERSION_5_0;
1203 break;
Stefan Wahren1a3619c2016-06-16 17:54:06 +00001204 case 8:
1205 mmc->version = MMC_VERSION_5_1;
1206 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001207 }
1208
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001209 /* The partition data may be non-zero but it is only
1210 * effective if PARTITION_SETTING_COMPLETED is set in
1211 * EXT_CSD, so ignore any data if this bit is not set,
1212 * except for enabling the high-capacity group size
1213 * definition (see below). */
1214 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1215 EXT_CSD_PARTITION_SETTING_COMPLETED);
1216
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001217 /* store the partition info of emmc */
1218 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1219 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1220 ext_csd[EXT_CSD_BOOT_MULT])
1221 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001222 if (part_completed &&
1223 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001224 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1225
1226 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1227
1228 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1229
1230 for (i = 0; i < 4; i++) {
1231 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001232 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001233 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001234 if (mult)
1235 has_parts = true;
1236 if (!part_completed)
1237 continue;
1238 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001239 mmc->capacity_gp[i] *=
1240 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1241 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001242 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001243 }
1244
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001245 if (part_completed) {
1246 mmc->enh_user_size =
1247 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1248 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1249 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1250 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1251 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1252 mmc->enh_user_size <<= 19;
1253 mmc->enh_user_start =
1254 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1255 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1256 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1257 ext_csd[EXT_CSD_ENH_START_ADDR];
1258 if (mmc->high_capacity)
1259 mmc->enh_user_start <<= 9;
1260 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001261
Lei Wene6f99a52011-06-22 17:03:31 +00001262 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001263 * Host needs to enable ERASE_GRP_DEF bit if device is
1264 * partitioned. This bit will be lost every time after a reset
1265 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001266 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001267 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001268 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001269 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001270 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1271 has_parts = true;
1272 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001273 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1274 EXT_CSD_ERASE_GROUP_DEF, 1);
1275
1276 if (err)
1277 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001278 else
1279 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001280 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001281
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001282 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001283 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001284 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001285 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001286 /*
1287 * if high capacity and partition setting completed
1288 * SEC_COUNT is valid even if it is smaller than 2 GiB
1289 * JEDEC Standard JESD84-B45, 6.2.4
1290 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001291 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001292 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1293 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1294 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1295 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1296 capacity *= MMC_MAX_BLOCK_LEN;
1297 mmc->capacity_user = capacity;
1298 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001299 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001300 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001301 int erase_gsz, erase_gmul;
1302 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1303 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1304 mmc->erase_grp_size = (erase_gsz + 1)
1305 * (erase_gmul + 1);
1306 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001307
1308 mmc->hc_wp_grp_size = 1024
1309 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1310 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001311
1312 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301313 }
1314
Simon Glassc40fdca2016-05-01 13:52:35 -06001315 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06001316 if (err)
1317 return err;
1318
Andy Fleming272cc702008-10-30 16:41:01 -05001319 if (IS_SD(mmc))
1320 err = sd_change_freq(mmc);
1321 else
1322 err = mmc_change_freq(mmc);
1323
1324 if (err)
1325 return err;
1326
1327 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001328 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001329
1330 if (IS_SD(mmc)) {
1331 if (mmc->card_caps & MMC_MODE_4BIT) {
1332 cmd.cmdidx = MMC_CMD_APP_CMD;
1333 cmd.resp_type = MMC_RSP_R1;
1334 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001335
1336 err = mmc_send_cmd(mmc, &cmd, NULL);
1337 if (err)
1338 return err;
1339
1340 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1341 cmd.resp_type = MMC_RSP_R1;
1342 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001343 err = mmc_send_cmd(mmc, &cmd, NULL);
1344 if (err)
1345 return err;
1346
1347 mmc_set_bus_width(mmc, 4);
1348 }
1349
1350 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001351 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001352 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001353 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001354 } else if (mmc->version >= MMC_VERSION_4) {
1355 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001356 int idx;
1357
1358 /* An array of possible bus widths in order of preference */
1359 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001360 EXT_CSD_DDR_BUS_WIDTH_8,
1361 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001362 EXT_CSD_BUS_WIDTH_8,
1363 EXT_CSD_BUS_WIDTH_4,
1364 EXT_CSD_BUS_WIDTH_1,
1365 };
1366
1367 /* An array to map CSD bus widths to host cap bits */
1368 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001369 [EXT_CSD_DDR_BUS_WIDTH_4] =
1370 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1371 [EXT_CSD_DDR_BUS_WIDTH_8] =
1372 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001373 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1374 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1375 };
1376
1377 /* An array to map chosen bus width to an integer */
1378 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001379 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001380 };
1381
1382 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1383 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001384 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001385
1386 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001387 * If the bus width is still not changed,
1388 * don't try to set the default again.
1389 * Otherwise, recover from switch attempts
1390 * by switching to 1-bit bus width.
1391 */
1392 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1393 mmc->bus_width == 1) {
1394 err = 0;
1395 break;
1396 }
1397
1398 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001399 * Check to make sure the card and controller support
1400 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001401 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001402 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001403 continue;
1404
Andy Fleming272cc702008-10-30 16:41:01 -05001405 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001406 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001407
1408 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001409 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001410
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001411 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001412 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001413
Lei Wen41378942011-10-03 20:35:11 +00001414 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001415
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001416 if (err)
1417 continue;
1418
1419 /* Only compare read only fields */
1420 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1421 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1422 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1423 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1424 ext_csd[EXT_CSD_REV]
1425 == test_csd[EXT_CSD_REV] &&
1426 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1427 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1428 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1429 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001430 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001431 else
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001432 err = -EBADMSG;
Andy Fleming272cc702008-10-30 16:41:01 -05001433 }
1434
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001435 if (err)
1436 return err;
1437
Andy Fleming272cc702008-10-30 16:41:01 -05001438 if (mmc->card_caps & MMC_MODE_HS) {
1439 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001440 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001441 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001442 mmc->tran_speed = 26000000;
1443 }
Andy Fleming272cc702008-10-30 16:41:01 -05001444 }
1445
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001446 mmc_set_clock(mmc, mmc->tran_speed);
1447
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001448 /* Fix the block length for DDR mode */
1449 if (mmc->ddr_mode) {
1450 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1451 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1452 }
1453
Andy Fleming272cc702008-10-30 16:41:01 -05001454 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06001455 bdesc = mmc_get_blk_desc(mmc);
1456 bdesc->lun = 0;
1457 bdesc->hwpart = 0;
1458 bdesc->type = 0;
1459 bdesc->blksz = mmc->read_bl_len;
1460 bdesc->log2blksz = LOG2(bdesc->blksz);
1461 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01001462#if !defined(CONFIG_SPL_BUILD) || \
1463 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1464 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06001465 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00001466 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1467 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001468 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001469 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1470 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1471 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001472 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001473 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001474#else
Simon Glassc40fdca2016-05-01 13:52:35 -06001475 bdesc->vendor[0] = 0;
1476 bdesc->product[0] = 0;
1477 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01001478#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001479#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glassc40fdca2016-05-01 13:52:35 -06001480 part_init(bdesc);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001481#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001482
1483 return 0;
1484}
1485
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001486static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001487{
1488 struct mmc_cmd cmd;
1489 int err;
1490
1491 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1492 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001493 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001494 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001495
1496 err = mmc_send_cmd(mmc, &cmd, NULL);
1497
1498 if (err)
1499 return err;
1500
Rabin Vincent998be3d2009-04-05 13:30:56 +05301501 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001502 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05001503 else
1504 mmc->version = SD_VERSION_2;
1505
1506 return 0;
1507}
1508
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001509/* board-specific MMC power initializations. */
1510__weak void board_mmc_power_init(void)
1511{
1512}
1513
Che-Liang Chioue9550442012-11-28 15:21:13 +00001514int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001515{
Simon Glass8ca51e52016-06-12 23:30:22 -06001516 bool no_card;
Macpaul Linafd59322011-11-14 23:35:39 +00001517 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001518
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001519 /* we pretend there's no card when init is NULL */
Simon Glass8ca51e52016-06-12 23:30:22 -06001520 no_card = mmc_getcd(mmc) == 0;
1521#ifndef CONFIG_DM_MMC_OPS
1522 no_card = no_card || (mmc->cfg->ops->init == NULL);
1523#endif
1524 if (no_card) {
Thierry Reding48972d92012-01-02 01:15:37 +00001525 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001526#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001527 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001528#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001529 return -ENOMEDIUM;
Thierry Reding48972d92012-01-02 01:15:37 +00001530 }
1531
Lei Wenbc897b12011-05-02 16:26:26 +00001532 if (mmc->has_init)
1533 return 0;
1534
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001535#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1536 mmc_adapter_card_type_ident();
1537#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001538 board_mmc_power_init();
1539
Simon Glass8ca51e52016-06-12 23:30:22 -06001540#ifdef CONFIG_DM_MMC_OPS
1541 /* The device has already been probed ready for use */
1542#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001543 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001544 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001545 if (err)
1546 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06001547#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001548 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001549 mmc_set_bus_width(mmc, 1);
1550 mmc_set_clock(mmc, 1);
1551
Andy Fleming272cc702008-10-30 16:41:01 -05001552 /* Reset the Card */
1553 err = mmc_go_idle(mmc);
1554
1555 if (err)
1556 return err;
1557
Lei Wenbc897b12011-05-02 16:26:26 +00001558 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06001559 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00001560
Andy Fleming272cc702008-10-30 16:41:01 -05001561 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001562 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001563
Andy Fleming272cc702008-10-30 16:41:01 -05001564 /* Now try to get the SD card's operating condition */
1565 err = sd_send_op_cond(mmc);
1566
1567 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001568 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05001569 err = mmc_send_op_cond(mmc);
1570
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001571 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001572#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001573 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001574#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001575 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05001576 }
1577 }
1578
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001579 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001580 mmc->init_in_progress = 1;
1581
1582 return err;
1583}
1584
1585static int mmc_complete_init(struct mmc *mmc)
1586{
1587 int err = 0;
1588
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001589 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001590 if (mmc->op_cond_pending)
1591 err = mmc_complete_op_cond(mmc);
1592
1593 if (!err)
1594 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001595 if (err)
1596 mmc->has_init = 0;
1597 else
1598 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001599 return err;
1600}
1601
1602int mmc_init(struct mmc *mmc)
1603{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001604 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001605 unsigned start;
Simon Glass33fb2112016-05-01 13:52:41 -06001606#ifdef CONFIG_DM_MMC
1607 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00001608
Simon Glass33fb2112016-05-01 13:52:41 -06001609 upriv->mmc = mmc;
1610#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001611 if (mmc->has_init)
1612 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001613
1614 start = get_timer(0);
1615
Che-Liang Chioue9550442012-11-28 15:21:13 +00001616 if (!mmc->init_in_progress)
1617 err = mmc_start_init(mmc);
1618
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001619 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001620 err = mmc_complete_init(mmc);
1621 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001622 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001623}
1624
Markus Niebelab711882013-12-16 13:40:46 +01001625int mmc_set_dsr(struct mmc *mmc, u16 val)
1626{
1627 mmc->dsr = val;
1628 return 0;
1629}
1630
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001631/* CPU-specific MMC initializations */
1632__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001633{
1634 return -1;
1635}
1636
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001637/* board-specific MMC initializations. */
1638__weak int board_mmc_init(bd_t *bis)
1639{
1640 return -1;
1641}
Andy Fleming272cc702008-10-30 16:41:01 -05001642
Che-Liang Chioue9550442012-11-28 15:21:13 +00001643void mmc_set_preinit(struct mmc *mmc, int preinit)
1644{
1645 mmc->preinit = preinit;
1646}
1647
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001648#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
1649static int mmc_probe(bd_t *bis)
1650{
1651 return 0;
1652}
1653#elif defined(CONFIG_DM_MMC)
1654static int mmc_probe(bd_t *bis)
1655{
Simon Glass4a1db6d2015-12-29 05:22:49 -07001656 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001657 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07001658 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001659
1660 ret = uclass_get(UCLASS_MMC, &uc);
1661 if (ret)
1662 return ret;
1663
Simon Glass4a1db6d2015-12-29 05:22:49 -07001664 /*
1665 * Try to add them in sequence order. Really with driver model we
1666 * should allow holes, but the current MMC list does not allow that.
1667 * So if we request 0, 1, 3 we will get 0, 1, 2.
1668 */
1669 for (i = 0; ; i++) {
1670 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
1671 if (ret == -ENODEV)
1672 break;
1673 }
1674 uclass_foreach_dev(dev, uc) {
1675 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001676 if (ret)
Simon Glass4a1db6d2015-12-29 05:22:49 -07001677 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001678 }
1679
1680 return 0;
1681}
1682#else
1683static int mmc_probe(bd_t *bis)
1684{
1685 if (board_mmc_init(bis) < 0)
1686 cpu_mmc_init(bis);
1687
1688 return 0;
1689}
1690#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001691
Andy Fleming272cc702008-10-30 16:41:01 -05001692int mmc_initialize(bd_t *bis)
1693{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001694 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001695 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001696 if (initialized) /* Avoid initializing mmc multiple times */
1697 return 0;
1698 initialized = 1;
1699
Simon Glassc40fdca2016-05-01 13:52:35 -06001700#ifndef CONFIG_BLK
1701 mmc_list_init();
1702#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001703 ret = mmc_probe(bis);
1704 if (ret)
1705 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001706
Ying Zhangbb0dc102013-08-16 15:16:11 +08001707#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001708 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001709#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001710
Simon Glassc40fdca2016-05-01 13:52:35 -06001711 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001712 return 0;
1713}