blob: 4380c7c195a628e343f1f0b4719be6b6bbf3fdb3 [file] [log] [blame]
Andy Flemingad347bb2008-10-30 16:41:01 -05001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Based vaguely on the Linux code
6 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Andy Flemingad347bb2008-10-30 16:41:01 -05008 */
9
10#include <config.h>
11#include <common.h>
12#include <command.h>
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -060013#include <dm.h>
14#include <dm/device-internal.h>
Stephen Warrenbf0c7852014-05-23 12:47:06 -060015#include <errno.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050016#include <mmc.h>
17#include <part.h>
Peng Fan15305962016-10-11 15:08:43 +080018#include <power/regulator.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050019#include <malloc.h>
Simon Glass2dd337a2015-09-02 17:24:58 -060020#include <memalign.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050021#include <linux/list.h>
Rabin Vincent69d4e2c2009-04-05 13:30:54 +053022#include <div64.h>
Paul Burton8d30cc92013-09-09 15:30:26 +010023#include "mmc_private.h"
Andy Flemingad347bb2008-10-30 16:41:01 -050024
Peng Fanb3fcf1e2016-09-01 11:13:38 +080025static const unsigned int sd_au_size[] = {
26 0, SZ_16K / 512, SZ_32K / 512,
27 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
28 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
29 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
30 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512,
31};
32
Simon Glass394dfc02016-06-12 23:30:22 -060033#ifndef CONFIG_DM_MMC_OPS
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +020034__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanov020f2612012-12-03 02:19:46 +000035{
36 return -1;
37}
38
39int mmc_getwp(struct mmc *mmc)
40{
41 int wp;
42
43 wp = board_mmc_getwp(mmc);
44
Peter Korsgaardf7b15102013-03-21 04:00:03 +000045 if (wp < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +020046 if (mmc->cfg->ops->getwp)
47 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +000048 else
49 wp = 0;
50 }
Nikita Kiryanov020f2612012-12-03 02:19:46 +000051
52 return wp;
53}
54
Jeroen Hofstee47726302014-07-10 22:46:28 +020055__weak int board_mmc_getcd(struct mmc *mmc)
56{
Stefano Babic6e00edf2010-02-05 15:04:43 +010057 return -1;
58}
Simon Glass394dfc02016-06-12 23:30:22 -060059#endif
Stefano Babic6e00edf2010-02-05 15:04:43 +010060
Simon Glassb23d96e2016-06-12 23:30:20 -060061#ifdef CONFIG_MMC_TRACE
62void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
Andy Flemingad347bb2008-10-30 16:41:01 -050063{
Simon Glassb23d96e2016-06-12 23:30:20 -060064 printf("CMD_SEND:%d\n", cmd->cmdidx);
65 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
66}
Marek Vasutdccb6082012-03-15 18:41:35 +000067
Simon Glassb23d96e2016-06-12 23:30:20 -060068void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
69{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000070 int i;
71 u8 *ptr;
72
Bin Meng8d1ad1e2016-03-17 21:53:14 -070073 if (ret) {
74 printf("\t\tRET\t\t\t %d\n", ret);
75 } else {
76 switch (cmd->resp_type) {
77 case MMC_RSP_NONE:
78 printf("\t\tMMC_RSP_NONE\n");
79 break;
80 case MMC_RSP_R1:
81 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
82 cmd->response[0]);
83 break;
84 case MMC_RSP_R1b:
85 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
86 cmd->response[0]);
87 break;
88 case MMC_RSP_R2:
89 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
90 cmd->response[0]);
91 printf("\t\t \t\t 0x%08X \n",
92 cmd->response[1]);
93 printf("\t\t \t\t 0x%08X \n",
94 cmd->response[2]);
95 printf("\t\t \t\t 0x%08X \n",
96 cmd->response[3]);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000097 printf("\n");
Bin Meng8d1ad1e2016-03-17 21:53:14 -070098 printf("\t\t\t\t\tDUMPING DATA\n");
99 for (i = 0; i < 4; i++) {
100 int j;
101 printf("\t\t\t\t\t%03d - ", i*4);
102 ptr = (u8 *)&cmd->response[i];
103 ptr += 3;
104 for (j = 0; j < 4; j++)
105 printf("%02X ", *ptr--);
106 printf("\n");
107 }
108 break;
109 case MMC_RSP_R3:
110 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
111 cmd->response[0]);
112 break;
113 default:
114 printf("\t\tERROR MMC rsp not supported\n");
115 break;
Bin Meng4a4ef872016-03-17 21:53:13 -0700116 }
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000117 }
Simon Glassb23d96e2016-06-12 23:30:20 -0600118}
119
120void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
121{
122 int status;
123
124 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
125 printf("CURR STATE:%d\n", status);
126}
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000127#endif
Simon Glassb23d96e2016-06-12 23:30:20 -0600128
Simon Glass394dfc02016-06-12 23:30:22 -0600129#ifndef CONFIG_DM_MMC_OPS
Simon Glassb23d96e2016-06-12 23:30:20 -0600130int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
131{
132 int ret;
133
134 mmmc_trace_before_send(mmc, cmd);
135 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
136 mmmc_trace_after_send(mmc, cmd, ret);
137
Marek Vasutdccb6082012-03-15 18:41:35 +0000138 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500139}
Simon Glass394dfc02016-06-12 23:30:22 -0600140#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500141
Paul Burton8d30cc92013-09-09 15:30:26 +0100142int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000143{
144 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000145 int err, retries = 5;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000146
147 cmd.cmdidx = MMC_CMD_SEND_STATUS;
148 cmd.resp_type = MMC_RSP_R1;
Marek Vasutc4427392011-08-10 09:24:48 +0200149 if (!mmc_host_is_spi(mmc))
150 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000151
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500152 while (1) {
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000153 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-02-05 22:29:12 +0000154 if (!err) {
155 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
156 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
157 MMC_STATE_PRG)
158 break;
159 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100160#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzke31789322012-02-05 22:29:12 +0000161 printf("Status Error: 0x%08X\n",
162 cmd.response[0]);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100163#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +0900164 return -ECOMM;
Jan Kloetzke31789322012-02-05 22:29:12 +0000165 }
166 } else if (--retries < 0)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000167 return err;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000168
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500169 if (timeout-- <= 0)
170 break;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000171
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500172 udelay(1000);
173 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000174
Simon Glassb23d96e2016-06-12 23:30:20 -0600175 mmc_trace_state(mmc, &cmd);
Jongman Heo1be00d92012-06-03 21:32:13 +0000176 if (timeout <= 0) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100177#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000178 printf("Timeout waiting card ready\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100179#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +0900180 return -ETIMEDOUT;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000181 }
182
183 return 0;
184}
185
Paul Burton8d30cc92013-09-09 15:30:26 +0100186int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500187{
188 struct mmc_cmd cmd;
189
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -0600190 if (mmc->ddr_mode)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900191 return 0;
192
Andy Flemingad347bb2008-10-30 16:41:01 -0500193 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
194 cmd.resp_type = MMC_RSP_R1;
195 cmd.cmdarg = len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500196
197 return mmc_send_cmd(mmc, &cmd, NULL);
198}
199
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200200static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000201 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500202{
203 struct mmc_cmd cmd;
204 struct mmc_data data;
205
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700206 if (blkcnt > 1)
207 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
208 else
209 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500210
211 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700212 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500213 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700214 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500215
216 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500217
218 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700219 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500220 data.blocksize = mmc->read_bl_len;
221 data.flags = MMC_DATA_READ;
222
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700223 if (mmc_send_cmd(mmc, &cmd, &data))
224 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500225
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700226 if (blkcnt > 1) {
227 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
228 cmd.cmdarg = 0;
229 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700230 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100231#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700232 printf("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100233#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700234 return 0;
235 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500236 }
237
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700238 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500239}
240
Simon Glass59bc6f22016-05-01 13:52:41 -0600241#ifdef CONFIG_BLK
Simon Glass62e293a2016-06-12 23:30:15 -0600242ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600243#else
Simon Glass62e293a2016-06-12 23:30:15 -0600244ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
245 void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600246#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500247{
Simon Glass59bc6f22016-05-01 13:52:41 -0600248#ifdef CONFIG_BLK
249 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
250#endif
Simon Glass2f26fff2016-02-29 15:25:51 -0700251 int dev_num = block_dev->devnum;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700252 int err;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700253 lbaint_t cur, blocks_todo = blkcnt;
254
255 if (blkcnt == 0)
256 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500257
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700258 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500259 if (!mmc)
260 return 0;
261
Simon Glass11f2bb62016-05-01 13:52:29 -0600262 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700263 if (err < 0)
264 return 0;
265
Simon Glasse5db1152016-05-01 13:52:35 -0600266 if ((start + blkcnt) > block_dev->lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100267#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200268 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glasse5db1152016-05-01 13:52:35 -0600269 start + blkcnt, block_dev->lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100270#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800271 return 0;
272 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500273
Simon Glassa4343c42015-06-23 15:38:50 -0600274 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
275 debug("%s: Failed to set blocklen\n", __func__);
Andy Flemingad347bb2008-10-30 16:41:01 -0500276 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600277 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500278
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700279 do {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200280 cur = (blocks_todo > mmc->cfg->b_max) ?
281 mmc->cfg->b_max : blocks_todo;
Simon Glassa4343c42015-06-23 15:38:50 -0600282 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
283 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700284 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600285 }
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700286 blocks_todo -= cur;
287 start += cur;
288 dst += cur * mmc->read_bl_len;
289 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500290
291 return blkcnt;
292}
293
Kim Phillips87ea3892012-10-29 13:34:43 +0000294static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500295{
296 struct mmc_cmd cmd;
297 int err;
298
299 udelay(1000);
300
301 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
302 cmd.cmdarg = 0;
303 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500304
305 err = mmc_send_cmd(mmc, &cmd, NULL);
306
307 if (err)
308 return err;
309
310 udelay(2000);
311
312 return 0;
313}
314
Kim Phillips87ea3892012-10-29 13:34:43 +0000315static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500316{
317 int timeout = 1000;
318 int err;
319 struct mmc_cmd cmd;
320
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500321 while (1) {
Andy Flemingad347bb2008-10-30 16:41:01 -0500322 cmd.cmdidx = MMC_CMD_APP_CMD;
323 cmd.resp_type = MMC_RSP_R1;
324 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500325
326 err = mmc_send_cmd(mmc, &cmd, NULL);
327
328 if (err)
329 return err;
330
331 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
332 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100333
334 /*
335 * Most cards do not answer if some reserved bits
336 * in the ocr are set. However, Some controller
337 * can set bit 7 (reserved for low voltages), but
338 * how to manage low voltages SD card is not yet
339 * specified.
340 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000341 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200342 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500343
344 if (mmc->version == SD_VERSION_2)
345 cmd.cmdarg |= OCR_HCS;
346
347 err = mmc_send_cmd(mmc, &cmd, NULL);
348
349 if (err)
350 return err;
351
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500352 if (cmd.response[0] & OCR_BUSY)
353 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500354
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500355 if (timeout-- <= 0)
Jaehoon Chung7825d202016-07-19 16:33:36 +0900356 return -EOPNOTSUPP;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500357
358 udelay(1000);
359 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500360
361 if (mmc->version != SD_VERSION_2)
362 mmc->version = SD_VERSION_1_0;
363
Thomas Chou1254c3d2010-12-24 13:12:21 +0000364 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
365 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
366 cmd.resp_type = MMC_RSP_R3;
367 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000368
369 err = mmc_send_cmd(mmc, &cmd, NULL);
370
371 if (err)
372 return err;
373 }
374
Rabin Vincentb6eed942009-04-05 13:30:56 +0530375 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500376
377 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
378 mmc->rca = 0;
379
380 return 0;
381}
382
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500383static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Flemingad347bb2008-10-30 16:41:01 -0500384{
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500385 struct mmc_cmd cmd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500386 int err;
387
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500388 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
389 cmd.resp_type = MMC_RSP_R3;
390 cmd.cmdarg = 0;
Rob Herring5fd3edd2015-03-23 17:56:59 -0500391 if (use_arg && !mmc_host_is_spi(mmc))
392 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200393 (mmc->cfg->voltages &
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500394 (mmc->ocr & OCR_VOLTAGE_MASK)) |
395 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000396
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500397 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000398 if (err)
399 return err;
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500400 mmc->ocr = cmd.response[0];
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000401 return 0;
402}
403
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200404static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000405{
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000406 int err, i;
407
Andy Flemingad347bb2008-10-30 16:41:01 -0500408 /* Some cards seem to need this */
409 mmc_go_idle(mmc);
410
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000411 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000412 for (i = 0; i < 2; i++) {
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500413 err = mmc_send_op_cond_iter(mmc, i != 0);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000414 if (err)
415 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200416
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000417 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500418 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500419 break;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000420 }
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500421 mmc->op_cond_pending = 1;
422 return 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000423}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200424
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200425static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000426{
427 struct mmc_cmd cmd;
428 int timeout = 1000;
429 uint start;
430 int err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200431
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000432 mmc->op_cond_pending = 0;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500433 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lu9c720612016-08-02 15:33:18 +0800434 /* Some cards seem to need this */
435 mmc_go_idle(mmc);
436
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500437 start = get_timer(0);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500438 while (1) {
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500439 err = mmc_send_op_cond_iter(mmc, 1);
440 if (err)
441 return err;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500442 if (mmc->ocr & OCR_BUSY)
443 break;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500444 if (get_timer(start) > timeout)
Jaehoon Chung7825d202016-07-19 16:33:36 +0900445 return -EOPNOTSUPP;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500446 udelay(100);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500447 }
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500448 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500449
Thomas Chou1254c3d2010-12-24 13:12:21 +0000450 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
451 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
452 cmd.resp_type = MMC_RSP_R3;
453 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000454
455 err = mmc_send_cmd(mmc, &cmd, NULL);
456
457 if (err)
458 return err;
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500459
460 mmc->ocr = cmd.response[0];
Thomas Chou1254c3d2010-12-24 13:12:21 +0000461 }
462
Andy Flemingad347bb2008-10-30 16:41:01 -0500463 mmc->version = MMC_VERSION_UNKNOWN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500464
465 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700466 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500467
468 return 0;
469}
470
471
Kim Phillips87ea3892012-10-29 13:34:43 +0000472static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500473{
474 struct mmc_cmd cmd;
475 struct mmc_data data;
476 int err;
477
478 /* Get the Card Status Register */
479 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
480 cmd.resp_type = MMC_RSP_R1;
481 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500482
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000483 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500484 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000485 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500486 data.flags = MMC_DATA_READ;
487
488 err = mmc_send_cmd(mmc, &cmd, &data);
489
490 return err;
491}
492
Simon Glass84f9df92016-06-12 23:30:18 -0600493int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500494{
495 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000496 int timeout = 1000;
497 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500498
499 cmd.cmdidx = MMC_CMD_SWITCH;
500 cmd.resp_type = MMC_RSP_R1b;
501 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000502 (index << 16) |
503 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500504
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000505 ret = mmc_send_cmd(mmc, &cmd, NULL);
506
507 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000508 if (!ret)
509 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000510
511 return ret;
512
Andy Flemingad347bb2008-10-30 16:41:01 -0500513}
514
Kim Phillips87ea3892012-10-29 13:34:43 +0000515static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500516{
Simon Glassa09c2b72013-04-03 08:54:30 +0000517 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500518 char cardtype;
519 int err;
520
Andrew Gabbasovccb7b042014-12-25 10:22:25 -0600521 mmc->card_caps = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500522
Thomas Chou1254c3d2010-12-24 13:12:21 +0000523 if (mmc_host_is_spi(mmc))
524 return 0;
525
Andy Flemingad347bb2008-10-30 16:41:01 -0500526 /* Only version 4 supports high-speed */
527 if (mmc->version < MMC_VERSION_4)
528 return 0;
529
Andrew Gabbasovccb7b042014-12-25 10:22:25 -0600530 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
531
Andy Flemingad347bb2008-10-30 16:41:01 -0500532 err = mmc_send_ext_csd(mmc, ext_csd);
533
534 if (err)
535 return err;
536
Lei Wen217467f2011-10-03 20:35:10 +0000537 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500538
539 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
540
541 if (err)
Heiko Schocher9016ab92016-06-07 08:31:21 +0200542 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500543
544 /* Now check to see that it worked */
545 err = mmc_send_ext_csd(mmc, ext_csd);
546
547 if (err)
548 return err;
549
550 /* No high-speed support */
Lei Wen217467f2011-10-03 20:35:10 +0000551 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500552 return 0;
553
554 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900555 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov95a37132014-12-01 06:59:10 -0600556 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900557 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Flemingad347bb2008-10-30 16:41:01 -0500558 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900559 } else {
Andy Flemingad347bb2008-10-30 16:41:01 -0500560 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900561 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500562
563 return 0;
564}
565
Stephen Warrene315ae82013-06-11 15:14:01 -0600566static int mmc_set_capacity(struct mmc *mmc, int part_num)
567{
568 switch (part_num) {
569 case 0:
570 mmc->capacity = mmc->capacity_user;
571 break;
572 case 1:
573 case 2:
574 mmc->capacity = mmc->capacity_boot;
575 break;
576 case 3:
577 mmc->capacity = mmc->capacity_rpmb;
578 break;
579 case 4:
580 case 5:
581 case 6:
582 case 7:
583 mmc->capacity = mmc->capacity_gp[part_num - 4];
584 break;
585 default:
586 return -1;
587 }
588
Simon Glasse5db1152016-05-01 13:52:35 -0600589 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrene315ae82013-06-11 15:14:01 -0600590
591 return 0;
592}
593
Simon Glass62e293a2016-06-12 23:30:15 -0600594int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wen31b99802011-05-02 16:26:26 +0000595{
Stephen Warrene315ae82013-06-11 15:14:01 -0600596 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000597
Stephen Warrene315ae82013-06-11 15:14:01 -0600598 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
599 (mmc->part_config & ~PART_ACCESS_MASK)
600 | (part_num & PART_ACCESS_MASK));
Peter Bigot45fde892014-09-02 18:31:23 -0500601
602 /*
603 * Set the capacity if the switch succeeded or was intended
604 * to return to representing the raw device.
605 */
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700606 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot45fde892014-09-02 18:31:23 -0500607 ret = mmc_set_capacity(mmc, part_num);
Simon Glass984db5d2016-05-01 13:52:37 -0600608 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700609 }
Stephen Warrene315ae82013-06-11 15:14:01 -0600610
Peter Bigot45fde892014-09-02 18:31:23 -0500611 return ret;
Lei Wen31b99802011-05-02 16:26:26 +0000612}
613
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100614int mmc_hwpart_config(struct mmc *mmc,
615 const struct mmc_hwpart_conf *conf,
616 enum mmc_hwpart_conf_mode mode)
617{
618 u8 part_attrs = 0;
619 u32 enh_size_mult;
620 u32 enh_start_addr;
621 u32 gp_size_mult[4];
622 u32 max_enh_size_mult;
623 u32 tot_enh_size_mult = 0;
Diego Santa Cruz80200272014-12-23 10:50:31 +0100624 u8 wr_rel_set;
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100625 int i, pidx, err;
626 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
627
628 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
629 return -EINVAL;
630
631 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
632 printf("eMMC >= 4.4 required for enhanced user data area\n");
633 return -EMEDIUMTYPE;
634 }
635
636 if (!(mmc->part_support & PART_SUPPORT)) {
637 printf("Card does not support partitioning\n");
638 return -EMEDIUMTYPE;
639 }
640
641 if (!mmc->hc_wp_grp_size) {
642 printf("Card does not define HC WP group size\n");
643 return -EMEDIUMTYPE;
644 }
645
646 /* check partition alignment and total enhanced size */
647 if (conf->user.enh_size) {
648 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
649 conf->user.enh_start % mmc->hc_wp_grp_size) {
650 printf("User data enhanced area not HC WP group "
651 "size aligned\n");
652 return -EINVAL;
653 }
654 part_attrs |= EXT_CSD_ENH_USR;
655 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
656 if (mmc->high_capacity) {
657 enh_start_addr = conf->user.enh_start;
658 } else {
659 enh_start_addr = (conf->user.enh_start << 9);
660 }
661 } else {
662 enh_size_mult = 0;
663 enh_start_addr = 0;
664 }
665 tot_enh_size_mult += enh_size_mult;
666
667 for (pidx = 0; pidx < 4; pidx++) {
668 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
669 printf("GP%i partition not HC WP group size "
670 "aligned\n", pidx+1);
671 return -EINVAL;
672 }
673 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
674 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
675 part_attrs |= EXT_CSD_ENH_GP(pidx);
676 tot_enh_size_mult += gp_size_mult[pidx];
677 }
678 }
679
680 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
681 printf("Card does not support enhanced attribute\n");
682 return -EMEDIUMTYPE;
683 }
684
685 err = mmc_send_ext_csd(mmc, ext_csd);
686 if (err)
687 return err;
688
689 max_enh_size_mult =
690 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
691 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
692 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
693 if (tot_enh_size_mult > max_enh_size_mult) {
694 printf("Total enhanced size exceeds maximum (%u > %u)\n",
695 tot_enh_size_mult, max_enh_size_mult);
696 return -EMEDIUMTYPE;
697 }
698
Diego Santa Cruz80200272014-12-23 10:50:31 +0100699 /* The default value of EXT_CSD_WR_REL_SET is device
700 * dependent, the values can only be changed if the
701 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
702 * changed only once and before partitioning is completed. */
703 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
704 if (conf->user.wr_rel_change) {
705 if (conf->user.wr_rel_set)
706 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
707 else
708 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
709 }
710 for (pidx = 0; pidx < 4; pidx++) {
711 if (conf->gp_part[pidx].wr_rel_change) {
712 if (conf->gp_part[pidx].wr_rel_set)
713 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
714 else
715 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
716 }
717 }
718
719 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
720 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
721 puts("Card does not support host controlled partition write "
722 "reliability settings\n");
723 return -EMEDIUMTYPE;
724 }
725
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100726 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
727 EXT_CSD_PARTITION_SETTING_COMPLETED) {
728 printf("Card already partitioned\n");
729 return -EPERM;
730 }
731
732 if (mode == MMC_HWPART_CONF_CHECK)
733 return 0;
734
735 /* Partitioning requires high-capacity size definitions */
736 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
737 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
738 EXT_CSD_ERASE_GROUP_DEF, 1);
739
740 if (err)
741 return err;
742
743 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
744
745 /* update erase group size to be high-capacity */
746 mmc->erase_grp_size =
747 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
748
749 }
750
751 /* all OK, write the configuration */
752 for (i = 0; i < 4; i++) {
753 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
754 EXT_CSD_ENH_START_ADDR+i,
755 (enh_start_addr >> (i*8)) & 0xFF);
756 if (err)
757 return err;
758 }
759 for (i = 0; i < 3; i++) {
760 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
761 EXT_CSD_ENH_SIZE_MULT+i,
762 (enh_size_mult >> (i*8)) & 0xFF);
763 if (err)
764 return err;
765 }
766 for (pidx = 0; pidx < 4; pidx++) {
767 for (i = 0; i < 3; i++) {
768 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
769 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
770 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
771 if (err)
772 return err;
773 }
774 }
775 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
776 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
777 if (err)
778 return err;
779
780 if (mode == MMC_HWPART_CONF_SET)
781 return 0;
782
Diego Santa Cruz80200272014-12-23 10:50:31 +0100783 /* The WR_REL_SET is a write-once register but shall be
784 * written before setting PART_SETTING_COMPLETED. As it is
785 * write-once we can only write it when completing the
786 * partitioning. */
787 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
788 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
789 EXT_CSD_WR_REL_SET, wr_rel_set);
790 if (err)
791 return err;
792 }
793
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +0100794 /* Setting PART_SETTING_COMPLETED confirms the partition
795 * configuration but it only becomes effective after power
796 * cycle, so we do not adjust the partition related settings
797 * in the mmc struct. */
798
799 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
800 EXT_CSD_PARTITION_SETTING,
801 EXT_CSD_PARTITION_SETTING_COMPLETED);
802 if (err)
803 return err;
804
805 return 0;
806}
807
Simon Glass394dfc02016-06-12 23:30:22 -0600808#ifndef CONFIG_DM_MMC_OPS
Thierry Redingb9c8b772012-01-02 01:15:37 +0000809int mmc_getcd(struct mmc *mmc)
810{
811 int cd;
812
813 cd = board_mmc_getcd(mmc);
814
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000815 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200816 if (mmc->cfg->ops->getcd)
817 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000818 else
819 cd = 1;
820 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000821
822 return cd;
823}
Simon Glass394dfc02016-06-12 23:30:22 -0600824#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +0000825
Kim Phillips87ea3892012-10-29 13:34:43 +0000826static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -0500827{
828 struct mmc_cmd cmd;
829 struct mmc_data data;
830
831 /* Switch the frequency */
832 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
833 cmd.resp_type = MMC_RSP_R1;
834 cmd.cmdarg = (mode << 31) | 0xffffff;
835 cmd.cmdarg &= ~(0xf << (group * 4));
836 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -0500837
838 data.dest = (char *)resp;
839 data.blocksize = 64;
840 data.blocks = 1;
841 data.flags = MMC_DATA_READ;
842
843 return mmc_send_cmd(mmc, &cmd, &data);
844}
845
846
Kim Phillips87ea3892012-10-29 13:34:43 +0000847static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500848{
849 int err;
850 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000851 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
852 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500853 struct mmc_data data;
854 int timeout;
855
856 mmc->card_caps = 0;
857
Thomas Chou1254c3d2010-12-24 13:12:21 +0000858 if (mmc_host_is_spi(mmc))
859 return 0;
860
Andy Flemingad347bb2008-10-30 16:41:01 -0500861 /* Read the SCR to find out if this card supports higher speeds */
862 cmd.cmdidx = MMC_CMD_APP_CMD;
863 cmd.resp_type = MMC_RSP_R1;
864 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500865
866 err = mmc_send_cmd(mmc, &cmd, NULL);
867
868 if (err)
869 return err;
870
871 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
872 cmd.resp_type = MMC_RSP_R1;
873 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500874
875 timeout = 3;
876
877retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000878 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -0500879 data.blocksize = 8;
880 data.blocks = 1;
881 data.flags = MMC_DATA_READ;
882
883 err = mmc_send_cmd(mmc, &cmd, &data);
884
885 if (err) {
886 if (timeout--)
887 goto retry_scr;
888
889 return err;
890 }
891
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300892 mmc->scr[0] = __be32_to_cpu(scr[0]);
893 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500894
895 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng4a4ef872016-03-17 21:53:13 -0700896 case 0:
897 mmc->version = SD_VERSION_1_0;
898 break;
899 case 1:
900 mmc->version = SD_VERSION_1_10;
901 break;
902 case 2:
903 mmc->version = SD_VERSION_2;
904 if ((mmc->scr[0] >> 15) & 0x1)
905 mmc->version = SD_VERSION_3;
906 break;
907 default:
908 mmc->version = SD_VERSION_1_0;
909 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500910 }
911
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530912 if (mmc->scr[0] & SD_DATA_4BIT)
913 mmc->card_caps |= MMC_MODE_4BIT;
914
Andy Flemingad347bb2008-10-30 16:41:01 -0500915 /* Version 1.0 doesn't support switching */
916 if (mmc->version == SD_VERSION_1_0)
917 return 0;
918
919 timeout = 4;
920 while (timeout--) {
921 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +0000922 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500923
924 if (err)
925 return err;
926
927 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300928 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500929 break;
930 }
931
Andy Flemingad347bb2008-10-30 16:41:01 -0500932 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300933 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500934 return 0;
935
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000936 /*
937 * If the host doesn't support SD_HIGHSPEED, do not switch card to
938 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
939 * This can avoid furthur problem when the card runs in different
940 * mode between the host.
941 */
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200942 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
943 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000944 return 0;
945
Anton staaf9b00f0d2011-10-03 13:54:59 +0000946 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500947
948 if (err)
949 return err;
950
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300951 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500952 mmc->card_caps |= MMC_MODE_HS;
953
954 return 0;
955}
956
Peng Fanb3fcf1e2016-09-01 11:13:38 +0800957static int sd_read_ssr(struct mmc *mmc)
958{
959 int err, i;
960 struct mmc_cmd cmd;
961 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
962 struct mmc_data data;
963 int timeout = 3;
964 unsigned int au, eo, et, es;
965
966 cmd.cmdidx = MMC_CMD_APP_CMD;
967 cmd.resp_type = MMC_RSP_R1;
968 cmd.cmdarg = mmc->rca << 16;
969
970 err = mmc_send_cmd(mmc, &cmd, NULL);
971 if (err)
972 return err;
973
974 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
975 cmd.resp_type = MMC_RSP_R1;
976 cmd.cmdarg = 0;
977
978retry_ssr:
979 data.dest = (char *)ssr;
980 data.blocksize = 64;
981 data.blocks = 1;
982 data.flags = MMC_DATA_READ;
983
984 err = mmc_send_cmd(mmc, &cmd, &data);
985 if (err) {
986 if (timeout--)
987 goto retry_ssr;
988
989 return err;
990 }
991
992 for (i = 0; i < 16; i++)
993 ssr[i] = be32_to_cpu(ssr[i]);
994
995 au = (ssr[2] >> 12) & 0xF;
996 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
997 mmc->ssr.au = sd_au_size[au];
998 es = (ssr[3] >> 24) & 0xFF;
999 es |= (ssr[2] & 0xFF) << 8;
1000 et = (ssr[3] >> 18) & 0x3F;
1001 if (es && et) {
1002 eo = (ssr[3] >> 16) & 0x3;
1003 mmc->ssr.erase_timeout = (et * 1000) / es;
1004 mmc->ssr.erase_offset = eo * 1000;
1005 }
1006 } else {
1007 debug("Invalid Allocation Unit Size.\n");
1008 }
1009
1010 return 0;
1011}
1012
Andy Flemingad347bb2008-10-30 16:41:01 -05001013/* frequency bases */
1014/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +00001015static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -05001016 10000,
1017 100000,
1018 1000000,
1019 10000000,
1020};
1021
1022/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1023 * to platforms without floating point.
1024 */
Simon Glass03317cc2016-05-14 14:02:57 -06001025static const u8 multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -05001026 0, /* reserved */
1027 10,
1028 12,
1029 13,
1030 15,
1031 20,
1032 25,
1033 30,
1034 35,
1035 40,
1036 45,
1037 50,
1038 55,
1039 60,
1040 70,
1041 80,
1042};
1043
Simon Glass394dfc02016-06-12 23:30:22 -06001044#ifndef CONFIG_DM_MMC_OPS
Kim Phillips87ea3892012-10-29 13:34:43 +00001045static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001046{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001047 if (mmc->cfg->ops->set_ios)
1048 mmc->cfg->ops->set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001049}
Simon Glass394dfc02016-06-12 23:30:22 -06001050#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001051
1052void mmc_set_clock(struct mmc *mmc, uint clock)
1053{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001054 if (clock > mmc->cfg->f_max)
1055 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -05001056
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001057 if (clock < mmc->cfg->f_min)
1058 clock = mmc->cfg->f_min;
Andy Flemingad347bb2008-10-30 16:41:01 -05001059
1060 mmc->clock = clock;
1061
1062 mmc_set_ios(mmc);
1063}
1064
Kim Phillips87ea3892012-10-29 13:34:43 +00001065static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -05001066{
1067 mmc->bus_width = width;
1068
1069 mmc_set_ios(mmc);
1070}
1071
Kim Phillips87ea3892012-10-29 13:34:43 +00001072static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001073{
Stephen Warrene315ae82013-06-11 15:14:01 -06001074 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -05001075 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001076 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -05001077 struct mmc_cmd cmd;
Simon Glassa09c2b72013-04-03 08:54:30 +00001078 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1079 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001080 int timeout = 1000;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001081 bool has_parts = false;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001082 bool part_completed;
Simon Glasse5db1152016-05-01 13:52:35 -06001083 struct blk_desc *bdesc;
Andy Flemingad347bb2008-10-30 16:41:01 -05001084
Thomas Chou1254c3d2010-12-24 13:12:21 +00001085#ifdef CONFIG_MMC_SPI_CRC_ON
1086 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1087 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1088 cmd.resp_type = MMC_RSP_R1;
1089 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001090 err = mmc_send_cmd(mmc, &cmd, NULL);
1091
1092 if (err)
1093 return err;
1094 }
1095#endif
1096
Andy Flemingad347bb2008-10-30 16:41:01 -05001097 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001098 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1099 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -05001100 cmd.resp_type = MMC_RSP_R2;
1101 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001102
1103 err = mmc_send_cmd(mmc, &cmd, NULL);
1104
1105 if (err)
1106 return err;
1107
1108 memcpy(mmc->cid, cmd.response, 16);
1109
1110 /*
1111 * For MMC cards, set the Relative Address.
1112 * For SD cards, get the Relatvie Address.
1113 * This also puts the cards into Standby State
1114 */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001115 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1116 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1117 cmd.cmdarg = mmc->rca << 16;
1118 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -05001119
Thomas Chou1254c3d2010-12-24 13:12:21 +00001120 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001121
Thomas Chou1254c3d2010-12-24 13:12:21 +00001122 if (err)
1123 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001124
Thomas Chou1254c3d2010-12-24 13:12:21 +00001125 if (IS_SD(mmc))
1126 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1127 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001128
1129 /* Get the Card-Specific Data */
1130 cmd.cmdidx = MMC_CMD_SEND_CSD;
1131 cmd.resp_type = MMC_RSP_R2;
1132 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001133
1134 err = mmc_send_cmd(mmc, &cmd, NULL);
1135
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +00001136 /* Waiting for the ready status */
1137 mmc_send_status(mmc, timeout);
1138
Andy Flemingad347bb2008-10-30 16:41:01 -05001139 if (err)
1140 return err;
1141
Rabin Vincentb6eed942009-04-05 13:30:56 +05301142 mmc->csd[0] = cmd.response[0];
1143 mmc->csd[1] = cmd.response[1];
1144 mmc->csd[2] = cmd.response[2];
1145 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -05001146
1147 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301148 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -05001149
1150 switch (version) {
Bin Meng4a4ef872016-03-17 21:53:13 -07001151 case 0:
1152 mmc->version = MMC_VERSION_1_2;
1153 break;
1154 case 1:
1155 mmc->version = MMC_VERSION_1_4;
1156 break;
1157 case 2:
1158 mmc->version = MMC_VERSION_2_2;
1159 break;
1160 case 3:
1161 mmc->version = MMC_VERSION_3;
1162 break;
1163 case 4:
1164 mmc->version = MMC_VERSION_4;
1165 break;
1166 default:
1167 mmc->version = MMC_VERSION_1_2;
1168 break;
Andy Flemingad347bb2008-10-30 16:41:01 -05001169 }
1170 }
1171
1172 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +05301173 freq = fbase[(cmd.response[0] & 0x7)];
1174 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -05001175
1176 mmc->tran_speed = freq * mult;
1177
Markus Niebel03951412013-12-16 13:40:46 +01001178 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +05301179 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001180
1181 if (IS_SD(mmc))
1182 mmc->write_bl_len = mmc->read_bl_len;
1183 else
Rabin Vincentb6eed942009-04-05 13:30:56 +05301184 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -05001185
1186 if (mmc->high_capacity) {
1187 csize = (mmc->csd[1] & 0x3f) << 16
1188 | (mmc->csd[2] & 0xffff0000) >> 16;
1189 cmult = 8;
1190 } else {
1191 csize = (mmc->csd[1] & 0x3ff) << 2
1192 | (mmc->csd[2] & 0xc0000000) >> 30;
1193 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1194 }
1195
Stephen Warrene315ae82013-06-11 15:14:01 -06001196 mmc->capacity_user = (csize + 1) << (cmult + 2);
1197 mmc->capacity_user *= mmc->read_bl_len;
1198 mmc->capacity_boot = 0;
1199 mmc->capacity_rpmb = 0;
1200 for (i = 0; i < 4; i++)
1201 mmc->capacity_gp[i] = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001202
Simon Glassa09c2b72013-04-03 08:54:30 +00001203 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1204 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001205
Simon Glassa09c2b72013-04-03 08:54:30 +00001206 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1207 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05001208
Markus Niebel03951412013-12-16 13:40:46 +01001209 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1210 cmd.cmdidx = MMC_CMD_SET_DSR;
1211 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1212 cmd.resp_type = MMC_RSP_NONE;
1213 if (mmc_send_cmd(mmc, &cmd, NULL))
1214 printf("MMC: SET_DSR failed\n");
1215 }
1216
Andy Flemingad347bb2008-10-30 16:41:01 -05001217 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00001218 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1219 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +00001220 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001221 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +00001222 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001223
Thomas Chou1254c3d2010-12-24 13:12:21 +00001224 if (err)
1225 return err;
1226 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001227
Lei Wenea526762011-06-22 17:03:31 +00001228 /*
1229 * For SD, its erase group is always one sector
1230 */
1231 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +00001232 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301233 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1234 /* check ext_csd version and capacity */
1235 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruzca25e062014-12-23 10:50:28 +01001236 if (err)
1237 return err;
1238 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +00001239 /*
1240 * According to the JEDEC Standard, the value of
1241 * ext_csd's capacity is valid if the value is more
1242 * than 2GB
1243 */
Lei Wen217467f2011-10-03 20:35:10 +00001244 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1245 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1246 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1247 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glassa09c2b72013-04-03 08:54:30 +00001248 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +00001249 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -06001250 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301251 }
Lei Wen31b99802011-05-02 16:26:26 +00001252
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001253 switch (ext_csd[EXT_CSD_REV]) {
1254 case 1:
1255 mmc->version = MMC_VERSION_4_1;
1256 break;
1257 case 2:
1258 mmc->version = MMC_VERSION_4_2;
1259 break;
1260 case 3:
1261 mmc->version = MMC_VERSION_4_3;
1262 break;
1263 case 5:
1264 mmc->version = MMC_VERSION_4_41;
1265 break;
1266 case 6:
1267 mmc->version = MMC_VERSION_4_5;
1268 break;
Markus Niebel32f53b62014-11-18 15:13:53 +01001269 case 7:
1270 mmc->version = MMC_VERSION_5_0;
1271 break;
Stefan Wahren1243cd82016-06-16 17:54:06 +00001272 case 8:
1273 mmc->version = MMC_VERSION_5_1;
1274 break;
Jaehoon Chung6108ef62013-01-29 19:31:16 +00001275 }
1276
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001277 /* The partition data may be non-zero but it is only
1278 * effective if PARTITION_SETTING_COMPLETED is set in
1279 * EXT_CSD, so ignore any data if this bit is not set,
1280 * except for enabling the high-capacity group size
1281 * definition (see below). */
1282 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1283 EXT_CSD_PARTITION_SETTING_COMPLETED);
1284
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001285 /* store the partition info of emmc */
1286 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1287 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1288 ext_csd[EXT_CSD_BOOT_MULT])
1289 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001290 if (part_completed &&
1291 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001292 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1293
1294 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1295
1296 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1297
1298 for (i = 0; i < 4; i++) {
1299 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001300 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001301 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001302 if (mult)
1303 has_parts = true;
1304 if (!part_completed)
1305 continue;
1306 mmc->capacity_gp[i] = mult;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001307 mmc->capacity_gp[i] *=
1308 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1309 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruze5a2a3a2014-12-23 10:50:21 +01001310 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001311 }
1312
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001313 if (part_completed) {
1314 mmc->enh_user_size =
1315 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1316 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1317 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1318 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1319 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1320 mmc->enh_user_size <<= 19;
1321 mmc->enh_user_start =
1322 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1323 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1324 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1325 ext_csd[EXT_CSD_ENH_START_ADDR];
1326 if (mmc->high_capacity)
1327 mmc->enh_user_start <<= 9;
1328 }
Diego Santa Cruz3b62d842014-12-23 10:50:22 +01001329
Lei Wenea526762011-06-22 17:03:31 +00001330 /*
Oliver Metzb3f14092013-10-01 20:32:07 +02001331 * Host needs to enable ERASE_GRP_DEF bit if device is
1332 * partitioned. This bit will be lost every time after a reset
1333 * or power off. This will affect erase size.
Lei Wenea526762011-06-22 17:03:31 +00001334 */
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001335 if (part_completed)
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001336 has_parts = true;
Oliver Metzb3f14092013-10-01 20:32:07 +02001337 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruzcea8c5c2014-12-23 10:50:20 +01001338 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1339 has_parts = true;
1340 if (has_parts) {
Oliver Metzb3f14092013-10-01 20:32:07 +02001341 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1342 EXT_CSD_ERASE_GROUP_DEF, 1);
1343
1344 if (err)
1345 return err;
Hannes Petermaier15e874d2014-08-08 09:47:22 +02001346 else
1347 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001348 }
Oliver Metzb3f14092013-10-01 20:32:07 +02001349
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001350 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metzb3f14092013-10-01 20:32:07 +02001351 /* Read out group size from ext_csd */
Lei Wen217467f2011-10-03 20:35:10 +00001352 mmc->erase_grp_size =
Diego Santa Cruz747f6fa2014-12-23 10:50:24 +01001353 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebel6d398922014-11-18 15:11:42 +01001354 /*
1355 * if high capacity and partition setting completed
1356 * SEC_COUNT is valid even if it is smaller than 2 GiB
1357 * JEDEC Standard JESD84-B45, 6.2.4
1358 */
Diego Santa Cruza7a75992014-12-23 10:50:27 +01001359 if (mmc->high_capacity && part_completed) {
Markus Niebel6d398922014-11-18 15:11:42 +01001360 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1361 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1362 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1363 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1364 capacity *= MMC_MAX_BLOCK_LEN;
1365 mmc->capacity_user = capacity;
1366 }
Simon Glassa09c2b72013-04-03 08:54:30 +00001367 } else {
Oliver Metzb3f14092013-10-01 20:32:07 +02001368 /* Calculate the group size from the csd value. */
Lei Wenea526762011-06-22 17:03:31 +00001369 int erase_gsz, erase_gmul;
1370 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1371 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1372 mmc->erase_grp_size = (erase_gsz + 1)
1373 * (erase_gmul + 1);
1374 }
Diego Santa Cruz61b78fe2014-12-23 10:50:25 +01001375
1376 mmc->hc_wp_grp_size = 1024
1377 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1378 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz37a50b92014-12-23 10:50:33 +01001379
1380 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301381 }
1382
Simon Glasse5db1152016-05-01 13:52:35 -06001383 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrene315ae82013-06-11 15:14:01 -06001384 if (err)
1385 return err;
1386
Andy Flemingad347bb2008-10-30 16:41:01 -05001387 if (IS_SD(mmc))
1388 err = sd_change_freq(mmc);
1389 else
1390 err = mmc_change_freq(mmc);
1391
1392 if (err)
1393 return err;
1394
1395 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001396 mmc->card_caps &= mmc->cfg->host_caps;
Andy Flemingad347bb2008-10-30 16:41:01 -05001397
1398 if (IS_SD(mmc)) {
1399 if (mmc->card_caps & MMC_MODE_4BIT) {
1400 cmd.cmdidx = MMC_CMD_APP_CMD;
1401 cmd.resp_type = MMC_RSP_R1;
1402 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001403
1404 err = mmc_send_cmd(mmc, &cmd, NULL);
1405 if (err)
1406 return err;
1407
1408 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1409 cmd.resp_type = MMC_RSP_R1;
1410 cmd.cmdarg = 2;
Andy Flemingad347bb2008-10-30 16:41:01 -05001411 err = mmc_send_cmd(mmc, &cmd, NULL);
1412 if (err)
1413 return err;
1414
1415 mmc_set_bus_width(mmc, 4);
1416 }
1417
Peng Fanb3fcf1e2016-09-01 11:13:38 +08001418 err = sd_read_ssr(mmc);
1419 if (err)
1420 return err;
1421
Andy Flemingad347bb2008-10-30 16:41:01 -05001422 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001423 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001424 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001425 mmc->tran_speed = 25000000;
Andrew Gabbasovccb7b042014-12-25 10:22:25 -06001426 } else if (mmc->version >= MMC_VERSION_4) {
1427 /* Only version 4 of MMC supports wider bus widths */
Andy Flemingeb766ad2012-10-31 19:02:38 +00001428 int idx;
1429
1430 /* An array of possible bus widths in order of preference */
1431 static unsigned ext_csd_bits[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001432 EXT_CSD_DDR_BUS_WIDTH_8,
1433 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001434 EXT_CSD_BUS_WIDTH_8,
1435 EXT_CSD_BUS_WIDTH_4,
1436 EXT_CSD_BUS_WIDTH_1,
1437 };
1438
1439 /* An array to map CSD bus widths to host cap bits */
1440 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001441 [EXT_CSD_DDR_BUS_WIDTH_4] =
1442 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1443 [EXT_CSD_DDR_BUS_WIDTH_8] =
1444 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001445 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1446 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1447 };
1448
1449 /* An array to map chosen bus width to an integer */
1450 static unsigned widths[] = {
Jaehoon Chung38ce30b2014-05-16 13:59:54 +09001451 8, 4, 8, 4, 1,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001452 };
1453
1454 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1455 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001456 unsigned int caps = ext_to_hostcaps[extw];
Andy Flemingeb766ad2012-10-31 19:02:38 +00001457
1458 /*
Andrew Gabbasovc1b2cf02014-12-25 10:22:24 -06001459 * If the bus width is still not changed,
1460 * don't try to set the default again.
1461 * Otherwise, recover from switch attempts
1462 * by switching to 1-bit bus width.
1463 */
1464 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1465 mmc->bus_width == 1) {
1466 err = 0;
1467 break;
1468 }
1469
1470 /*
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001471 * Check to make sure the card and controller support
1472 * these capabilities
Andy Flemingeb766ad2012-10-31 19:02:38 +00001473 */
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001474 if ((mmc->card_caps & caps) != caps)
Andy Flemingeb766ad2012-10-31 19:02:38 +00001475 continue;
1476
Andy Flemingad347bb2008-10-30 16:41:01 -05001477 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001478 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001479
1480 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001481 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001482
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001483 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Flemingeb766ad2012-10-31 19:02:38 +00001484 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001485
Lei Wen4f5a6a52011-10-03 20:35:11 +00001486 err = mmc_send_ext_csd(mmc, test_csd);
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001487
1488 if (err)
1489 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001490
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001491 /* Only compare read only fields */
1492 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1493 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1494 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1495 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1496 ext_csd[EXT_CSD_REV]
1497 == test_csd[EXT_CSD_REV] &&
1498 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1499 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1500 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1501 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001502 break;
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001503 else
Jaehoon Chung7825d202016-07-19 16:33:36 +09001504 err = -EBADMSG;
Andy Flemingad347bb2008-10-30 16:41:01 -05001505 }
1506
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001507 if (err)
1508 return err;
1509
Andy Flemingad347bb2008-10-30 16:41:01 -05001510 if (mmc->card_caps & MMC_MODE_HS) {
1511 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001512 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001513 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001514 mmc->tran_speed = 26000000;
1515 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001516 }
1517
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001518 mmc_set_clock(mmc, mmc->tran_speed);
1519
Andrew Gabbasov532663b2014-12-01 06:59:11 -06001520 /* Fix the block length for DDR mode */
1521 if (mmc->ddr_mode) {
1522 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1523 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1524 }
1525
Andy Flemingad347bb2008-10-30 16:41:01 -05001526 /* fill in device description */
Simon Glasse5db1152016-05-01 13:52:35 -06001527 bdesc = mmc_get_blk_desc(mmc);
1528 bdesc->lun = 0;
1529 bdesc->hwpart = 0;
1530 bdesc->type = 0;
1531 bdesc->blksz = mmc->read_bl_len;
1532 bdesc->log2blksz = LOG2(bdesc->blksz);
1533 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsd67754f2015-12-04 23:27:40 +01001534#if !defined(CONFIG_SPL_BUILD) || \
1535 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1536 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glasse5db1152016-05-01 13:52:35 -06001537 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Hutt7367ec22012-10-20 17:15:59 +00001538 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1539 (mmc->cid[3] >> 16) & 0xffff);
Simon Glasse5db1152016-05-01 13:52:35 -06001540 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Hutt7367ec22012-10-20 17:15:59 +00001541 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1542 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1543 (mmc->cid[2] >> 24) & 0xff);
Simon Glasse5db1152016-05-01 13:52:35 -06001544 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Hutt7367ec22012-10-20 17:15:59 +00001545 (mmc->cid[2] >> 16) & 0xf);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001546#else
Simon Glasse5db1152016-05-01 13:52:35 -06001547 bdesc->vendor[0] = 0;
1548 bdesc->product[0] = 0;
1549 bdesc->revision[0] = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001550#endif
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001551#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glasse5db1152016-05-01 13:52:35 -06001552 part_init(bdesc);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001553#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001554
1555 return 0;
1556}
1557
Kim Phillips87ea3892012-10-29 13:34:43 +00001558static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001559{
1560 struct mmc_cmd cmd;
1561 int err;
1562
1563 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1564 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001565 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05001566 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001567
1568 err = mmc_send_cmd(mmc, &cmd, NULL);
1569
1570 if (err)
1571 return err;
1572
Rabin Vincentb6eed942009-04-05 13:30:56 +05301573 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung7825d202016-07-19 16:33:36 +09001574 return -EOPNOTSUPP;
Andy Flemingad347bb2008-10-30 16:41:01 -05001575 else
1576 mmc->version = SD_VERSION_2;
1577
1578 return 0;
1579}
1580
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01001581/* board-specific MMC power initializations. */
1582__weak void board_mmc_power_init(void)
1583{
1584}
1585
Peng Fan15305962016-10-11 15:08:43 +08001586static int mmc_power_init(struct mmc *mmc)
1587{
1588 board_mmc_power_init();
1589
1590#if defined(CONFIG_DM_MMC) && defined(CONFIG_DM_REGULATOR) && \
1591 !defined(CONFIG_SPL_BUILD)
1592 struct udevice *vmmc_supply;
1593 int ret;
1594
1595 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
1596 &vmmc_supply);
1597 if (ret) {
Jaehoon Chung44462502016-10-24 15:22:22 +09001598 debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan15305962016-10-11 15:08:43 +08001599 return 0;
1600 }
1601
1602 ret = regulator_set_enable(vmmc_supply, true);
1603 if (ret) {
1604 puts("Error enabling VMMC supply\n");
1605 return ret;
1606 }
1607#endif
1608 return 0;
1609}
1610
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001611int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001612{
Simon Glass394dfc02016-06-12 23:30:22 -06001613 bool no_card;
Macpaul Lin028bde12011-11-14 23:35:39 +00001614 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001615
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001616 /* we pretend there's no card when init is NULL */
Simon Glass394dfc02016-06-12 23:30:22 -06001617 no_card = mmc_getcd(mmc) == 0;
1618#ifndef CONFIG_DM_MMC_OPS
1619 no_card = no_card || (mmc->cfg->ops->init == NULL);
1620#endif
1621 if (no_card) {
Thierry Redingb9c8b772012-01-02 01:15:37 +00001622 mmc->has_init = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001623#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001624 printf("MMC: no card present\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001625#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +09001626 return -ENOMEDIUM;
Thierry Redingb9c8b772012-01-02 01:15:37 +00001627 }
1628
Lei Wen31b99802011-05-02 16:26:26 +00001629 if (mmc->has_init)
1630 return 0;
1631
Yangbo Lub124f8a2015-04-22 13:57:00 +08001632#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1633 mmc_adapter_card_type_ident();
1634#endif
Peng Fan15305962016-10-11 15:08:43 +08001635 err = mmc_power_init(mmc);
1636 if (err)
1637 return err;
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01001638
Simon Glass394dfc02016-06-12 23:30:22 -06001639#ifdef CONFIG_DM_MMC_OPS
1640 /* The device has already been probed ready for use */
1641#else
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001642 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001643 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001644 if (err)
1645 return err;
Simon Glass394dfc02016-06-12 23:30:22 -06001646#endif
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06001647 mmc->ddr_mode = 0;
Ilya Yanok8459aab2009-06-29 17:53:16 +04001648 mmc_set_bus_width(mmc, 1);
1649 mmc_set_clock(mmc, 1);
1650
Andy Flemingad347bb2008-10-30 16:41:01 -05001651 /* Reset the Card */
1652 err = mmc_go_idle(mmc);
1653
1654 if (err)
1655 return err;
1656
Lei Wen31b99802011-05-02 16:26:26 +00001657 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glasse5db1152016-05-01 13:52:35 -06001658 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001659
Andy Flemingad347bb2008-10-30 16:41:01 -05001660 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001661 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001662
Andy Flemingad347bb2008-10-30 16:41:01 -05001663 /* Now try to get the SD card's operating condition */
1664 err = sd_send_op_cond(mmc);
1665
1666 /* If the command timed out, we check for an MMC card */
Jaehoon Chung7825d202016-07-19 16:33:36 +09001667 if (err == -ETIMEDOUT) {
Andy Flemingad347bb2008-10-30 16:41:01 -05001668 err = mmc_send_op_cond(mmc);
1669
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001670 if (err) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001671#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001672 printf("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001673#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +09001674 return -EOPNOTSUPP;
Andy Flemingad347bb2008-10-30 16:41:01 -05001675 }
1676 }
1677
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001678 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001679 mmc->init_in_progress = 1;
1680
1681 return err;
1682}
1683
1684static int mmc_complete_init(struct mmc *mmc)
1685{
1686 int err = 0;
1687
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001688 mmc->init_in_progress = 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001689 if (mmc->op_cond_pending)
1690 err = mmc_complete_op_cond(mmc);
1691
1692 if (!err)
1693 err = mmc_startup(mmc);
Lei Wen31b99802011-05-02 16:26:26 +00001694 if (err)
1695 mmc->has_init = 0;
1696 else
1697 mmc->has_init = 1;
1698 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001699}
1700
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001701int mmc_init(struct mmc *mmc)
1702{
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001703 int err = 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001704 unsigned start;
Simon Glass59bc6f22016-05-01 13:52:41 -06001705#ifdef CONFIG_DM_MMC
1706 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001707
Simon Glass59bc6f22016-05-01 13:52:41 -06001708 upriv->mmc = mmc;
1709#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001710 if (mmc->has_init)
1711 return 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001712
1713 start = get_timer(0);
1714
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001715 if (!mmc->init_in_progress)
1716 err = mmc_start_init(mmc);
1717
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05001718 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001719 err = mmc_complete_init(mmc);
1720 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
1721 return err;
1722}
1723
Markus Niebel03951412013-12-16 13:40:46 +01001724int mmc_set_dsr(struct mmc *mmc, u16 val)
1725{
1726 mmc->dsr = val;
1727 return 0;
1728}
1729
Jeroen Hofstee47726302014-07-10 22:46:28 +02001730/* CPU-specific MMC initializations */
1731__weak int cpu_mmc_init(bd_t *bis)
Andy Flemingad347bb2008-10-30 16:41:01 -05001732{
1733 return -1;
1734}
1735
Jeroen Hofstee47726302014-07-10 22:46:28 +02001736/* board-specific MMC initializations. */
1737__weak int board_mmc_init(bd_t *bis)
1738{
1739 return -1;
1740}
Andy Flemingad347bb2008-10-30 16:41:01 -05001741
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001742void mmc_set_preinit(struct mmc *mmc, int preinit)
1743{
1744 mmc->preinit = preinit;
1745}
1746
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001747#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
1748static int mmc_probe(bd_t *bis)
1749{
1750 return 0;
1751}
1752#elif defined(CONFIG_DM_MMC)
1753static int mmc_probe(bd_t *bis)
1754{
Simon Glass547cb342015-12-29 05:22:49 -07001755 int ret, i;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001756 struct uclass *uc;
Simon Glass547cb342015-12-29 05:22:49 -07001757 struct udevice *dev;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001758
1759 ret = uclass_get(UCLASS_MMC, &uc);
1760 if (ret)
1761 return ret;
1762
Simon Glass547cb342015-12-29 05:22:49 -07001763 /*
1764 * Try to add them in sequence order. Really with driver model we
1765 * should allow holes, but the current MMC list does not allow that.
1766 * So if we request 0, 1, 3 we will get 0, 1, 2.
1767 */
1768 for (i = 0; ; i++) {
1769 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
1770 if (ret == -ENODEV)
1771 break;
1772 }
1773 uclass_foreach_dev(dev, uc) {
1774 ret = device_probe(dev);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001775 if (ret)
Simon Glass547cb342015-12-29 05:22:49 -07001776 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001777 }
1778
1779 return 0;
1780}
1781#else
1782static int mmc_probe(bd_t *bis)
1783{
1784 if (board_mmc_init(bis) < 0)
1785 cpu_mmc_init(bis);
1786
1787 return 0;
1788}
1789#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001790
Andy Flemingad347bb2008-10-30 16:41:01 -05001791int mmc_initialize(bd_t *bis)
1792{
Daniel Kochmański13df57b2015-05-29 16:55:43 +02001793 static int initialized = 0;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001794 int ret;
Daniel Kochmański13df57b2015-05-29 16:55:43 +02001795 if (initialized) /* Avoid initializing mmc multiple times */
1796 return 0;
1797 initialized = 1;
1798
Simon Glasse5db1152016-05-01 13:52:35 -06001799#ifndef CONFIG_BLK
1800 mmc_list_init();
1801#endif
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06001802 ret = mmc_probe(bis);
1803 if (ret)
1804 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -05001805
Ying Zhang9ff70262013-08-16 15:16:11 +08001806#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05001807 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08001808#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001809
Simon Glasse5db1152016-05-01 13:52:35 -06001810 mmc_do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001811 return 0;
1812}