blob: fe00a193a62f9f111a289418e5e0441278e95f3c [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
121 do {
122 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
138 udelay(1000);
139
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000140 } while (timeout--);
141
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000142#ifdef CONFIG_MMC_TRACE
143 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
144 printf("CURR STATE:%d\n", status);
145#endif
Jongman Heo5b0c9422012-06-03 21:32:13 +0000146 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100147#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000148 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100149#endif
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000150 return TIMEOUT;
151 }
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500152 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
153 return SWITCH_ERR;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000154
155 return 0;
156}
157
Paul Burtonda61fa52013-09-09 15:30:26 +0100158int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500159{
160 struct mmc_cmd cmd;
161
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600162 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900163 return 0;
164
Andy Fleming272cc702008-10-30 16:41:01 -0500165 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
166 cmd.resp_type = MMC_RSP_R1;
167 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500168
169 return mmc_send_cmd(mmc, &cmd, NULL);
170}
171
172struct mmc *find_mmc_device(int dev_num)
173{
174 struct mmc *m;
175 struct list_head *entry;
176
177 list_for_each(entry, &mmc_devices) {
178 m = list_entry(entry, struct mmc, link);
179
180 if (m->block_dev.dev == dev_num)
181 return m;
182 }
183
Paul Burton56196822013-09-04 16:12:25 +0100184#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -0500185 printf("MMC Device %d not found\n", dev_num);
Paul Burton56196822013-09-04 16:12:25 +0100186#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500187
188 return NULL;
189}
190
Sascha Silbeff8fef52013-06-14 13:07:25 +0200191static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000192 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500193{
194 struct mmc_cmd cmd;
195 struct mmc_data data;
196
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700197 if (blkcnt > 1)
198 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
199 else
200 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500201
202 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700203 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500204 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700205 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500206
207 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500208
209 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700210 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500211 data.blocksize = mmc->read_bl_len;
212 data.flags = MMC_DATA_READ;
213
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700214 if (mmc_send_cmd(mmc, &cmd, &data))
215 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500216
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700217 if (blkcnt > 1) {
218 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
219 cmd.cmdarg = 0;
220 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700221 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100222#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700223 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100224#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700225 return 0;
226 }
Andy Fleming272cc702008-10-30 16:41:01 -0500227 }
228
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700229 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500230}
231
Sascha Silbeff8fef52013-06-14 13:07:25 +0200232static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500233{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700234 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500235
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700236 if (blkcnt == 0)
237 return 0;
238
239 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500240 if (!mmc)
241 return 0;
242
Lei Wend2bf29e2010-09-13 22:07:27 +0800243 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton56196822013-09-04 16:12:25 +0100244#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200245 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800246 start + blkcnt, mmc->block_dev.lba);
Paul Burton56196822013-09-04 16:12:25 +0100247#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800248 return 0;
249 }
Andy Fleming272cc702008-10-30 16:41:01 -0500250
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700251 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Fleming272cc702008-10-30 16:41:01 -0500252 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500253
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700254 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200255 cur = (blocks_todo > mmc->cfg->b_max) ?
256 mmc->cfg->b_max : blocks_todo;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700257 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
258 return 0;
259 blocks_todo -= cur;
260 start += cur;
261 dst += cur * mmc->read_bl_len;
262 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500263
264 return blkcnt;
265}
266
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000267static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500268{
269 struct mmc_cmd cmd;
270 int err;
271
272 udelay(1000);
273
274 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
275 cmd.cmdarg = 0;
276 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500277
278 err = mmc_send_cmd(mmc, &cmd, NULL);
279
280 if (err)
281 return err;
282
283 udelay(2000);
284
285 return 0;
286}
287
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000288static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500289{
290 int timeout = 1000;
291 int err;
292 struct mmc_cmd cmd;
293
294 do {
295 cmd.cmdidx = MMC_CMD_APP_CMD;
296 cmd.resp_type = MMC_RSP_R1;
297 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500298
299 err = mmc_send_cmd(mmc, &cmd, NULL);
300
301 if (err)
302 return err;
303
304 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
305 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100306
307 /*
308 * Most cards do not answer if some reserved bits
309 * in the ocr are set. However, Some controller
310 * can set bit 7 (reserved for low voltages), but
311 * how to manage low voltages SD card is not yet
312 * specified.
313 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000314 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200315 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500316
317 if (mmc->version == SD_VERSION_2)
318 cmd.cmdarg |= OCR_HCS;
319
320 err = mmc_send_cmd(mmc, &cmd, NULL);
321
322 if (err)
323 return err;
324
325 udelay(1000);
326 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
327
328 if (timeout <= 0)
329 return UNUSABLE_ERR;
330
331 if (mmc->version != SD_VERSION_2)
332 mmc->version = SD_VERSION_1_0;
333
Thomas Choud52ebf12010-12-24 13:12:21 +0000334 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
335 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
336 cmd.resp_type = MMC_RSP_R3;
337 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000338
339 err = mmc_send_cmd(mmc, &cmd, NULL);
340
341 if (err)
342 return err;
343 }
344
Rabin Vincent998be3d2009-04-05 13:30:56 +0530345 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500346
347 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
348 mmc->rca = 0;
349
350 return 0;
351}
352
Che-Liang Chioue9550442012-11-28 15:21:13 +0000353/* We pass in the cmd since otherwise the init seems to fail */
354static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
355 int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500356{
Andy Fleming272cc702008-10-30 16:41:01 -0500357 int err;
358
Che-Liang Chioue9550442012-11-28 15:21:13 +0000359 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
360 cmd->resp_type = MMC_RSP_R3;
361 cmd->cmdarg = 0;
362 if (use_arg && !mmc_host_is_spi(mmc)) {
363 cmd->cmdarg =
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200364 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500365 (mmc->ocr & OCR_VOLTAGE_MASK)) |
366 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000367
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200368 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000369 cmd->cmdarg |= OCR_HCS;
370 }
371 err = mmc_send_cmd(mmc, cmd, NULL);
372 if (err)
373 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500374 mmc->ocr = cmd->response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000375 return 0;
376}
377
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200378static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000379{
380 struct mmc_cmd cmd;
381 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 mmc->op_cond_pending = 1;
388 for (i = 0; i < 2; i++) {
389 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500390 if (err)
391 return err;
392
Che-Liang Chioue9550442012-11-28 15:21:13 +0000393 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500394 if (mmc->ocr & OCR_BUSY)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000395 return 0;
396 }
397 return IN_PROGRESS;
398}
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;
408 start = get_timer(0);
409 do {
410 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
411 if (err)
412 return err;
413 if (get_timer(start) > timeout)
414 return UNUSABLE_ERR;
415 udelay(100);
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500416 } while (!(mmc->ocr & OCR_BUSY));
Andy Fleming272cc702008-10-30 16:41:01 -0500417
Thomas Choud52ebf12010-12-24 13:12:21 +0000418 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
419 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
420 cmd.resp_type = MMC_RSP_R3;
421 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000422
423 err = mmc_send_cmd(mmc, &cmd, NULL);
424
425 if (err)
426 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500427
428 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000429 }
430
Andy Fleming272cc702008-10-30 16:41:01 -0500431 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500432
433 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700434 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500435
436 return 0;
437}
438
439
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000440static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500441{
442 struct mmc_cmd cmd;
443 struct mmc_data data;
444 int err;
445
446 /* Get the Card Status Register */
447 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
448 cmd.resp_type = MMC_RSP_R1;
449 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500450
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000451 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500452 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000453 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500454 data.flags = MMC_DATA_READ;
455
456 err = mmc_send_cmd(mmc, &cmd, &data);
457
458 return err;
459}
460
461
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000462static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500463{
464 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000465 int timeout = 1000;
466 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500467
468 cmd.cmdidx = MMC_CMD_SWITCH;
469 cmd.resp_type = MMC_RSP_R1b;
470 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000471 (index << 16) |
472 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500473
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000474 ret = mmc_send_cmd(mmc, &cmd, NULL);
475
476 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000477 if (!ret)
478 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000479
480 return ret;
481
Andy Fleming272cc702008-10-30 16:41:01 -0500482}
483
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000484static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500485{
Simon Glass8bfa1952013-04-03 08:54:30 +0000486 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500487 char cardtype;
488 int err;
489
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600490 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500491
Thomas Choud52ebf12010-12-24 13:12:21 +0000492 if (mmc_host_is_spi(mmc))
493 return 0;
494
Andy Fleming272cc702008-10-30 16:41:01 -0500495 /* Only version 4 supports high-speed */
496 if (mmc->version < MMC_VERSION_4)
497 return 0;
498
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600499 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
500
Andy Fleming272cc702008-10-30 16:41:01 -0500501 err = mmc_send_ext_csd(mmc, ext_csd);
502
503 if (err)
504 return err;
505
Lei Wen0560db12011-10-03 20:35:10 +0000506 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500507
508 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
509
510 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500511 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500512
513 /* Now check to see that it worked */
514 err = mmc_send_ext_csd(mmc, ext_csd);
515
516 if (err)
517 return err;
518
519 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000520 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500521 return 0;
522
523 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900524 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600525 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900526 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500527 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900528 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500529 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900530 }
Andy Fleming272cc702008-10-30 16:41:01 -0500531
532 return 0;
533}
534
Stephen Warrenf866a462013-06-11 15:14:01 -0600535static int mmc_set_capacity(struct mmc *mmc, int part_num)
536{
537 switch (part_num) {
538 case 0:
539 mmc->capacity = mmc->capacity_user;
540 break;
541 case 1:
542 case 2:
543 mmc->capacity = mmc->capacity_boot;
544 break;
545 case 3:
546 mmc->capacity = mmc->capacity_rpmb;
547 break;
548 case 4:
549 case 5:
550 case 6:
551 case 7:
552 mmc->capacity = mmc->capacity_gp[part_num - 4];
553 break;
554 default:
555 return -1;
556 }
557
558 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
559
560 return 0;
561}
562
Stephen Warrend2356282014-05-07 12:19:02 -0600563int mmc_select_hwpart(int dev_num, int hwpart)
564{
565 struct mmc *mmc = find_mmc_device(dev_num);
566 int ret;
567
568 if (!mmc)
Stephen Warrend4622df2014-05-23 12:47:06 -0600569 return -ENODEV;
Stephen Warrend2356282014-05-07 12:19:02 -0600570
571 if (mmc->part_num == hwpart)
572 return 0;
573
574 if (mmc->part_config == MMCPART_NOAVAILABLE) {
575 printf("Card doesn't support part_switch\n");
Stephen Warrend4622df2014-05-23 12:47:06 -0600576 return -EMEDIUMTYPE;
Stephen Warrend2356282014-05-07 12:19:02 -0600577 }
578
579 ret = mmc_switch_part(dev_num, hwpart);
580 if (ret)
Stephen Warrend4622df2014-05-23 12:47:06 -0600581 return ret;
Stephen Warrend2356282014-05-07 12:19:02 -0600582
583 mmc->part_num = hwpart;
584
585 return 0;
586}
587
588
Lei Wenbc897b12011-05-02 16:26:26 +0000589int mmc_switch_part(int dev_num, unsigned int part_num)
590{
591 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600592 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000593
594 if (!mmc)
595 return -1;
596
Stephen Warrenf866a462013-06-11 15:14:01 -0600597 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
598 (mmc->part_config & ~PART_ACCESS_MASK)
599 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600600
Peter Bigot6dc93e72014-09-02 18:31:23 -0500601 /*
602 * Set the capacity if the switch succeeded or was intended
603 * to return to representing the raw device.
604 */
605 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
606 ret = mmc_set_capacity(mmc, part_num);
607
608 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000609}
610
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100611int mmc_hwpart_config(struct mmc *mmc,
612 const struct mmc_hwpart_conf *conf,
613 enum mmc_hwpart_conf_mode mode)
614{
615 u8 part_attrs = 0;
616 u32 enh_size_mult;
617 u32 enh_start_addr;
618 u32 gp_size_mult[4];
619 u32 max_enh_size_mult;
620 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100621 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100622 int i, pidx, err;
623 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
624
625 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
626 return -EINVAL;
627
628 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
629 printf("eMMC >= 4.4 required for enhanced user data area\n");
630 return -EMEDIUMTYPE;
631 }
632
633 if (!(mmc->part_support & PART_SUPPORT)) {
634 printf("Card does not support partitioning\n");
635 return -EMEDIUMTYPE;
636 }
637
638 if (!mmc->hc_wp_grp_size) {
639 printf("Card does not define HC WP group size\n");
640 return -EMEDIUMTYPE;
641 }
642
643 /* check partition alignment and total enhanced size */
644 if (conf->user.enh_size) {
645 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
646 conf->user.enh_start % mmc->hc_wp_grp_size) {
647 printf("User data enhanced area not HC WP group "
648 "size aligned\n");
649 return -EINVAL;
650 }
651 part_attrs |= EXT_CSD_ENH_USR;
652 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
653 if (mmc->high_capacity) {
654 enh_start_addr = conf->user.enh_start;
655 } else {
656 enh_start_addr = (conf->user.enh_start << 9);
657 }
658 } else {
659 enh_size_mult = 0;
660 enh_start_addr = 0;
661 }
662 tot_enh_size_mult += enh_size_mult;
663
664 for (pidx = 0; pidx < 4; pidx++) {
665 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
666 printf("GP%i partition not HC WP group size "
667 "aligned\n", pidx+1);
668 return -EINVAL;
669 }
670 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
671 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
672 part_attrs |= EXT_CSD_ENH_GP(pidx);
673 tot_enh_size_mult += gp_size_mult[pidx];
674 }
675 }
676
677 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
678 printf("Card does not support enhanced attribute\n");
679 return -EMEDIUMTYPE;
680 }
681
682 err = mmc_send_ext_csd(mmc, ext_csd);
683 if (err)
684 return err;
685
686 max_enh_size_mult =
687 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
688 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
689 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
690 if (tot_enh_size_mult > max_enh_size_mult) {
691 printf("Total enhanced size exceeds maximum (%u > %u)\n",
692 tot_enh_size_mult, max_enh_size_mult);
693 return -EMEDIUMTYPE;
694 }
695
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100696 /* The default value of EXT_CSD_WR_REL_SET is device
697 * dependent, the values can only be changed if the
698 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
699 * changed only once and before partitioning is completed. */
700 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
701 if (conf->user.wr_rel_change) {
702 if (conf->user.wr_rel_set)
703 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
704 else
705 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
706 }
707 for (pidx = 0; pidx < 4; pidx++) {
708 if (conf->gp_part[pidx].wr_rel_change) {
709 if (conf->gp_part[pidx].wr_rel_set)
710 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
711 else
712 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
713 }
714 }
715
716 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
717 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
718 puts("Card does not support host controlled partition write "
719 "reliability settings\n");
720 return -EMEDIUMTYPE;
721 }
722
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100723 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
724 EXT_CSD_PARTITION_SETTING_COMPLETED) {
725 printf("Card already partitioned\n");
726 return -EPERM;
727 }
728
729 if (mode == MMC_HWPART_CONF_CHECK)
730 return 0;
731
732 /* Partitioning requires high-capacity size definitions */
733 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
734 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
735 EXT_CSD_ERASE_GROUP_DEF, 1);
736
737 if (err)
738 return err;
739
740 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
741
742 /* update erase group size to be high-capacity */
743 mmc->erase_grp_size =
744 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
745
746 }
747
748 /* all OK, write the configuration */
749 for (i = 0; i < 4; i++) {
750 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
751 EXT_CSD_ENH_START_ADDR+i,
752 (enh_start_addr >> (i*8)) & 0xFF);
753 if (err)
754 return err;
755 }
756 for (i = 0; i < 3; i++) {
757 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
758 EXT_CSD_ENH_SIZE_MULT+i,
759 (enh_size_mult >> (i*8)) & 0xFF);
760 if (err)
761 return err;
762 }
763 for (pidx = 0; pidx < 4; pidx++) {
764 for (i = 0; i < 3; i++) {
765 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
766 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
767 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
768 if (err)
769 return err;
770 }
771 }
772 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
773 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
774 if (err)
775 return err;
776
777 if (mode == MMC_HWPART_CONF_SET)
778 return 0;
779
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100780 /* The WR_REL_SET is a write-once register but shall be
781 * written before setting PART_SETTING_COMPLETED. As it is
782 * write-once we can only write it when completing the
783 * partitioning. */
784 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
785 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
786 EXT_CSD_WR_REL_SET, wr_rel_set);
787 if (err)
788 return err;
789 }
790
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100791 /* Setting PART_SETTING_COMPLETED confirms the partition
792 * configuration but it only becomes effective after power
793 * cycle, so we do not adjust the partition related settings
794 * in the mmc struct. */
795
796 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
797 EXT_CSD_PARTITION_SETTING,
798 EXT_CSD_PARTITION_SETTING_COMPLETED);
799 if (err)
800 return err;
801
802 return 0;
803}
804
Thierry Reding48972d92012-01-02 01:15:37 +0000805int mmc_getcd(struct mmc *mmc)
806{
807 int cd;
808
809 cd = board_mmc_getcd(mmc);
810
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000811 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200812 if (mmc->cfg->ops->getcd)
813 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000814 else
815 cd = 1;
816 }
Thierry Reding48972d92012-01-02 01:15:37 +0000817
818 return cd;
819}
820
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000821static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500822{
823 struct mmc_cmd cmd;
824 struct mmc_data data;
825
826 /* Switch the frequency */
827 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
828 cmd.resp_type = MMC_RSP_R1;
829 cmd.cmdarg = (mode << 31) | 0xffffff;
830 cmd.cmdarg &= ~(0xf << (group * 4));
831 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500832
833 data.dest = (char *)resp;
834 data.blocksize = 64;
835 data.blocks = 1;
836 data.flags = MMC_DATA_READ;
837
838 return mmc_send_cmd(mmc, &cmd, &data);
839}
840
841
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000842static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500843{
844 int err;
845 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000846 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
847 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500848 struct mmc_data data;
849 int timeout;
850
851 mmc->card_caps = 0;
852
Thomas Choud52ebf12010-12-24 13:12:21 +0000853 if (mmc_host_is_spi(mmc))
854 return 0;
855
Andy Fleming272cc702008-10-30 16:41:01 -0500856 /* Read the SCR to find out if this card supports higher speeds */
857 cmd.cmdidx = MMC_CMD_APP_CMD;
858 cmd.resp_type = MMC_RSP_R1;
859 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500860
861 err = mmc_send_cmd(mmc, &cmd, NULL);
862
863 if (err)
864 return err;
865
866 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
867 cmd.resp_type = MMC_RSP_R1;
868 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500869
870 timeout = 3;
871
872retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000873 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500874 data.blocksize = 8;
875 data.blocks = 1;
876 data.flags = MMC_DATA_READ;
877
878 err = mmc_send_cmd(mmc, &cmd, &data);
879
880 if (err) {
881 if (timeout--)
882 goto retry_scr;
883
884 return err;
885 }
886
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300887 mmc->scr[0] = __be32_to_cpu(scr[0]);
888 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500889
890 switch ((mmc->scr[0] >> 24) & 0xf) {
891 case 0:
892 mmc->version = SD_VERSION_1_0;
893 break;
894 case 1:
895 mmc->version = SD_VERSION_1_10;
896 break;
897 case 2:
898 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000899 if ((mmc->scr[0] >> 15) & 0x1)
900 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500901 break;
902 default:
903 mmc->version = SD_VERSION_1_0;
904 break;
905 }
906
Alagu Sankarb44c7082010-05-12 15:08:24 +0530907 if (mmc->scr[0] & SD_DATA_4BIT)
908 mmc->card_caps |= MMC_MODE_4BIT;
909
Andy Fleming272cc702008-10-30 16:41:01 -0500910 /* Version 1.0 doesn't support switching */
911 if (mmc->version == SD_VERSION_1_0)
912 return 0;
913
914 timeout = 4;
915 while (timeout--) {
916 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000917 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500918
919 if (err)
920 return err;
921
922 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300923 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500924 break;
925 }
926
Andy Fleming272cc702008-10-30 16:41:01 -0500927 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300928 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500929 return 0;
930
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000931 /*
932 * If the host doesn't support SD_HIGHSPEED, do not switch card to
933 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
934 * This can avoid furthur problem when the card runs in different
935 * mode between the host.
936 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200937 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
938 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000939 return 0;
940
Anton staaff781dd32011-10-03 13:54:59 +0000941 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500942
943 if (err)
944 return err;
945
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300946 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500947 mmc->card_caps |= MMC_MODE_HS;
948
949 return 0;
950}
951
952/* frequency bases */
953/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000954static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500955 10000,
956 100000,
957 1000000,
958 10000000,
959};
960
961/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
962 * to platforms without floating point.
963 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000964static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500965 0, /* reserved */
966 10,
967 12,
968 13,
969 15,
970 20,
971 25,
972 30,
973 35,
974 40,
975 45,
976 50,
977 55,
978 60,
979 70,
980 80,
981};
982
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000983static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500984{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200985 if (mmc->cfg->ops->set_ios)
986 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500987}
988
989void mmc_set_clock(struct mmc *mmc, uint clock)
990{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200991 if (clock > mmc->cfg->f_max)
992 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -0500993
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200994 if (clock < mmc->cfg->f_min)
995 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -0500996
997 mmc->clock = clock;
998
999 mmc_set_ios(mmc);
1000}
1001
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001002static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001003{
1004 mmc->bus_width = width;
1005
1006 mmc_set_ios(mmc);
1007}
1008
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001009static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001010{
Stephen Warrenf866a462013-06-11 15:14:01 -06001011 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001012 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001013 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001014 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001015 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1016 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001017 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001018 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001019 bool part_completed;
Andy Fleming272cc702008-10-30 16:41:01 -05001020
Thomas Choud52ebf12010-12-24 13:12:21 +00001021#ifdef CONFIG_MMC_SPI_CRC_ON
1022 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1023 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1024 cmd.resp_type = MMC_RSP_R1;
1025 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001026 err = mmc_send_cmd(mmc, &cmd, NULL);
1027
1028 if (err)
1029 return err;
1030 }
1031#endif
1032
Andy Fleming272cc702008-10-30 16:41:01 -05001033 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001034 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1035 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001036 cmd.resp_type = MMC_RSP_R2;
1037 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001038
1039 err = mmc_send_cmd(mmc, &cmd, NULL);
1040
1041 if (err)
1042 return err;
1043
1044 memcpy(mmc->cid, cmd.response, 16);
1045
1046 /*
1047 * For MMC cards, set the Relative Address.
1048 * For SD cards, get the Relatvie Address.
1049 * This also puts the cards into Standby State
1050 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001051 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1052 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1053 cmd.cmdarg = mmc->rca << 16;
1054 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001055
Thomas Choud52ebf12010-12-24 13:12:21 +00001056 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001057
Thomas Choud52ebf12010-12-24 13:12:21 +00001058 if (err)
1059 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001060
Thomas Choud52ebf12010-12-24 13:12:21 +00001061 if (IS_SD(mmc))
1062 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1063 }
Andy Fleming272cc702008-10-30 16:41:01 -05001064
1065 /* Get the Card-Specific Data */
1066 cmd.cmdidx = MMC_CMD_SEND_CSD;
1067 cmd.resp_type = MMC_RSP_R2;
1068 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001069
1070 err = mmc_send_cmd(mmc, &cmd, NULL);
1071
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001072 /* Waiting for the ready status */
1073 mmc_send_status(mmc, timeout);
1074
Andy Fleming272cc702008-10-30 16:41:01 -05001075 if (err)
1076 return err;
1077
Rabin Vincent998be3d2009-04-05 13:30:56 +05301078 mmc->csd[0] = cmd.response[0];
1079 mmc->csd[1] = cmd.response[1];
1080 mmc->csd[2] = cmd.response[2];
1081 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001082
1083 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301084 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001085
1086 switch (version) {
1087 case 0:
1088 mmc->version = MMC_VERSION_1_2;
1089 break;
1090 case 1:
1091 mmc->version = MMC_VERSION_1_4;
1092 break;
1093 case 2:
1094 mmc->version = MMC_VERSION_2_2;
1095 break;
1096 case 3:
1097 mmc->version = MMC_VERSION_3;
1098 break;
1099 case 4:
1100 mmc->version = MMC_VERSION_4;
1101 break;
1102 default:
1103 mmc->version = MMC_VERSION_1_2;
1104 break;
1105 }
1106 }
1107
1108 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301109 freq = fbase[(cmd.response[0] & 0x7)];
1110 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001111
1112 mmc->tran_speed = freq * mult;
1113
Markus Niebelab711882013-12-16 13:40:46 +01001114 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301115 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001116
1117 if (IS_SD(mmc))
1118 mmc->write_bl_len = mmc->read_bl_len;
1119 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301120 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001121
1122 if (mmc->high_capacity) {
1123 csize = (mmc->csd[1] & 0x3f) << 16
1124 | (mmc->csd[2] & 0xffff0000) >> 16;
1125 cmult = 8;
1126 } else {
1127 csize = (mmc->csd[1] & 0x3ff) << 2
1128 | (mmc->csd[2] & 0xc0000000) >> 30;
1129 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1130 }
1131
Stephen Warrenf866a462013-06-11 15:14:01 -06001132 mmc->capacity_user = (csize + 1) << (cmult + 2);
1133 mmc->capacity_user *= mmc->read_bl_len;
1134 mmc->capacity_boot = 0;
1135 mmc->capacity_rpmb = 0;
1136 for (i = 0; i < 4; i++)
1137 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001138
Simon Glass8bfa1952013-04-03 08:54:30 +00001139 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1140 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001141
Simon Glass8bfa1952013-04-03 08:54:30 +00001142 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1143 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001144
Markus Niebelab711882013-12-16 13:40:46 +01001145 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1146 cmd.cmdidx = MMC_CMD_SET_DSR;
1147 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1148 cmd.resp_type = MMC_RSP_NONE;
1149 if (mmc_send_cmd(mmc, &cmd, NULL))
1150 printf("MMC: SET_DSR failed\n");
1151 }
1152
Andy Fleming272cc702008-10-30 16:41:01 -05001153 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001154 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1155 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001156 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001157 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001158 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001159
Thomas Choud52ebf12010-12-24 13:12:21 +00001160 if (err)
1161 return err;
1162 }
Andy Fleming272cc702008-10-30 16:41:01 -05001163
Lei Wene6f99a52011-06-22 17:03:31 +00001164 /*
1165 * For SD, its erase group is always one sector
1166 */
1167 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001168 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301169 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1170 /* check ext_csd version and capacity */
1171 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001172 if (err)
1173 return err;
1174 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001175 /*
1176 * According to the JEDEC Standard, the value of
1177 * ext_csd's capacity is valid if the value is more
1178 * than 2GB
1179 */
Lei Wen0560db12011-10-03 20:35:10 +00001180 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1181 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1182 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1183 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001184 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001185 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001186 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301187 }
Lei Wenbc897b12011-05-02 16:26:26 +00001188
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001189 switch (ext_csd[EXT_CSD_REV]) {
1190 case 1:
1191 mmc->version = MMC_VERSION_4_1;
1192 break;
1193 case 2:
1194 mmc->version = MMC_VERSION_4_2;
1195 break;
1196 case 3:
1197 mmc->version = MMC_VERSION_4_3;
1198 break;
1199 case 5:
1200 mmc->version = MMC_VERSION_4_41;
1201 break;
1202 case 6:
1203 mmc->version = MMC_VERSION_4_5;
1204 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001205 case 7:
1206 mmc->version = MMC_VERSION_5_0;
1207 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001208 }
1209
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001210 /* The partition data may be non-zero but it is only
1211 * effective if PARTITION_SETTING_COMPLETED is set in
1212 * EXT_CSD, so ignore any data if this bit is not set,
1213 * except for enabling the high-capacity group size
1214 * definition (see below). */
1215 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1216 EXT_CSD_PARTITION_SETTING_COMPLETED);
1217
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001218 /* store the partition info of emmc */
1219 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1220 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1221 ext_csd[EXT_CSD_BOOT_MULT])
1222 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001223 if (part_completed &&
1224 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001225 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1226
1227 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1228
1229 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1230
1231 for (i = 0; i < 4; i++) {
1232 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001233 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001234 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001235 if (mult)
1236 has_parts = true;
1237 if (!part_completed)
1238 continue;
1239 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001240 mmc->capacity_gp[i] *=
1241 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1242 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001243 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001244 }
1245
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001246 if (part_completed) {
1247 mmc->enh_user_size =
1248 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1249 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1250 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1251 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1252 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1253 mmc->enh_user_size <<= 19;
1254 mmc->enh_user_start =
1255 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1256 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1257 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1258 ext_csd[EXT_CSD_ENH_START_ADDR];
1259 if (mmc->high_capacity)
1260 mmc->enh_user_start <<= 9;
1261 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001262
Lei Wene6f99a52011-06-22 17:03:31 +00001263 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001264 * Host needs to enable ERASE_GRP_DEF bit if device is
1265 * partitioned. This bit will be lost every time after a reset
1266 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001267 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001268 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001269 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001270 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001271 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1272 has_parts = true;
1273 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001274 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1275 EXT_CSD_ERASE_GROUP_DEF, 1);
1276
1277 if (err)
1278 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001279 else
1280 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001281 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001282
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001283 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001284 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001285 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001286 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001287 /*
1288 * if high capacity and partition setting completed
1289 * SEC_COUNT is valid even if it is smaller than 2 GiB
1290 * JEDEC Standard JESD84-B45, 6.2.4
1291 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001292 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001293 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1294 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1295 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1296 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1297 capacity *= MMC_MAX_BLOCK_LEN;
1298 mmc->capacity_user = capacity;
1299 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001300 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001301 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001302 int erase_gsz, erase_gmul;
1303 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1304 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1305 mmc->erase_grp_size = (erase_gsz + 1)
1306 * (erase_gmul + 1);
1307 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001308
1309 mmc->hc_wp_grp_size = 1024
1310 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1311 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001312
1313 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301314 }
1315
Stephen Warrenf866a462013-06-11 15:14:01 -06001316 err = mmc_set_capacity(mmc, mmc->part_num);
1317 if (err)
1318 return err;
1319
Andy Fleming272cc702008-10-30 16:41:01 -05001320 if (IS_SD(mmc))
1321 err = sd_change_freq(mmc);
1322 else
1323 err = mmc_change_freq(mmc);
1324
1325 if (err)
1326 return err;
1327
1328 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001329 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001330
1331 if (IS_SD(mmc)) {
1332 if (mmc->card_caps & MMC_MODE_4BIT) {
1333 cmd.cmdidx = MMC_CMD_APP_CMD;
1334 cmd.resp_type = MMC_RSP_R1;
1335 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001336
1337 err = mmc_send_cmd(mmc, &cmd, NULL);
1338 if (err)
1339 return err;
1340
1341 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1342 cmd.resp_type = MMC_RSP_R1;
1343 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001344 err = mmc_send_cmd(mmc, &cmd, NULL);
1345 if (err)
1346 return err;
1347
1348 mmc_set_bus_width(mmc, 4);
1349 }
1350
1351 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001352 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001353 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001354 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001355 } else if (mmc->version >= MMC_VERSION_4) {
1356 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001357 int idx;
1358
1359 /* An array of possible bus widths in order of preference */
1360 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001361 EXT_CSD_DDR_BUS_WIDTH_8,
1362 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001363 EXT_CSD_BUS_WIDTH_8,
1364 EXT_CSD_BUS_WIDTH_4,
1365 EXT_CSD_BUS_WIDTH_1,
1366 };
1367
1368 /* An array to map CSD bus widths to host cap bits */
1369 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001370 [EXT_CSD_DDR_BUS_WIDTH_4] =
1371 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1372 [EXT_CSD_DDR_BUS_WIDTH_8] =
1373 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001374 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1375 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1376 };
1377
1378 /* An array to map chosen bus width to an integer */
1379 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001380 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001381 };
1382
1383 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1384 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001385 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001386
1387 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001388 * If the bus width is still not changed,
1389 * don't try to set the default again.
1390 * Otherwise, recover from switch attempts
1391 * by switching to 1-bit bus width.
1392 */
1393 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1394 mmc->bus_width == 1) {
1395 err = 0;
1396 break;
1397 }
1398
1399 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001400 * Check to make sure the card and controller support
1401 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001402 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001403 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001404 continue;
1405
Andy Fleming272cc702008-10-30 16:41:01 -05001406 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001407 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001408
1409 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001410 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001411
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001412 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001413 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001414
Lei Wen41378942011-10-03 20:35:11 +00001415 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001416
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001417 if (err)
1418 continue;
1419
1420 /* Only compare read only fields */
1421 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1422 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1423 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1424 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1425 ext_csd[EXT_CSD_REV]
1426 == test_csd[EXT_CSD_REV] &&
1427 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1428 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1429 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1430 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001431 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001432 else
1433 err = SWITCH_ERR;
Andy Fleming272cc702008-10-30 16:41:01 -05001434 }
1435
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001436 if (err)
1437 return err;
1438
Andy Fleming272cc702008-10-30 16:41:01 -05001439 if (mmc->card_caps & MMC_MODE_HS) {
1440 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001441 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001442 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001443 mmc->tran_speed = 26000000;
1444 }
Andy Fleming272cc702008-10-30 16:41:01 -05001445 }
1446
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001447 mmc_set_clock(mmc, mmc->tran_speed);
1448
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001449 /* Fix the block length for DDR mode */
1450 if (mmc->ddr_mode) {
1451 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1452 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1453 }
1454
Andy Fleming272cc702008-10-30 16:41:01 -05001455 /* fill in device description */
1456 mmc->block_dev.lun = 0;
1457 mmc->block_dev.type = 0;
1458 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001459 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301460 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton56196822013-09-04 16:12:25 +01001461#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Huttbabce5f2012-10-20 17:15:59 +00001462 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1463 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1464 (mmc->cid[3] >> 16) & 0xffff);
1465 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1466 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1467 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1468 (mmc->cid[2] >> 24) & 0xff);
1469 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1470 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001471#else
1472 mmc->block_dev.vendor[0] = 0;
1473 mmc->block_dev.product[0] = 0;
1474 mmc->block_dev.revision[0] = 0;
1475#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001476#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001477 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001478#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001479
1480 return 0;
1481}
1482
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001483static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001484{
1485 struct mmc_cmd cmd;
1486 int err;
1487
1488 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1489 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001490 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001491 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001492
1493 err = mmc_send_cmd(mmc, &cmd, NULL);
1494
1495 if (err)
1496 return err;
1497
Rabin Vincent998be3d2009-04-05 13:30:56 +05301498 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001499 return UNUSABLE_ERR;
1500 else
1501 mmc->version = SD_VERSION_2;
1502
1503 return 0;
1504}
1505
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001506/* not used any more */
1507int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001508{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001509#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1510 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1511#endif
1512 return -1;
1513}
1514
1515struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1516{
1517 struct mmc *mmc;
1518
1519 /* quick validation */
1520 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1521 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1522 return NULL;
1523
1524 mmc = calloc(1, sizeof(*mmc));
1525 if (mmc == NULL)
1526 return NULL;
1527
1528 mmc->cfg = cfg;
1529 mmc->priv = priv;
1530
1531 /* the following chunk was mmc_register() */
1532
Markus Niebelab711882013-12-16 13:40:46 +01001533 /* Setup dsr related values */
1534 mmc->dsr_imp = 0;
1535 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001536 /* Setup the universal parts of the block interface just once */
1537 mmc->block_dev.if_type = IF_TYPE_MMC;
1538 mmc->block_dev.dev = cur_dev_num++;
1539 mmc->block_dev.removable = 1;
1540 mmc->block_dev.block_read = mmc_bread;
1541 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001542 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001543
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001544 /* setup initial part type */
1545 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001546
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001547 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001548
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001549 list_add_tail(&mmc->link, &mmc_devices);
1550
1551 return mmc;
1552}
1553
1554void mmc_destroy(struct mmc *mmc)
1555{
1556 /* only freeing memory for now */
1557 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001558}
1559
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001560#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001561block_dev_desc_t *mmc_get_dev(int dev)
1562{
1563 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001564 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001565 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001566
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001567 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001568}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001569#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001570
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001571/* board-specific MMC power initializations. */
1572__weak void board_mmc_power_init(void)
1573{
1574}
1575
Che-Liang Chioue9550442012-11-28 15:21:13 +00001576int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001577{
Macpaul Linafd59322011-11-14 23:35:39 +00001578 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001579
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001580 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001581 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001582 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001583#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001584 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001585#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001586 return NO_CARD_ERR;
1587 }
1588
Lei Wenbc897b12011-05-02 16:26:26 +00001589 if (mmc->has_init)
1590 return 0;
1591
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001592 board_mmc_power_init();
1593
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001594 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001595 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001596
1597 if (err)
1598 return err;
1599
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001600 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001601 mmc_set_bus_width(mmc, 1);
1602 mmc_set_clock(mmc, 1);
1603
Andy Fleming272cc702008-10-30 16:41:01 -05001604 /* Reset the Card */
1605 err = mmc_go_idle(mmc);
1606
1607 if (err)
1608 return err;
1609
Lei Wenbc897b12011-05-02 16:26:26 +00001610 /* The internal partition reset to user partition(0) at every CMD0*/
1611 mmc->part_num = 0;
1612
Andy Fleming272cc702008-10-30 16:41:01 -05001613 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001614 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001615
Andy Fleming272cc702008-10-30 16:41:01 -05001616 /* Now try to get the SD card's operating condition */
1617 err = sd_send_op_cond(mmc);
1618
1619 /* If the command timed out, we check for an MMC card */
1620 if (err == TIMEOUT) {
1621 err = mmc_send_op_cond(mmc);
1622
Che-Liang Chioue9550442012-11-28 15:21:13 +00001623 if (err && err != IN_PROGRESS) {
Paul Burton56196822013-09-04 16:12:25 +01001624#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001625 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001626#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001627 return UNUSABLE_ERR;
1628 }
1629 }
1630
Che-Liang Chioue9550442012-11-28 15:21:13 +00001631 if (err == IN_PROGRESS)
1632 mmc->init_in_progress = 1;
1633
1634 return err;
1635}
1636
1637static int mmc_complete_init(struct mmc *mmc)
1638{
1639 int err = 0;
1640
1641 if (mmc->op_cond_pending)
1642 err = mmc_complete_op_cond(mmc);
1643
1644 if (!err)
1645 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001646 if (err)
1647 mmc->has_init = 0;
1648 else
1649 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001650 mmc->init_in_progress = 0;
1651 return err;
1652}
1653
1654int mmc_init(struct mmc *mmc)
1655{
1656 int err = IN_PROGRESS;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001657 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001658
1659 if (mmc->has_init)
1660 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001661
1662 start = get_timer(0);
1663
Che-Liang Chioue9550442012-11-28 15:21:13 +00001664 if (!mmc->init_in_progress)
1665 err = mmc_start_init(mmc);
1666
1667 if (!err || err == IN_PROGRESS)
1668 err = mmc_complete_init(mmc);
1669 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001670 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001671}
1672
Markus Niebelab711882013-12-16 13:40:46 +01001673int mmc_set_dsr(struct mmc *mmc, u16 val)
1674{
1675 mmc->dsr = val;
1676 return 0;
1677}
1678
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001679/* CPU-specific MMC initializations */
1680__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001681{
1682 return -1;
1683}
1684
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001685/* board-specific MMC initializations. */
1686__weak int board_mmc_init(bd_t *bis)
1687{
1688 return -1;
1689}
Andy Fleming272cc702008-10-30 16:41:01 -05001690
Paul Burton56196822013-09-04 16:12:25 +01001691#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1692
Andy Fleming272cc702008-10-30 16:41:01 -05001693void print_mmc_devices(char separator)
1694{
1695 struct mmc *m;
1696 struct list_head *entry;
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001697 char *mmc_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001698
1699 list_for_each(entry, &mmc_devices) {
1700 m = list_entry(entry, struct mmc, link);
1701
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001702 if (m->has_init)
1703 mmc_type = IS_SD(m) ? "SD" : "eMMC";
1704 else
1705 mmc_type = NULL;
1706
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001707 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001708 if (mmc_type)
1709 printf(" (%s)", mmc_type);
Andy Fleming272cc702008-10-30 16:41:01 -05001710
Lubomir Popove75eaf12014-11-11 12:25:42 +02001711 if (entry->next != &mmc_devices) {
1712 printf("%c", separator);
1713 if (separator != '\n')
1714 puts (" ");
1715 }
Andy Fleming272cc702008-10-30 16:41:01 -05001716 }
1717
1718 printf("\n");
1719}
1720
Paul Burton56196822013-09-04 16:12:25 +01001721#else
1722void print_mmc_devices(char separator) { }
1723#endif
1724
Lei Wenea6ebe22011-05-02 16:26:25 +00001725int get_mmc_num(void)
1726{
1727 return cur_dev_num;
1728}
1729
Che-Liang Chioue9550442012-11-28 15:21:13 +00001730void mmc_set_preinit(struct mmc *mmc, int preinit)
1731{
1732 mmc->preinit = preinit;
1733}
1734
1735static void do_preinit(void)
1736{
1737 struct mmc *m;
1738 struct list_head *entry;
1739
1740 list_for_each(entry, &mmc_devices) {
1741 m = list_entry(entry, struct mmc, link);
1742
1743 if (m->preinit)
1744 mmc_start_init(m);
1745 }
1746}
1747
1748
Andy Fleming272cc702008-10-30 16:41:01 -05001749int mmc_initialize(bd_t *bis)
1750{
1751 INIT_LIST_HEAD (&mmc_devices);
1752 cur_dev_num = 0;
1753
1754 if (board_mmc_init(bis) < 0)
1755 cpu_mmc_init(bis);
1756
Ying Zhangbb0dc102013-08-16 15:16:11 +08001757#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001758 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001759#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001760
Che-Liang Chioue9550442012-11-28 15:21:13 +00001761 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001762 return 0;
1763}
Amar3690d6d2013-04-27 11:42:58 +05301764
1765#ifdef CONFIG_SUPPORT_EMMC_BOOT
1766/*
1767 * This function changes the size of boot partition and the size of rpmb
1768 * partition present on EMMC devices.
1769 *
1770 * Input Parameters:
1771 * struct *mmc: pointer for the mmc device strcuture
1772 * bootsize: size of boot partition
1773 * rpmbsize: size of rpmb partition
1774 *
1775 * Returns 0 on success.
1776 */
1777
1778int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1779 unsigned long rpmbsize)
1780{
1781 int err;
1782 struct mmc_cmd cmd;
1783
1784 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1785 cmd.cmdidx = MMC_CMD_RES_MAN;
1786 cmd.resp_type = MMC_RSP_R1b;
1787 cmd.cmdarg = MMC_CMD62_ARG1;
1788
1789 err = mmc_send_cmd(mmc, &cmd, NULL);
1790 if (err) {
1791 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1792 return err;
1793 }
1794
1795 /* Boot partition changing mode */
1796 cmd.cmdidx = MMC_CMD_RES_MAN;
1797 cmd.resp_type = MMC_RSP_R1b;
1798 cmd.cmdarg = MMC_CMD62_ARG2;
1799
1800 err = mmc_send_cmd(mmc, &cmd, NULL);
1801 if (err) {
1802 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1803 return err;
1804 }
1805 /* boot partition size is multiple of 128KB */
1806 bootsize = (bootsize * 1024) / 128;
1807
1808 /* Arg: boot partition size */
1809 cmd.cmdidx = MMC_CMD_RES_MAN;
1810 cmd.resp_type = MMC_RSP_R1b;
1811 cmd.cmdarg = bootsize;
1812
1813 err = mmc_send_cmd(mmc, &cmd, NULL);
1814 if (err) {
1815 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1816 return err;
1817 }
1818 /* RPMB partition size is multiple of 128KB */
1819 rpmbsize = (rpmbsize * 1024) / 128;
1820 /* Arg: RPMB partition size */
1821 cmd.cmdidx = MMC_CMD_RES_MAN;
1822 cmd.resp_type = MMC_RSP_R1b;
1823 cmd.cmdarg = rpmbsize;
1824
1825 err = mmc_send_cmd(mmc, &cmd, NULL);
1826 if (err) {
1827 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1828 return err;
1829 }
1830 return 0;
1831}
1832
1833/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001834 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1835 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1836 * and BOOT_MODE.
1837 *
1838 * Returns 0 on success.
1839 */
1840int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1841{
1842 int err;
1843
1844 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1845 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1846 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1847 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1848
1849 if (err)
1850 return err;
1851 return 0;
1852}
1853
1854/*
Tom Rini792970b2014-02-05 10:24:21 -05001855 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1856 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1857 * PARTITION_ACCESS.
1858 *
1859 * Returns 0 on success.
1860 */
1861int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1862{
1863 int err;
1864
1865 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1866 EXT_CSD_BOOT_ACK(ack) |
1867 EXT_CSD_BOOT_PART_NUM(part_num) |
1868 EXT_CSD_PARTITION_ACCESS(access));
1869
1870 if (err)
1871 return err;
1872 return 0;
1873}
Tom Rini33ace362014-02-07 14:15:20 -05001874
1875/*
1876 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1877 * for enable. Note that this is a write-once field for non-zero values.
1878 *
1879 * Returns 0 on success.
1880 */
1881int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1882{
1883 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1884 enable);
1885}
Amar3690d6d2013-04-27 11:42:58 +05301886#endif