blob: 31f8647d8615987e94bb4d1de86203c660749bae [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
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700253 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500254 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500255
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700256 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200257 cur = (blocks_todo > mmc->cfg->b_max) ?
258 mmc->cfg->b_max : blocks_todo;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700259 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
260 return 0;
261 blocks_todo -= cur;
262 start += cur;
263 dst += cur * mmc->read_bl_len;
264 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500265
266 return blkcnt;
267}
268
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000269static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500270{
271 struct mmc_cmd cmd;
272 int err;
273
274 udelay(1000);
275
276 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
277 cmd.cmdarg = 0;
278 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500279
280 err = mmc_send_cmd(mmc, &cmd, NULL);
281
282 if (err)
283 return err;
284
285 udelay(2000);
286
287 return 0;
288}
289
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000290static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500291{
292 int timeout = 1000;
293 int err;
294 struct mmc_cmd cmd;
295
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500296 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500297 cmd.cmdidx = MMC_CMD_APP_CMD;
298 cmd.resp_type = MMC_RSP_R1;
299 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500300
301 err = mmc_send_cmd(mmc, &cmd, NULL);
302
303 if (err)
304 return err;
305
306 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
307 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100308
309 /*
310 * Most cards do not answer if some reserved bits
311 * in the ocr are set. However, Some controller
312 * can set bit 7 (reserved for low voltages), but
313 * how to manage low voltages SD card is not yet
314 * specified.
315 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000316 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200317 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500318
319 if (mmc->version == SD_VERSION_2)
320 cmd.cmdarg |= OCR_HCS;
321
322 err = mmc_send_cmd(mmc, &cmd, NULL);
323
324 if (err)
325 return err;
326
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500327 if (cmd.response[0] & OCR_BUSY)
328 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500329
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500330 if (timeout-- <= 0)
331 return UNUSABLE_ERR;
332
333 udelay(1000);
334 }
Andy Fleming272cc702008-10-30 16:41:01 -0500335
336 if (mmc->version != SD_VERSION_2)
337 mmc->version = SD_VERSION_1_0;
338
Thomas Choud52ebf12010-12-24 13:12:21 +0000339 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
340 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
341 cmd.resp_type = MMC_RSP_R3;
342 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000343
344 err = mmc_send_cmd(mmc, &cmd, NULL);
345
346 if (err)
347 return err;
348 }
349
Rabin Vincent998be3d2009-04-05 13:30:56 +0530350 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500351
352 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
353 mmc->rca = 0;
354
355 return 0;
356}
357
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500358static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500359{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500360 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500361 int err;
362
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500363 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
364 cmd.resp_type = MMC_RSP_R3;
365 cmd.cmdarg = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000366 if (use_arg && !mmc_host_is_spi(mmc)) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500367 cmd.cmdarg =
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200368 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500369 (mmc->ocr & OCR_VOLTAGE_MASK)) |
370 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000371
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200372 if (mmc->cfg->host_caps & MMC_MODE_HC)
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500373 cmd.cmdarg |= OCR_HCS;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000374 }
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500375 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000376 if (err)
377 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500378 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000379 return 0;
380}
381
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200382static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000383{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000384 int err, i;
385
Andy Fleming272cc702008-10-30 16:41:01 -0500386 /* Some cards seem to need this */
387 mmc_go_idle(mmc);
388
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000389 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000390 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500391 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500392 if (err)
393 return err;
394
Che-Liang Chioue9550442012-11-28 15:21:13 +0000395 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500396 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500397 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000398 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500399 mmc->op_cond_pending = 1;
400 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000401}
Andy Fleming272cc702008-10-30 16:41:01 -0500402
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200403static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000404{
405 struct mmc_cmd cmd;
406 int timeout = 1000;
407 uint start;
408 int err;
409
410 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500411 if (!(mmc->ocr & OCR_BUSY)) {
412 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500413 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500414 err = mmc_send_op_cond_iter(mmc, 1);
415 if (err)
416 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500417 if (mmc->ocr & OCR_BUSY)
418 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500419 if (get_timer(start) > timeout)
420 return UNUSABLE_ERR;
421 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500422 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500423 }
Andy Fleming272cc702008-10-30 16:41:01 -0500424
Thomas Choud52ebf12010-12-24 13:12:21 +0000425 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
426 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
427 cmd.resp_type = MMC_RSP_R3;
428 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000429
430 err = mmc_send_cmd(mmc, &cmd, NULL);
431
432 if (err)
433 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500434
435 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000436 }
437
Andy Fleming272cc702008-10-30 16:41:01 -0500438 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500439
440 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700441 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500442
443 return 0;
444}
445
446
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000447static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500448{
449 struct mmc_cmd cmd;
450 struct mmc_data data;
451 int err;
452
453 /* Get the Card Status Register */
454 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
455 cmd.resp_type = MMC_RSP_R1;
456 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500457
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000458 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500459 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000460 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500461 data.flags = MMC_DATA_READ;
462
463 err = mmc_send_cmd(mmc, &cmd, &data);
464
465 return err;
466}
467
468
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000469static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500470{
471 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000472 int timeout = 1000;
473 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500474
475 cmd.cmdidx = MMC_CMD_SWITCH;
476 cmd.resp_type = MMC_RSP_R1b;
477 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000478 (index << 16) |
479 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500480
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000481 ret = mmc_send_cmd(mmc, &cmd, NULL);
482
483 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000484 if (!ret)
485 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000486
487 return ret;
488
Andy Fleming272cc702008-10-30 16:41:01 -0500489}
490
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000491static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500492{
Simon Glass8bfa1952013-04-03 08:54:30 +0000493 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500494 char cardtype;
495 int err;
496
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600497 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500498
Thomas Choud52ebf12010-12-24 13:12:21 +0000499 if (mmc_host_is_spi(mmc))
500 return 0;
501
Andy Fleming272cc702008-10-30 16:41:01 -0500502 /* Only version 4 supports high-speed */
503 if (mmc->version < MMC_VERSION_4)
504 return 0;
505
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600506 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
507
Andy Fleming272cc702008-10-30 16:41:01 -0500508 err = mmc_send_ext_csd(mmc, ext_csd);
509
510 if (err)
511 return err;
512
Lei Wen0560db12011-10-03 20:35:10 +0000513 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500514
515 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
516
517 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500518 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500519
520 /* Now check to see that it worked */
521 err = mmc_send_ext_csd(mmc, ext_csd);
522
523 if (err)
524 return err;
525
526 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000527 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500528 return 0;
529
530 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900531 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600532 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900533 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500534 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900535 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500536 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900537 }
Andy Fleming272cc702008-10-30 16:41:01 -0500538
539 return 0;
540}
541
Stephen Warrenf866a462013-06-11 15:14:01 -0600542static int mmc_set_capacity(struct mmc *mmc, int part_num)
543{
544 switch (part_num) {
545 case 0:
546 mmc->capacity = mmc->capacity_user;
547 break;
548 case 1:
549 case 2:
550 mmc->capacity = mmc->capacity_boot;
551 break;
552 case 3:
553 mmc->capacity = mmc->capacity_rpmb;
554 break;
555 case 4:
556 case 5:
557 case 6:
558 case 7:
559 mmc->capacity = mmc->capacity_gp[part_num - 4];
560 break;
561 default:
562 return -1;
563 }
564
565 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
566
567 return 0;
568}
569
Stephen Warrend2356282014-05-07 12:19:02 -0600570int mmc_select_hwpart(int dev_num, int hwpart)
571{
572 struct mmc *mmc = find_mmc_device(dev_num);
573 int ret;
574
575 if (!mmc)
Stephen Warrend4622df2014-05-23 12:47:06 -0600576 return -ENODEV;
Stephen Warrend2356282014-05-07 12:19:02 -0600577
578 if (mmc->part_num == hwpart)
579 return 0;
580
581 if (mmc->part_config == MMCPART_NOAVAILABLE) {
582 printf("Card doesn't support part_switch\n");
Stephen Warrend4622df2014-05-23 12:47:06 -0600583 return -EMEDIUMTYPE;
Stephen Warrend2356282014-05-07 12:19:02 -0600584 }
585
586 ret = mmc_switch_part(dev_num, hwpart);
587 if (ret)
Stephen Warrend4622df2014-05-23 12:47:06 -0600588 return ret;
Stephen Warrend2356282014-05-07 12:19:02 -0600589
590 mmc->part_num = hwpart;
591
592 return 0;
593}
594
595
Lei Wenbc897b12011-05-02 16:26:26 +0000596int mmc_switch_part(int dev_num, unsigned int part_num)
597{
598 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600599 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000600
601 if (!mmc)
602 return -1;
603
Stephen Warrenf866a462013-06-11 15:14:01 -0600604 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
605 (mmc->part_config & ~PART_ACCESS_MASK)
606 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600607
Peter Bigot6dc93e72014-09-02 18:31:23 -0500608 /*
609 * Set the capacity if the switch succeeded or was intended
610 * to return to representing the raw device.
611 */
612 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
613 ret = mmc_set_capacity(mmc, part_num);
614
615 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000616}
617
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100618int mmc_hwpart_config(struct mmc *mmc,
619 const struct mmc_hwpart_conf *conf,
620 enum mmc_hwpart_conf_mode mode)
621{
622 u8 part_attrs = 0;
623 u32 enh_size_mult;
624 u32 enh_start_addr;
625 u32 gp_size_mult[4];
626 u32 max_enh_size_mult;
627 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100628 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100629 int i, pidx, err;
630 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
631
632 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
633 return -EINVAL;
634
635 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
636 printf("eMMC >= 4.4 required for enhanced user data area\n");
637 return -EMEDIUMTYPE;
638 }
639
640 if (!(mmc->part_support & PART_SUPPORT)) {
641 printf("Card does not support partitioning\n");
642 return -EMEDIUMTYPE;
643 }
644
645 if (!mmc->hc_wp_grp_size) {
646 printf("Card does not define HC WP group size\n");
647 return -EMEDIUMTYPE;
648 }
649
650 /* check partition alignment and total enhanced size */
651 if (conf->user.enh_size) {
652 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
653 conf->user.enh_start % mmc->hc_wp_grp_size) {
654 printf("User data enhanced area not HC WP group "
655 "size aligned\n");
656 return -EINVAL;
657 }
658 part_attrs |= EXT_CSD_ENH_USR;
659 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
660 if (mmc->high_capacity) {
661 enh_start_addr = conf->user.enh_start;
662 } else {
663 enh_start_addr = (conf->user.enh_start << 9);
664 }
665 } else {
666 enh_size_mult = 0;
667 enh_start_addr = 0;
668 }
669 tot_enh_size_mult += enh_size_mult;
670
671 for (pidx = 0; pidx < 4; pidx++) {
672 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
673 printf("GP%i partition not HC WP group size "
674 "aligned\n", pidx+1);
675 return -EINVAL;
676 }
677 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
678 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
679 part_attrs |= EXT_CSD_ENH_GP(pidx);
680 tot_enh_size_mult += gp_size_mult[pidx];
681 }
682 }
683
684 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
685 printf("Card does not support enhanced attribute\n");
686 return -EMEDIUMTYPE;
687 }
688
689 err = mmc_send_ext_csd(mmc, ext_csd);
690 if (err)
691 return err;
692
693 max_enh_size_mult =
694 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
695 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
696 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
697 if (tot_enh_size_mult > max_enh_size_mult) {
698 printf("Total enhanced size exceeds maximum (%u > %u)\n",
699 tot_enh_size_mult, max_enh_size_mult);
700 return -EMEDIUMTYPE;
701 }
702
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100703 /* The default value of EXT_CSD_WR_REL_SET is device
704 * dependent, the values can only be changed if the
705 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
706 * changed only once and before partitioning is completed. */
707 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
708 if (conf->user.wr_rel_change) {
709 if (conf->user.wr_rel_set)
710 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
711 else
712 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
713 }
714 for (pidx = 0; pidx < 4; pidx++) {
715 if (conf->gp_part[pidx].wr_rel_change) {
716 if (conf->gp_part[pidx].wr_rel_set)
717 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
718 else
719 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
720 }
721 }
722
723 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
724 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
725 puts("Card does not support host controlled partition write "
726 "reliability settings\n");
727 return -EMEDIUMTYPE;
728 }
729
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100730 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
731 EXT_CSD_PARTITION_SETTING_COMPLETED) {
732 printf("Card already partitioned\n");
733 return -EPERM;
734 }
735
736 if (mode == MMC_HWPART_CONF_CHECK)
737 return 0;
738
739 /* Partitioning requires high-capacity size definitions */
740 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
741 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
742 EXT_CSD_ERASE_GROUP_DEF, 1);
743
744 if (err)
745 return err;
746
747 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
748
749 /* update erase group size to be high-capacity */
750 mmc->erase_grp_size =
751 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
752
753 }
754
755 /* all OK, write the configuration */
756 for (i = 0; i < 4; i++) {
757 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
758 EXT_CSD_ENH_START_ADDR+i,
759 (enh_start_addr >> (i*8)) & 0xFF);
760 if (err)
761 return err;
762 }
763 for (i = 0; i < 3; i++) {
764 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
765 EXT_CSD_ENH_SIZE_MULT+i,
766 (enh_size_mult >> (i*8)) & 0xFF);
767 if (err)
768 return err;
769 }
770 for (pidx = 0; pidx < 4; pidx++) {
771 for (i = 0; i < 3; i++) {
772 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
773 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
774 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
775 if (err)
776 return err;
777 }
778 }
779 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
780 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
781 if (err)
782 return err;
783
784 if (mode == MMC_HWPART_CONF_SET)
785 return 0;
786
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100787 /* The WR_REL_SET is a write-once register but shall be
788 * written before setting PART_SETTING_COMPLETED. As it is
789 * write-once we can only write it when completing the
790 * partitioning. */
791 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
792 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
793 EXT_CSD_WR_REL_SET, wr_rel_set);
794 if (err)
795 return err;
796 }
797
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100798 /* Setting PART_SETTING_COMPLETED confirms the partition
799 * configuration but it only becomes effective after power
800 * cycle, so we do not adjust the partition related settings
801 * in the mmc struct. */
802
803 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
804 EXT_CSD_PARTITION_SETTING,
805 EXT_CSD_PARTITION_SETTING_COMPLETED);
806 if (err)
807 return err;
808
809 return 0;
810}
811
Thierry Reding48972d92012-01-02 01:15:37 +0000812int mmc_getcd(struct mmc *mmc)
813{
814 int cd;
815
816 cd = board_mmc_getcd(mmc);
817
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000818 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200819 if (mmc->cfg->ops->getcd)
820 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000821 else
822 cd = 1;
823 }
Thierry Reding48972d92012-01-02 01:15:37 +0000824
825 return cd;
826}
827
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000828static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500829{
830 struct mmc_cmd cmd;
831 struct mmc_data data;
832
833 /* Switch the frequency */
834 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
835 cmd.resp_type = MMC_RSP_R1;
836 cmd.cmdarg = (mode << 31) | 0xffffff;
837 cmd.cmdarg &= ~(0xf << (group * 4));
838 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500839
840 data.dest = (char *)resp;
841 data.blocksize = 64;
842 data.blocks = 1;
843 data.flags = MMC_DATA_READ;
844
845 return mmc_send_cmd(mmc, &cmd, &data);
846}
847
848
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000849static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500850{
851 int err;
852 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000853 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
854 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500855 struct mmc_data data;
856 int timeout;
857
858 mmc->card_caps = 0;
859
Thomas Choud52ebf12010-12-24 13:12:21 +0000860 if (mmc_host_is_spi(mmc))
861 return 0;
862
Andy Fleming272cc702008-10-30 16:41:01 -0500863 /* Read the SCR to find out if this card supports higher speeds */
864 cmd.cmdidx = MMC_CMD_APP_CMD;
865 cmd.resp_type = MMC_RSP_R1;
866 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500867
868 err = mmc_send_cmd(mmc, &cmd, NULL);
869
870 if (err)
871 return err;
872
873 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
874 cmd.resp_type = MMC_RSP_R1;
875 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500876
877 timeout = 3;
878
879retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000880 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500881 data.blocksize = 8;
882 data.blocks = 1;
883 data.flags = MMC_DATA_READ;
884
885 err = mmc_send_cmd(mmc, &cmd, &data);
886
887 if (err) {
888 if (timeout--)
889 goto retry_scr;
890
891 return err;
892 }
893
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300894 mmc->scr[0] = __be32_to_cpu(scr[0]);
895 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500896
897 switch ((mmc->scr[0] >> 24) & 0xf) {
898 case 0:
899 mmc->version = SD_VERSION_1_0;
900 break;
901 case 1:
902 mmc->version = SD_VERSION_1_10;
903 break;
904 case 2:
905 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000906 if ((mmc->scr[0] >> 15) & 0x1)
907 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500908 break;
909 default:
910 mmc->version = SD_VERSION_1_0;
911 break;
912 }
913
Alagu Sankarb44c7082010-05-12 15:08:24 +0530914 if (mmc->scr[0] & SD_DATA_4BIT)
915 mmc->card_caps |= MMC_MODE_4BIT;
916
Andy Fleming272cc702008-10-30 16:41:01 -0500917 /* Version 1.0 doesn't support switching */
918 if (mmc->version == SD_VERSION_1_0)
919 return 0;
920
921 timeout = 4;
922 while (timeout--) {
923 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000924 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500925
926 if (err)
927 return err;
928
929 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300930 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500931 break;
932 }
933
Andy Fleming272cc702008-10-30 16:41:01 -0500934 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300935 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500936 return 0;
937
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000938 /*
939 * If the host doesn't support SD_HIGHSPEED, do not switch card to
940 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
941 * This can avoid furthur problem when the card runs in different
942 * mode between the host.
943 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200944 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
945 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000946 return 0;
947
Anton staaff781dd32011-10-03 13:54:59 +0000948 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500949
950 if (err)
951 return err;
952
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300953 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500954 mmc->card_caps |= MMC_MODE_HS;
955
956 return 0;
957}
958
959/* frequency bases */
960/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000961static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500962 10000,
963 100000,
964 1000000,
965 10000000,
966};
967
968/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
969 * to platforms without floating point.
970 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000971static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500972 0, /* reserved */
973 10,
974 12,
975 13,
976 15,
977 20,
978 25,
979 30,
980 35,
981 40,
982 45,
983 50,
984 55,
985 60,
986 70,
987 80,
988};
989
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000990static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500991{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200992 if (mmc->cfg->ops->set_ios)
993 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500994}
995
996void mmc_set_clock(struct mmc *mmc, uint clock)
997{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200998 if (clock > mmc->cfg->f_max)
999 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001000
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001001 if (clock < mmc->cfg->f_min)
1002 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001003
1004 mmc->clock = clock;
1005
1006 mmc_set_ios(mmc);
1007}
1008
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001009static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001010{
1011 mmc->bus_width = width;
1012
1013 mmc_set_ios(mmc);
1014}
1015
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001016static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001017{
Stephen Warrenf866a462013-06-11 15:14:01 -06001018 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001019 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001020 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001021 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001022 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1023 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001024 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001025 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001026 bool part_completed;
Andy Fleming272cc702008-10-30 16:41:01 -05001027
Thomas Choud52ebf12010-12-24 13:12:21 +00001028#ifdef CONFIG_MMC_SPI_CRC_ON
1029 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1030 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1031 cmd.resp_type = MMC_RSP_R1;
1032 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001033 err = mmc_send_cmd(mmc, &cmd, NULL);
1034
1035 if (err)
1036 return err;
1037 }
1038#endif
1039
Andy Fleming272cc702008-10-30 16:41:01 -05001040 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001041 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1042 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001043 cmd.resp_type = MMC_RSP_R2;
1044 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001045
1046 err = mmc_send_cmd(mmc, &cmd, NULL);
1047
1048 if (err)
1049 return err;
1050
1051 memcpy(mmc->cid, cmd.response, 16);
1052
1053 /*
1054 * For MMC cards, set the Relative Address.
1055 * For SD cards, get the Relatvie Address.
1056 * This also puts the cards into Standby State
1057 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001058 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1059 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1060 cmd.cmdarg = mmc->rca << 16;
1061 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001062
Thomas Choud52ebf12010-12-24 13:12:21 +00001063 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001064
Thomas Choud52ebf12010-12-24 13:12:21 +00001065 if (err)
1066 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001067
Thomas Choud52ebf12010-12-24 13:12:21 +00001068 if (IS_SD(mmc))
1069 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1070 }
Andy Fleming272cc702008-10-30 16:41:01 -05001071
1072 /* Get the Card-Specific Data */
1073 cmd.cmdidx = MMC_CMD_SEND_CSD;
1074 cmd.resp_type = MMC_RSP_R2;
1075 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001076
1077 err = mmc_send_cmd(mmc, &cmd, NULL);
1078
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001079 /* Waiting for the ready status */
1080 mmc_send_status(mmc, timeout);
1081
Andy Fleming272cc702008-10-30 16:41:01 -05001082 if (err)
1083 return err;
1084
Rabin Vincent998be3d2009-04-05 13:30:56 +05301085 mmc->csd[0] = cmd.response[0];
1086 mmc->csd[1] = cmd.response[1];
1087 mmc->csd[2] = cmd.response[2];
1088 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001089
1090 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301091 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001092
1093 switch (version) {
1094 case 0:
1095 mmc->version = MMC_VERSION_1_2;
1096 break;
1097 case 1:
1098 mmc->version = MMC_VERSION_1_4;
1099 break;
1100 case 2:
1101 mmc->version = MMC_VERSION_2_2;
1102 break;
1103 case 3:
1104 mmc->version = MMC_VERSION_3;
1105 break;
1106 case 4:
1107 mmc->version = MMC_VERSION_4;
1108 break;
1109 default:
1110 mmc->version = MMC_VERSION_1_2;
1111 break;
1112 }
1113 }
1114
1115 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301116 freq = fbase[(cmd.response[0] & 0x7)];
1117 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001118
1119 mmc->tran_speed = freq * mult;
1120
Markus Niebelab711882013-12-16 13:40:46 +01001121 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301122 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001123
1124 if (IS_SD(mmc))
1125 mmc->write_bl_len = mmc->read_bl_len;
1126 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301127 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001128
1129 if (mmc->high_capacity) {
1130 csize = (mmc->csd[1] & 0x3f) << 16
1131 | (mmc->csd[2] & 0xffff0000) >> 16;
1132 cmult = 8;
1133 } else {
1134 csize = (mmc->csd[1] & 0x3ff) << 2
1135 | (mmc->csd[2] & 0xc0000000) >> 30;
1136 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1137 }
1138
Stephen Warrenf866a462013-06-11 15:14:01 -06001139 mmc->capacity_user = (csize + 1) << (cmult + 2);
1140 mmc->capacity_user *= mmc->read_bl_len;
1141 mmc->capacity_boot = 0;
1142 mmc->capacity_rpmb = 0;
1143 for (i = 0; i < 4; i++)
1144 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001145
Simon Glass8bfa1952013-04-03 08:54:30 +00001146 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1147 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001148
Simon Glass8bfa1952013-04-03 08:54:30 +00001149 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1150 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001151
Markus Niebelab711882013-12-16 13:40:46 +01001152 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1153 cmd.cmdidx = MMC_CMD_SET_DSR;
1154 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1155 cmd.resp_type = MMC_RSP_NONE;
1156 if (mmc_send_cmd(mmc, &cmd, NULL))
1157 printf("MMC: SET_DSR failed\n");
1158 }
1159
Andy Fleming272cc702008-10-30 16:41:01 -05001160 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001161 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1162 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001163 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001164 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001165 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001166
Thomas Choud52ebf12010-12-24 13:12:21 +00001167 if (err)
1168 return err;
1169 }
Andy Fleming272cc702008-10-30 16:41:01 -05001170
Lei Wene6f99a52011-06-22 17:03:31 +00001171 /*
1172 * For SD, its erase group is always one sector
1173 */
1174 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001175 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301176 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1177 /* check ext_csd version and capacity */
1178 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001179 if (err)
1180 return err;
1181 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001182 /*
1183 * According to the JEDEC Standard, the value of
1184 * ext_csd's capacity is valid if the value is more
1185 * than 2GB
1186 */
Lei Wen0560db12011-10-03 20:35:10 +00001187 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1188 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1189 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1190 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001191 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001192 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001193 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301194 }
Lei Wenbc897b12011-05-02 16:26:26 +00001195
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001196 switch (ext_csd[EXT_CSD_REV]) {
1197 case 1:
1198 mmc->version = MMC_VERSION_4_1;
1199 break;
1200 case 2:
1201 mmc->version = MMC_VERSION_4_2;
1202 break;
1203 case 3:
1204 mmc->version = MMC_VERSION_4_3;
1205 break;
1206 case 5:
1207 mmc->version = MMC_VERSION_4_41;
1208 break;
1209 case 6:
1210 mmc->version = MMC_VERSION_4_5;
1211 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001212 case 7:
1213 mmc->version = MMC_VERSION_5_0;
1214 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001215 }
1216
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001217 /* The partition data may be non-zero but it is only
1218 * effective if PARTITION_SETTING_COMPLETED is set in
1219 * EXT_CSD, so ignore any data if this bit is not set,
1220 * except for enabling the high-capacity group size
1221 * definition (see below). */
1222 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1223 EXT_CSD_PARTITION_SETTING_COMPLETED);
1224
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001225 /* store the partition info of emmc */
1226 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1227 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1228 ext_csd[EXT_CSD_BOOT_MULT])
1229 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001230 if (part_completed &&
1231 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001232 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1233
1234 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1235
1236 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1237
1238 for (i = 0; i < 4; i++) {
1239 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001240 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001241 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001242 if (mult)
1243 has_parts = true;
1244 if (!part_completed)
1245 continue;
1246 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001247 mmc->capacity_gp[i] *=
1248 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1249 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001250 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001251 }
1252
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001253 if (part_completed) {
1254 mmc->enh_user_size =
1255 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1256 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1257 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1258 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1259 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1260 mmc->enh_user_size <<= 19;
1261 mmc->enh_user_start =
1262 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1263 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1264 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1265 ext_csd[EXT_CSD_ENH_START_ADDR];
1266 if (mmc->high_capacity)
1267 mmc->enh_user_start <<= 9;
1268 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001269
Lei Wene6f99a52011-06-22 17:03:31 +00001270 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001271 * Host needs to enable ERASE_GRP_DEF bit if device is
1272 * partitioned. This bit will be lost every time after a reset
1273 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001274 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001275 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001276 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001277 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001278 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1279 has_parts = true;
1280 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001281 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1282 EXT_CSD_ERASE_GROUP_DEF, 1);
1283
1284 if (err)
1285 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001286 else
1287 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001288 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001289
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001290 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001291 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001292 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001293 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001294 /*
1295 * if high capacity and partition setting completed
1296 * SEC_COUNT is valid even if it is smaller than 2 GiB
1297 * JEDEC Standard JESD84-B45, 6.2.4
1298 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001299 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001300 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1301 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1302 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1303 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1304 capacity *= MMC_MAX_BLOCK_LEN;
1305 mmc->capacity_user = capacity;
1306 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001307 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001308 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001309 int erase_gsz, erase_gmul;
1310 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1311 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1312 mmc->erase_grp_size = (erase_gsz + 1)
1313 * (erase_gmul + 1);
1314 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001315
1316 mmc->hc_wp_grp_size = 1024
1317 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1318 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001319
1320 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301321 }
1322
Stephen Warrenf866a462013-06-11 15:14:01 -06001323 err = mmc_set_capacity(mmc, mmc->part_num);
1324 if (err)
1325 return err;
1326
Andy Fleming272cc702008-10-30 16:41:01 -05001327 if (IS_SD(mmc))
1328 err = sd_change_freq(mmc);
1329 else
1330 err = mmc_change_freq(mmc);
1331
1332 if (err)
1333 return err;
1334
1335 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001336 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001337
1338 if (IS_SD(mmc)) {
1339 if (mmc->card_caps & MMC_MODE_4BIT) {
1340 cmd.cmdidx = MMC_CMD_APP_CMD;
1341 cmd.resp_type = MMC_RSP_R1;
1342 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001343
1344 err = mmc_send_cmd(mmc, &cmd, NULL);
1345 if (err)
1346 return err;
1347
1348 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1349 cmd.resp_type = MMC_RSP_R1;
1350 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001351 err = mmc_send_cmd(mmc, &cmd, NULL);
1352 if (err)
1353 return err;
1354
1355 mmc_set_bus_width(mmc, 4);
1356 }
1357
1358 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001359 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001360 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001361 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001362 } else if (mmc->version >= MMC_VERSION_4) {
1363 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001364 int idx;
1365
1366 /* An array of possible bus widths in order of preference */
1367 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001368 EXT_CSD_DDR_BUS_WIDTH_8,
1369 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001370 EXT_CSD_BUS_WIDTH_8,
1371 EXT_CSD_BUS_WIDTH_4,
1372 EXT_CSD_BUS_WIDTH_1,
1373 };
1374
1375 /* An array to map CSD bus widths to host cap bits */
1376 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001377 [EXT_CSD_DDR_BUS_WIDTH_4] =
1378 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1379 [EXT_CSD_DDR_BUS_WIDTH_8] =
1380 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001381 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1382 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1383 };
1384
1385 /* An array to map chosen bus width to an integer */
1386 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001387 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001388 };
1389
1390 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1391 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001392 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001393
1394 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001395 * If the bus width is still not changed,
1396 * don't try to set the default again.
1397 * Otherwise, recover from switch attempts
1398 * by switching to 1-bit bus width.
1399 */
1400 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1401 mmc->bus_width == 1) {
1402 err = 0;
1403 break;
1404 }
1405
1406 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001407 * Check to make sure the card and controller support
1408 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001409 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001410 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001411 continue;
1412
Andy Fleming272cc702008-10-30 16:41:01 -05001413 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001414 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001415
1416 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001417 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001418
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001419 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001420 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001421
Lei Wen41378942011-10-03 20:35:11 +00001422 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001423
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001424 if (err)
1425 continue;
1426
1427 /* Only compare read only fields */
1428 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1429 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1430 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1431 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1432 ext_csd[EXT_CSD_REV]
1433 == test_csd[EXT_CSD_REV] &&
1434 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1435 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1436 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1437 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001438 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001439 else
1440 err = SWITCH_ERR;
Andy Fleming272cc702008-10-30 16:41:01 -05001441 }
1442
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001443 if (err)
1444 return err;
1445
Andy Fleming272cc702008-10-30 16:41:01 -05001446 if (mmc->card_caps & MMC_MODE_HS) {
1447 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001448 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001449 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001450 mmc->tran_speed = 26000000;
1451 }
Andy Fleming272cc702008-10-30 16:41:01 -05001452 }
1453
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001454 mmc_set_clock(mmc, mmc->tran_speed);
1455
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001456 /* Fix the block length for DDR mode */
1457 if (mmc->ddr_mode) {
1458 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1459 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1460 }
1461
Andy Fleming272cc702008-10-30 16:41:01 -05001462 /* fill in device description */
1463 mmc->block_dev.lun = 0;
1464 mmc->block_dev.type = 0;
1465 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001466 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301467 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001468#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001469 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1470 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1471 (mmc->cid[3] >> 16) & 0xffff);
1472 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1473 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1474 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1475 (mmc->cid[2] >> 24) & 0xff);
1476 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1477 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001478#else
1479 mmc->block_dev.vendor[0] = 0;
1480 mmc->block_dev.product[0] = 0;
1481 mmc->block_dev.revision[0] = 0;
1482#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001483#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001484 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001485#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001486
1487 return 0;
1488}
1489
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001490static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001491{
1492 struct mmc_cmd cmd;
1493 int err;
1494
1495 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1496 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001497 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001498 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001499
1500 err = mmc_send_cmd(mmc, &cmd, NULL);
1501
1502 if (err)
1503 return err;
1504
Rabin Vincent998be3d2009-04-05 13:30:56 +05301505 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001506 return UNUSABLE_ERR;
1507 else
1508 mmc->version = SD_VERSION_2;
1509
1510 return 0;
1511}
1512
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001513/* not used any more */
1514int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001515{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001516#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1517 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1518#endif
1519 return -1;
1520}
1521
1522struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1523{
1524 struct mmc *mmc;
1525
1526 /* quick validation */
1527 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1528 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1529 return NULL;
1530
1531 mmc = calloc(1, sizeof(*mmc));
1532 if (mmc == NULL)
1533 return NULL;
1534
1535 mmc->cfg = cfg;
1536 mmc->priv = priv;
1537
1538 /* the following chunk was mmc_register() */
1539
Markus Niebelab711882013-12-16 13:40:46 +01001540 /* Setup dsr related values */
1541 mmc->dsr_imp = 0;
1542 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001543 /* Setup the universal parts of the block interface just once */
1544 mmc->block_dev.if_type = IF_TYPE_MMC;
1545 mmc->block_dev.dev = cur_dev_num++;
1546 mmc->block_dev.removable = 1;
1547 mmc->block_dev.block_read = mmc_bread;
1548 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001549 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001550
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001551 /* setup initial part type */
1552 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001553
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001554 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001555
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001556 list_add_tail(&mmc->link, &mmc_devices);
1557
1558 return mmc;
1559}
1560
1561void mmc_destroy(struct mmc *mmc)
1562{
1563 /* only freeing memory for now */
1564 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001565}
1566
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001567#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001568block_dev_desc_t *mmc_get_dev(int dev)
1569{
1570 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001571 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001572 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001573
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001574 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001575}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001576#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001577
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001578/* board-specific MMC power initializations. */
1579__weak void board_mmc_power_init(void)
1580{
1581}
1582
Che-Liang Chioue9550442012-11-28 15:21:13 +00001583int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001584{
Macpaul Linafd59322011-11-14 23:35:39 +00001585 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001586
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001587 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001588 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001589 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001590#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001591 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001592#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001593 return NO_CARD_ERR;
1594 }
1595
Lei Wenbc897b12011-05-02 16:26:26 +00001596 if (mmc->has_init)
1597 return 0;
1598
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001599 board_mmc_power_init();
1600
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001601 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001602 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001603
1604 if (err)
1605 return err;
1606
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001607 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001608 mmc_set_bus_width(mmc, 1);
1609 mmc_set_clock(mmc, 1);
1610
Andy Fleming272cc702008-10-30 16:41:01 -05001611 /* Reset the Card */
1612 err = mmc_go_idle(mmc);
1613
1614 if (err)
1615 return err;
1616
Lei Wenbc897b12011-05-02 16:26:26 +00001617 /* The internal partition reset to user partition(0) at every CMD0*/
1618 mmc->part_num = 0;
1619
Andy Fleming272cc702008-10-30 16:41:01 -05001620 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001621 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001622
Andy Fleming272cc702008-10-30 16:41:01 -05001623 /* Now try to get the SD card's operating condition */
1624 err = sd_send_op_cond(mmc);
1625
1626 /* If the command timed out, we check for an MMC card */
1627 if (err == TIMEOUT) {
1628 err = mmc_send_op_cond(mmc);
1629
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001630 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001631#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001632 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001633#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001634 return UNUSABLE_ERR;
1635 }
1636 }
1637
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001638 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001639 mmc->init_in_progress = 1;
1640
1641 return err;
1642}
1643
1644static int mmc_complete_init(struct mmc *mmc)
1645{
1646 int err = 0;
1647
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001648 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001649 if (mmc->op_cond_pending)
1650 err = mmc_complete_op_cond(mmc);
1651
1652 if (!err)
1653 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001654 if (err)
1655 mmc->has_init = 0;
1656 else
1657 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001658 return err;
1659}
1660
1661int mmc_init(struct mmc *mmc)
1662{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001663 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001664 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001665
1666 if (mmc->has_init)
1667 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001668
1669 start = get_timer(0);
1670
Che-Liang Chioue9550442012-11-28 15:21:13 +00001671 if (!mmc->init_in_progress)
1672 err = mmc_start_init(mmc);
1673
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001674 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001675 err = mmc_complete_init(mmc);
1676 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001677 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001678}
1679
Markus Niebelab711882013-12-16 13:40:46 +01001680int mmc_set_dsr(struct mmc *mmc, u16 val)
1681{
1682 mmc->dsr = val;
1683 return 0;
1684}
1685
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001686/* CPU-specific MMC initializations */
1687__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001688{
1689 return -1;
1690}
1691
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001692/* board-specific MMC initializations. */
1693__weak int board_mmc_init(bd_t *bis)
1694{
1695 return -1;
1696}
Andy Fleming272cc702008-10-30 16:41:01 -05001697
Paul Burton56196822013-09-04 16:12:25 +01001698#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1699
Andy Fleming272cc702008-10-30 16:41:01 -05001700void print_mmc_devices(char separator)
1701{
1702 struct mmc *m;
1703 struct list_head *entry;
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001704 char *mmc_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001705
1706 list_for_each(entry, &mmc_devices) {
1707 m = list_entry(entry, struct mmc, link);
1708
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001709 if (m->has_init)
1710 mmc_type = IS_SD(m) ? "SD" : "eMMC";
1711 else
1712 mmc_type = NULL;
1713
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001714 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001715 if (mmc_type)
1716 printf(" (%s)", mmc_type);
Andy Fleming272cc702008-10-30 16:41:01 -05001717
Lubomir Popove75eaf12014-11-11 12:25:42 +02001718 if (entry->next != &mmc_devices) {
1719 printf("%c", separator);
1720 if (separator != '\n')
1721 puts (" ");
1722 }
Andy Fleming272cc702008-10-30 16:41:01 -05001723 }
1724
1725 printf("\n");
1726}
1727
Paul Burton56196822013-09-04 16:12:25 +01001728#else
1729void print_mmc_devices(char separator) { }
1730#endif
1731
Lei Wenea6ebe22011-05-02 16:26:25 +00001732int get_mmc_num(void)
1733{
1734 return cur_dev_num;
1735}
1736
Che-Liang Chioue9550442012-11-28 15:21:13 +00001737void mmc_set_preinit(struct mmc *mmc, int preinit)
1738{
1739 mmc->preinit = preinit;
1740}
1741
1742static void do_preinit(void)
1743{
1744 struct mmc *m;
1745 struct list_head *entry;
1746
1747 list_for_each(entry, &mmc_devices) {
1748 m = list_entry(entry, struct mmc, link);
1749
1750 if (m->preinit)
1751 mmc_start_init(m);
1752 }
1753}
1754
1755
Andy Fleming272cc702008-10-30 16:41:01 -05001756int mmc_initialize(bd_t *bis)
1757{
1758 INIT_LIST_HEAD (&mmc_devices);
1759 cur_dev_num = 0;
1760
1761 if (board_mmc_init(bis) < 0)
1762 cpu_mmc_init(bis);
1763
Ying Zhangbb0dc102013-08-16 15:16:11 +08001764#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001765 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001766#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001767
Che-Liang Chioue9550442012-11-28 15:21:13 +00001768 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001769 return 0;
1770}
Amar3690d6d2013-04-27 11:42:58 +05301771
1772#ifdef CONFIG_SUPPORT_EMMC_BOOT
1773/*
1774 * This function changes the size of boot partition and the size of rpmb
1775 * partition present on EMMC devices.
1776 *
1777 * Input Parameters:
1778 * struct *mmc: pointer for the mmc device strcuture
1779 * bootsize: size of boot partition
1780 * rpmbsize: size of rpmb partition
1781 *
1782 * Returns 0 on success.
1783 */
1784
1785int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1786 unsigned long rpmbsize)
1787{
1788 int err;
1789 struct mmc_cmd cmd;
1790
1791 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1792 cmd.cmdidx = MMC_CMD_RES_MAN;
1793 cmd.resp_type = MMC_RSP_R1b;
1794 cmd.cmdarg = MMC_CMD62_ARG1;
1795
1796 err = mmc_send_cmd(mmc, &cmd, NULL);
1797 if (err) {
1798 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1799 return err;
1800 }
1801
1802 /* Boot partition changing mode */
1803 cmd.cmdidx = MMC_CMD_RES_MAN;
1804 cmd.resp_type = MMC_RSP_R1b;
1805 cmd.cmdarg = MMC_CMD62_ARG2;
1806
1807 err = mmc_send_cmd(mmc, &cmd, NULL);
1808 if (err) {
1809 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1810 return err;
1811 }
1812 /* boot partition size is multiple of 128KB */
1813 bootsize = (bootsize * 1024) / 128;
1814
1815 /* Arg: boot partition size */
1816 cmd.cmdidx = MMC_CMD_RES_MAN;
1817 cmd.resp_type = MMC_RSP_R1b;
1818 cmd.cmdarg = bootsize;
1819
1820 err = mmc_send_cmd(mmc, &cmd, NULL);
1821 if (err) {
1822 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1823 return err;
1824 }
1825 /* RPMB partition size is multiple of 128KB */
1826 rpmbsize = (rpmbsize * 1024) / 128;
1827 /* Arg: RPMB partition size */
1828 cmd.cmdidx = MMC_CMD_RES_MAN;
1829 cmd.resp_type = MMC_RSP_R1b;
1830 cmd.cmdarg = rpmbsize;
1831
1832 err = mmc_send_cmd(mmc, &cmd, NULL);
1833 if (err) {
1834 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1835 return err;
1836 }
1837 return 0;
1838}
1839
1840/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001841 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1842 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1843 * and BOOT_MODE.
1844 *
1845 * Returns 0 on success.
1846 */
1847int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1848{
1849 int err;
1850
1851 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1852 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1853 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1854 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1855
1856 if (err)
1857 return err;
1858 return 0;
1859}
1860
1861/*
Tom Rini792970b2014-02-05 10:24:21 -05001862 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1863 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1864 * PARTITION_ACCESS.
1865 *
1866 * Returns 0 on success.
1867 */
1868int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1869{
1870 int err;
1871
1872 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1873 EXT_CSD_BOOT_ACK(ack) |
1874 EXT_CSD_BOOT_PART_NUM(part_num) |
1875 EXT_CSD_PARTITION_ACCESS(access));
1876
1877 if (err)
1878 return err;
1879 return 0;
1880}
Tom Rini33ace362014-02-07 14:15:20 -05001881
1882/*
1883 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1884 * for enable. Note that this is a write-once field for non-zero values.
1885 *
1886 * Returns 0 on success.
1887 */
1888int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1889{
1890 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1891 enable);
1892}
Amar3690d6d2013-04-27 11:42:58 +05301893#endif