blob: 3909e14e72f31b4a6f699a8407ffa6637763192b [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;
Rob Herring5a203972015-03-23 17:56:59 -0500366 if (use_arg && !mmc_host_is_spi(mmc))
367 cmd.cmdarg = OCR_HCS |
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
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500372 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000373 if (err)
374 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500375 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000376 return 0;
377}
378
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200379static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000380{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000381 int err, i;
382
Andy Fleming272cc702008-10-30 16:41:01 -0500383 /* Some cards seem to need this */
384 mmc_go_idle(mmc);
385
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000386 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000387 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500388 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500389 if (err)
390 return err;
391
Che-Liang Chioue9550442012-11-28 15:21:13 +0000392 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500393 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500394 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000395 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500396 mmc->op_cond_pending = 1;
397 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000398}
Andy Fleming272cc702008-10-30 16:41:01 -0500399
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200400static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000401{
402 struct mmc_cmd cmd;
403 int timeout = 1000;
404 uint start;
405 int err;
406
407 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500408 if (!(mmc->ocr & OCR_BUSY)) {
409 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500410 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500411 err = mmc_send_op_cond_iter(mmc, 1);
412 if (err)
413 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500414 if (mmc->ocr & OCR_BUSY)
415 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500416 if (get_timer(start) > timeout)
417 return UNUSABLE_ERR;
418 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500419 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500420 }
Andy Fleming272cc702008-10-30 16:41:01 -0500421
Thomas Choud52ebf12010-12-24 13:12:21 +0000422 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
423 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
424 cmd.resp_type = MMC_RSP_R3;
425 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000426
427 err = mmc_send_cmd(mmc, &cmd, NULL);
428
429 if (err)
430 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500431
432 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000433 }
434
Andy Fleming272cc702008-10-30 16:41:01 -0500435 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500436
437 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700438 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500439
440 return 0;
441}
442
443
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000444static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500445{
446 struct mmc_cmd cmd;
447 struct mmc_data data;
448 int err;
449
450 /* Get the Card Status Register */
451 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
452 cmd.resp_type = MMC_RSP_R1;
453 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500454
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000455 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500456 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000457 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500458 data.flags = MMC_DATA_READ;
459
460 err = mmc_send_cmd(mmc, &cmd, &data);
461
462 return err;
463}
464
465
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000466static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500467{
468 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000469 int timeout = 1000;
470 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500471
472 cmd.cmdidx = MMC_CMD_SWITCH;
473 cmd.resp_type = MMC_RSP_R1b;
474 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000475 (index << 16) |
476 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500477
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000478 ret = mmc_send_cmd(mmc, &cmd, NULL);
479
480 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000481 if (!ret)
482 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000483
484 return ret;
485
Andy Fleming272cc702008-10-30 16:41:01 -0500486}
487
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000488static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500489{
Simon Glass8bfa1952013-04-03 08:54:30 +0000490 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500491 char cardtype;
492 int err;
493
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600494 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500495
Thomas Choud52ebf12010-12-24 13:12:21 +0000496 if (mmc_host_is_spi(mmc))
497 return 0;
498
Andy Fleming272cc702008-10-30 16:41:01 -0500499 /* Only version 4 supports high-speed */
500 if (mmc->version < MMC_VERSION_4)
501 return 0;
502
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600503 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
504
Andy Fleming272cc702008-10-30 16:41:01 -0500505 err = mmc_send_ext_csd(mmc, ext_csd);
506
507 if (err)
508 return err;
509
Lei Wen0560db12011-10-03 20:35:10 +0000510 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500511
512 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
513
514 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500515 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500516
517 /* Now check to see that it worked */
518 err = mmc_send_ext_csd(mmc, ext_csd);
519
520 if (err)
521 return err;
522
523 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000524 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500525 return 0;
526
527 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900528 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600529 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900530 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500531 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900532 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500533 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900534 }
Andy Fleming272cc702008-10-30 16:41:01 -0500535
536 return 0;
537}
538
Stephen Warrenf866a462013-06-11 15:14:01 -0600539static int mmc_set_capacity(struct mmc *mmc, int part_num)
540{
541 switch (part_num) {
542 case 0:
543 mmc->capacity = mmc->capacity_user;
544 break;
545 case 1:
546 case 2:
547 mmc->capacity = mmc->capacity_boot;
548 break;
549 case 3:
550 mmc->capacity = mmc->capacity_rpmb;
551 break;
552 case 4:
553 case 5:
554 case 6:
555 case 7:
556 mmc->capacity = mmc->capacity_gp[part_num - 4];
557 break;
558 default:
559 return -1;
560 }
561
562 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
563
564 return 0;
565}
566
Stephen Warrend2356282014-05-07 12:19:02 -0600567int mmc_select_hwpart(int dev_num, int hwpart)
568{
569 struct mmc *mmc = find_mmc_device(dev_num);
570 int ret;
571
572 if (!mmc)
Stephen Warrend4622df2014-05-23 12:47:06 -0600573 return -ENODEV;
Stephen Warrend2356282014-05-07 12:19:02 -0600574
575 if (mmc->part_num == hwpart)
576 return 0;
577
578 if (mmc->part_config == MMCPART_NOAVAILABLE) {
579 printf("Card doesn't support part_switch\n");
Stephen Warrend4622df2014-05-23 12:47:06 -0600580 return -EMEDIUMTYPE;
Stephen Warrend2356282014-05-07 12:19:02 -0600581 }
582
583 ret = mmc_switch_part(dev_num, hwpart);
584 if (ret)
Stephen Warrend4622df2014-05-23 12:47:06 -0600585 return ret;
Stephen Warrend2356282014-05-07 12:19:02 -0600586
587 mmc->part_num = hwpart;
588
589 return 0;
590}
591
592
Lei Wenbc897b12011-05-02 16:26:26 +0000593int mmc_switch_part(int dev_num, unsigned int part_num)
594{
595 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600596 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000597
598 if (!mmc)
599 return -1;
600
Stephen Warrenf866a462013-06-11 15:14:01 -0600601 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
602 (mmc->part_config & ~PART_ACCESS_MASK)
603 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600604
Peter Bigot6dc93e72014-09-02 18:31:23 -0500605 /*
606 * Set the capacity if the switch succeeded or was intended
607 * to return to representing the raw device.
608 */
609 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
610 ret = mmc_set_capacity(mmc, part_num);
611
612 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000613}
614
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100615int mmc_hwpart_config(struct mmc *mmc,
616 const struct mmc_hwpart_conf *conf,
617 enum mmc_hwpart_conf_mode mode)
618{
619 u8 part_attrs = 0;
620 u32 enh_size_mult;
621 u32 enh_start_addr;
622 u32 gp_size_mult[4];
623 u32 max_enh_size_mult;
624 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100625 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100626 int i, pidx, err;
627 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
628
629 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
630 return -EINVAL;
631
632 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
633 printf("eMMC >= 4.4 required for enhanced user data area\n");
634 return -EMEDIUMTYPE;
635 }
636
637 if (!(mmc->part_support & PART_SUPPORT)) {
638 printf("Card does not support partitioning\n");
639 return -EMEDIUMTYPE;
640 }
641
642 if (!mmc->hc_wp_grp_size) {
643 printf("Card does not define HC WP group size\n");
644 return -EMEDIUMTYPE;
645 }
646
647 /* check partition alignment and total enhanced size */
648 if (conf->user.enh_size) {
649 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
650 conf->user.enh_start % mmc->hc_wp_grp_size) {
651 printf("User data enhanced area not HC WP group "
652 "size aligned\n");
653 return -EINVAL;
654 }
655 part_attrs |= EXT_CSD_ENH_USR;
656 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
657 if (mmc->high_capacity) {
658 enh_start_addr = conf->user.enh_start;
659 } else {
660 enh_start_addr = (conf->user.enh_start << 9);
661 }
662 } else {
663 enh_size_mult = 0;
664 enh_start_addr = 0;
665 }
666 tot_enh_size_mult += enh_size_mult;
667
668 for (pidx = 0; pidx < 4; pidx++) {
669 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
670 printf("GP%i partition not HC WP group size "
671 "aligned\n", pidx+1);
672 return -EINVAL;
673 }
674 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
675 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
676 part_attrs |= EXT_CSD_ENH_GP(pidx);
677 tot_enh_size_mult += gp_size_mult[pidx];
678 }
679 }
680
681 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
682 printf("Card does not support enhanced attribute\n");
683 return -EMEDIUMTYPE;
684 }
685
686 err = mmc_send_ext_csd(mmc, ext_csd);
687 if (err)
688 return err;
689
690 max_enh_size_mult =
691 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
692 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
693 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
694 if (tot_enh_size_mult > max_enh_size_mult) {
695 printf("Total enhanced size exceeds maximum (%u > %u)\n",
696 tot_enh_size_mult, max_enh_size_mult);
697 return -EMEDIUMTYPE;
698 }
699
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100700 /* The default value of EXT_CSD_WR_REL_SET is device
701 * dependent, the values can only be changed if the
702 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
703 * changed only once and before partitioning is completed. */
704 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
705 if (conf->user.wr_rel_change) {
706 if (conf->user.wr_rel_set)
707 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
708 else
709 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
710 }
711 for (pidx = 0; pidx < 4; pidx++) {
712 if (conf->gp_part[pidx].wr_rel_change) {
713 if (conf->gp_part[pidx].wr_rel_set)
714 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
715 else
716 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
717 }
718 }
719
720 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
721 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
722 puts("Card does not support host controlled partition write "
723 "reliability settings\n");
724 return -EMEDIUMTYPE;
725 }
726
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100727 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
728 EXT_CSD_PARTITION_SETTING_COMPLETED) {
729 printf("Card already partitioned\n");
730 return -EPERM;
731 }
732
733 if (mode == MMC_HWPART_CONF_CHECK)
734 return 0;
735
736 /* Partitioning requires high-capacity size definitions */
737 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
738 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
739 EXT_CSD_ERASE_GROUP_DEF, 1);
740
741 if (err)
742 return err;
743
744 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
745
746 /* update erase group size to be high-capacity */
747 mmc->erase_grp_size =
748 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
749
750 }
751
752 /* all OK, write the configuration */
753 for (i = 0; i < 4; i++) {
754 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
755 EXT_CSD_ENH_START_ADDR+i,
756 (enh_start_addr >> (i*8)) & 0xFF);
757 if (err)
758 return err;
759 }
760 for (i = 0; i < 3; i++) {
761 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
762 EXT_CSD_ENH_SIZE_MULT+i,
763 (enh_size_mult >> (i*8)) & 0xFF);
764 if (err)
765 return err;
766 }
767 for (pidx = 0; pidx < 4; pidx++) {
768 for (i = 0; i < 3; i++) {
769 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
770 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
771 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
772 if (err)
773 return err;
774 }
775 }
776 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
777 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
778 if (err)
779 return err;
780
781 if (mode == MMC_HWPART_CONF_SET)
782 return 0;
783
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100784 /* The WR_REL_SET is a write-once register but shall be
785 * written before setting PART_SETTING_COMPLETED. As it is
786 * write-once we can only write it when completing the
787 * partitioning. */
788 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
789 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
790 EXT_CSD_WR_REL_SET, wr_rel_set);
791 if (err)
792 return err;
793 }
794
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100795 /* Setting PART_SETTING_COMPLETED confirms the partition
796 * configuration but it only becomes effective after power
797 * cycle, so we do not adjust the partition related settings
798 * in the mmc struct. */
799
800 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
801 EXT_CSD_PARTITION_SETTING,
802 EXT_CSD_PARTITION_SETTING_COMPLETED);
803 if (err)
804 return err;
805
806 return 0;
807}
808
Thierry Reding48972d92012-01-02 01:15:37 +0000809int mmc_getcd(struct mmc *mmc)
810{
811 int cd;
812
813 cd = board_mmc_getcd(mmc);
814
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000815 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200816 if (mmc->cfg->ops->getcd)
817 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000818 else
819 cd = 1;
820 }
Thierry Reding48972d92012-01-02 01:15:37 +0000821
822 return cd;
823}
824
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000825static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500826{
827 struct mmc_cmd cmd;
828 struct mmc_data data;
829
830 /* Switch the frequency */
831 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
832 cmd.resp_type = MMC_RSP_R1;
833 cmd.cmdarg = (mode << 31) | 0xffffff;
834 cmd.cmdarg &= ~(0xf << (group * 4));
835 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500836
837 data.dest = (char *)resp;
838 data.blocksize = 64;
839 data.blocks = 1;
840 data.flags = MMC_DATA_READ;
841
842 return mmc_send_cmd(mmc, &cmd, &data);
843}
844
845
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000846static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500847{
848 int err;
849 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000850 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
851 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500852 struct mmc_data data;
853 int timeout;
854
855 mmc->card_caps = 0;
856
Thomas Choud52ebf12010-12-24 13:12:21 +0000857 if (mmc_host_is_spi(mmc))
858 return 0;
859
Andy Fleming272cc702008-10-30 16:41:01 -0500860 /* Read the SCR to find out if this card supports higher speeds */
861 cmd.cmdidx = MMC_CMD_APP_CMD;
862 cmd.resp_type = MMC_RSP_R1;
863 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500864
865 err = mmc_send_cmd(mmc, &cmd, NULL);
866
867 if (err)
868 return err;
869
870 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
871 cmd.resp_type = MMC_RSP_R1;
872 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500873
874 timeout = 3;
875
876retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000877 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500878 data.blocksize = 8;
879 data.blocks = 1;
880 data.flags = MMC_DATA_READ;
881
882 err = mmc_send_cmd(mmc, &cmd, &data);
883
884 if (err) {
885 if (timeout--)
886 goto retry_scr;
887
888 return err;
889 }
890
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300891 mmc->scr[0] = __be32_to_cpu(scr[0]);
892 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500893
894 switch ((mmc->scr[0] >> 24) & 0xf) {
895 case 0:
896 mmc->version = SD_VERSION_1_0;
897 break;
898 case 1:
899 mmc->version = SD_VERSION_1_10;
900 break;
901 case 2:
902 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000903 if ((mmc->scr[0] >> 15) & 0x1)
904 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500905 break;
906 default:
907 mmc->version = SD_VERSION_1_0;
908 break;
909 }
910
Alagu Sankarb44c7082010-05-12 15:08:24 +0530911 if (mmc->scr[0] & SD_DATA_4BIT)
912 mmc->card_caps |= MMC_MODE_4BIT;
913
Andy Fleming272cc702008-10-30 16:41:01 -0500914 /* Version 1.0 doesn't support switching */
915 if (mmc->version == SD_VERSION_1_0)
916 return 0;
917
918 timeout = 4;
919 while (timeout--) {
920 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000921 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500922
923 if (err)
924 return err;
925
926 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300927 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500928 break;
929 }
930
Andy Fleming272cc702008-10-30 16:41:01 -0500931 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300932 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500933 return 0;
934
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000935 /*
936 * If the host doesn't support SD_HIGHSPEED, do not switch card to
937 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
938 * This can avoid furthur problem when the card runs in different
939 * mode between the host.
940 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200941 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
942 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000943 return 0;
944
Anton staaff781dd32011-10-03 13:54:59 +0000945 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500946
947 if (err)
948 return err;
949
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300950 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500951 mmc->card_caps |= MMC_MODE_HS;
952
953 return 0;
954}
955
956/* frequency bases */
957/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000958static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500959 10000,
960 100000,
961 1000000,
962 10000000,
963};
964
965/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
966 * to platforms without floating point.
967 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000968static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500969 0, /* reserved */
970 10,
971 12,
972 13,
973 15,
974 20,
975 25,
976 30,
977 35,
978 40,
979 45,
980 50,
981 55,
982 60,
983 70,
984 80,
985};
986
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000987static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500988{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200989 if (mmc->cfg->ops->set_ios)
990 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500991}
992
993void mmc_set_clock(struct mmc *mmc, uint clock)
994{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200995 if (clock > mmc->cfg->f_max)
996 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500997
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200998 if (clock < mmc->cfg->f_min)
999 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001000
1001 mmc->clock = clock;
1002
1003 mmc_set_ios(mmc);
1004}
1005
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001006static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001007{
1008 mmc->bus_width = width;
1009
1010 mmc_set_ios(mmc);
1011}
1012
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001013static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001014{
Stephen Warrenf866a462013-06-11 15:14:01 -06001015 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001016 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001017 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001018 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001019 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1020 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001021 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001022 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001023 bool part_completed;
Andy Fleming272cc702008-10-30 16:41:01 -05001024
Thomas Choud52ebf12010-12-24 13:12:21 +00001025#ifdef CONFIG_MMC_SPI_CRC_ON
1026 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1027 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1028 cmd.resp_type = MMC_RSP_R1;
1029 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001030 err = mmc_send_cmd(mmc, &cmd, NULL);
1031
1032 if (err)
1033 return err;
1034 }
1035#endif
1036
Andy Fleming272cc702008-10-30 16:41:01 -05001037 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001038 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1039 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001040 cmd.resp_type = MMC_RSP_R2;
1041 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001042
1043 err = mmc_send_cmd(mmc, &cmd, NULL);
1044
1045 if (err)
1046 return err;
1047
1048 memcpy(mmc->cid, cmd.response, 16);
1049
1050 /*
1051 * For MMC cards, set the Relative Address.
1052 * For SD cards, get the Relatvie Address.
1053 * This also puts the cards into Standby State
1054 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001055 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1056 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1057 cmd.cmdarg = mmc->rca << 16;
1058 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001059
Thomas Choud52ebf12010-12-24 13:12:21 +00001060 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001061
Thomas Choud52ebf12010-12-24 13:12:21 +00001062 if (err)
1063 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001064
Thomas Choud52ebf12010-12-24 13:12:21 +00001065 if (IS_SD(mmc))
1066 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1067 }
Andy Fleming272cc702008-10-30 16:41:01 -05001068
1069 /* Get the Card-Specific Data */
1070 cmd.cmdidx = MMC_CMD_SEND_CSD;
1071 cmd.resp_type = MMC_RSP_R2;
1072 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001073
1074 err = mmc_send_cmd(mmc, &cmd, NULL);
1075
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001076 /* Waiting for the ready status */
1077 mmc_send_status(mmc, timeout);
1078
Andy Fleming272cc702008-10-30 16:41:01 -05001079 if (err)
1080 return err;
1081
Rabin Vincent998be3d2009-04-05 13:30:56 +05301082 mmc->csd[0] = cmd.response[0];
1083 mmc->csd[1] = cmd.response[1];
1084 mmc->csd[2] = cmd.response[2];
1085 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001086
1087 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301088 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001089
1090 switch (version) {
1091 case 0:
1092 mmc->version = MMC_VERSION_1_2;
1093 break;
1094 case 1:
1095 mmc->version = MMC_VERSION_1_4;
1096 break;
1097 case 2:
1098 mmc->version = MMC_VERSION_2_2;
1099 break;
1100 case 3:
1101 mmc->version = MMC_VERSION_3;
1102 break;
1103 case 4:
1104 mmc->version = MMC_VERSION_4;
1105 break;
1106 default:
1107 mmc->version = MMC_VERSION_1_2;
1108 break;
1109 }
1110 }
1111
1112 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301113 freq = fbase[(cmd.response[0] & 0x7)];
1114 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001115
1116 mmc->tran_speed = freq * mult;
1117
Markus Niebelab711882013-12-16 13:40:46 +01001118 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301119 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001120
1121 if (IS_SD(mmc))
1122 mmc->write_bl_len = mmc->read_bl_len;
1123 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301124 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001125
1126 if (mmc->high_capacity) {
1127 csize = (mmc->csd[1] & 0x3f) << 16
1128 | (mmc->csd[2] & 0xffff0000) >> 16;
1129 cmult = 8;
1130 } else {
1131 csize = (mmc->csd[1] & 0x3ff) << 2
1132 | (mmc->csd[2] & 0xc0000000) >> 30;
1133 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1134 }
1135
Stephen Warrenf866a462013-06-11 15:14:01 -06001136 mmc->capacity_user = (csize + 1) << (cmult + 2);
1137 mmc->capacity_user *= mmc->read_bl_len;
1138 mmc->capacity_boot = 0;
1139 mmc->capacity_rpmb = 0;
1140 for (i = 0; i < 4; i++)
1141 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001142
Simon Glass8bfa1952013-04-03 08:54:30 +00001143 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1144 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001145
Simon Glass8bfa1952013-04-03 08:54:30 +00001146 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1147 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001148
Markus Niebelab711882013-12-16 13:40:46 +01001149 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1150 cmd.cmdidx = MMC_CMD_SET_DSR;
1151 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1152 cmd.resp_type = MMC_RSP_NONE;
1153 if (mmc_send_cmd(mmc, &cmd, NULL))
1154 printf("MMC: SET_DSR failed\n");
1155 }
1156
Andy Fleming272cc702008-10-30 16:41:01 -05001157 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001158 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1159 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001160 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001161 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001162 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001163
Thomas Choud52ebf12010-12-24 13:12:21 +00001164 if (err)
1165 return err;
1166 }
Andy Fleming272cc702008-10-30 16:41:01 -05001167
Lei Wene6f99a52011-06-22 17:03:31 +00001168 /*
1169 * For SD, its erase group is always one sector
1170 */
1171 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001172 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301173 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1174 /* check ext_csd version and capacity */
1175 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001176 if (err)
1177 return err;
1178 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001179 /*
1180 * According to the JEDEC Standard, the value of
1181 * ext_csd's capacity is valid if the value is more
1182 * than 2GB
1183 */
Lei Wen0560db12011-10-03 20:35:10 +00001184 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1185 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1186 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1187 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001188 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001189 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001190 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301191 }
Lei Wenbc897b12011-05-02 16:26:26 +00001192
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001193 switch (ext_csd[EXT_CSD_REV]) {
1194 case 1:
1195 mmc->version = MMC_VERSION_4_1;
1196 break;
1197 case 2:
1198 mmc->version = MMC_VERSION_4_2;
1199 break;
1200 case 3:
1201 mmc->version = MMC_VERSION_4_3;
1202 break;
1203 case 5:
1204 mmc->version = MMC_VERSION_4_41;
1205 break;
1206 case 6:
1207 mmc->version = MMC_VERSION_4_5;
1208 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001209 case 7:
1210 mmc->version = MMC_VERSION_5_0;
1211 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001212 }
1213
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001214 /* The partition data may be non-zero but it is only
1215 * effective if PARTITION_SETTING_COMPLETED is set in
1216 * EXT_CSD, so ignore any data if this bit is not set,
1217 * except for enabling the high-capacity group size
1218 * definition (see below). */
1219 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1220 EXT_CSD_PARTITION_SETTING_COMPLETED);
1221
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001222 /* store the partition info of emmc */
1223 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1224 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1225 ext_csd[EXT_CSD_BOOT_MULT])
1226 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001227 if (part_completed &&
1228 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001229 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1230
1231 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1232
1233 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1234
1235 for (i = 0; i < 4; i++) {
1236 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001237 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001238 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001239 if (mult)
1240 has_parts = true;
1241 if (!part_completed)
1242 continue;
1243 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001244 mmc->capacity_gp[i] *=
1245 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1246 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001247 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001248 }
1249
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001250 if (part_completed) {
1251 mmc->enh_user_size =
1252 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1253 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1254 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1255 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1256 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1257 mmc->enh_user_size <<= 19;
1258 mmc->enh_user_start =
1259 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1260 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1261 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1262 ext_csd[EXT_CSD_ENH_START_ADDR];
1263 if (mmc->high_capacity)
1264 mmc->enh_user_start <<= 9;
1265 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001266
Lei Wene6f99a52011-06-22 17:03:31 +00001267 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001268 * Host needs to enable ERASE_GRP_DEF bit if device is
1269 * partitioned. This bit will be lost every time after a reset
1270 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001271 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001272 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001273 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001274 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001275 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1276 has_parts = true;
1277 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001278 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1279 EXT_CSD_ERASE_GROUP_DEF, 1);
1280
1281 if (err)
1282 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001283 else
1284 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001285 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001286
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001287 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001288 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001289 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001290 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001291 /*
1292 * if high capacity and partition setting completed
1293 * SEC_COUNT is valid even if it is smaller than 2 GiB
1294 * JEDEC Standard JESD84-B45, 6.2.4
1295 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001296 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001297 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1298 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1299 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1300 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1301 capacity *= MMC_MAX_BLOCK_LEN;
1302 mmc->capacity_user = capacity;
1303 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001304 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001305 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001306 int erase_gsz, erase_gmul;
1307 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1308 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1309 mmc->erase_grp_size = (erase_gsz + 1)
1310 * (erase_gmul + 1);
1311 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001312
1313 mmc->hc_wp_grp_size = 1024
1314 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1315 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001316
1317 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301318 }
1319
Stephen Warrenf866a462013-06-11 15:14:01 -06001320 err = mmc_set_capacity(mmc, mmc->part_num);
1321 if (err)
1322 return err;
1323
Andy Fleming272cc702008-10-30 16:41:01 -05001324 if (IS_SD(mmc))
1325 err = sd_change_freq(mmc);
1326 else
1327 err = mmc_change_freq(mmc);
1328
1329 if (err)
1330 return err;
1331
1332 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001333 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001334
1335 if (IS_SD(mmc)) {
1336 if (mmc->card_caps & MMC_MODE_4BIT) {
1337 cmd.cmdidx = MMC_CMD_APP_CMD;
1338 cmd.resp_type = MMC_RSP_R1;
1339 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001340
1341 err = mmc_send_cmd(mmc, &cmd, NULL);
1342 if (err)
1343 return err;
1344
1345 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1346 cmd.resp_type = MMC_RSP_R1;
1347 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001348 err = mmc_send_cmd(mmc, &cmd, NULL);
1349 if (err)
1350 return err;
1351
1352 mmc_set_bus_width(mmc, 4);
1353 }
1354
1355 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001356 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001357 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001358 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001359 } else if (mmc->version >= MMC_VERSION_4) {
1360 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001361 int idx;
1362
1363 /* An array of possible bus widths in order of preference */
1364 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001365 EXT_CSD_DDR_BUS_WIDTH_8,
1366 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001367 EXT_CSD_BUS_WIDTH_8,
1368 EXT_CSD_BUS_WIDTH_4,
1369 EXT_CSD_BUS_WIDTH_1,
1370 };
1371
1372 /* An array to map CSD bus widths to host cap bits */
1373 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001374 [EXT_CSD_DDR_BUS_WIDTH_4] =
1375 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1376 [EXT_CSD_DDR_BUS_WIDTH_8] =
1377 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001378 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1379 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1380 };
1381
1382 /* An array to map chosen bus width to an integer */
1383 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001384 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001385 };
1386
1387 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1388 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001389 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001390
1391 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001392 * If the bus width is still not changed,
1393 * don't try to set the default again.
1394 * Otherwise, recover from switch attempts
1395 * by switching to 1-bit bus width.
1396 */
1397 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1398 mmc->bus_width == 1) {
1399 err = 0;
1400 break;
1401 }
1402
1403 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001404 * Check to make sure the card and controller support
1405 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001406 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001407 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001408 continue;
1409
Andy Fleming272cc702008-10-30 16:41:01 -05001410 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001411 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001412
1413 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001414 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001415
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001416 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001417 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001418
Lei Wen41378942011-10-03 20:35:11 +00001419 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001420
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001421 if (err)
1422 continue;
1423
1424 /* Only compare read only fields */
1425 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1426 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1427 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1428 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1429 ext_csd[EXT_CSD_REV]
1430 == test_csd[EXT_CSD_REV] &&
1431 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1432 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1433 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1434 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001435 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001436 else
1437 err = SWITCH_ERR;
Andy Fleming272cc702008-10-30 16:41:01 -05001438 }
1439
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001440 if (err)
1441 return err;
1442
Andy Fleming272cc702008-10-30 16:41:01 -05001443 if (mmc->card_caps & MMC_MODE_HS) {
1444 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001445 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001446 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001447 mmc->tran_speed = 26000000;
1448 }
Andy Fleming272cc702008-10-30 16:41:01 -05001449 }
1450
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001451 mmc_set_clock(mmc, mmc->tran_speed);
1452
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001453 /* Fix the block length for DDR mode */
1454 if (mmc->ddr_mode) {
1455 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1456 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1457 }
1458
Andy Fleming272cc702008-10-30 16:41:01 -05001459 /* fill in device description */
1460 mmc->block_dev.lun = 0;
1461 mmc->block_dev.type = 0;
1462 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001463 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301464 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001465#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001466 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1467 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1468 (mmc->cid[3] >> 16) & 0xffff);
1469 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1470 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1471 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1472 (mmc->cid[2] >> 24) & 0xff);
1473 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1474 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001475#else
1476 mmc->block_dev.vendor[0] = 0;
1477 mmc->block_dev.product[0] = 0;
1478 mmc->block_dev.revision[0] = 0;
1479#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001480#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001481 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001482#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001483
1484 return 0;
1485}
1486
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001487static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001488{
1489 struct mmc_cmd cmd;
1490 int err;
1491
1492 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1493 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001494 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001495 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001496
1497 err = mmc_send_cmd(mmc, &cmd, NULL);
1498
1499 if (err)
1500 return err;
1501
Rabin Vincent998be3d2009-04-05 13:30:56 +05301502 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001503 return UNUSABLE_ERR;
1504 else
1505 mmc->version = SD_VERSION_2;
1506
1507 return 0;
1508}
1509
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001510/* not used any more */
1511int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001512{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001513#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1514 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1515#endif
1516 return -1;
1517}
1518
1519struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1520{
1521 struct mmc *mmc;
1522
1523 /* quick validation */
1524 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1525 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1526 return NULL;
1527
1528 mmc = calloc(1, sizeof(*mmc));
1529 if (mmc == NULL)
1530 return NULL;
1531
1532 mmc->cfg = cfg;
1533 mmc->priv = priv;
1534
1535 /* the following chunk was mmc_register() */
1536
Markus Niebelab711882013-12-16 13:40:46 +01001537 /* Setup dsr related values */
1538 mmc->dsr_imp = 0;
1539 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001540 /* Setup the universal parts of the block interface just once */
1541 mmc->block_dev.if_type = IF_TYPE_MMC;
1542 mmc->block_dev.dev = cur_dev_num++;
1543 mmc->block_dev.removable = 1;
1544 mmc->block_dev.block_read = mmc_bread;
1545 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001546 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001547
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001548 /* setup initial part type */
1549 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001550
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001551 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001552
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001553 list_add_tail(&mmc->link, &mmc_devices);
1554
1555 return mmc;
1556}
1557
1558void mmc_destroy(struct mmc *mmc)
1559{
1560 /* only freeing memory for now */
1561 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001562}
1563
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001564#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001565block_dev_desc_t *mmc_get_dev(int dev)
1566{
1567 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001568 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001569 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001570
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001571 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001572}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001573#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001574
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001575/* board-specific MMC power initializations. */
1576__weak void board_mmc_power_init(void)
1577{
1578}
1579
Che-Liang Chioue9550442012-11-28 15:21:13 +00001580int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001581{
Macpaul Linafd59322011-11-14 23:35:39 +00001582 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001583
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001584 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001585 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001586 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001587#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001588 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001589#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001590 return NO_CARD_ERR;
1591 }
1592
Lei Wenbc897b12011-05-02 16:26:26 +00001593 if (mmc->has_init)
1594 return 0;
1595
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001596 board_mmc_power_init();
1597
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001598 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001599 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001600
1601 if (err)
1602 return err;
1603
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001604 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001605 mmc_set_bus_width(mmc, 1);
1606 mmc_set_clock(mmc, 1);
1607
Andy Fleming272cc702008-10-30 16:41:01 -05001608 /* Reset the Card */
1609 err = mmc_go_idle(mmc);
1610
1611 if (err)
1612 return err;
1613
Lei Wenbc897b12011-05-02 16:26:26 +00001614 /* The internal partition reset to user partition(0) at every CMD0*/
1615 mmc->part_num = 0;
1616
Andy Fleming272cc702008-10-30 16:41:01 -05001617 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001618 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001619
Andy Fleming272cc702008-10-30 16:41:01 -05001620 /* Now try to get the SD card's operating condition */
1621 err = sd_send_op_cond(mmc);
1622
1623 /* If the command timed out, we check for an MMC card */
1624 if (err == TIMEOUT) {
1625 err = mmc_send_op_cond(mmc);
1626
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001627 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001628#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001629 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001630#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001631 return UNUSABLE_ERR;
1632 }
1633 }
1634
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001635 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001636 mmc->init_in_progress = 1;
1637
1638 return err;
1639}
1640
1641static int mmc_complete_init(struct mmc *mmc)
1642{
1643 int err = 0;
1644
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001645 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001646 if (mmc->op_cond_pending)
1647 err = mmc_complete_op_cond(mmc);
1648
1649 if (!err)
1650 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001651 if (err)
1652 mmc->has_init = 0;
1653 else
1654 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001655 return err;
1656}
1657
1658int mmc_init(struct mmc *mmc)
1659{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001660 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001661 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001662
1663 if (mmc->has_init)
1664 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001665
1666 start = get_timer(0);
1667
Che-Liang Chioue9550442012-11-28 15:21:13 +00001668 if (!mmc->init_in_progress)
1669 err = mmc_start_init(mmc);
1670
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001671 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001672 err = mmc_complete_init(mmc);
1673 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001674 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001675}
1676
Markus Niebelab711882013-12-16 13:40:46 +01001677int mmc_set_dsr(struct mmc *mmc, u16 val)
1678{
1679 mmc->dsr = val;
1680 return 0;
1681}
1682
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001683/* CPU-specific MMC initializations */
1684__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001685{
1686 return -1;
1687}
1688
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001689/* board-specific MMC initializations. */
1690__weak int board_mmc_init(bd_t *bis)
1691{
1692 return -1;
1693}
Andy Fleming272cc702008-10-30 16:41:01 -05001694
Paul Burton56196822013-09-04 16:12:25 +01001695#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1696
Andy Fleming272cc702008-10-30 16:41:01 -05001697void print_mmc_devices(char separator)
1698{
1699 struct mmc *m;
1700 struct list_head *entry;
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001701 char *mmc_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001702
1703 list_for_each(entry, &mmc_devices) {
1704 m = list_entry(entry, struct mmc, link);
1705
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001706 if (m->has_init)
1707 mmc_type = IS_SD(m) ? "SD" : "eMMC";
1708 else
1709 mmc_type = NULL;
1710
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001711 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001712 if (mmc_type)
1713 printf(" (%s)", mmc_type);
Andy Fleming272cc702008-10-30 16:41:01 -05001714
Lubomir Popove75eaf12014-11-11 12:25:42 +02001715 if (entry->next != &mmc_devices) {
1716 printf("%c", separator);
1717 if (separator != '\n')
1718 puts (" ");
1719 }
Andy Fleming272cc702008-10-30 16:41:01 -05001720 }
1721
1722 printf("\n");
1723}
1724
Paul Burton56196822013-09-04 16:12:25 +01001725#else
1726void print_mmc_devices(char separator) { }
1727#endif
1728
Lei Wenea6ebe22011-05-02 16:26:25 +00001729int get_mmc_num(void)
1730{
1731 return cur_dev_num;
1732}
1733
Che-Liang Chioue9550442012-11-28 15:21:13 +00001734void mmc_set_preinit(struct mmc *mmc, int preinit)
1735{
1736 mmc->preinit = preinit;
1737}
1738
1739static void do_preinit(void)
1740{
1741 struct mmc *m;
1742 struct list_head *entry;
1743
1744 list_for_each(entry, &mmc_devices) {
1745 m = list_entry(entry, struct mmc, link);
1746
1747 if (m->preinit)
1748 mmc_start_init(m);
1749 }
1750}
1751
1752
Andy Fleming272cc702008-10-30 16:41:01 -05001753int mmc_initialize(bd_t *bis)
1754{
1755 INIT_LIST_HEAD (&mmc_devices);
1756 cur_dev_num = 0;
1757
1758 if (board_mmc_init(bis) < 0)
1759 cpu_mmc_init(bis);
1760
Ying Zhangbb0dc102013-08-16 15:16:11 +08001761#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001762 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001763#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001764
Che-Liang Chioue9550442012-11-28 15:21:13 +00001765 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001766 return 0;
1767}
Amar3690d6d2013-04-27 11:42:58 +05301768
1769#ifdef CONFIG_SUPPORT_EMMC_BOOT
1770/*
1771 * This function changes the size of boot partition and the size of rpmb
1772 * partition present on EMMC devices.
1773 *
1774 * Input Parameters:
1775 * struct *mmc: pointer for the mmc device strcuture
1776 * bootsize: size of boot partition
1777 * rpmbsize: size of rpmb partition
1778 *
1779 * Returns 0 on success.
1780 */
1781
1782int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1783 unsigned long rpmbsize)
1784{
1785 int err;
1786 struct mmc_cmd cmd;
1787
1788 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1789 cmd.cmdidx = MMC_CMD_RES_MAN;
1790 cmd.resp_type = MMC_RSP_R1b;
1791 cmd.cmdarg = MMC_CMD62_ARG1;
1792
1793 err = mmc_send_cmd(mmc, &cmd, NULL);
1794 if (err) {
1795 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1796 return err;
1797 }
1798
1799 /* Boot partition changing mode */
1800 cmd.cmdidx = MMC_CMD_RES_MAN;
1801 cmd.resp_type = MMC_RSP_R1b;
1802 cmd.cmdarg = MMC_CMD62_ARG2;
1803
1804 err = mmc_send_cmd(mmc, &cmd, NULL);
1805 if (err) {
1806 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1807 return err;
1808 }
1809 /* boot partition size is multiple of 128KB */
1810 bootsize = (bootsize * 1024) / 128;
1811
1812 /* Arg: boot partition size */
1813 cmd.cmdidx = MMC_CMD_RES_MAN;
1814 cmd.resp_type = MMC_RSP_R1b;
1815 cmd.cmdarg = bootsize;
1816
1817 err = mmc_send_cmd(mmc, &cmd, NULL);
1818 if (err) {
1819 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1820 return err;
1821 }
1822 /* RPMB partition size is multiple of 128KB */
1823 rpmbsize = (rpmbsize * 1024) / 128;
1824 /* Arg: RPMB partition size */
1825 cmd.cmdidx = MMC_CMD_RES_MAN;
1826 cmd.resp_type = MMC_RSP_R1b;
1827 cmd.cmdarg = rpmbsize;
1828
1829 err = mmc_send_cmd(mmc, &cmd, NULL);
1830 if (err) {
1831 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1832 return err;
1833 }
1834 return 0;
1835}
1836
1837/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001838 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1839 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1840 * and BOOT_MODE.
1841 *
1842 * Returns 0 on success.
1843 */
1844int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1845{
1846 int err;
1847
1848 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1849 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1850 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1851 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1852
1853 if (err)
1854 return err;
1855 return 0;
1856}
1857
1858/*
Tom Rini792970b2014-02-05 10:24:21 -05001859 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1860 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1861 * PARTITION_ACCESS.
1862 *
1863 * Returns 0 on success.
1864 */
1865int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1866{
1867 int err;
1868
1869 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1870 EXT_CSD_BOOT_ACK(ack) |
1871 EXT_CSD_BOOT_PART_NUM(part_num) |
1872 EXT_CSD_PARTITION_ACCESS(access));
1873
1874 if (err)
1875 return err;
1876 return 0;
1877}
Tom Rini33ace362014-02-07 14:15:20 -05001878
1879/*
1880 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1881 * for enable. Note that this is a write-once field for non-zero values.
1882 *
1883 * Returns 0 on success.
1884 */
1885int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1886{
1887 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1888 enable);
1889}
Amar3690d6d2013-04-27 11:42:58 +05301890#endif