blob: 48aedc212c31e46fe0492a807c2911932a241eb7 [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
Jeroen Hofstee750121c2014-07-12 21:24:08 +020024__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000025{
26 return -1;
27}
28
29int mmc_getwp(struct mmc *mmc)
30{
31 int wp;
32
33 wp = board_mmc_getwp(mmc);
34
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000035 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020036 if (mmc->cfg->ops->getwp)
37 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000038 else
39 wp = 0;
40 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000041
42 return wp;
43}
44
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020045__weak int board_mmc_getcd(struct mmc *mmc)
46{
Stefano Babic11fdade2010-02-05 15:04:43 +010047 return -1;
48}
49
Paul Burtonda61fa52013-09-09 15:30:26 +010050int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
Andy Fleming272cc702008-10-30 16:41:01 -050051{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000052 int ret;
Marek Vasut8635ff92012-03-15 18:41:35 +000053
Marek Vasut8635ff92012-03-15 18:41:35 +000054#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000055 int i;
56 u8 *ptr;
57
58 printf("CMD_SEND:%d\n", cmd->cmdidx);
59 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020060 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Bin Meng7863ce52016-03-17 21:53:14 -070061 if (ret) {
62 printf("\t\tRET\t\t\t %d\n", ret);
63 } else {
64 switch (cmd->resp_type) {
65 case MMC_RSP_NONE:
66 printf("\t\tMMC_RSP_NONE\n");
67 break;
68 case MMC_RSP_R1:
69 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
70 cmd->response[0]);
71 break;
72 case MMC_RSP_R1b:
73 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
74 cmd->response[0]);
75 break;
76 case MMC_RSP_R2:
77 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
78 cmd->response[0]);
79 printf("\t\t \t\t 0x%08X \n",
80 cmd->response[1]);
81 printf("\t\t \t\t 0x%08X \n",
82 cmd->response[2]);
83 printf("\t\t \t\t 0x%08X \n",
84 cmd->response[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000085 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -070086 printf("\t\t\t\t\tDUMPING DATA\n");
87 for (i = 0; i < 4; i++) {
88 int j;
89 printf("\t\t\t\t\t%03d - ", i*4);
90 ptr = (u8 *)&cmd->response[i];
91 ptr += 3;
92 for (j = 0; j < 4; j++)
93 printf("%02X ", *ptr--);
94 printf("\n");
95 }
96 break;
97 case MMC_RSP_R3:
98 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
99 cmd->response[0]);
100 break;
101 default:
102 printf("\t\tERROR MMC rsp not supported\n");
103 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700104 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000105 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000106#else
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200107 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000108#endif
Marek Vasut8635ff92012-03-15 18:41:35 +0000109 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500110}
111
Paul Burtonda61fa52013-09-09 15:30:26 +0100112int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000113{
114 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000115 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000116#ifdef CONFIG_MMC_TRACE
117 int status;
118#endif
119
120 cmd.cmdidx = MMC_CMD_SEND_STATUS;
121 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200122 if (!mmc_host_is_spi(mmc))
123 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000124
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500125 while (1) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000126 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000127 if (!err) {
128 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
129 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
130 MMC_STATE_PRG)
131 break;
132 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton56196822013-09-04 16:12:25 +0100133#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000134 printf("Status Error: 0x%08X\n",
135 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100136#endif
Jan Kloetzked617c422012-02-05 22:29:12 +0000137 return COMM_ERR;
138 }
139 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000140 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000141
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500142 if (timeout-- <= 0)
143 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000144
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500145 udelay(1000);
146 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000147
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000148#ifdef CONFIG_MMC_TRACE
149 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
150 printf("CURR STATE:%d\n", status);
151#endif
Jongman Heo5b0c9422012-06-03 21:32:13 +0000152 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100153#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000154 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100155#endif
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000156 return TIMEOUT;
157 }
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500158 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
159 return SWITCH_ERR;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000160
161 return 0;
162}
163
Paul Burtonda61fa52013-09-09 15:30:26 +0100164int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500165{
166 struct mmc_cmd cmd;
167
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600168 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900169 return 0;
170
Andy Fleming272cc702008-10-30 16:41:01 -0500171 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
172 cmd.resp_type = MMC_RSP_R1;
173 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500174
175 return mmc_send_cmd(mmc, &cmd, NULL);
176}
177
Sascha Silbeff8fef52013-06-14 13:07:25 +0200178static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000179 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500180{
181 struct mmc_cmd cmd;
182 struct mmc_data data;
183
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700184 if (blkcnt > 1)
185 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
186 else
187 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500188
189 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700190 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500191 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700192 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500193
194 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500195
196 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700197 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500198 data.blocksize = mmc->read_bl_len;
199 data.flags = MMC_DATA_READ;
200
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700201 if (mmc_send_cmd(mmc, &cmd, &data))
202 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500203
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700204 if (blkcnt > 1) {
205 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
206 cmd.cmdarg = 0;
207 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700208 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100209#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700210 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100211#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700212 return 0;
213 }
Andy Fleming272cc702008-10-30 16:41:01 -0500214 }
215
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700216 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500217}
218
Simon Glass4101f682016-02-29 15:25:34 -0700219static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
Stephen Warren7c4213f2015-12-07 11:38:48 -0700220 lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500221{
Simon Glassbcce53d2016-02-29 15:25:51 -0700222 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700223 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700224 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500225
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700226 if (blkcnt == 0)
227 return 0;
228
229 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500230 if (!mmc)
231 return 0;
232
Simon Glass69f45cd2016-05-01 13:52:29 -0600233 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
Stephen Warren873cc1d2015-12-07 11:38:49 -0700234 if (err < 0)
235 return 0;
236
Simon Glassc40fdca2016-05-01 13:52:35 -0600237 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100238#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200239 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glassc40fdca2016-05-01 13:52:35 -0600240 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100241#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800242 return 0;
243 }
Andy Fleming272cc702008-10-30 16:41:01 -0500244
Simon Glass11692992015-06-23 15:38:50 -0600245 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
246 debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500247 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600248 }
Andy Fleming272cc702008-10-30 16:41:01 -0500249
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700250 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200251 cur = (blocks_todo > mmc->cfg->b_max) ?
252 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600253 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
254 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700255 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600256 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700257 blocks_todo -= cur;
258 start += cur;
259 dst += cur * mmc->read_bl_len;
260 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500261
262 return blkcnt;
263}
264
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000265static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500266{
267 struct mmc_cmd cmd;
268 int err;
269
270 udelay(1000);
271
272 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
273 cmd.cmdarg = 0;
274 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500275
276 err = mmc_send_cmd(mmc, &cmd, NULL);
277
278 if (err)
279 return err;
280
281 udelay(2000);
282
283 return 0;
284}
285
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000286static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500287{
288 int timeout = 1000;
289 int err;
290 struct mmc_cmd cmd;
291
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500292 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500293 cmd.cmdidx = MMC_CMD_APP_CMD;
294 cmd.resp_type = MMC_RSP_R1;
295 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500296
297 err = mmc_send_cmd(mmc, &cmd, NULL);
298
299 if (err)
300 return err;
301
302 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
303 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100304
305 /*
306 * Most cards do not answer if some reserved bits
307 * in the ocr are set. However, Some controller
308 * can set bit 7 (reserved for low voltages), but
309 * how to manage low voltages SD card is not yet
310 * specified.
311 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000312 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200313 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500314
315 if (mmc->version == SD_VERSION_2)
316 cmd.cmdarg |= OCR_HCS;
317
318 err = mmc_send_cmd(mmc, &cmd, NULL);
319
320 if (err)
321 return err;
322
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500323 if (cmd.response[0] & OCR_BUSY)
324 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500325
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500326 if (timeout-- <= 0)
327 return UNUSABLE_ERR;
328
329 udelay(1000);
330 }
Andy Fleming272cc702008-10-30 16:41:01 -0500331
332 if (mmc->version != SD_VERSION_2)
333 mmc->version = SD_VERSION_1_0;
334
Thomas Choud52ebf12010-12-24 13:12:21 +0000335 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
336 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
337 cmd.resp_type = MMC_RSP_R3;
338 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000339
340 err = mmc_send_cmd(mmc, &cmd, NULL);
341
342 if (err)
343 return err;
344 }
345
Rabin Vincent998be3d2009-04-05 13:30:56 +0530346 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500347
348 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
349 mmc->rca = 0;
350
351 return 0;
352}
353
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500354static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500355{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500356 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500357 int err;
358
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500359 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
360 cmd.resp_type = MMC_RSP_R3;
361 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500362 if (use_arg && !mmc_host_is_spi(mmc))
363 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200364 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500365 (mmc->ocr & OCR_VOLTAGE_MASK)) |
366 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000367
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500368 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000369 if (err)
370 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500371 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000372 return 0;
373}
374
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200375static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000376{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000377 int err, i;
378
Andy Fleming272cc702008-10-30 16:41:01 -0500379 /* Some cards seem to need this */
380 mmc_go_idle(mmc);
381
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000382 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000383 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500384 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500385 if (err)
386 return err;
387
Che-Liang Chioue9550442012-11-28 15:21:13 +0000388 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500389 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500390 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000391 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500392 mmc->op_cond_pending = 1;
393 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000394}
Andy Fleming272cc702008-10-30 16:41:01 -0500395
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200396static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000397{
398 struct mmc_cmd cmd;
399 int timeout = 1000;
400 uint start;
401 int err;
402
403 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500404 if (!(mmc->ocr & OCR_BUSY)) {
405 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500406 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500407 err = mmc_send_op_cond_iter(mmc, 1);
408 if (err)
409 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500410 if (mmc->ocr & OCR_BUSY)
411 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500412 if (get_timer(start) > timeout)
413 return UNUSABLE_ERR;
414 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500415 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500416 }
Andy Fleming272cc702008-10-30 16:41:01 -0500417
Thomas Choud52ebf12010-12-24 13:12:21 +0000418 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
419 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
420 cmd.resp_type = MMC_RSP_R3;
421 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000422
423 err = mmc_send_cmd(mmc, &cmd, NULL);
424
425 if (err)
426 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500427
428 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000429 }
430
Andy Fleming272cc702008-10-30 16:41:01 -0500431 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500432
433 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700434 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500435
436 return 0;
437}
438
439
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000440static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500441{
442 struct mmc_cmd cmd;
443 struct mmc_data data;
444 int err;
445
446 /* Get the Card Status Register */
447 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
448 cmd.resp_type = MMC_RSP_R1;
449 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500450
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000451 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500452 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000453 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500454 data.flags = MMC_DATA_READ;
455
456 err = mmc_send_cmd(mmc, &cmd, &data);
457
458 return err;
459}
460
461
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000462static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500463{
464 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000465 int timeout = 1000;
466 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500467
468 cmd.cmdidx = MMC_CMD_SWITCH;
469 cmd.resp_type = MMC_RSP_R1b;
470 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000471 (index << 16) |
472 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500473
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000474 ret = mmc_send_cmd(mmc, &cmd, NULL);
475
476 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000477 if (!ret)
478 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000479
480 return ret;
481
Andy Fleming272cc702008-10-30 16:41:01 -0500482}
483
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000484static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500485{
Simon Glass8bfa1952013-04-03 08:54:30 +0000486 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500487 char cardtype;
488 int err;
489
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600490 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500491
Thomas Choud52ebf12010-12-24 13:12:21 +0000492 if (mmc_host_is_spi(mmc))
493 return 0;
494
Andy Fleming272cc702008-10-30 16:41:01 -0500495 /* Only version 4 supports high-speed */
496 if (mmc->version < MMC_VERSION_4)
497 return 0;
498
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600499 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
500
Andy Fleming272cc702008-10-30 16:41:01 -0500501 err = mmc_send_ext_csd(mmc, ext_csd);
502
503 if (err)
504 return err;
505
Lei Wen0560db12011-10-03 20:35:10 +0000506 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500507
508 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
509
510 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500511 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500512
513 /* Now check to see that it worked */
514 err = mmc_send_ext_csd(mmc, ext_csd);
515
516 if (err)
517 return err;
518
519 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000520 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500521 return 0;
522
523 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900524 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600525 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900526 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500527 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900528 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500529 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900530 }
Andy Fleming272cc702008-10-30 16:41:01 -0500531
532 return 0;
533}
534
Stephen Warrenf866a462013-06-11 15:14:01 -0600535static int mmc_set_capacity(struct mmc *mmc, int part_num)
536{
537 switch (part_num) {
538 case 0:
539 mmc->capacity = mmc->capacity_user;
540 break;
541 case 1:
542 case 2:
543 mmc->capacity = mmc->capacity_boot;
544 break;
545 case 3:
546 mmc->capacity = mmc->capacity_rpmb;
547 break;
548 case 4:
549 case 5:
550 case 6:
551 case 7:
552 mmc->capacity = mmc->capacity_gp[part_num - 4];
553 break;
554 default:
555 return -1;
556 }
557
Simon Glassc40fdca2016-05-01 13:52:35 -0600558 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600559
560 return 0;
561}
562
Lei Wenbc897b12011-05-02 16:26:26 +0000563int mmc_switch_part(int dev_num, unsigned int part_num)
564{
565 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600566 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000567
568 if (!mmc)
569 return -1;
570
Stephen Warrenf866a462013-06-11 15:14:01 -0600571 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
572 (mmc->part_config & ~PART_ACCESS_MASK)
573 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600574
Peter Bigot6dc93e72014-09-02 18:31:23 -0500575 /*
576 * Set the capacity if the switch succeeded or was intended
577 * to return to representing the raw device.
578 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700579 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500580 ret = mmc_set_capacity(mmc, part_num);
Stephen Warren873cc1d2015-12-07 11:38:49 -0700581 mmc->block_dev.hwpart = part_num;
582 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500583
584 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000585}
586
Simon Glasse17d1142016-05-01 13:52:26 -0600587static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
588{
589 struct mmc *mmc = find_mmc_device(desc->devnum);
590 int ret;
591
592 if (!mmc)
593 return -ENODEV;
594
595 if (mmc->block_dev.hwpart == hwpart)
596 return 0;
597
598 if (mmc->part_config == MMCPART_NOAVAILABLE)
599 return -EMEDIUMTYPE;
600
601 ret = mmc_switch_part(desc->devnum, hwpart);
602 if (ret)
603 return ret;
604
605 return 0;
606}
607
Simon Glassff3882a2016-05-01 13:52:25 -0600608int mmc_select_hwpart(int dev_num, int hwpart)
609{
610 struct mmc *mmc = find_mmc_device(dev_num);
611 int ret;
612
613 if (!mmc)
614 return -ENODEV;
615
616 if (mmc->block_dev.hwpart == hwpart)
617 return 0;
618
619 if (mmc->part_config == MMCPART_NOAVAILABLE)
620 return -EMEDIUMTYPE;
621
622 ret = mmc_switch_part(dev_num, hwpart);
623 if (ret)
624 return ret;
625
626 return 0;
627}
628
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100629int mmc_hwpart_config(struct mmc *mmc,
630 const struct mmc_hwpart_conf *conf,
631 enum mmc_hwpart_conf_mode mode)
632{
633 u8 part_attrs = 0;
634 u32 enh_size_mult;
635 u32 enh_start_addr;
636 u32 gp_size_mult[4];
637 u32 max_enh_size_mult;
638 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100639 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100640 int i, pidx, err;
641 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
642
643 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
644 return -EINVAL;
645
646 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
647 printf("eMMC >= 4.4 required for enhanced user data area\n");
648 return -EMEDIUMTYPE;
649 }
650
651 if (!(mmc->part_support & PART_SUPPORT)) {
652 printf("Card does not support partitioning\n");
653 return -EMEDIUMTYPE;
654 }
655
656 if (!mmc->hc_wp_grp_size) {
657 printf("Card does not define HC WP group size\n");
658 return -EMEDIUMTYPE;
659 }
660
661 /* check partition alignment and total enhanced size */
662 if (conf->user.enh_size) {
663 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
664 conf->user.enh_start % mmc->hc_wp_grp_size) {
665 printf("User data enhanced area not HC WP group "
666 "size aligned\n");
667 return -EINVAL;
668 }
669 part_attrs |= EXT_CSD_ENH_USR;
670 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
671 if (mmc->high_capacity) {
672 enh_start_addr = conf->user.enh_start;
673 } else {
674 enh_start_addr = (conf->user.enh_start << 9);
675 }
676 } else {
677 enh_size_mult = 0;
678 enh_start_addr = 0;
679 }
680 tot_enh_size_mult += enh_size_mult;
681
682 for (pidx = 0; pidx < 4; pidx++) {
683 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
684 printf("GP%i partition not HC WP group size "
685 "aligned\n", pidx+1);
686 return -EINVAL;
687 }
688 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
689 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
690 part_attrs |= EXT_CSD_ENH_GP(pidx);
691 tot_enh_size_mult += gp_size_mult[pidx];
692 }
693 }
694
695 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
696 printf("Card does not support enhanced attribute\n");
697 return -EMEDIUMTYPE;
698 }
699
700 err = mmc_send_ext_csd(mmc, ext_csd);
701 if (err)
702 return err;
703
704 max_enh_size_mult =
705 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
706 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
707 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
708 if (tot_enh_size_mult > max_enh_size_mult) {
709 printf("Total enhanced size exceeds maximum (%u > %u)\n",
710 tot_enh_size_mult, max_enh_size_mult);
711 return -EMEDIUMTYPE;
712 }
713
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100714 /* The default value of EXT_CSD_WR_REL_SET is device
715 * dependent, the values can only be changed if the
716 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
717 * changed only once and before partitioning is completed. */
718 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
719 if (conf->user.wr_rel_change) {
720 if (conf->user.wr_rel_set)
721 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
722 else
723 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
724 }
725 for (pidx = 0; pidx < 4; pidx++) {
726 if (conf->gp_part[pidx].wr_rel_change) {
727 if (conf->gp_part[pidx].wr_rel_set)
728 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
729 else
730 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
731 }
732 }
733
734 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
735 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
736 puts("Card does not support host controlled partition write "
737 "reliability settings\n");
738 return -EMEDIUMTYPE;
739 }
740
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100741 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
742 EXT_CSD_PARTITION_SETTING_COMPLETED) {
743 printf("Card already partitioned\n");
744 return -EPERM;
745 }
746
747 if (mode == MMC_HWPART_CONF_CHECK)
748 return 0;
749
750 /* Partitioning requires high-capacity size definitions */
751 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
752 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
753 EXT_CSD_ERASE_GROUP_DEF, 1);
754
755 if (err)
756 return err;
757
758 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
759
760 /* update erase group size to be high-capacity */
761 mmc->erase_grp_size =
762 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
763
764 }
765
766 /* all OK, write the configuration */
767 for (i = 0; i < 4; i++) {
768 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
769 EXT_CSD_ENH_START_ADDR+i,
770 (enh_start_addr >> (i*8)) & 0xFF);
771 if (err)
772 return err;
773 }
774 for (i = 0; i < 3; i++) {
775 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
776 EXT_CSD_ENH_SIZE_MULT+i,
777 (enh_size_mult >> (i*8)) & 0xFF);
778 if (err)
779 return err;
780 }
781 for (pidx = 0; pidx < 4; pidx++) {
782 for (i = 0; i < 3; i++) {
783 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
784 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
785 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
786 if (err)
787 return err;
788 }
789 }
790 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
791 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
792 if (err)
793 return err;
794
795 if (mode == MMC_HWPART_CONF_SET)
796 return 0;
797
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100798 /* The WR_REL_SET is a write-once register but shall be
799 * written before setting PART_SETTING_COMPLETED. As it is
800 * write-once we can only write it when completing the
801 * partitioning. */
802 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
803 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
804 EXT_CSD_WR_REL_SET, wr_rel_set);
805 if (err)
806 return err;
807 }
808
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100809 /* Setting PART_SETTING_COMPLETED confirms the partition
810 * configuration but it only becomes effective after power
811 * cycle, so we do not adjust the partition related settings
812 * in the mmc struct. */
813
814 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
815 EXT_CSD_PARTITION_SETTING,
816 EXT_CSD_PARTITION_SETTING_COMPLETED);
817 if (err)
818 return err;
819
820 return 0;
821}
822
Thierry Reding48972d92012-01-02 01:15:37 +0000823int mmc_getcd(struct mmc *mmc)
824{
825 int cd;
826
827 cd = board_mmc_getcd(mmc);
828
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000829 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200830 if (mmc->cfg->ops->getcd)
831 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000832 else
833 cd = 1;
834 }
Thierry Reding48972d92012-01-02 01:15:37 +0000835
836 return cd;
837}
838
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000839static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500840{
841 struct mmc_cmd cmd;
842 struct mmc_data data;
843
844 /* Switch the frequency */
845 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
846 cmd.resp_type = MMC_RSP_R1;
847 cmd.cmdarg = (mode << 31) | 0xffffff;
848 cmd.cmdarg &= ~(0xf << (group * 4));
849 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500850
851 data.dest = (char *)resp;
852 data.blocksize = 64;
853 data.blocks = 1;
854 data.flags = MMC_DATA_READ;
855
856 return mmc_send_cmd(mmc, &cmd, &data);
857}
858
859
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000860static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500861{
862 int err;
863 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000864 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
865 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500866 struct mmc_data data;
867 int timeout;
868
869 mmc->card_caps = 0;
870
Thomas Choud52ebf12010-12-24 13:12:21 +0000871 if (mmc_host_is_spi(mmc))
872 return 0;
873
Andy Fleming272cc702008-10-30 16:41:01 -0500874 /* Read the SCR to find out if this card supports higher speeds */
875 cmd.cmdidx = MMC_CMD_APP_CMD;
876 cmd.resp_type = MMC_RSP_R1;
877 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500878
879 err = mmc_send_cmd(mmc, &cmd, NULL);
880
881 if (err)
882 return err;
883
884 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
885 cmd.resp_type = MMC_RSP_R1;
886 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500887
888 timeout = 3;
889
890retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000891 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500892 data.blocksize = 8;
893 data.blocks = 1;
894 data.flags = MMC_DATA_READ;
895
896 err = mmc_send_cmd(mmc, &cmd, &data);
897
898 if (err) {
899 if (timeout--)
900 goto retry_scr;
901
902 return err;
903 }
904
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300905 mmc->scr[0] = __be32_to_cpu(scr[0]);
906 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500907
908 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -0700909 case 0:
910 mmc->version = SD_VERSION_1_0;
911 break;
912 case 1:
913 mmc->version = SD_VERSION_1_10;
914 break;
915 case 2:
916 mmc->version = SD_VERSION_2;
917 if ((mmc->scr[0] >> 15) & 0x1)
918 mmc->version = SD_VERSION_3;
919 break;
920 default:
921 mmc->version = SD_VERSION_1_0;
922 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500923 }
924
Alagu Sankarb44c7082010-05-12 15:08:24 +0530925 if (mmc->scr[0] & SD_DATA_4BIT)
926 mmc->card_caps |= MMC_MODE_4BIT;
927
Andy Fleming272cc702008-10-30 16:41:01 -0500928 /* Version 1.0 doesn't support switching */
929 if (mmc->version == SD_VERSION_1_0)
930 return 0;
931
932 timeout = 4;
933 while (timeout--) {
934 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000935 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500936
937 if (err)
938 return err;
939
940 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300941 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500942 break;
943 }
944
Andy Fleming272cc702008-10-30 16:41:01 -0500945 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300946 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500947 return 0;
948
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000949 /*
950 * If the host doesn't support SD_HIGHSPEED, do not switch card to
951 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
952 * This can avoid furthur problem when the card runs in different
953 * mode between the host.
954 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200955 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
956 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000957 return 0;
958
Anton staaff781dd32011-10-03 13:54:59 +0000959 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500960
961 if (err)
962 return err;
963
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300964 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500965 mmc->card_caps |= MMC_MODE_HS;
966
967 return 0;
968}
969
970/* frequency bases */
971/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000972static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500973 10000,
974 100000,
975 1000000,
976 10000000,
977};
978
979/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
980 * to platforms without floating point.
981 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000982static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500983 0, /* reserved */
984 10,
985 12,
986 13,
987 15,
988 20,
989 25,
990 30,
991 35,
992 40,
993 45,
994 50,
995 55,
996 60,
997 70,
998 80,
999};
1000
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001001static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001002{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001003 if (mmc->cfg->ops->set_ios)
1004 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001005}
1006
1007void mmc_set_clock(struct mmc *mmc, uint clock)
1008{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001009 if (clock > mmc->cfg->f_max)
1010 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001011
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001012 if (clock < mmc->cfg->f_min)
1013 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001014
1015 mmc->clock = clock;
1016
1017 mmc_set_ios(mmc);
1018}
1019
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001020static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001021{
1022 mmc->bus_width = width;
1023
1024 mmc_set_ios(mmc);
1025}
1026
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001027static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001028{
Stephen Warrenf866a462013-06-11 15:14:01 -06001029 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001030 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001031 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001032 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001033 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1034 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001035 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001036 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001037 bool part_completed;
Simon Glassc40fdca2016-05-01 13:52:35 -06001038 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05001039
Thomas Choud52ebf12010-12-24 13:12:21 +00001040#ifdef CONFIG_MMC_SPI_CRC_ON
1041 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1042 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1043 cmd.resp_type = MMC_RSP_R1;
1044 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001045 err = mmc_send_cmd(mmc, &cmd, NULL);
1046
1047 if (err)
1048 return err;
1049 }
1050#endif
1051
Andy Fleming272cc702008-10-30 16:41:01 -05001052 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001053 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1054 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001055 cmd.resp_type = MMC_RSP_R2;
1056 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001057
1058 err = mmc_send_cmd(mmc, &cmd, NULL);
1059
1060 if (err)
1061 return err;
1062
1063 memcpy(mmc->cid, cmd.response, 16);
1064
1065 /*
1066 * For MMC cards, set the Relative Address.
1067 * For SD cards, get the Relatvie Address.
1068 * This also puts the cards into Standby State
1069 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001070 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1071 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1072 cmd.cmdarg = mmc->rca << 16;
1073 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001074
Thomas Choud52ebf12010-12-24 13:12:21 +00001075 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001076
Thomas Choud52ebf12010-12-24 13:12:21 +00001077 if (err)
1078 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001079
Thomas Choud52ebf12010-12-24 13:12:21 +00001080 if (IS_SD(mmc))
1081 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1082 }
Andy Fleming272cc702008-10-30 16:41:01 -05001083
1084 /* Get the Card-Specific Data */
1085 cmd.cmdidx = MMC_CMD_SEND_CSD;
1086 cmd.resp_type = MMC_RSP_R2;
1087 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001088
1089 err = mmc_send_cmd(mmc, &cmd, NULL);
1090
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001091 /* Waiting for the ready status */
1092 mmc_send_status(mmc, timeout);
1093
Andy Fleming272cc702008-10-30 16:41:01 -05001094 if (err)
1095 return err;
1096
Rabin Vincent998be3d2009-04-05 13:30:56 +05301097 mmc->csd[0] = cmd.response[0];
1098 mmc->csd[1] = cmd.response[1];
1099 mmc->csd[2] = cmd.response[2];
1100 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001101
1102 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301103 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001104
1105 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07001106 case 0:
1107 mmc->version = MMC_VERSION_1_2;
1108 break;
1109 case 1:
1110 mmc->version = MMC_VERSION_1_4;
1111 break;
1112 case 2:
1113 mmc->version = MMC_VERSION_2_2;
1114 break;
1115 case 3:
1116 mmc->version = MMC_VERSION_3;
1117 break;
1118 case 4:
1119 mmc->version = MMC_VERSION_4;
1120 break;
1121 default:
1122 mmc->version = MMC_VERSION_1_2;
1123 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001124 }
1125 }
1126
1127 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301128 freq = fbase[(cmd.response[0] & 0x7)];
1129 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001130
1131 mmc->tran_speed = freq * mult;
1132
Markus Niebelab711882013-12-16 13:40:46 +01001133 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301134 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001135
1136 if (IS_SD(mmc))
1137 mmc->write_bl_len = mmc->read_bl_len;
1138 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301139 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001140
1141 if (mmc->high_capacity) {
1142 csize = (mmc->csd[1] & 0x3f) << 16
1143 | (mmc->csd[2] & 0xffff0000) >> 16;
1144 cmult = 8;
1145 } else {
1146 csize = (mmc->csd[1] & 0x3ff) << 2
1147 | (mmc->csd[2] & 0xc0000000) >> 30;
1148 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1149 }
1150
Stephen Warrenf866a462013-06-11 15:14:01 -06001151 mmc->capacity_user = (csize + 1) << (cmult + 2);
1152 mmc->capacity_user *= mmc->read_bl_len;
1153 mmc->capacity_boot = 0;
1154 mmc->capacity_rpmb = 0;
1155 for (i = 0; i < 4; i++)
1156 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001157
Simon Glass8bfa1952013-04-03 08:54:30 +00001158 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1159 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001160
Simon Glass8bfa1952013-04-03 08:54:30 +00001161 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1162 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001163
Markus Niebelab711882013-12-16 13:40:46 +01001164 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1165 cmd.cmdidx = MMC_CMD_SET_DSR;
1166 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1167 cmd.resp_type = MMC_RSP_NONE;
1168 if (mmc_send_cmd(mmc, &cmd, NULL))
1169 printf("MMC: SET_DSR failed\n");
1170 }
1171
Andy Fleming272cc702008-10-30 16:41:01 -05001172 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001173 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1174 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001175 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001176 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001177 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001178
Thomas Choud52ebf12010-12-24 13:12:21 +00001179 if (err)
1180 return err;
1181 }
Andy Fleming272cc702008-10-30 16:41:01 -05001182
Lei Wene6f99a52011-06-22 17:03:31 +00001183 /*
1184 * For SD, its erase group is always one sector
1185 */
1186 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001187 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301188 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1189 /* check ext_csd version and capacity */
1190 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001191 if (err)
1192 return err;
1193 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001194 /*
1195 * According to the JEDEC Standard, the value of
1196 * ext_csd's capacity is valid if the value is more
1197 * than 2GB
1198 */
Lei Wen0560db12011-10-03 20:35:10 +00001199 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1200 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1201 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1202 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001203 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001204 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001205 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301206 }
Lei Wenbc897b12011-05-02 16:26:26 +00001207
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001208 switch (ext_csd[EXT_CSD_REV]) {
1209 case 1:
1210 mmc->version = MMC_VERSION_4_1;
1211 break;
1212 case 2:
1213 mmc->version = MMC_VERSION_4_2;
1214 break;
1215 case 3:
1216 mmc->version = MMC_VERSION_4_3;
1217 break;
1218 case 5:
1219 mmc->version = MMC_VERSION_4_41;
1220 break;
1221 case 6:
1222 mmc->version = MMC_VERSION_4_5;
1223 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001224 case 7:
1225 mmc->version = MMC_VERSION_5_0;
1226 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001227 }
1228
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001229 /* The partition data may be non-zero but it is only
1230 * effective if PARTITION_SETTING_COMPLETED is set in
1231 * EXT_CSD, so ignore any data if this bit is not set,
1232 * except for enabling the high-capacity group size
1233 * definition (see below). */
1234 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1235 EXT_CSD_PARTITION_SETTING_COMPLETED);
1236
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001237 /* store the partition info of emmc */
1238 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1239 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1240 ext_csd[EXT_CSD_BOOT_MULT])
1241 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001242 if (part_completed &&
1243 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001244 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1245
1246 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1247
1248 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1249
1250 for (i = 0; i < 4; i++) {
1251 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001252 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001253 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001254 if (mult)
1255 has_parts = true;
1256 if (!part_completed)
1257 continue;
1258 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001259 mmc->capacity_gp[i] *=
1260 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1261 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001262 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001263 }
1264
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001265 if (part_completed) {
1266 mmc->enh_user_size =
1267 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1268 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1269 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1270 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1271 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1272 mmc->enh_user_size <<= 19;
1273 mmc->enh_user_start =
1274 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1275 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1276 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1277 ext_csd[EXT_CSD_ENH_START_ADDR];
1278 if (mmc->high_capacity)
1279 mmc->enh_user_start <<= 9;
1280 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001281
Lei Wene6f99a52011-06-22 17:03:31 +00001282 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001283 * Host needs to enable ERASE_GRP_DEF bit if device is
1284 * partitioned. This bit will be lost every time after a reset
1285 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001286 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001287 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001288 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001289 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001290 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1291 has_parts = true;
1292 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001293 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1294 EXT_CSD_ERASE_GROUP_DEF, 1);
1295
1296 if (err)
1297 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001298 else
1299 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001300 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001301
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001302 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001303 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001304 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001305 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001306 /*
1307 * if high capacity and partition setting completed
1308 * SEC_COUNT is valid even if it is smaller than 2 GiB
1309 * JEDEC Standard JESD84-B45, 6.2.4
1310 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001311 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001312 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1313 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1314 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1315 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1316 capacity *= MMC_MAX_BLOCK_LEN;
1317 mmc->capacity_user = capacity;
1318 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001319 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001320 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001321 int erase_gsz, erase_gmul;
1322 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1323 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1324 mmc->erase_grp_size = (erase_gsz + 1)
1325 * (erase_gmul + 1);
1326 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001327
1328 mmc->hc_wp_grp_size = 1024
1329 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1330 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001331
1332 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301333 }
1334
Simon Glassc40fdca2016-05-01 13:52:35 -06001335 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06001336 if (err)
1337 return err;
1338
Andy Fleming272cc702008-10-30 16:41:01 -05001339 if (IS_SD(mmc))
1340 err = sd_change_freq(mmc);
1341 else
1342 err = mmc_change_freq(mmc);
1343
1344 if (err)
1345 return err;
1346
1347 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001348 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001349
1350 if (IS_SD(mmc)) {
1351 if (mmc->card_caps & MMC_MODE_4BIT) {
1352 cmd.cmdidx = MMC_CMD_APP_CMD;
1353 cmd.resp_type = MMC_RSP_R1;
1354 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001355
1356 err = mmc_send_cmd(mmc, &cmd, NULL);
1357 if (err)
1358 return err;
1359
1360 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1361 cmd.resp_type = MMC_RSP_R1;
1362 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001363 err = mmc_send_cmd(mmc, &cmd, NULL);
1364 if (err)
1365 return err;
1366
1367 mmc_set_bus_width(mmc, 4);
1368 }
1369
1370 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001371 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001372 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001373 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001374 } else if (mmc->version >= MMC_VERSION_4) {
1375 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001376 int idx;
1377
1378 /* An array of possible bus widths in order of preference */
1379 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001380 EXT_CSD_DDR_BUS_WIDTH_8,
1381 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001382 EXT_CSD_BUS_WIDTH_8,
1383 EXT_CSD_BUS_WIDTH_4,
1384 EXT_CSD_BUS_WIDTH_1,
1385 };
1386
1387 /* An array to map CSD bus widths to host cap bits */
1388 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001389 [EXT_CSD_DDR_BUS_WIDTH_4] =
1390 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1391 [EXT_CSD_DDR_BUS_WIDTH_8] =
1392 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001393 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1394 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1395 };
1396
1397 /* An array to map chosen bus width to an integer */
1398 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001399 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001400 };
1401
1402 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1403 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001404 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001405
1406 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001407 * If the bus width is still not changed,
1408 * don't try to set the default again.
1409 * Otherwise, recover from switch attempts
1410 * by switching to 1-bit bus width.
1411 */
1412 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1413 mmc->bus_width == 1) {
1414 err = 0;
1415 break;
1416 }
1417
1418 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001419 * Check to make sure the card and controller support
1420 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001421 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001422 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001423 continue;
1424
Andy Fleming272cc702008-10-30 16:41:01 -05001425 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001426 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001427
1428 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001429 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001430
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001431 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001432 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001433
Lei Wen41378942011-10-03 20:35:11 +00001434 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001435
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001436 if (err)
1437 continue;
1438
1439 /* Only compare read only fields */
1440 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1441 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1442 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1443 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1444 ext_csd[EXT_CSD_REV]
1445 == test_csd[EXT_CSD_REV] &&
1446 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1447 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1448 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1449 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001450 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001451 else
1452 err = SWITCH_ERR;
Andy Fleming272cc702008-10-30 16:41:01 -05001453 }
1454
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001455 if (err)
1456 return err;
1457
Andy Fleming272cc702008-10-30 16:41:01 -05001458 if (mmc->card_caps & MMC_MODE_HS) {
1459 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001460 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001461 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001462 mmc->tran_speed = 26000000;
1463 }
Andy Fleming272cc702008-10-30 16:41:01 -05001464 }
1465
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001466 mmc_set_clock(mmc, mmc->tran_speed);
1467
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001468 /* Fix the block length for DDR mode */
1469 if (mmc->ddr_mode) {
1470 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1471 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1472 }
1473
Andy Fleming272cc702008-10-30 16:41:01 -05001474 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06001475 bdesc = mmc_get_blk_desc(mmc);
1476 bdesc->lun = 0;
1477 bdesc->hwpart = 0;
1478 bdesc->type = 0;
1479 bdesc->blksz = mmc->read_bl_len;
1480 bdesc->log2blksz = LOG2(bdesc->blksz);
1481 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01001482#if !defined(CONFIG_SPL_BUILD) || \
1483 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1484 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06001485 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00001486 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1487 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001488 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001489 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1490 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1491 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001492 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001493 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001494#else
Simon Glassc40fdca2016-05-01 13:52:35 -06001495 bdesc->vendor[0] = 0;
1496 bdesc->product[0] = 0;
1497 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01001498#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001499#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glassc40fdca2016-05-01 13:52:35 -06001500 part_init(bdesc);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001501#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001502
1503 return 0;
1504}
1505
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001506static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001507{
1508 struct mmc_cmd cmd;
1509 int err;
1510
1511 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1512 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001513 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001514 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001515
1516 err = mmc_send_cmd(mmc, &cmd, NULL);
1517
1518 if (err)
1519 return err;
1520
Rabin Vincent998be3d2009-04-05 13:30:56 +05301521 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001522 return UNUSABLE_ERR;
1523 else
1524 mmc->version = SD_VERSION_2;
1525
1526 return 0;
1527}
1528
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001529/* not used any more */
1530int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001531{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001532#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1533 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1534#endif
1535 return -1;
1536}
1537
1538struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1539{
Simon Glassc40fdca2016-05-01 13:52:35 -06001540 struct blk_desc *bdesc;
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001541 struct mmc *mmc;
1542
1543 /* quick validation */
1544 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1545 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1546 return NULL;
1547
1548 mmc = calloc(1, sizeof(*mmc));
1549 if (mmc == NULL)
1550 return NULL;
1551
1552 mmc->cfg = cfg;
1553 mmc->priv = priv;
1554
1555 /* the following chunk was mmc_register() */
1556
Markus Niebelab711882013-12-16 13:40:46 +01001557 /* Setup dsr related values */
1558 mmc->dsr_imp = 0;
1559 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001560 /* Setup the universal parts of the block interface just once */
Simon Glassc40fdca2016-05-01 13:52:35 -06001561 bdesc = mmc_get_blk_desc(mmc);
1562 bdesc->if_type = IF_TYPE_MMC;
1563 bdesc->removable = 1;
1564 bdesc->devnum = mmc_get_next_devnum();
1565 bdesc->block_read = mmc_bread;
1566 bdesc->block_write = mmc_bwrite;
1567 bdesc->block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001568
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001569 /* setup initial part type */
Simon Glassc40fdca2016-05-01 13:52:35 -06001570 bdesc->part_type = mmc->cfg->part_type;
1571 mmc_list_add(mmc);
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001572
1573 return mmc;
1574}
1575
1576void mmc_destroy(struct mmc *mmc)
1577{
1578 /* only freeing memory for now */
1579 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001580}
1581
Simon Glass3c457f42016-05-01 11:36:15 -06001582static int mmc_get_dev(int dev, struct blk_desc **descp)
Simon Glass663acab2016-05-01 11:36:07 -06001583{
1584 struct mmc *mmc = find_mmc_device(dev);
1585 int ret;
1586
1587 if (!mmc)
1588 return -ENODEV;
1589 ret = mmc_init(mmc);
1590 if (ret)
1591 return ret;
1592
1593 *descp = &mmc->block_dev;
1594
1595 return 0;
1596}
1597
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001598/* board-specific MMC power initializations. */
1599__weak void board_mmc_power_init(void)
1600{
1601}
1602
Che-Liang Chioue9550442012-11-28 15:21:13 +00001603int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001604{
Macpaul Linafd59322011-11-14 23:35:39 +00001605 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001606
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001607 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001608 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001609 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001610#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001611 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001612#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001613 return NO_CARD_ERR;
1614 }
1615
Lei Wenbc897b12011-05-02 16:26:26 +00001616 if (mmc->has_init)
1617 return 0;
1618
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001619#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1620 mmc_adapter_card_type_ident();
1621#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001622 board_mmc_power_init();
1623
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001624 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001625 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001626
1627 if (err)
1628 return err;
1629
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001630 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001631 mmc_set_bus_width(mmc, 1);
1632 mmc_set_clock(mmc, 1);
1633
Andy Fleming272cc702008-10-30 16:41:01 -05001634 /* Reset the Card */
1635 err = mmc_go_idle(mmc);
1636
1637 if (err)
1638 return err;
1639
Lei Wenbc897b12011-05-02 16:26:26 +00001640 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06001641 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00001642
Andy Fleming272cc702008-10-30 16:41:01 -05001643 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001644 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001645
Andy Fleming272cc702008-10-30 16:41:01 -05001646 /* Now try to get the SD card's operating condition */
1647 err = sd_send_op_cond(mmc);
1648
1649 /* If the command timed out, we check for an MMC card */
1650 if (err == TIMEOUT) {
1651 err = mmc_send_op_cond(mmc);
1652
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001653 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001654#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001655 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001656#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001657 return UNUSABLE_ERR;
1658 }
1659 }
1660
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001661 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001662 mmc->init_in_progress = 1;
1663
1664 return err;
1665}
1666
1667static int mmc_complete_init(struct mmc *mmc)
1668{
1669 int err = 0;
1670
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001671 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001672 if (mmc->op_cond_pending)
1673 err = mmc_complete_op_cond(mmc);
1674
1675 if (!err)
1676 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001677 if (err)
1678 mmc->has_init = 0;
1679 else
1680 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001681 return err;
1682}
1683
1684int mmc_init(struct mmc *mmc)
1685{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001686 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001687 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001688
1689 if (mmc->has_init)
1690 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001691
1692 start = get_timer(0);
1693
Che-Liang Chioue9550442012-11-28 15:21:13 +00001694 if (!mmc->init_in_progress)
1695 err = mmc_start_init(mmc);
1696
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001697 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001698 err = mmc_complete_init(mmc);
1699 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001700 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001701}
1702
Markus Niebelab711882013-12-16 13:40:46 +01001703int mmc_set_dsr(struct mmc *mmc, u16 val)
1704{
1705 mmc->dsr = val;
1706 return 0;
1707}
1708
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001709/* CPU-specific MMC initializations */
1710__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001711{
1712 return -1;
1713}
1714
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001715/* board-specific MMC initializations. */
1716__weak int board_mmc_init(bd_t *bis)
1717{
1718 return -1;
1719}
Andy Fleming272cc702008-10-30 16:41:01 -05001720
Che-Liang Chioue9550442012-11-28 15:21:13 +00001721void mmc_set_preinit(struct mmc *mmc, int preinit)
1722{
1723 mmc->preinit = preinit;
1724}
1725
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001726#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
1727static int mmc_probe(bd_t *bis)
1728{
1729 return 0;
1730}
1731#elif defined(CONFIG_DM_MMC)
1732static int mmc_probe(bd_t *bis)
1733{
Simon Glass4a1db6d2015-12-29 05:22:49 -07001734 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001735 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07001736 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001737
1738 ret = uclass_get(UCLASS_MMC, &uc);
1739 if (ret)
1740 return ret;
1741
Simon Glass4a1db6d2015-12-29 05:22:49 -07001742 /*
1743 * Try to add them in sequence order. Really with driver model we
1744 * should allow holes, but the current MMC list does not allow that.
1745 * So if we request 0, 1, 3 we will get 0, 1, 2.
1746 */
1747 for (i = 0; ; i++) {
1748 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
1749 if (ret == -ENODEV)
1750 break;
1751 }
1752 uclass_foreach_dev(dev, uc) {
1753 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001754 if (ret)
Simon Glass4a1db6d2015-12-29 05:22:49 -07001755 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001756 }
1757
1758 return 0;
1759}
1760#else
1761static int mmc_probe(bd_t *bis)
1762{
1763 if (board_mmc_init(bis) < 0)
1764 cpu_mmc_init(bis);
1765
1766 return 0;
1767}
1768#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001769
Andy Fleming272cc702008-10-30 16:41:01 -05001770int mmc_initialize(bd_t *bis)
1771{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001772 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001773 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001774 if (initialized) /* Avoid initializing mmc multiple times */
1775 return 0;
1776 initialized = 1;
1777
Simon Glassc40fdca2016-05-01 13:52:35 -06001778#ifndef CONFIG_BLK
1779 mmc_list_init();
1780#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001781 ret = mmc_probe(bis);
1782 if (ret)
1783 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001784
Ying Zhangbb0dc102013-08-16 15:16:11 +08001785#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001786 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001787#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001788
Simon Glassc40fdca2016-05-01 13:52:35 -06001789 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001790 return 0;
1791}
Amar3690d6d2013-04-27 11:42:58 +05301792
1793#ifdef CONFIG_SUPPORT_EMMC_BOOT
1794/*
1795 * This function changes the size of boot partition and the size of rpmb
1796 * partition present on EMMC devices.
1797 *
1798 * Input Parameters:
1799 * struct *mmc: pointer for the mmc device strcuture
1800 * bootsize: size of boot partition
1801 * rpmbsize: size of rpmb partition
1802 *
1803 * Returns 0 on success.
1804 */
1805
1806int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1807 unsigned long rpmbsize)
1808{
1809 int err;
1810 struct mmc_cmd cmd;
1811
1812 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1813 cmd.cmdidx = MMC_CMD_RES_MAN;
1814 cmd.resp_type = MMC_RSP_R1b;
1815 cmd.cmdarg = MMC_CMD62_ARG1;
1816
1817 err = mmc_send_cmd(mmc, &cmd, NULL);
1818 if (err) {
1819 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1820 return err;
1821 }
1822
1823 /* Boot partition changing mode */
1824 cmd.cmdidx = MMC_CMD_RES_MAN;
1825 cmd.resp_type = MMC_RSP_R1b;
1826 cmd.cmdarg = MMC_CMD62_ARG2;
1827
1828 err = mmc_send_cmd(mmc, &cmd, NULL);
1829 if (err) {
1830 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1831 return err;
1832 }
1833 /* boot partition size is multiple of 128KB */
1834 bootsize = (bootsize * 1024) / 128;
1835
1836 /* Arg: boot partition size */
1837 cmd.cmdidx = MMC_CMD_RES_MAN;
1838 cmd.resp_type = MMC_RSP_R1b;
1839 cmd.cmdarg = bootsize;
1840
1841 err = mmc_send_cmd(mmc, &cmd, NULL);
1842 if (err) {
1843 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1844 return err;
1845 }
1846 /* RPMB partition size is multiple of 128KB */
1847 rpmbsize = (rpmbsize * 1024) / 128;
1848 /* Arg: RPMB partition size */
1849 cmd.cmdidx = MMC_CMD_RES_MAN;
1850 cmd.resp_type = MMC_RSP_R1b;
1851 cmd.cmdarg = rpmbsize;
1852
1853 err = mmc_send_cmd(mmc, &cmd, NULL);
1854 if (err) {
1855 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1856 return err;
1857 }
1858 return 0;
1859}
1860
1861/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001862 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1863 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1864 * and BOOT_MODE.
1865 *
1866 * Returns 0 on success.
1867 */
1868int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1869{
1870 int err;
1871
1872 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1873 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1874 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1875 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1876
1877 if (err)
1878 return err;
1879 return 0;
1880}
1881
1882/*
Tom Rini792970b2014-02-05 10:24:21 -05001883 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1884 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1885 * PARTITION_ACCESS.
1886 *
1887 * Returns 0 on success.
1888 */
1889int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1890{
1891 int err;
1892
1893 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1894 EXT_CSD_BOOT_ACK(ack) |
1895 EXT_CSD_BOOT_PART_NUM(part_num) |
1896 EXT_CSD_PARTITION_ACCESS(access));
1897
1898 if (err)
1899 return err;
1900 return 0;
1901}
Tom Rini33ace362014-02-07 14:15:20 -05001902
1903/*
1904 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1905 * for enable. Note that this is a write-once field for non-zero values.
1906 *
1907 * Returns 0 on success.
1908 */
1909int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1910{
1911 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1912 enable);
1913}
Amar3690d6d2013-04-27 11:42:58 +05301914#endif
Simon Glass663acab2016-05-01 11:36:07 -06001915
1916U_BOOT_LEGACY_BLK(mmc) = {
1917 .if_typename = "mmc",
1918 .if_type = IF_TYPE_MMC,
1919 .max_devs = -1,
Simon Glass3c457f42016-05-01 11:36:15 -06001920 .get_dev = mmc_get_dev,
Simon Glasse17d1142016-05-01 13:52:26 -06001921 .select_hwpart = mmc_select_hwpartp,
Simon Glass663acab2016-05-01 11:36:07 -06001922};