blob: f12546ac51925a9e249ffb1a8fbdf8cd6f91ea04 [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>
Stephen Warrend4622df2014-05-23 12:47:06 -060013#include <errno.h>
Andy Fleming272cc702008-10-30 16:41:01 -050014#include <mmc.h>
15#include <part.h>
16#include <malloc.h>
17#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053018#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010019#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050020
21static struct list_head mmc_devices;
22static int cur_dev_num = -1;
23
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);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000061 switch (cmd->resp_type) {
62 case MMC_RSP_NONE:
63 printf("\t\tMMC_RSP_NONE\n");
64 break;
65 case MMC_RSP_R1:
66 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
67 cmd->response[0]);
68 break;
69 case MMC_RSP_R1b:
70 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
71 cmd->response[0]);
72 break;
73 case MMC_RSP_R2:
74 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
75 cmd->response[0]);
76 printf("\t\t \t\t 0x%08X \n",
77 cmd->response[1]);
78 printf("\t\t \t\t 0x%08X \n",
79 cmd->response[2]);
80 printf("\t\t \t\t 0x%08X \n",
81 cmd->response[3]);
82 printf("\n");
83 printf("\t\t\t\t\tDUMPING DATA\n");
84 for (i = 0; i < 4; i++) {
85 int j;
86 printf("\t\t\t\t\t%03d - ", i*4);
Dirk Behme146bec72012-03-08 02:35:34 +000087 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000088 ptr += 3;
89 for (j = 0; j < 4; j++)
90 printf("%02X ", *ptr--);
91 printf("\n");
92 }
93 break;
94 case MMC_RSP_R3:
95 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
96 cmd->response[0]);
97 break;
98 default:
99 printf("\t\tERROR MMC rsp not supported\n");
100 break;
101 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000102#else
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200103 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000104#endif
Marek Vasut8635ff92012-03-15 18:41:35 +0000105 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500106}
107
Paul Burtonda61fa52013-09-09 15:30:26 +0100108int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000109{
110 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000111 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000112#ifdef CONFIG_MMC_TRACE
113 int status;
114#endif
115
116 cmd.cmdidx = MMC_CMD_SEND_STATUS;
117 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200118 if (!mmc_host_is_spi(mmc))
119 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000120
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500121 while (1) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000122 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000123 if (!err) {
124 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
125 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
126 MMC_STATE_PRG)
127 break;
128 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton56196822013-09-04 16:12:25 +0100129#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000130 printf("Status Error: 0x%08X\n",
131 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100132#endif
Jan Kloetzked617c422012-02-05 22:29:12 +0000133 return COMM_ERR;
134 }
135 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000136 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000137
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500138 if (timeout-- <= 0)
139 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000140
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500141 udelay(1000);
142 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000143
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000144#ifdef CONFIG_MMC_TRACE
145 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
146 printf("CURR STATE:%d\n", status);
147#endif
Jongman Heo5b0c9422012-06-03 21:32:13 +0000148 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100149#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000150 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100151#endif
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000152 return TIMEOUT;
153 }
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500154 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
155 return SWITCH_ERR;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000156
157 return 0;
158}
159
Paul Burtonda61fa52013-09-09 15:30:26 +0100160int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500161{
162 struct mmc_cmd cmd;
163
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600164 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900165 return 0;
166
Andy Fleming272cc702008-10-30 16:41:01 -0500167 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
168 cmd.resp_type = MMC_RSP_R1;
169 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500170
171 return mmc_send_cmd(mmc, &cmd, NULL);
172}
173
174struct mmc *find_mmc_device(int dev_num)
175{
176 struct mmc *m;
177 struct list_head *entry;
178
179 list_for_each(entry, &mmc_devices) {
180 m = list_entry(entry, struct mmc, link);
181
182 if (m->block_dev.dev == dev_num)
183 return m;
184 }
185
Paul Burton56196822013-09-04 16:12:25 +0100186#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -0500187 printf("MMC Device %d not found\n", dev_num);
Paul Burton56196822013-09-04 16:12:25 +0100188#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500189
190 return NULL;
191}
192
Sascha Silbeff8fef52013-06-14 13:07:25 +0200193static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000194 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500195{
196 struct mmc_cmd cmd;
197 struct mmc_data data;
198
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700199 if (blkcnt > 1)
200 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
201 else
202 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500203
204 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700205 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500206 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700207 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500208
209 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500210
211 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700212 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500213 data.blocksize = mmc->read_bl_len;
214 data.flags = MMC_DATA_READ;
215
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700216 if (mmc_send_cmd(mmc, &cmd, &data))
217 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500218
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700219 if (blkcnt > 1) {
220 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
221 cmd.cmdarg = 0;
222 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700223 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100224#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700225 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100226#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700227 return 0;
228 }
Andy Fleming272cc702008-10-30 16:41:01 -0500229 }
230
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700231 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500232}
233
Sascha Silbeff8fef52013-06-14 13:07:25 +0200234static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500235{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700236 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500237
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700238 if (blkcnt == 0)
239 return 0;
240
241 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500242 if (!mmc)
243 return 0;
244
Lei Wend2bf29e2010-09-13 22:07:27 +0800245 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton56196822013-09-04 16:12:25 +0100246#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200247 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800248 start + blkcnt, mmc->block_dev.lba);
Paul Burton56196822013-09-04 16:12:25 +0100249#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800250 return 0;
251 }
Andy Fleming272cc702008-10-30 16:41:01 -0500252
Simon Glass11692992015-06-23 15:38:50 -0600253 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
254 debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500255 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600256 }
Andy Fleming272cc702008-10-30 16:41:01 -0500257
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700258 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200259 cur = (blocks_todo > mmc->cfg->b_max) ?
260 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600261 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
262 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700263 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600264 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700265 blocks_todo -= cur;
266 start += cur;
267 dst += cur * mmc->read_bl_len;
268 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500269
270 return blkcnt;
271}
272
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000273static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500274{
275 struct mmc_cmd cmd;
276 int err;
277
278 udelay(1000);
279
280 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
281 cmd.cmdarg = 0;
282 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500283
284 err = mmc_send_cmd(mmc, &cmd, NULL);
285
286 if (err)
287 return err;
288
289 udelay(2000);
290
291 return 0;
292}
293
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000294static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500295{
296 int timeout = 1000;
297 int err;
298 struct mmc_cmd cmd;
299
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500300 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500301 cmd.cmdidx = MMC_CMD_APP_CMD;
302 cmd.resp_type = MMC_RSP_R1;
303 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500304
305 err = mmc_send_cmd(mmc, &cmd, NULL);
306
307 if (err)
308 return err;
309
310 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
311 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100312
313 /*
314 * Most cards do not answer if some reserved bits
315 * in the ocr are set. However, Some controller
316 * can set bit 7 (reserved for low voltages), but
317 * how to manage low voltages SD card is not yet
318 * specified.
319 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000320 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200321 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500322
323 if (mmc->version == SD_VERSION_2)
324 cmd.cmdarg |= OCR_HCS;
325
326 err = mmc_send_cmd(mmc, &cmd, NULL);
327
328 if (err)
329 return err;
330
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500331 if (cmd.response[0] & OCR_BUSY)
332 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500333
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500334 if (timeout-- <= 0)
335 return UNUSABLE_ERR;
336
337 udelay(1000);
338 }
Andy Fleming272cc702008-10-30 16:41:01 -0500339
340 if (mmc->version != SD_VERSION_2)
341 mmc->version = SD_VERSION_1_0;
342
Thomas Choud52ebf12010-12-24 13:12:21 +0000343 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
344 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
345 cmd.resp_type = MMC_RSP_R3;
346 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000347
348 err = mmc_send_cmd(mmc, &cmd, NULL);
349
350 if (err)
351 return err;
352 }
353
Rabin Vincent998be3d2009-04-05 13:30:56 +0530354 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500355
356 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
357 mmc->rca = 0;
358
359 return 0;
360}
361
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500362static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500363{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500364 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500365 int err;
366
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500367 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
368 cmd.resp_type = MMC_RSP_R3;
369 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500370 if (use_arg && !mmc_host_is_spi(mmc))
371 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200372 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500373 (mmc->ocr & OCR_VOLTAGE_MASK)) |
374 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000375
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500376 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000377 if (err)
378 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500379 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000380 return 0;
381}
382
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200383static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000384{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000385 int err, i;
386
Andy Fleming272cc702008-10-30 16:41:01 -0500387 /* Some cards seem to need this */
388 mmc_go_idle(mmc);
389
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000390 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000391 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500392 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500393 if (err)
394 return err;
395
Che-Liang Chioue9550442012-11-28 15:21:13 +0000396 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500397 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500398 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000399 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500400 mmc->op_cond_pending = 1;
401 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000402}
Andy Fleming272cc702008-10-30 16:41:01 -0500403
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200404static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000405{
406 struct mmc_cmd cmd;
407 int timeout = 1000;
408 uint start;
409 int err;
410
411 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500412 if (!(mmc->ocr & OCR_BUSY)) {
413 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500414 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500415 err = mmc_send_op_cond_iter(mmc, 1);
416 if (err)
417 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500418 if (mmc->ocr & OCR_BUSY)
419 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500420 if (get_timer(start) > timeout)
421 return UNUSABLE_ERR;
422 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500423 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500424 }
Andy Fleming272cc702008-10-30 16:41:01 -0500425
Thomas Choud52ebf12010-12-24 13:12:21 +0000426 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
427 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
428 cmd.resp_type = MMC_RSP_R3;
429 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000430
431 err = mmc_send_cmd(mmc, &cmd, NULL);
432
433 if (err)
434 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500435
436 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000437 }
438
Andy Fleming272cc702008-10-30 16:41:01 -0500439 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500440
441 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700442 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500443
444 return 0;
445}
446
447
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000448static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500449{
450 struct mmc_cmd cmd;
451 struct mmc_data data;
452 int err;
453
454 /* Get the Card Status Register */
455 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
456 cmd.resp_type = MMC_RSP_R1;
457 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500458
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000459 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500460 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000461 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500462 data.flags = MMC_DATA_READ;
463
464 err = mmc_send_cmd(mmc, &cmd, &data);
465
466 return err;
467}
468
469
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000470static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500471{
472 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000473 int timeout = 1000;
474 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500475
476 cmd.cmdidx = MMC_CMD_SWITCH;
477 cmd.resp_type = MMC_RSP_R1b;
478 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000479 (index << 16) |
480 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500481
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000482 ret = mmc_send_cmd(mmc, &cmd, NULL);
483
484 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000485 if (!ret)
486 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000487
488 return ret;
489
Andy Fleming272cc702008-10-30 16:41:01 -0500490}
491
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000492static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500493{
Simon Glass8bfa1952013-04-03 08:54:30 +0000494 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500495 char cardtype;
496 int err;
497
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600498 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500499
Thomas Choud52ebf12010-12-24 13:12:21 +0000500 if (mmc_host_is_spi(mmc))
501 return 0;
502
Andy Fleming272cc702008-10-30 16:41:01 -0500503 /* Only version 4 supports high-speed */
504 if (mmc->version < MMC_VERSION_4)
505 return 0;
506
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600507 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
508
Andy Fleming272cc702008-10-30 16:41:01 -0500509 err = mmc_send_ext_csd(mmc, ext_csd);
510
511 if (err)
512 return err;
513
Lei Wen0560db12011-10-03 20:35:10 +0000514 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500515
516 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
517
518 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500519 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500520
521 /* Now check to see that it worked */
522 err = mmc_send_ext_csd(mmc, ext_csd);
523
524 if (err)
525 return err;
526
527 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000528 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500529 return 0;
530
531 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900532 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600533 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900534 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500535 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900536 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500537 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900538 }
Andy Fleming272cc702008-10-30 16:41:01 -0500539
540 return 0;
541}
542
Stephen Warrenf866a462013-06-11 15:14:01 -0600543static int mmc_set_capacity(struct mmc *mmc, int part_num)
544{
545 switch (part_num) {
546 case 0:
547 mmc->capacity = mmc->capacity_user;
548 break;
549 case 1:
550 case 2:
551 mmc->capacity = mmc->capacity_boot;
552 break;
553 case 3:
554 mmc->capacity = mmc->capacity_rpmb;
555 break;
556 case 4:
557 case 5:
558 case 6:
559 case 7:
560 mmc->capacity = mmc->capacity_gp[part_num - 4];
561 break;
562 default:
563 return -1;
564 }
565
566 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
567
568 return 0;
569}
570
Stephen Warrend2356282014-05-07 12:19:02 -0600571int mmc_select_hwpart(int dev_num, int hwpart)
572{
573 struct mmc *mmc = find_mmc_device(dev_num);
574 int ret;
575
576 if (!mmc)
Stephen Warrend4622df2014-05-23 12:47:06 -0600577 return -ENODEV;
Stephen Warrend2356282014-05-07 12:19:02 -0600578
579 if (mmc->part_num == hwpart)
580 return 0;
581
582 if (mmc->part_config == MMCPART_NOAVAILABLE) {
583 printf("Card doesn't support part_switch\n");
Stephen Warrend4622df2014-05-23 12:47:06 -0600584 return -EMEDIUMTYPE;
Stephen Warrend2356282014-05-07 12:19:02 -0600585 }
586
587 ret = mmc_switch_part(dev_num, hwpart);
588 if (ret)
Stephen Warrend4622df2014-05-23 12:47:06 -0600589 return ret;
Stephen Warrend2356282014-05-07 12:19:02 -0600590
591 mmc->part_num = hwpart;
592
593 return 0;
594}
595
596
Lei Wenbc897b12011-05-02 16:26:26 +0000597int mmc_switch_part(int dev_num, unsigned int part_num)
598{
599 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600600 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000601
602 if (!mmc)
603 return -1;
604
Stephen Warrenf866a462013-06-11 15:14:01 -0600605 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
606 (mmc->part_config & ~PART_ACCESS_MASK)
607 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600608
Peter Bigot6dc93e72014-09-02 18:31:23 -0500609 /*
610 * Set the capacity if the switch succeeded or was intended
611 * to return to representing the raw device.
612 */
613 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
614 ret = mmc_set_capacity(mmc, part_num);
615
616 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000617}
618
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100619int mmc_hwpart_config(struct mmc *mmc,
620 const struct mmc_hwpart_conf *conf,
621 enum mmc_hwpart_conf_mode mode)
622{
623 u8 part_attrs = 0;
624 u32 enh_size_mult;
625 u32 enh_start_addr;
626 u32 gp_size_mult[4];
627 u32 max_enh_size_mult;
628 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100629 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100630 int i, pidx, err;
631 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
632
633 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
634 return -EINVAL;
635
636 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
637 printf("eMMC >= 4.4 required for enhanced user data area\n");
638 return -EMEDIUMTYPE;
639 }
640
641 if (!(mmc->part_support & PART_SUPPORT)) {
642 printf("Card does not support partitioning\n");
643 return -EMEDIUMTYPE;
644 }
645
646 if (!mmc->hc_wp_grp_size) {
647 printf("Card does not define HC WP group size\n");
648 return -EMEDIUMTYPE;
649 }
650
651 /* check partition alignment and total enhanced size */
652 if (conf->user.enh_size) {
653 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
654 conf->user.enh_start % mmc->hc_wp_grp_size) {
655 printf("User data enhanced area not HC WP group "
656 "size aligned\n");
657 return -EINVAL;
658 }
659 part_attrs |= EXT_CSD_ENH_USR;
660 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
661 if (mmc->high_capacity) {
662 enh_start_addr = conf->user.enh_start;
663 } else {
664 enh_start_addr = (conf->user.enh_start << 9);
665 }
666 } else {
667 enh_size_mult = 0;
668 enh_start_addr = 0;
669 }
670 tot_enh_size_mult += enh_size_mult;
671
672 for (pidx = 0; pidx < 4; pidx++) {
673 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
674 printf("GP%i partition not HC WP group size "
675 "aligned\n", pidx+1);
676 return -EINVAL;
677 }
678 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
679 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
680 part_attrs |= EXT_CSD_ENH_GP(pidx);
681 tot_enh_size_mult += gp_size_mult[pidx];
682 }
683 }
684
685 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
686 printf("Card does not support enhanced attribute\n");
687 return -EMEDIUMTYPE;
688 }
689
690 err = mmc_send_ext_csd(mmc, ext_csd);
691 if (err)
692 return err;
693
694 max_enh_size_mult =
695 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
696 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
697 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
698 if (tot_enh_size_mult > max_enh_size_mult) {
699 printf("Total enhanced size exceeds maximum (%u > %u)\n",
700 tot_enh_size_mult, max_enh_size_mult);
701 return -EMEDIUMTYPE;
702 }
703
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100704 /* The default value of EXT_CSD_WR_REL_SET is device
705 * dependent, the values can only be changed if the
706 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
707 * changed only once and before partitioning is completed. */
708 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
709 if (conf->user.wr_rel_change) {
710 if (conf->user.wr_rel_set)
711 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
712 else
713 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
714 }
715 for (pidx = 0; pidx < 4; pidx++) {
716 if (conf->gp_part[pidx].wr_rel_change) {
717 if (conf->gp_part[pidx].wr_rel_set)
718 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
719 else
720 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
721 }
722 }
723
724 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
725 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
726 puts("Card does not support host controlled partition write "
727 "reliability settings\n");
728 return -EMEDIUMTYPE;
729 }
730
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100731 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
732 EXT_CSD_PARTITION_SETTING_COMPLETED) {
733 printf("Card already partitioned\n");
734 return -EPERM;
735 }
736
737 if (mode == MMC_HWPART_CONF_CHECK)
738 return 0;
739
740 /* Partitioning requires high-capacity size definitions */
741 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
742 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
743 EXT_CSD_ERASE_GROUP_DEF, 1);
744
745 if (err)
746 return err;
747
748 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
749
750 /* update erase group size to be high-capacity */
751 mmc->erase_grp_size =
752 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
753
754 }
755
756 /* all OK, write the configuration */
757 for (i = 0; i < 4; i++) {
758 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
759 EXT_CSD_ENH_START_ADDR+i,
760 (enh_start_addr >> (i*8)) & 0xFF);
761 if (err)
762 return err;
763 }
764 for (i = 0; i < 3; i++) {
765 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
766 EXT_CSD_ENH_SIZE_MULT+i,
767 (enh_size_mult >> (i*8)) & 0xFF);
768 if (err)
769 return err;
770 }
771 for (pidx = 0; pidx < 4; pidx++) {
772 for (i = 0; i < 3; i++) {
773 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
774 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
775 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
776 if (err)
777 return err;
778 }
779 }
780 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
781 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
782 if (err)
783 return err;
784
785 if (mode == MMC_HWPART_CONF_SET)
786 return 0;
787
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100788 /* The WR_REL_SET is a write-once register but shall be
789 * written before setting PART_SETTING_COMPLETED. As it is
790 * write-once we can only write it when completing the
791 * partitioning. */
792 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
793 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
794 EXT_CSD_WR_REL_SET, wr_rel_set);
795 if (err)
796 return err;
797 }
798
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100799 /* Setting PART_SETTING_COMPLETED confirms the partition
800 * configuration but it only becomes effective after power
801 * cycle, so we do not adjust the partition related settings
802 * in the mmc struct. */
803
804 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
805 EXT_CSD_PARTITION_SETTING,
806 EXT_CSD_PARTITION_SETTING_COMPLETED);
807 if (err)
808 return err;
809
810 return 0;
811}
812
Thierry Reding48972d92012-01-02 01:15:37 +0000813int mmc_getcd(struct mmc *mmc)
814{
815 int cd;
816
817 cd = board_mmc_getcd(mmc);
818
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000819 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200820 if (mmc->cfg->ops->getcd)
821 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000822 else
823 cd = 1;
824 }
Thierry Reding48972d92012-01-02 01:15:37 +0000825
826 return cd;
827}
828
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000829static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500830{
831 struct mmc_cmd cmd;
832 struct mmc_data data;
833
834 /* Switch the frequency */
835 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
836 cmd.resp_type = MMC_RSP_R1;
837 cmd.cmdarg = (mode << 31) | 0xffffff;
838 cmd.cmdarg &= ~(0xf << (group * 4));
839 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500840
841 data.dest = (char *)resp;
842 data.blocksize = 64;
843 data.blocks = 1;
844 data.flags = MMC_DATA_READ;
845
846 return mmc_send_cmd(mmc, &cmd, &data);
847}
848
849
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000850static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500851{
852 int err;
853 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000854 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
855 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500856 struct mmc_data data;
857 int timeout;
858
859 mmc->card_caps = 0;
860
Thomas Choud52ebf12010-12-24 13:12:21 +0000861 if (mmc_host_is_spi(mmc))
862 return 0;
863
Andy Fleming272cc702008-10-30 16:41:01 -0500864 /* Read the SCR to find out if this card supports higher speeds */
865 cmd.cmdidx = MMC_CMD_APP_CMD;
866 cmd.resp_type = MMC_RSP_R1;
867 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500868
869 err = mmc_send_cmd(mmc, &cmd, NULL);
870
871 if (err)
872 return err;
873
874 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
875 cmd.resp_type = MMC_RSP_R1;
876 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500877
878 timeout = 3;
879
880retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000881 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500882 data.blocksize = 8;
883 data.blocks = 1;
884 data.flags = MMC_DATA_READ;
885
886 err = mmc_send_cmd(mmc, &cmd, &data);
887
888 if (err) {
889 if (timeout--)
890 goto retry_scr;
891
892 return err;
893 }
894
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300895 mmc->scr[0] = __be32_to_cpu(scr[0]);
896 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500897
898 switch ((mmc->scr[0] >> 24) & 0xf) {
899 case 0:
900 mmc->version = SD_VERSION_1_0;
901 break;
902 case 1:
903 mmc->version = SD_VERSION_1_10;
904 break;
905 case 2:
906 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000907 if ((mmc->scr[0] >> 15) & 0x1)
908 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500909 break;
910 default:
911 mmc->version = SD_VERSION_1_0;
912 break;
913 }
914
Alagu Sankarb44c7082010-05-12 15:08:24 +0530915 if (mmc->scr[0] & SD_DATA_4BIT)
916 mmc->card_caps |= MMC_MODE_4BIT;
917
Andy Fleming272cc702008-10-30 16:41:01 -0500918 /* Version 1.0 doesn't support switching */
919 if (mmc->version == SD_VERSION_1_0)
920 return 0;
921
922 timeout = 4;
923 while (timeout--) {
924 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000925 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500926
927 if (err)
928 return err;
929
930 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300931 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500932 break;
933 }
934
Andy Fleming272cc702008-10-30 16:41:01 -0500935 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300936 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500937 return 0;
938
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000939 /*
940 * If the host doesn't support SD_HIGHSPEED, do not switch card to
941 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
942 * This can avoid furthur problem when the card runs in different
943 * mode between the host.
944 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200945 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
946 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000947 return 0;
948
Anton staaff781dd32011-10-03 13:54:59 +0000949 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500950
951 if (err)
952 return err;
953
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300954 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500955 mmc->card_caps |= MMC_MODE_HS;
956
957 return 0;
958}
959
960/* frequency bases */
961/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000962static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500963 10000,
964 100000,
965 1000000,
966 10000000,
967};
968
969/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
970 * to platforms without floating point.
971 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000972static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500973 0, /* reserved */
974 10,
975 12,
976 13,
977 15,
978 20,
979 25,
980 30,
981 35,
982 40,
983 45,
984 50,
985 55,
986 60,
987 70,
988 80,
989};
990
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000991static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500992{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200993 if (mmc->cfg->ops->set_ios)
994 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500995}
996
997void mmc_set_clock(struct mmc *mmc, uint clock)
998{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200999 if (clock > mmc->cfg->f_max)
1000 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001001
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001002 if (clock < mmc->cfg->f_min)
1003 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001004
1005 mmc->clock = clock;
1006
1007 mmc_set_ios(mmc);
1008}
1009
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001010static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001011{
1012 mmc->bus_width = width;
1013
1014 mmc_set_ios(mmc);
1015}
1016
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001017static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001018{
Stephen Warrenf866a462013-06-11 15:14:01 -06001019 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001020 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001021 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001022 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001023 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1024 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001025 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001026 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001027 bool part_completed;
Andy Fleming272cc702008-10-30 16:41:01 -05001028
Thomas Choud52ebf12010-12-24 13:12:21 +00001029#ifdef CONFIG_MMC_SPI_CRC_ON
1030 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1031 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1032 cmd.resp_type = MMC_RSP_R1;
1033 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001034 err = mmc_send_cmd(mmc, &cmd, NULL);
1035
1036 if (err)
1037 return err;
1038 }
1039#endif
1040
Andy Fleming272cc702008-10-30 16:41:01 -05001041 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001042 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1043 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001044 cmd.resp_type = MMC_RSP_R2;
1045 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001046
1047 err = mmc_send_cmd(mmc, &cmd, NULL);
1048
1049 if (err)
1050 return err;
1051
1052 memcpy(mmc->cid, cmd.response, 16);
1053
1054 /*
1055 * For MMC cards, set the Relative Address.
1056 * For SD cards, get the Relatvie Address.
1057 * This also puts the cards into Standby State
1058 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001059 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1060 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1061 cmd.cmdarg = mmc->rca << 16;
1062 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001063
Thomas Choud52ebf12010-12-24 13:12:21 +00001064 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001065
Thomas Choud52ebf12010-12-24 13:12:21 +00001066 if (err)
1067 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001068
Thomas Choud52ebf12010-12-24 13:12:21 +00001069 if (IS_SD(mmc))
1070 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1071 }
Andy Fleming272cc702008-10-30 16:41:01 -05001072
1073 /* Get the Card-Specific Data */
1074 cmd.cmdidx = MMC_CMD_SEND_CSD;
1075 cmd.resp_type = MMC_RSP_R2;
1076 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001077
1078 err = mmc_send_cmd(mmc, &cmd, NULL);
1079
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001080 /* Waiting for the ready status */
1081 mmc_send_status(mmc, timeout);
1082
Andy Fleming272cc702008-10-30 16:41:01 -05001083 if (err)
1084 return err;
1085
Rabin Vincent998be3d2009-04-05 13:30:56 +05301086 mmc->csd[0] = cmd.response[0];
1087 mmc->csd[1] = cmd.response[1];
1088 mmc->csd[2] = cmd.response[2];
1089 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001090
1091 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301092 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001093
1094 switch (version) {
1095 case 0:
1096 mmc->version = MMC_VERSION_1_2;
1097 break;
1098 case 1:
1099 mmc->version = MMC_VERSION_1_4;
1100 break;
1101 case 2:
1102 mmc->version = MMC_VERSION_2_2;
1103 break;
1104 case 3:
1105 mmc->version = MMC_VERSION_3;
1106 break;
1107 case 4:
1108 mmc->version = MMC_VERSION_4;
1109 break;
1110 default:
1111 mmc->version = MMC_VERSION_1_2;
1112 break;
1113 }
1114 }
1115
1116 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301117 freq = fbase[(cmd.response[0] & 0x7)];
1118 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001119
1120 mmc->tran_speed = freq * mult;
1121
Markus Niebelab711882013-12-16 13:40:46 +01001122 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301123 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001124
1125 if (IS_SD(mmc))
1126 mmc->write_bl_len = mmc->read_bl_len;
1127 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301128 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001129
1130 if (mmc->high_capacity) {
1131 csize = (mmc->csd[1] & 0x3f) << 16
1132 | (mmc->csd[2] & 0xffff0000) >> 16;
1133 cmult = 8;
1134 } else {
1135 csize = (mmc->csd[1] & 0x3ff) << 2
1136 | (mmc->csd[2] & 0xc0000000) >> 30;
1137 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1138 }
1139
Stephen Warrenf866a462013-06-11 15:14:01 -06001140 mmc->capacity_user = (csize + 1) << (cmult + 2);
1141 mmc->capacity_user *= mmc->read_bl_len;
1142 mmc->capacity_boot = 0;
1143 mmc->capacity_rpmb = 0;
1144 for (i = 0; i < 4; i++)
1145 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001146
Simon Glass8bfa1952013-04-03 08:54:30 +00001147 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1148 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001149
Simon Glass8bfa1952013-04-03 08:54:30 +00001150 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1151 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001152
Markus Niebelab711882013-12-16 13:40:46 +01001153 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1154 cmd.cmdidx = MMC_CMD_SET_DSR;
1155 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1156 cmd.resp_type = MMC_RSP_NONE;
1157 if (mmc_send_cmd(mmc, &cmd, NULL))
1158 printf("MMC: SET_DSR failed\n");
1159 }
1160
Andy Fleming272cc702008-10-30 16:41:01 -05001161 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001162 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1163 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001164 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001165 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001166 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001167
Thomas Choud52ebf12010-12-24 13:12:21 +00001168 if (err)
1169 return err;
1170 }
Andy Fleming272cc702008-10-30 16:41:01 -05001171
Lei Wene6f99a52011-06-22 17:03:31 +00001172 /*
1173 * For SD, its erase group is always one sector
1174 */
1175 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001176 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301177 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1178 /* check ext_csd version and capacity */
1179 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001180 if (err)
1181 return err;
1182 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001183 /*
1184 * According to the JEDEC Standard, the value of
1185 * ext_csd's capacity is valid if the value is more
1186 * than 2GB
1187 */
Lei Wen0560db12011-10-03 20:35:10 +00001188 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1189 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1190 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1191 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001192 capacity *= MMC_MAX_BLOCK_LEN;
Ɓukasz Majewskib1f1e8212011-07-05 02:19:44 +00001193 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001194 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301195 }
Lei Wenbc897b12011-05-02 16:26:26 +00001196
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001197 switch (ext_csd[EXT_CSD_REV]) {
1198 case 1:
1199 mmc->version = MMC_VERSION_4_1;
1200 break;
1201 case 2:
1202 mmc->version = MMC_VERSION_4_2;
1203 break;
1204 case 3:
1205 mmc->version = MMC_VERSION_4_3;
1206 break;
1207 case 5:
1208 mmc->version = MMC_VERSION_4_41;
1209 break;
1210 case 6:
1211 mmc->version = MMC_VERSION_4_5;
1212 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001213 case 7:
1214 mmc->version = MMC_VERSION_5_0;
1215 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001216 }
1217
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001218 /* The partition data may be non-zero but it is only
1219 * effective if PARTITION_SETTING_COMPLETED is set in
1220 * EXT_CSD, so ignore any data if this bit is not set,
1221 * except for enabling the high-capacity group size
1222 * definition (see below). */
1223 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1224 EXT_CSD_PARTITION_SETTING_COMPLETED);
1225
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001226 /* store the partition info of emmc */
1227 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1228 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1229 ext_csd[EXT_CSD_BOOT_MULT])
1230 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001231 if (part_completed &&
1232 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001233 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1234
1235 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1236
1237 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1238
1239 for (i = 0; i < 4; i++) {
1240 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001241 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001242 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001243 if (mult)
1244 has_parts = true;
1245 if (!part_completed)
1246 continue;
1247 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001248 mmc->capacity_gp[i] *=
1249 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1250 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001251 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001252 }
1253
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001254 if (part_completed) {
1255 mmc->enh_user_size =
1256 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1257 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1258 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1259 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1260 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1261 mmc->enh_user_size <<= 19;
1262 mmc->enh_user_start =
1263 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1264 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1265 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1266 ext_csd[EXT_CSD_ENH_START_ADDR];
1267 if (mmc->high_capacity)
1268 mmc->enh_user_start <<= 9;
1269 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001270
Lei Wene6f99a52011-06-22 17:03:31 +00001271 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001272 * Host needs to enable ERASE_GRP_DEF bit if device is
1273 * partitioned. This bit will be lost every time after a reset
1274 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001275 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001276 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001277 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001278 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001279 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1280 has_parts = true;
1281 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001282 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1283 EXT_CSD_ERASE_GROUP_DEF, 1);
1284
1285 if (err)
1286 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001287 else
1288 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001289 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001290
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001291 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001292 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001293 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001294 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001295 /*
1296 * if high capacity and partition setting completed
1297 * SEC_COUNT is valid even if it is smaller than 2 GiB
1298 * JEDEC Standard JESD84-B45, 6.2.4
1299 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001300 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001301 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1302 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1303 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1304 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1305 capacity *= MMC_MAX_BLOCK_LEN;
1306 mmc->capacity_user = capacity;
1307 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001308 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001309 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001310 int erase_gsz, erase_gmul;
1311 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1312 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1313 mmc->erase_grp_size = (erase_gsz + 1)
1314 * (erase_gmul + 1);
1315 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001316
1317 mmc->hc_wp_grp_size = 1024
1318 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1319 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001320
1321 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301322 }
1323
Stephen Warrenf866a462013-06-11 15:14:01 -06001324 err = mmc_set_capacity(mmc, mmc->part_num);
1325 if (err)
1326 return err;
1327
Andy Fleming272cc702008-10-30 16:41:01 -05001328 if (IS_SD(mmc))
1329 err = sd_change_freq(mmc);
1330 else
1331 err = mmc_change_freq(mmc);
1332
1333 if (err)
1334 return err;
1335
1336 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001337 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001338
1339 if (IS_SD(mmc)) {
1340 if (mmc->card_caps & MMC_MODE_4BIT) {
1341 cmd.cmdidx = MMC_CMD_APP_CMD;
1342 cmd.resp_type = MMC_RSP_R1;
1343 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001344
1345 err = mmc_send_cmd(mmc, &cmd, NULL);
1346 if (err)
1347 return err;
1348
1349 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1350 cmd.resp_type = MMC_RSP_R1;
1351 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001352 err = mmc_send_cmd(mmc, &cmd, NULL);
1353 if (err)
1354 return err;
1355
1356 mmc_set_bus_width(mmc, 4);
1357 }
1358
1359 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001360 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001361 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001362 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001363 } else if (mmc->version >= MMC_VERSION_4) {
1364 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001365 int idx;
1366
1367 /* An array of possible bus widths in order of preference */
1368 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001369 EXT_CSD_DDR_BUS_WIDTH_8,
1370 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001371 EXT_CSD_BUS_WIDTH_8,
1372 EXT_CSD_BUS_WIDTH_4,
1373 EXT_CSD_BUS_WIDTH_1,
1374 };
1375
1376 /* An array to map CSD bus widths to host cap bits */
1377 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001378 [EXT_CSD_DDR_BUS_WIDTH_4] =
1379 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1380 [EXT_CSD_DDR_BUS_WIDTH_8] =
1381 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001382 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1383 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1384 };
1385
1386 /* An array to map chosen bus width to an integer */
1387 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001388 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001389 };
1390
1391 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1392 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001393 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001394
1395 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001396 * If the bus width is still not changed,
1397 * don't try to set the default again.
1398 * Otherwise, recover from switch attempts
1399 * by switching to 1-bit bus width.
1400 */
1401 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1402 mmc->bus_width == 1) {
1403 err = 0;
1404 break;
1405 }
1406
1407 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001408 * Check to make sure the card and controller support
1409 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001410 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001411 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001412 continue;
1413
Andy Fleming272cc702008-10-30 16:41:01 -05001414 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001415 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001416
1417 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001418 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001419
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001420 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001421 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001422
Lei Wen41378942011-10-03 20:35:11 +00001423 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001424
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001425 if (err)
1426 continue;
1427
1428 /* Only compare read only fields */
1429 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1430 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1431 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1432 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1433 ext_csd[EXT_CSD_REV]
1434 == test_csd[EXT_CSD_REV] &&
1435 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1436 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1437 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1438 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001439 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001440 else
1441 err = SWITCH_ERR;
Andy Fleming272cc702008-10-30 16:41:01 -05001442 }
1443
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001444 if (err)
1445 return err;
1446
Andy Fleming272cc702008-10-30 16:41:01 -05001447 if (mmc->card_caps & MMC_MODE_HS) {
1448 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001449 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001450 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001451 mmc->tran_speed = 26000000;
1452 }
Andy Fleming272cc702008-10-30 16:41:01 -05001453 }
1454
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001455 mmc_set_clock(mmc, mmc->tran_speed);
1456
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001457 /* Fix the block length for DDR mode */
1458 if (mmc->ddr_mode) {
1459 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1460 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1461 }
1462
Andy Fleming272cc702008-10-30 16:41:01 -05001463 /* fill in device description */
1464 mmc->block_dev.lun = 0;
1465 mmc->block_dev.type = 0;
1466 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001467 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301468 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001469#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001470 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1471 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1472 (mmc->cid[3] >> 16) & 0xffff);
1473 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1474 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1475 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1476 (mmc->cid[2] >> 24) & 0xff);
1477 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1478 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001479#else
1480 mmc->block_dev.vendor[0] = 0;
1481 mmc->block_dev.product[0] = 0;
1482 mmc->block_dev.revision[0] = 0;
1483#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001484#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001485 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001486#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001487
1488 return 0;
1489}
1490
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001491static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001492{
1493 struct mmc_cmd cmd;
1494 int err;
1495
1496 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1497 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001498 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001499 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001500
1501 err = mmc_send_cmd(mmc, &cmd, NULL);
1502
1503 if (err)
1504 return err;
1505
Rabin Vincent998be3d2009-04-05 13:30:56 +05301506 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001507 return UNUSABLE_ERR;
1508 else
1509 mmc->version = SD_VERSION_2;
1510
1511 return 0;
1512}
1513
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001514/* not used any more */
1515int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001516{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001517#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1518 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1519#endif
1520 return -1;
1521}
1522
1523struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1524{
1525 struct mmc *mmc;
1526
1527 /* quick validation */
1528 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1529 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1530 return NULL;
1531
1532 mmc = calloc(1, sizeof(*mmc));
1533 if (mmc == NULL)
1534 return NULL;
1535
1536 mmc->cfg = cfg;
1537 mmc->priv = priv;
1538
1539 /* the following chunk was mmc_register() */
1540
Markus Niebelab711882013-12-16 13:40:46 +01001541 /* Setup dsr related values */
1542 mmc->dsr_imp = 0;
1543 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001544 /* Setup the universal parts of the block interface just once */
1545 mmc->block_dev.if_type = IF_TYPE_MMC;
1546 mmc->block_dev.dev = cur_dev_num++;
1547 mmc->block_dev.removable = 1;
1548 mmc->block_dev.block_read = mmc_bread;
1549 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001550 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001551
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001552 /* setup initial part type */
1553 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001554
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001555 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001556
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001557 list_add_tail(&mmc->link, &mmc_devices);
1558
1559 return mmc;
1560}
1561
1562void mmc_destroy(struct mmc *mmc)
1563{
1564 /* only freeing memory for now */
1565 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001566}
1567
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001568#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001569block_dev_desc_t *mmc_get_dev(int dev)
1570{
1571 struct mmc *mmc = find_mmc_device(dev);
Benoßt Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001572 if (!mmc || mmc_init(mmc))
Ɓukasz Majewski40242bc2012-04-19 02:39:18 +00001573 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001574
Ɓukasz Majewski40242bc2012-04-19 02:39:18 +00001575 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001576}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001577#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001578
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001579/* board-specific MMC power initializations. */
1580__weak void board_mmc_power_init(void)
1581{
1582}
1583
Che-Liang Chioue9550442012-11-28 15:21:13 +00001584int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001585{
Macpaul Linafd59322011-11-14 23:35:39 +00001586 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001587
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001588 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001589 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001590 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001591#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001592 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001593#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001594 return NO_CARD_ERR;
1595 }
1596
Lei Wenbc897b12011-05-02 16:26:26 +00001597 if (mmc->has_init)
1598 return 0;
1599
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001600#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1601 mmc_adapter_card_type_ident();
1602#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001603 board_mmc_power_init();
1604
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001605 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001606 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001607
1608 if (err)
1609 return err;
1610
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001611 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001612 mmc_set_bus_width(mmc, 1);
1613 mmc_set_clock(mmc, 1);
1614
Andy Fleming272cc702008-10-30 16:41:01 -05001615 /* Reset the Card */
1616 err = mmc_go_idle(mmc);
1617
1618 if (err)
1619 return err;
1620
Lei Wenbc897b12011-05-02 16:26:26 +00001621 /* The internal partition reset to user partition(0) at every CMD0*/
1622 mmc->part_num = 0;
1623
Andy Fleming272cc702008-10-30 16:41:01 -05001624 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001625 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001626
Andy Fleming272cc702008-10-30 16:41:01 -05001627 /* Now try to get the SD card's operating condition */
1628 err = sd_send_op_cond(mmc);
1629
1630 /* If the command timed out, we check for an MMC card */
1631 if (err == TIMEOUT) {
1632 err = mmc_send_op_cond(mmc);
1633
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001634 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001635#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001636 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001637#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001638 return UNUSABLE_ERR;
1639 }
1640 }
1641
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001642 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001643 mmc->init_in_progress = 1;
1644
1645 return err;
1646}
1647
1648static int mmc_complete_init(struct mmc *mmc)
1649{
1650 int err = 0;
1651
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001652 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001653 if (mmc->op_cond_pending)
1654 err = mmc_complete_op_cond(mmc);
1655
1656 if (!err)
1657 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001658 if (err)
1659 mmc->has_init = 0;
1660 else
1661 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001662 return err;
1663}
1664
1665int mmc_init(struct mmc *mmc)
1666{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001667 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001668 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001669
1670 if (mmc->has_init)
1671 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001672
1673 start = get_timer(0);
1674
Che-Liang Chioue9550442012-11-28 15:21:13 +00001675 if (!mmc->init_in_progress)
1676 err = mmc_start_init(mmc);
1677
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001678 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001679 err = mmc_complete_init(mmc);
1680 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001681 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001682}
1683
Markus Niebelab711882013-12-16 13:40:46 +01001684int mmc_set_dsr(struct mmc *mmc, u16 val)
1685{
1686 mmc->dsr = val;
1687 return 0;
1688}
1689
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001690/* CPU-specific MMC initializations */
1691__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001692{
1693 return -1;
1694}
1695
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001696/* board-specific MMC initializations. */
1697__weak int board_mmc_init(bd_t *bis)
1698{
1699 return -1;
1700}
Andy Fleming272cc702008-10-30 16:41:01 -05001701
Paul Burton56196822013-09-04 16:12:25 +01001702#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1703
Andy Fleming272cc702008-10-30 16:41:01 -05001704void print_mmc_devices(char separator)
1705{
1706 struct mmc *m;
1707 struct list_head *entry;
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001708 char *mmc_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001709
1710 list_for_each(entry, &mmc_devices) {
1711 m = list_entry(entry, struct mmc, link);
1712
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001713 if (m->has_init)
1714 mmc_type = IS_SD(m) ? "SD" : "eMMC";
1715 else
1716 mmc_type = NULL;
1717
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001718 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001719 if (mmc_type)
1720 printf(" (%s)", mmc_type);
Andy Fleming272cc702008-10-30 16:41:01 -05001721
Lubomir Popove75eaf12014-11-11 12:25:42 +02001722 if (entry->next != &mmc_devices) {
1723 printf("%c", separator);
1724 if (separator != '\n')
1725 puts (" ");
1726 }
Andy Fleming272cc702008-10-30 16:41:01 -05001727 }
1728
1729 printf("\n");
1730}
1731
Paul Burton56196822013-09-04 16:12:25 +01001732#else
1733void print_mmc_devices(char separator) { }
1734#endif
1735
Lei Wenea6ebe22011-05-02 16:26:25 +00001736int get_mmc_num(void)
1737{
1738 return cur_dev_num;
1739}
1740
Che-Liang Chioue9550442012-11-28 15:21:13 +00001741void mmc_set_preinit(struct mmc *mmc, int preinit)
1742{
1743 mmc->preinit = preinit;
1744}
1745
1746static void do_preinit(void)
1747{
1748 struct mmc *m;
1749 struct list_head *entry;
1750
1751 list_for_each(entry, &mmc_devices) {
1752 m = list_entry(entry, struct mmc, link);
1753
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001754#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1755 mmc_set_preinit(m, 1);
1756#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001757 if (m->preinit)
1758 mmc_start_init(m);
1759 }
1760}
1761
1762
Andy Fleming272cc702008-10-30 16:41:01 -05001763int mmc_initialize(bd_t *bis)
1764{
Daniel KochmaƄski1b26bab2015-05-29 16:55:43 +02001765 static int initialized = 0;
1766 if (initialized) /* Avoid initializing mmc multiple times */
1767 return 0;
1768 initialized = 1;
1769
Andy Fleming272cc702008-10-30 16:41:01 -05001770 INIT_LIST_HEAD (&mmc_devices);
1771 cur_dev_num = 0;
1772
Simon Glasse7ecf7c2015-06-23 15:38:48 -06001773#ifndef CONFIG_DM_MMC
Andy Fleming272cc702008-10-30 16:41:01 -05001774 if (board_mmc_init(bis) < 0)
1775 cpu_mmc_init(bis);
Simon Glasse7ecf7c2015-06-23 15:38:48 -06001776#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001777
Ying Zhangbb0dc102013-08-16 15:16:11 +08001778#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001779 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001780#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001781
Che-Liang Chioue9550442012-11-28 15:21:13 +00001782 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001783 return 0;
1784}
Amar3690d6d2013-04-27 11:42:58 +05301785
1786#ifdef CONFIG_SUPPORT_EMMC_BOOT
1787/*
1788 * This function changes the size of boot partition and the size of rpmb
1789 * partition present on EMMC devices.
1790 *
1791 * Input Parameters:
1792 * struct *mmc: pointer for the mmc device strcuture
1793 * bootsize: size of boot partition
1794 * rpmbsize: size of rpmb partition
1795 *
1796 * Returns 0 on success.
1797 */
1798
1799int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1800 unsigned long rpmbsize)
1801{
1802 int err;
1803 struct mmc_cmd cmd;
1804
1805 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1806 cmd.cmdidx = MMC_CMD_RES_MAN;
1807 cmd.resp_type = MMC_RSP_R1b;
1808 cmd.cmdarg = MMC_CMD62_ARG1;
1809
1810 err = mmc_send_cmd(mmc, &cmd, NULL);
1811 if (err) {
1812 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1813 return err;
1814 }
1815
1816 /* Boot partition changing mode */
1817 cmd.cmdidx = MMC_CMD_RES_MAN;
1818 cmd.resp_type = MMC_RSP_R1b;
1819 cmd.cmdarg = MMC_CMD62_ARG2;
1820
1821 err = mmc_send_cmd(mmc, &cmd, NULL);
1822 if (err) {
1823 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1824 return err;
1825 }
1826 /* boot partition size is multiple of 128KB */
1827 bootsize = (bootsize * 1024) / 128;
1828
1829 /* Arg: boot partition size */
1830 cmd.cmdidx = MMC_CMD_RES_MAN;
1831 cmd.resp_type = MMC_RSP_R1b;
1832 cmd.cmdarg = bootsize;
1833
1834 err = mmc_send_cmd(mmc, &cmd, NULL);
1835 if (err) {
1836 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1837 return err;
1838 }
1839 /* RPMB partition size is multiple of 128KB */
1840 rpmbsize = (rpmbsize * 1024) / 128;
1841 /* Arg: RPMB partition size */
1842 cmd.cmdidx = MMC_CMD_RES_MAN;
1843 cmd.resp_type = MMC_RSP_R1b;
1844 cmd.cmdarg = rpmbsize;
1845
1846 err = mmc_send_cmd(mmc, &cmd, NULL);
1847 if (err) {
1848 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1849 return err;
1850 }
1851 return 0;
1852}
1853
1854/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001855 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1856 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1857 * and BOOT_MODE.
1858 *
1859 * Returns 0 on success.
1860 */
1861int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1862{
1863 int err;
1864
1865 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1866 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1867 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1868 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1869
1870 if (err)
1871 return err;
1872 return 0;
1873}
1874
1875/*
Tom Rini792970b2014-02-05 10:24:21 -05001876 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1877 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1878 * PARTITION_ACCESS.
1879 *
1880 * Returns 0 on success.
1881 */
1882int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1883{
1884 int err;
1885
1886 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1887 EXT_CSD_BOOT_ACK(ack) |
1888 EXT_CSD_BOOT_PART_NUM(part_num) |
1889 EXT_CSD_PARTITION_ACCESS(access));
1890
1891 if (err)
1892 return err;
1893 return 0;
1894}
Tom Rini33ace362014-02-07 14:15:20 -05001895
1896/*
1897 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1898 * for enable. Note that this is a write-once field for non-zero values.
1899 *
1900 * Returns 0 on success.
1901 */
1902int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1903{
1904 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1905 enable);
1906}
Amar3690d6d2013-04-27 11:42:58 +05301907#endif