blob: 3a34028c9177ef1d917910dfd61a7c4b14e12749 [file] [log] [blame]
Andy Fleming272cc702008-10-30 16:41:01 -05001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Based vaguely on the Linux code
6 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Andy Fleming272cc702008-10-30 16:41:01 -05008 */
9
10#include <config.h>
11#include <common.h>
12#include <command.h>
Sjoerd Simons8e3332e2015-08-30 16:55:45 -060013#include <dm.h>
14#include <dm/device-internal.h>
Stephen Warrend4622df2014-05-23 12:47:06 -060015#include <errno.h>
Andy Fleming272cc702008-10-30 16:41:01 -050016#include <mmc.h>
17#include <part.h>
18#include <malloc.h>
Simon Glasscf92e052015-09-02 17:24:58 -060019#include <memalign.h>
Andy Fleming272cc702008-10-30 16:41:01 -050020#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053021#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010022#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050023
24static struct list_head mmc_devices;
25static int cur_dev_num = -1;
26
Jeroen Hofstee750121c2014-07-12 21:24:08 +020027__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000028{
29 return -1;
30}
31
32int mmc_getwp(struct mmc *mmc)
33{
34 int wp;
35
36 wp = board_mmc_getwp(mmc);
37
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000038 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020039 if (mmc->cfg->ops->getwp)
40 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000041 else
42 wp = 0;
43 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000044
45 return wp;
46}
47
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020048__weak int board_mmc_getcd(struct mmc *mmc)
49{
Stefano Babic11fdade2010-02-05 15:04:43 +010050 return -1;
51}
52
Paul Burtonda61fa52013-09-09 15:30:26 +010053int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
Andy Fleming272cc702008-10-30 16:41:01 -050054{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000055 int ret;
Marek Vasut8635ff92012-03-15 18:41:35 +000056
Marek Vasut8635ff92012-03-15 18:41:35 +000057#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000058 int i;
59 u8 *ptr;
60
61 printf("CMD_SEND:%d\n", cmd->cmdidx);
62 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020063 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000064 switch (cmd->resp_type) {
65 case MMC_RSP_NONE:
66 printf("\t\tMMC_RSP_NONE\n");
67 break;
68 case MMC_RSP_R1:
69 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
70 cmd->response[0]);
71 break;
72 case MMC_RSP_R1b:
73 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
74 cmd->response[0]);
75 break;
76 case MMC_RSP_R2:
77 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
78 cmd->response[0]);
79 printf("\t\t \t\t 0x%08X \n",
80 cmd->response[1]);
81 printf("\t\t \t\t 0x%08X \n",
82 cmd->response[2]);
83 printf("\t\t \t\t 0x%08X \n",
84 cmd->response[3]);
85 printf("\n");
86 printf("\t\t\t\t\tDUMPING DATA\n");
87 for (i = 0; i < 4; i++) {
88 int j;
89 printf("\t\t\t\t\t%03d - ", i*4);
Dirk Behme146bec72012-03-08 02:35:34 +000090 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000091 ptr += 3;
92 for (j = 0; j < 4; j++)
93 printf("%02X ", *ptr--);
94 printf("\n");
95 }
96 break;
97 case MMC_RSP_R3:
98 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
99 cmd->response[0]);
100 break;
101 default:
102 printf("\t\tERROR MMC rsp not supported\n");
103 break;
104 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000105#else
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200106 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000107#endif
Marek Vasut8635ff92012-03-15 18:41:35 +0000108 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500109}
110
Paul Burtonda61fa52013-09-09 15:30:26 +0100111int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000112{
113 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000114 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000115#ifdef CONFIG_MMC_TRACE
116 int status;
117#endif
118
119 cmd.cmdidx = MMC_CMD_SEND_STATUS;
120 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200121 if (!mmc_host_is_spi(mmc))
122 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000123
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500124 while (1) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000125 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000126 if (!err) {
127 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
128 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
129 MMC_STATE_PRG)
130 break;
131 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton56196822013-09-04 16:12:25 +0100132#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000133 printf("Status Error: 0x%08X\n",
134 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100135#endif
Jan Kloetzked617c422012-02-05 22:29:12 +0000136 return COMM_ERR;
137 }
138 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000139 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000140
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500141 if (timeout-- <= 0)
142 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000143
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500144 udelay(1000);
145 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000146
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000147#ifdef CONFIG_MMC_TRACE
148 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
149 printf("CURR STATE:%d\n", status);
150#endif
Jongman Heo5b0c9422012-06-03 21:32:13 +0000151 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100152#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000153 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100154#endif
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000155 return TIMEOUT;
156 }
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500157 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
158 return SWITCH_ERR;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000159
160 return 0;
161}
162
Paul Burtonda61fa52013-09-09 15:30:26 +0100163int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500164{
165 struct mmc_cmd cmd;
166
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600167 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900168 return 0;
169
Andy Fleming272cc702008-10-30 16:41:01 -0500170 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
171 cmd.resp_type = MMC_RSP_R1;
172 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500173
174 return mmc_send_cmd(mmc, &cmd, NULL);
175}
176
177struct mmc *find_mmc_device(int dev_num)
178{
179 struct mmc *m;
180 struct list_head *entry;
181
182 list_for_each(entry, &mmc_devices) {
183 m = list_entry(entry, struct mmc, link);
184
185 if (m->block_dev.dev == dev_num)
186 return m;
187 }
188
Paul Burton56196822013-09-04 16:12:25 +0100189#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -0500190 printf("MMC Device %d not found\n", dev_num);
Paul Burton56196822013-09-04 16:12:25 +0100191#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500192
193 return NULL;
194}
195
Sascha Silbeff8fef52013-06-14 13:07:25 +0200196static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000197 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500198{
199 struct mmc_cmd cmd;
200 struct mmc_data data;
201
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700202 if (blkcnt > 1)
203 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
204 else
205 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500206
207 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700208 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500209 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700210 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500211
212 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500213
214 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700215 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500216 data.blocksize = mmc->read_bl_len;
217 data.flags = MMC_DATA_READ;
218
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700219 if (mmc_send_cmd(mmc, &cmd, &data))
220 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500221
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700222 if (blkcnt > 1) {
223 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
224 cmd.cmdarg = 0;
225 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700226 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100227#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700228 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100229#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700230 return 0;
231 }
Andy Fleming272cc702008-10-30 16:41:01 -0500232 }
233
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700234 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500235}
236
Sascha Silbeff8fef52013-06-14 13:07:25 +0200237static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Fleming272cc702008-10-30 16:41:01 -0500238{
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700239 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500240
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700241 if (blkcnt == 0)
242 return 0;
243
244 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500245 if (!mmc)
246 return 0;
247
Lei Wend2bf29e2010-09-13 22:07:27 +0800248 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton56196822013-09-04 16:12:25 +0100249#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200250 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wend2bf29e2010-09-13 22:07:27 +0800251 start + blkcnt, mmc->block_dev.lba);
Paul Burton56196822013-09-04 16:12:25 +0100252#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800253 return 0;
254 }
Andy Fleming272cc702008-10-30 16:41:01 -0500255
Simon Glass11692992015-06-23 15:38:50 -0600256 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
257 debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500258 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600259 }
Andy Fleming272cc702008-10-30 16:41:01 -0500260
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700261 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200262 cur = (blocks_todo > mmc->cfg->b_max) ?
263 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600264 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
265 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700266 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600267 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700268 blocks_todo -= cur;
269 start += cur;
270 dst += cur * mmc->read_bl_len;
271 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500272
273 return blkcnt;
274}
275
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000276static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500277{
278 struct mmc_cmd cmd;
279 int err;
280
281 udelay(1000);
282
283 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
284 cmd.cmdarg = 0;
285 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500286
287 err = mmc_send_cmd(mmc, &cmd, NULL);
288
289 if (err)
290 return err;
291
292 udelay(2000);
293
294 return 0;
295}
296
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000297static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500298{
299 int timeout = 1000;
300 int err;
301 struct mmc_cmd cmd;
302
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500303 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500304 cmd.cmdidx = MMC_CMD_APP_CMD;
305 cmd.resp_type = MMC_RSP_R1;
306 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500307
308 err = mmc_send_cmd(mmc, &cmd, NULL);
309
310 if (err)
311 return err;
312
313 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
314 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100315
316 /*
317 * Most cards do not answer if some reserved bits
318 * in the ocr are set. However, Some controller
319 * can set bit 7 (reserved for low voltages), but
320 * how to manage low voltages SD card is not yet
321 * specified.
322 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000323 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200324 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500325
326 if (mmc->version == SD_VERSION_2)
327 cmd.cmdarg |= OCR_HCS;
328
329 err = mmc_send_cmd(mmc, &cmd, NULL);
330
331 if (err)
332 return err;
333
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500334 if (cmd.response[0] & OCR_BUSY)
335 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500336
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500337 if (timeout-- <= 0)
338 return UNUSABLE_ERR;
339
340 udelay(1000);
341 }
Andy Fleming272cc702008-10-30 16:41:01 -0500342
343 if (mmc->version != SD_VERSION_2)
344 mmc->version = SD_VERSION_1_0;
345
Thomas Choud52ebf12010-12-24 13:12:21 +0000346 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
347 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
348 cmd.resp_type = MMC_RSP_R3;
349 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000350
351 err = mmc_send_cmd(mmc, &cmd, NULL);
352
353 if (err)
354 return err;
355 }
356
Rabin Vincent998be3d2009-04-05 13:30:56 +0530357 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500358
359 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
360 mmc->rca = 0;
361
362 return 0;
363}
364
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500365static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500366{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500367 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500368 int err;
369
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500370 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
371 cmd.resp_type = MMC_RSP_R3;
372 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500373 if (use_arg && !mmc_host_is_spi(mmc))
374 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200375 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500376 (mmc->ocr & OCR_VOLTAGE_MASK)) |
377 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000378
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500379 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000380 if (err)
381 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500382 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000383 return 0;
384}
385
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200386static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000387{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000388 int err, i;
389
Andy Fleming272cc702008-10-30 16:41:01 -0500390 /* Some cards seem to need this */
391 mmc_go_idle(mmc);
392
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000393 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000394 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500395 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500396 if (err)
397 return err;
398
Che-Liang Chioue9550442012-11-28 15:21:13 +0000399 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500400 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500401 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000402 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500403 mmc->op_cond_pending = 1;
404 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000405}
Andy Fleming272cc702008-10-30 16:41:01 -0500406
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200407static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000408{
409 struct mmc_cmd cmd;
410 int timeout = 1000;
411 uint start;
412 int err;
413
414 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500415 if (!(mmc->ocr & OCR_BUSY)) {
416 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500417 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500418 err = mmc_send_op_cond_iter(mmc, 1);
419 if (err)
420 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500421 if (mmc->ocr & OCR_BUSY)
422 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500423 if (get_timer(start) > timeout)
424 return UNUSABLE_ERR;
425 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500426 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500427 }
Andy Fleming272cc702008-10-30 16:41:01 -0500428
Thomas Choud52ebf12010-12-24 13:12:21 +0000429 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
430 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
431 cmd.resp_type = MMC_RSP_R3;
432 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000433
434 err = mmc_send_cmd(mmc, &cmd, NULL);
435
436 if (err)
437 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500438
439 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000440 }
441
Andy Fleming272cc702008-10-30 16:41:01 -0500442 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500443
444 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700445 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500446
447 return 0;
448}
449
450
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000451static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500452{
453 struct mmc_cmd cmd;
454 struct mmc_data data;
455 int err;
456
457 /* Get the Card Status Register */
458 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
459 cmd.resp_type = MMC_RSP_R1;
460 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500461
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000462 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500463 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000464 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500465 data.flags = MMC_DATA_READ;
466
467 err = mmc_send_cmd(mmc, &cmd, &data);
468
469 return err;
470}
471
472
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000473static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500474{
475 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000476 int timeout = 1000;
477 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500478
479 cmd.cmdidx = MMC_CMD_SWITCH;
480 cmd.resp_type = MMC_RSP_R1b;
481 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000482 (index << 16) |
483 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500484
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000485 ret = mmc_send_cmd(mmc, &cmd, NULL);
486
487 /* Waiting for the ready status */
Jan Kloetzke93ad0d12012-02-05 22:29:11 +0000488 if (!ret)
489 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000490
491 return ret;
492
Andy Fleming272cc702008-10-30 16:41:01 -0500493}
494
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000495static int mmc_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500496{
Simon Glass8bfa1952013-04-03 08:54:30 +0000497 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Fleming272cc702008-10-30 16:41:01 -0500498 char cardtype;
499 int err;
500
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600501 mmc->card_caps = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500502
Thomas Choud52ebf12010-12-24 13:12:21 +0000503 if (mmc_host_is_spi(mmc))
504 return 0;
505
Andy Fleming272cc702008-10-30 16:41:01 -0500506 /* Only version 4 supports high-speed */
507 if (mmc->version < MMC_VERSION_4)
508 return 0;
509
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600510 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
511
Andy Fleming272cc702008-10-30 16:41:01 -0500512 err = mmc_send_ext_csd(mmc, ext_csd);
513
514 if (err)
515 return err;
516
Lei Wen0560db12011-10-03 20:35:10 +0000517 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -0500518
519 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
520
521 if (err)
Andrew Gabbasov6b2221b2014-04-03 04:34:32 -0500522 return err == SWITCH_ERR ? 0 : err;
Andy Fleming272cc702008-10-30 16:41:01 -0500523
524 /* Now check to see that it worked */
525 err = mmc_send_ext_csd(mmc, ext_csd);
526
527 if (err)
528 return err;
529
530 /* No high-speed support */
Lei Wen0560db12011-10-03 20:35:10 +0000531 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Fleming272cc702008-10-30 16:41:01 -0500532 return 0;
533
534 /* High Speed is set, there are two types: 52MHz and 26MHz */
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900535 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Andrew Gabbasov201d5ac2014-12-01 06:59:10 -0600536 if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900537 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Andy Fleming272cc702008-10-30 16:41:01 -0500538 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900539 } else {
Andy Fleming272cc702008-10-30 16:41:01 -0500540 mmc->card_caps |= MMC_MODE_HS;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900541 }
Andy Fleming272cc702008-10-30 16:41:01 -0500542
543 return 0;
544}
545
Stephen Warrenf866a462013-06-11 15:14:01 -0600546static int mmc_set_capacity(struct mmc *mmc, int part_num)
547{
548 switch (part_num) {
549 case 0:
550 mmc->capacity = mmc->capacity_user;
551 break;
552 case 1:
553 case 2:
554 mmc->capacity = mmc->capacity_boot;
555 break;
556 case 3:
557 mmc->capacity = mmc->capacity_rpmb;
558 break;
559 case 4:
560 case 5:
561 case 6:
562 case 7:
563 mmc->capacity = mmc->capacity_gp[part_num - 4];
564 break;
565 default:
566 return -1;
567 }
568
569 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
570
571 return 0;
572}
573
Stephen Warrend2356282014-05-07 12:19:02 -0600574int mmc_select_hwpart(int dev_num, int hwpart)
575{
576 struct mmc *mmc = find_mmc_device(dev_num);
577 int ret;
578
579 if (!mmc)
Stephen Warrend4622df2014-05-23 12:47:06 -0600580 return -ENODEV;
Stephen Warrend2356282014-05-07 12:19:02 -0600581
582 if (mmc->part_num == hwpart)
583 return 0;
584
585 if (mmc->part_config == MMCPART_NOAVAILABLE) {
586 printf("Card doesn't support part_switch\n");
Stephen Warrend4622df2014-05-23 12:47:06 -0600587 return -EMEDIUMTYPE;
Stephen Warrend2356282014-05-07 12:19:02 -0600588 }
589
590 ret = mmc_switch_part(dev_num, hwpart);
591 if (ret)
Stephen Warrend4622df2014-05-23 12:47:06 -0600592 return ret;
Stephen Warrend2356282014-05-07 12:19:02 -0600593
594 mmc->part_num = hwpart;
595
596 return 0;
597}
598
599
Lei Wenbc897b12011-05-02 16:26:26 +0000600int mmc_switch_part(int dev_num, unsigned int part_num)
601{
602 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrenf866a462013-06-11 15:14:01 -0600603 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000604
605 if (!mmc)
606 return -1;
607
Stephen Warrenf866a462013-06-11 15:14:01 -0600608 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
609 (mmc->part_config & ~PART_ACCESS_MASK)
610 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600611
Peter Bigot6dc93e72014-09-02 18:31:23 -0500612 /*
613 * Set the capacity if the switch succeeded or was intended
614 * to return to representing the raw device.
615 */
616 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
617 ret = mmc_set_capacity(mmc, part_num);
618
619 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000620}
621
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100622int mmc_hwpart_config(struct mmc *mmc,
623 const struct mmc_hwpart_conf *conf,
624 enum mmc_hwpart_conf_mode mode)
625{
626 u8 part_attrs = 0;
627 u32 enh_size_mult;
628 u32 enh_start_addr;
629 u32 gp_size_mult[4];
630 u32 max_enh_size_mult;
631 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100632 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100633 int i, pidx, err;
634 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
635
636 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
637 return -EINVAL;
638
639 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
640 printf("eMMC >= 4.4 required for enhanced user data area\n");
641 return -EMEDIUMTYPE;
642 }
643
644 if (!(mmc->part_support & PART_SUPPORT)) {
645 printf("Card does not support partitioning\n");
646 return -EMEDIUMTYPE;
647 }
648
649 if (!mmc->hc_wp_grp_size) {
650 printf("Card does not define HC WP group size\n");
651 return -EMEDIUMTYPE;
652 }
653
654 /* check partition alignment and total enhanced size */
655 if (conf->user.enh_size) {
656 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
657 conf->user.enh_start % mmc->hc_wp_grp_size) {
658 printf("User data enhanced area not HC WP group "
659 "size aligned\n");
660 return -EINVAL;
661 }
662 part_attrs |= EXT_CSD_ENH_USR;
663 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
664 if (mmc->high_capacity) {
665 enh_start_addr = conf->user.enh_start;
666 } else {
667 enh_start_addr = (conf->user.enh_start << 9);
668 }
669 } else {
670 enh_size_mult = 0;
671 enh_start_addr = 0;
672 }
673 tot_enh_size_mult += enh_size_mult;
674
675 for (pidx = 0; pidx < 4; pidx++) {
676 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
677 printf("GP%i partition not HC WP group size "
678 "aligned\n", pidx+1);
679 return -EINVAL;
680 }
681 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
682 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
683 part_attrs |= EXT_CSD_ENH_GP(pidx);
684 tot_enh_size_mult += gp_size_mult[pidx];
685 }
686 }
687
688 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
689 printf("Card does not support enhanced attribute\n");
690 return -EMEDIUMTYPE;
691 }
692
693 err = mmc_send_ext_csd(mmc, ext_csd);
694 if (err)
695 return err;
696
697 max_enh_size_mult =
698 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
699 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
700 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
701 if (tot_enh_size_mult > max_enh_size_mult) {
702 printf("Total enhanced size exceeds maximum (%u > %u)\n",
703 tot_enh_size_mult, max_enh_size_mult);
704 return -EMEDIUMTYPE;
705 }
706
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100707 /* The default value of EXT_CSD_WR_REL_SET is device
708 * dependent, the values can only be changed if the
709 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
710 * changed only once and before partitioning is completed. */
711 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
712 if (conf->user.wr_rel_change) {
713 if (conf->user.wr_rel_set)
714 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
715 else
716 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
717 }
718 for (pidx = 0; pidx < 4; pidx++) {
719 if (conf->gp_part[pidx].wr_rel_change) {
720 if (conf->gp_part[pidx].wr_rel_set)
721 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
722 else
723 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
724 }
725 }
726
727 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
728 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
729 puts("Card does not support host controlled partition write "
730 "reliability settings\n");
731 return -EMEDIUMTYPE;
732 }
733
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100734 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
735 EXT_CSD_PARTITION_SETTING_COMPLETED) {
736 printf("Card already partitioned\n");
737 return -EPERM;
738 }
739
740 if (mode == MMC_HWPART_CONF_CHECK)
741 return 0;
742
743 /* Partitioning requires high-capacity size definitions */
744 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
745 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
746 EXT_CSD_ERASE_GROUP_DEF, 1);
747
748 if (err)
749 return err;
750
751 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
752
753 /* update erase group size to be high-capacity */
754 mmc->erase_grp_size =
755 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
756
757 }
758
759 /* all OK, write the configuration */
760 for (i = 0; i < 4; i++) {
761 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
762 EXT_CSD_ENH_START_ADDR+i,
763 (enh_start_addr >> (i*8)) & 0xFF);
764 if (err)
765 return err;
766 }
767 for (i = 0; i < 3; i++) {
768 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
769 EXT_CSD_ENH_SIZE_MULT+i,
770 (enh_size_mult >> (i*8)) & 0xFF);
771 if (err)
772 return err;
773 }
774 for (pidx = 0; pidx < 4; pidx++) {
775 for (i = 0; i < 3; i++) {
776 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
777 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
778 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
779 if (err)
780 return err;
781 }
782 }
783 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
784 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
785 if (err)
786 return err;
787
788 if (mode == MMC_HWPART_CONF_SET)
789 return 0;
790
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100791 /* The WR_REL_SET is a write-once register but shall be
792 * written before setting PART_SETTING_COMPLETED. As it is
793 * write-once we can only write it when completing the
794 * partitioning. */
795 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
796 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
797 EXT_CSD_WR_REL_SET, wr_rel_set);
798 if (err)
799 return err;
800 }
801
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100802 /* Setting PART_SETTING_COMPLETED confirms the partition
803 * configuration but it only becomes effective after power
804 * cycle, so we do not adjust the partition related settings
805 * in the mmc struct. */
806
807 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
808 EXT_CSD_PARTITION_SETTING,
809 EXT_CSD_PARTITION_SETTING_COMPLETED);
810 if (err)
811 return err;
812
813 return 0;
814}
815
Thierry Reding48972d92012-01-02 01:15:37 +0000816int mmc_getcd(struct mmc *mmc)
817{
818 int cd;
819
820 cd = board_mmc_getcd(mmc);
821
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000822 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200823 if (mmc->cfg->ops->getcd)
824 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000825 else
826 cd = 1;
827 }
Thierry Reding48972d92012-01-02 01:15:37 +0000828
829 return cd;
830}
831
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000832static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500833{
834 struct mmc_cmd cmd;
835 struct mmc_data data;
836
837 /* Switch the frequency */
838 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
839 cmd.resp_type = MMC_RSP_R1;
840 cmd.cmdarg = (mode << 31) | 0xffffff;
841 cmd.cmdarg &= ~(0xf << (group * 4));
842 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500843
844 data.dest = (char *)resp;
845 data.blocksize = 64;
846 data.blocks = 1;
847 data.flags = MMC_DATA_READ;
848
849 return mmc_send_cmd(mmc, &cmd, &data);
850}
851
852
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000853static int sd_change_freq(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500854{
855 int err;
856 struct mmc_cmd cmd;
Anton staaff781dd32011-10-03 13:54:59 +0000857 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
858 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500859 struct mmc_data data;
860 int timeout;
861
862 mmc->card_caps = 0;
863
Thomas Choud52ebf12010-12-24 13:12:21 +0000864 if (mmc_host_is_spi(mmc))
865 return 0;
866
Andy Fleming272cc702008-10-30 16:41:01 -0500867 /* Read the SCR to find out if this card supports higher speeds */
868 cmd.cmdidx = MMC_CMD_APP_CMD;
869 cmd.resp_type = MMC_RSP_R1;
870 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500871
872 err = mmc_send_cmd(mmc, &cmd, NULL);
873
874 if (err)
875 return err;
876
877 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
878 cmd.resp_type = MMC_RSP_R1;
879 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500880
881 timeout = 3;
882
883retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +0000884 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -0500885 data.blocksize = 8;
886 data.blocks = 1;
887 data.flags = MMC_DATA_READ;
888
889 err = mmc_send_cmd(mmc, &cmd, &data);
890
891 if (err) {
892 if (timeout--)
893 goto retry_scr;
894
895 return err;
896 }
897
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300898 mmc->scr[0] = __be32_to_cpu(scr[0]);
899 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -0500900
901 switch ((mmc->scr[0] >> 24) & 0xf) {
902 case 0:
903 mmc->version = SD_VERSION_1_0;
904 break;
905 case 1:
906 mmc->version = SD_VERSION_1_10;
907 break;
908 case 2:
909 mmc->version = SD_VERSION_2;
Jaehoon Chung1741c642013-01-29 22:58:16 +0000910 if ((mmc->scr[0] >> 15) & 0x1)
911 mmc->version = SD_VERSION_3;
Andy Fleming272cc702008-10-30 16:41:01 -0500912 break;
913 default:
914 mmc->version = SD_VERSION_1_0;
915 break;
916 }
917
Alagu Sankarb44c7082010-05-12 15:08:24 +0530918 if (mmc->scr[0] & SD_DATA_4BIT)
919 mmc->card_caps |= MMC_MODE_4BIT;
920
Andy Fleming272cc702008-10-30 16:41:01 -0500921 /* Version 1.0 doesn't support switching */
922 if (mmc->version == SD_VERSION_1_0)
923 return 0;
924
925 timeout = 4;
926 while (timeout--) {
927 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +0000928 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500929
930 if (err)
931 return err;
932
933 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300934 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -0500935 break;
936 }
937
Andy Fleming272cc702008-10-30 16:41:01 -0500938 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300939 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Fleming272cc702008-10-30 16:41:01 -0500940 return 0;
941
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000942 /*
943 * If the host doesn't support SD_HIGHSPEED, do not switch card to
944 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
945 * This can avoid furthur problem when the card runs in different
946 * mode between the host.
947 */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200948 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
949 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin2c3fbf42011-11-28 16:31:09 +0000950 return 0;
951
Anton staaff781dd32011-10-03 13:54:59 +0000952 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -0500953
954 if (err)
955 return err;
956
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +0300957 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Fleming272cc702008-10-30 16:41:01 -0500958 mmc->card_caps |= MMC_MODE_HS;
959
960 return 0;
961}
962
963/* frequency bases */
964/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000965static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500966 10000,
967 100000,
968 1000000,
969 10000000,
970};
971
972/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
973 * to platforms without floating point.
974 */
Mike Frysinger5f837c22010-10-20 01:15:53 +0000975static const int multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -0500976 0, /* reserved */
977 10,
978 12,
979 13,
980 15,
981 20,
982 25,
983 30,
984 35,
985 40,
986 45,
987 50,
988 55,
989 60,
990 70,
991 80,
992};
993
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000994static void mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500995{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200996 if (mmc->cfg->ops->set_ios)
997 mmc->cfg->ops->set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -0500998}
999
1000void mmc_set_clock(struct mmc *mmc, uint clock)
1001{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001002 if (clock > mmc->cfg->f_max)
1003 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001004
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001005 if (clock < mmc->cfg->f_min)
1006 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001007
1008 mmc->clock = clock;
1009
1010 mmc_set_ios(mmc);
1011}
1012
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001013static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001014{
1015 mmc->bus_width = width;
1016
1017 mmc_set_ios(mmc);
1018}
1019
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001020static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001021{
Stephen Warrenf866a462013-06-11 15:14:01 -06001022 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001023 uint mult, freq;
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001024 u64 cmult, csize, capacity;
Andy Fleming272cc702008-10-30 16:41:01 -05001025 struct mmc_cmd cmd;
Simon Glass8bfa1952013-04-03 08:54:30 +00001026 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1027 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001028 int timeout = 1000;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001029 bool has_parts = false;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001030 bool part_completed;
Andy Fleming272cc702008-10-30 16:41:01 -05001031
Thomas Choud52ebf12010-12-24 13:12:21 +00001032#ifdef CONFIG_MMC_SPI_CRC_ON
1033 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1034 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1035 cmd.resp_type = MMC_RSP_R1;
1036 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001037 err = mmc_send_cmd(mmc, &cmd, NULL);
1038
1039 if (err)
1040 return err;
1041 }
1042#endif
1043
Andy Fleming272cc702008-10-30 16:41:01 -05001044 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001045 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1046 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001047 cmd.resp_type = MMC_RSP_R2;
1048 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001049
1050 err = mmc_send_cmd(mmc, &cmd, NULL);
1051
1052 if (err)
1053 return err;
1054
1055 memcpy(mmc->cid, cmd.response, 16);
1056
1057 /*
1058 * For MMC cards, set the Relative Address.
1059 * For SD cards, get the Relatvie Address.
1060 * This also puts the cards into Standby State
1061 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001062 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1063 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1064 cmd.cmdarg = mmc->rca << 16;
1065 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001066
Thomas Choud52ebf12010-12-24 13:12:21 +00001067 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001068
Thomas Choud52ebf12010-12-24 13:12:21 +00001069 if (err)
1070 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001071
Thomas Choud52ebf12010-12-24 13:12:21 +00001072 if (IS_SD(mmc))
1073 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1074 }
Andy Fleming272cc702008-10-30 16:41:01 -05001075
1076 /* Get the Card-Specific Data */
1077 cmd.cmdidx = MMC_CMD_SEND_CSD;
1078 cmd.resp_type = MMC_RSP_R2;
1079 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001080
1081 err = mmc_send_cmd(mmc, &cmd, NULL);
1082
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +00001083 /* Waiting for the ready status */
1084 mmc_send_status(mmc, timeout);
1085
Andy Fleming272cc702008-10-30 16:41:01 -05001086 if (err)
1087 return err;
1088
Rabin Vincent998be3d2009-04-05 13:30:56 +05301089 mmc->csd[0] = cmd.response[0];
1090 mmc->csd[1] = cmd.response[1];
1091 mmc->csd[2] = cmd.response[2];
1092 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001093
1094 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301095 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001096
1097 switch (version) {
1098 case 0:
1099 mmc->version = MMC_VERSION_1_2;
1100 break;
1101 case 1:
1102 mmc->version = MMC_VERSION_1_4;
1103 break;
1104 case 2:
1105 mmc->version = MMC_VERSION_2_2;
1106 break;
1107 case 3:
1108 mmc->version = MMC_VERSION_3;
1109 break;
1110 case 4:
1111 mmc->version = MMC_VERSION_4;
1112 break;
1113 default:
1114 mmc->version = MMC_VERSION_1_2;
1115 break;
1116 }
1117 }
1118
1119 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301120 freq = fbase[(cmd.response[0] & 0x7)];
1121 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001122
1123 mmc->tran_speed = freq * mult;
1124
Markus Niebelab711882013-12-16 13:40:46 +01001125 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301126 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001127
1128 if (IS_SD(mmc))
1129 mmc->write_bl_len = mmc->read_bl_len;
1130 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301131 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001132
1133 if (mmc->high_capacity) {
1134 csize = (mmc->csd[1] & 0x3f) << 16
1135 | (mmc->csd[2] & 0xffff0000) >> 16;
1136 cmult = 8;
1137 } else {
1138 csize = (mmc->csd[1] & 0x3ff) << 2
1139 | (mmc->csd[2] & 0xc0000000) >> 30;
1140 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1141 }
1142
Stephen Warrenf866a462013-06-11 15:14:01 -06001143 mmc->capacity_user = (csize + 1) << (cmult + 2);
1144 mmc->capacity_user *= mmc->read_bl_len;
1145 mmc->capacity_boot = 0;
1146 mmc->capacity_rpmb = 0;
1147 for (i = 0; i < 4; i++)
1148 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001149
Simon Glass8bfa1952013-04-03 08:54:30 +00001150 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1151 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001152
Simon Glass8bfa1952013-04-03 08:54:30 +00001153 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1154 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001155
Markus Niebelab711882013-12-16 13:40:46 +01001156 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1157 cmd.cmdidx = MMC_CMD_SET_DSR;
1158 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1159 cmd.resp_type = MMC_RSP_NONE;
1160 if (mmc_send_cmd(mmc, &cmd, NULL))
1161 printf("MMC: SET_DSR failed\n");
1162 }
1163
Andy Fleming272cc702008-10-30 16:41:01 -05001164 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001165 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1166 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001167 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001168 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001169 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001170
Thomas Choud52ebf12010-12-24 13:12:21 +00001171 if (err)
1172 return err;
1173 }
Andy Fleming272cc702008-10-30 16:41:01 -05001174
Lei Wene6f99a52011-06-22 17:03:31 +00001175 /*
1176 * For SD, its erase group is always one sector
1177 */
1178 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001179 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301180 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1181 /* check ext_csd version and capacity */
1182 err = mmc_send_ext_csd(mmc, ext_csd);
Diego Santa Cruz9cf199e2014-12-23 10:50:28 +01001183 if (err)
1184 return err;
1185 if (ext_csd[EXT_CSD_REV] >= 2) {
Yoshihiro Shimoda639b7822011-07-04 22:13:26 +00001186 /*
1187 * According to the JEDEC Standard, the value of
1188 * ext_csd's capacity is valid if the value is more
1189 * than 2GB
1190 */
Lei Wen0560db12011-10-03 20:35:10 +00001191 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1192 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1193 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1194 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glass8bfa1952013-04-03 08:54:30 +00001195 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewskib1f1e8212011-07-05 02:19:44 +00001196 if ((capacity >> 20) > 2 * 1024)
Stephen Warrenf866a462013-06-11 15:14:01 -06001197 mmc->capacity_user = capacity;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301198 }
Lei Wenbc897b12011-05-02 16:26:26 +00001199
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001200 switch (ext_csd[EXT_CSD_REV]) {
1201 case 1:
1202 mmc->version = MMC_VERSION_4_1;
1203 break;
1204 case 2:
1205 mmc->version = MMC_VERSION_4_2;
1206 break;
1207 case 3:
1208 mmc->version = MMC_VERSION_4_3;
1209 break;
1210 case 5:
1211 mmc->version = MMC_VERSION_4_41;
1212 break;
1213 case 6:
1214 mmc->version = MMC_VERSION_4_5;
1215 break;
Markus Niebeledab7232014-11-18 15:13:53 +01001216 case 7:
1217 mmc->version = MMC_VERSION_5_0;
1218 break;
Jaehoon Chung64f4a612013-01-29 19:31:16 +00001219 }
1220
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001221 /* The partition data may be non-zero but it is only
1222 * effective if PARTITION_SETTING_COMPLETED is set in
1223 * EXT_CSD, so ignore any data if this bit is not set,
1224 * except for enabling the high-capacity group size
1225 * definition (see below). */
1226 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1227 EXT_CSD_PARTITION_SETTING_COMPLETED);
1228
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001229 /* store the partition info of emmc */
1230 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1231 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1232 ext_csd[EXT_CSD_BOOT_MULT])
1233 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001234 if (part_completed &&
1235 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001236 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1237
1238 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1239
1240 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1241
1242 for (i = 0; i < 4; i++) {
1243 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001244 uint mult = (ext_csd[idx + 2] << 16) +
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001245 (ext_csd[idx + 1] << 8) + ext_csd[idx];
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001246 if (mult)
1247 has_parts = true;
1248 if (!part_completed)
1249 continue;
1250 mmc->capacity_gp[i] = mult;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001251 mmc->capacity_gp[i] *=
1252 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1253 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruzf8e89d62014-12-23 10:50:21 +01001254 mmc->capacity_gp[i] <<= 19;
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001255 }
1256
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001257 if (part_completed) {
1258 mmc->enh_user_size =
1259 (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
1260 (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
1261 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1262 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1263 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1264 mmc->enh_user_size <<= 19;
1265 mmc->enh_user_start =
1266 (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
1267 (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
1268 (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
1269 ext_csd[EXT_CSD_ENH_START_ADDR];
1270 if (mmc->high_capacity)
1271 mmc->enh_user_start <<= 9;
1272 }
Diego Santa Cruza7f852b2014-12-23 10:50:22 +01001273
Lei Wene6f99a52011-06-22 17:03:31 +00001274 /*
Oliver Metz1937e5a2013-10-01 20:32:07 +02001275 * Host needs to enable ERASE_GRP_DEF bit if device is
1276 * partitioned. This bit will be lost every time after a reset
1277 * or power off. This will affect erase size.
Lei Wene6f99a52011-06-22 17:03:31 +00001278 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001279 if (part_completed)
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001280 has_parts = true;
Oliver Metz1937e5a2013-10-01 20:32:07 +02001281 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
Diego Santa Cruz0c453bb2014-12-23 10:50:20 +01001282 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1283 has_parts = true;
1284 if (has_parts) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001285 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1286 EXT_CSD_ERASE_GROUP_DEF, 1);
1287
1288 if (err)
1289 return err;
Hannes Petermaier021a8052014-08-08 09:47:22 +02001290 else
1291 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001292 }
Oliver Metz1937e5a2013-10-01 20:32:07 +02001293
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001294 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001295 /* Read out group size from ext_csd */
Lei Wen0560db12011-10-03 20:35:10 +00001296 mmc->erase_grp_size =
Diego Santa Cruza4ff9f82014-12-23 10:50:24 +01001297 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Markus Niebeld7b29122014-11-18 15:11:42 +01001298 /*
1299 * if high capacity and partition setting completed
1300 * SEC_COUNT is valid even if it is smaller than 2 GiB
1301 * JEDEC Standard JESD84-B45, 6.2.4
1302 */
Diego Santa Cruz8a0cf492014-12-23 10:50:27 +01001303 if (mmc->high_capacity && part_completed) {
Markus Niebeld7b29122014-11-18 15:11:42 +01001304 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1305 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1306 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1307 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1308 capacity *= MMC_MAX_BLOCK_LEN;
1309 mmc->capacity_user = capacity;
1310 }
Simon Glass8bfa1952013-04-03 08:54:30 +00001311 } else {
Oliver Metz1937e5a2013-10-01 20:32:07 +02001312 /* Calculate the group size from the csd value. */
Lei Wene6f99a52011-06-22 17:03:31 +00001313 int erase_gsz, erase_gmul;
1314 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1315 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1316 mmc->erase_grp_size = (erase_gsz + 1)
1317 * (erase_gmul + 1);
1318 }
Diego Santa Cruz037dc0a2014-12-23 10:50:25 +01001319
1320 mmc->hc_wp_grp_size = 1024
1321 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1322 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Diego Santa Cruz9e41a002014-12-23 10:50:33 +01001323
1324 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301325 }
1326
Stephen Warrenf866a462013-06-11 15:14:01 -06001327 err = mmc_set_capacity(mmc, mmc->part_num);
1328 if (err)
1329 return err;
1330
Andy Fleming272cc702008-10-30 16:41:01 -05001331 if (IS_SD(mmc))
1332 err = sd_change_freq(mmc);
1333 else
1334 err = mmc_change_freq(mmc);
1335
1336 if (err)
1337 return err;
1338
1339 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001340 mmc->card_caps &= mmc->cfg->host_caps;
Andy Fleming272cc702008-10-30 16:41:01 -05001341
1342 if (IS_SD(mmc)) {
1343 if (mmc->card_caps & MMC_MODE_4BIT) {
1344 cmd.cmdidx = MMC_CMD_APP_CMD;
1345 cmd.resp_type = MMC_RSP_R1;
1346 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001347
1348 err = mmc_send_cmd(mmc, &cmd, NULL);
1349 if (err)
1350 return err;
1351
1352 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1353 cmd.resp_type = MMC_RSP_R1;
1354 cmd.cmdarg = 2;
Andy Fleming272cc702008-10-30 16:41:01 -05001355 err = mmc_send_cmd(mmc, &cmd, NULL);
1356 if (err)
1357 return err;
1358
1359 mmc_set_bus_width(mmc, 4);
1360 }
1361
1362 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001363 mmc->tran_speed = 50000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001364 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001365 mmc->tran_speed = 25000000;
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -06001366 } else if (mmc->version >= MMC_VERSION_4) {
1367 /* Only version 4 of MMC supports wider bus widths */
Andy Fleming7798f6d2012-10-31 19:02:38 +00001368 int idx;
1369
1370 /* An array of possible bus widths in order of preference */
1371 static unsigned ext_csd_bits[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001372 EXT_CSD_DDR_BUS_WIDTH_8,
1373 EXT_CSD_DDR_BUS_WIDTH_4,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001374 EXT_CSD_BUS_WIDTH_8,
1375 EXT_CSD_BUS_WIDTH_4,
1376 EXT_CSD_BUS_WIDTH_1,
1377 };
1378
1379 /* An array to map CSD bus widths to host cap bits */
1380 static unsigned ext_to_hostcaps[] = {
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001381 [EXT_CSD_DDR_BUS_WIDTH_4] =
1382 MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
1383 [EXT_CSD_DDR_BUS_WIDTH_8] =
1384 MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001385 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1386 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1387 };
1388
1389 /* An array to map chosen bus width to an integer */
1390 static unsigned widths[] = {
Jaehoon Chungd22e3d42014-05-16 13:59:54 +09001391 8, 4, 8, 4, 1,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001392 };
1393
1394 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1395 unsigned int extw = ext_csd_bits[idx];
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001396 unsigned int caps = ext_to_hostcaps[extw];
Andy Fleming7798f6d2012-10-31 19:02:38 +00001397
1398 /*
Andrew Gabbasovbf477072014-12-25 10:22:24 -06001399 * If the bus width is still not changed,
1400 * don't try to set the default again.
1401 * Otherwise, recover from switch attempts
1402 * by switching to 1-bit bus width.
1403 */
1404 if (extw == EXT_CSD_BUS_WIDTH_1 &&
1405 mmc->bus_width == 1) {
1406 err = 0;
1407 break;
1408 }
1409
1410 /*
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001411 * Check to make sure the card and controller support
1412 * these capabilities
Andy Fleming7798f6d2012-10-31 19:02:38 +00001413 */
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001414 if ((mmc->card_caps & caps) != caps)
Andy Fleming7798f6d2012-10-31 19:02:38 +00001415 continue;
1416
Andy Fleming272cc702008-10-30 16:41:01 -05001417 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Fleming7798f6d2012-10-31 19:02:38 +00001418 EXT_CSD_BUS_WIDTH, extw);
Andy Fleming272cc702008-10-30 16:41:01 -05001419
1420 if (err)
Lei Wen41378942011-10-03 20:35:11 +00001421 continue;
Andy Fleming272cc702008-10-30 16:41:01 -05001422
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001423 mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
Andy Fleming7798f6d2012-10-31 19:02:38 +00001424 mmc_set_bus_width(mmc, widths[idx]);
Andy Fleming272cc702008-10-30 16:41:01 -05001425
Lei Wen41378942011-10-03 20:35:11 +00001426 err = mmc_send_ext_csd(mmc, test_csd);
Andy Fleming272cc702008-10-30 16:41:01 -05001427
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001428 if (err)
1429 continue;
1430
1431 /* Only compare read only fields */
1432 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1433 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1434 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1435 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1436 ext_csd[EXT_CSD_REV]
1437 == test_csd[EXT_CSD_REV] &&
1438 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1439 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1440 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1441 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
Lei Wen41378942011-10-03 20:35:11 +00001442 break;
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001443 else
1444 err = SWITCH_ERR;
Andy Fleming272cc702008-10-30 16:41:01 -05001445 }
1446
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001447 if (err)
1448 return err;
1449
Andy Fleming272cc702008-10-30 16:41:01 -05001450 if (mmc->card_caps & MMC_MODE_HS) {
1451 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001452 mmc->tran_speed = 52000000;
Andy Fleming272cc702008-10-30 16:41:01 -05001453 else
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001454 mmc->tran_speed = 26000000;
1455 }
Andy Fleming272cc702008-10-30 16:41:01 -05001456 }
1457
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001458 mmc_set_clock(mmc, mmc->tran_speed);
1459
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001460 /* Fix the block length for DDR mode */
1461 if (mmc->ddr_mode) {
1462 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1463 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1464 }
1465
Andy Fleming272cc702008-10-30 16:41:01 -05001466 /* fill in device description */
1467 mmc->block_dev.lun = 0;
1468 mmc->block_dev.type = 0;
1469 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001470 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent9b1f9422009-04-05 13:30:54 +05301471 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01001472#if !defined(CONFIG_SPL_BUILD) || \
1473 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1474 !defined(CONFIG_USE_TINY_PRINTF))
Taylor Huttbabce5f2012-10-20 17:15:59 +00001475 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1476 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1477 (mmc->cid[3] >> 16) & 0xffff);
1478 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1479 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1480 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1481 (mmc->cid[2] >> 24) & 0xff);
1482 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1483 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001484#else
1485 mmc->block_dev.vendor[0] = 0;
1486 mmc->block_dev.product[0] = 0;
1487 mmc->block_dev.revision[0] = 0;
1488#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001489#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001490 init_part(&mmc->block_dev);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001491#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001492
1493 return 0;
1494}
1495
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001496static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001497{
1498 struct mmc_cmd cmd;
1499 int err;
1500
1501 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1502 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001503 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001504 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001505
1506 err = mmc_send_cmd(mmc, &cmd, NULL);
1507
1508 if (err)
1509 return err;
1510
Rabin Vincent998be3d2009-04-05 13:30:56 +05301511 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Fleming272cc702008-10-30 16:41:01 -05001512 return UNUSABLE_ERR;
1513 else
1514 mmc->version = SD_VERSION_2;
1515
1516 return 0;
1517}
1518
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001519/* not used any more */
1520int __deprecated mmc_register(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001521{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001522#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1523 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1524#endif
1525 return -1;
1526}
1527
1528struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
1529{
1530 struct mmc *mmc;
1531
1532 /* quick validation */
1533 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1534 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1535 return NULL;
1536
1537 mmc = calloc(1, sizeof(*mmc));
1538 if (mmc == NULL)
1539 return NULL;
1540
1541 mmc->cfg = cfg;
1542 mmc->priv = priv;
1543
1544 /* the following chunk was mmc_register() */
1545
Markus Niebelab711882013-12-16 13:40:46 +01001546 /* Setup dsr related values */
1547 mmc->dsr_imp = 0;
1548 mmc->dsr = 0xffffffff;
Andy Fleming272cc702008-10-30 16:41:01 -05001549 /* Setup the universal parts of the block interface just once */
1550 mmc->block_dev.if_type = IF_TYPE_MMC;
1551 mmc->block_dev.dev = cur_dev_num++;
1552 mmc->block_dev.removable = 1;
1553 mmc->block_dev.block_read = mmc_bread;
1554 mmc->block_dev.block_write = mmc_bwrite;
Lei Wene6f99a52011-06-22 17:03:31 +00001555 mmc->block_dev.block_erase = mmc_berase;
Andy Fleming272cc702008-10-30 16:41:01 -05001556
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001557 /* setup initial part type */
1558 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001559
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001560 INIT_LIST_HEAD(&mmc->link);
Andy Fleming272cc702008-10-30 16:41:01 -05001561
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001562 list_add_tail(&mmc->link, &mmc_devices);
1563
1564 return mmc;
1565}
1566
1567void mmc_destroy(struct mmc *mmc)
1568{
1569 /* only freeing memory for now */
1570 free(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001571}
1572
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001573#ifdef CONFIG_PARTITIONS
Andy Fleming272cc702008-10-30 16:41:01 -05001574block_dev_desc_t *mmc_get_dev(int dev)
1575{
1576 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6bb4b4b2012-08-10 08:59:12 +00001577 if (!mmc || mmc_init(mmc))
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001578 return NULL;
Andy Fleming272cc702008-10-30 16:41:01 -05001579
Łukasz Majewski40242bc2012-04-19 02:39:18 +00001580 return &mmc->block_dev;
Andy Fleming272cc702008-10-30 16:41:01 -05001581}
Matthew McClintockdf3fc522011-05-24 05:31:19 +00001582#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001583
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001584/* board-specific MMC power initializations. */
1585__weak void board_mmc_power_init(void)
1586{
1587}
1588
Che-Liang Chioue9550442012-11-28 15:21:13 +00001589int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001590{
Macpaul Linafd59322011-11-14 23:35:39 +00001591 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05001592
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001593 /* we pretend there's no card when init is NULL */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001594 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Reding48972d92012-01-02 01:15:37 +00001595 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01001596#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00001597 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01001598#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001599 return NO_CARD_ERR;
1600 }
1601
Lei Wenbc897b12011-05-02 16:26:26 +00001602 if (mmc->has_init)
1603 return 0;
1604
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001605#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1606 mmc_adapter_card_type_ident();
1607#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001608 board_mmc_power_init();
1609
Pantelis Antoniouab769f22014-02-26 19:28:45 +02001610 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001611 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001612
1613 if (err)
1614 return err;
1615
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06001616 mmc->ddr_mode = 0;
Ilya Yanokb86b85e2009-06-29 17:53:16 +04001617 mmc_set_bus_width(mmc, 1);
1618 mmc_set_clock(mmc, 1);
1619
Andy Fleming272cc702008-10-30 16:41:01 -05001620 /* Reset the Card */
1621 err = mmc_go_idle(mmc);
1622
1623 if (err)
1624 return err;
1625
Lei Wenbc897b12011-05-02 16:26:26 +00001626 /* The internal partition reset to user partition(0) at every CMD0*/
1627 mmc->part_num = 0;
1628
Andy Fleming272cc702008-10-30 16:41:01 -05001629 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00001630 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001631
Andy Fleming272cc702008-10-30 16:41:01 -05001632 /* Now try to get the SD card's operating condition */
1633 err = sd_send_op_cond(mmc);
1634
1635 /* If the command timed out, we check for an MMC card */
1636 if (err == TIMEOUT) {
1637 err = mmc_send_op_cond(mmc);
1638
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001639 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01001640#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05001641 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01001642#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001643 return UNUSABLE_ERR;
1644 }
1645 }
1646
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001647 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001648 mmc->init_in_progress = 1;
1649
1650 return err;
1651}
1652
1653static int mmc_complete_init(struct mmc *mmc)
1654{
1655 int err = 0;
1656
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001657 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001658 if (mmc->op_cond_pending)
1659 err = mmc_complete_op_cond(mmc);
1660
1661 if (!err)
1662 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00001663 if (err)
1664 mmc->has_init = 0;
1665 else
1666 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001667 return err;
1668}
1669
1670int mmc_init(struct mmc *mmc)
1671{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001672 int err = 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001673 unsigned start;
Che-Liang Chioue9550442012-11-28 15:21:13 +00001674
1675 if (mmc->has_init)
1676 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02001677
1678 start = get_timer(0);
1679
Che-Liang Chioue9550442012-11-28 15:21:13 +00001680 if (!mmc->init_in_progress)
1681 err = mmc_start_init(mmc);
1682
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05001683 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00001684 err = mmc_complete_init(mmc);
1685 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
Lei Wenbc897b12011-05-02 16:26:26 +00001686 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001687}
1688
Markus Niebelab711882013-12-16 13:40:46 +01001689int mmc_set_dsr(struct mmc *mmc, u16 val)
1690{
1691 mmc->dsr = val;
1692 return 0;
1693}
1694
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001695/* CPU-specific MMC initializations */
1696__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05001697{
1698 return -1;
1699}
1700
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02001701/* board-specific MMC initializations. */
1702__weak int board_mmc_init(bd_t *bis)
1703{
1704 return -1;
1705}
Andy Fleming272cc702008-10-30 16:41:01 -05001706
Paul Burton56196822013-09-04 16:12:25 +01001707#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1708
Andy Fleming272cc702008-10-30 16:41:01 -05001709void print_mmc_devices(char separator)
1710{
1711 struct mmc *m;
1712 struct list_head *entry;
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001713 char *mmc_type;
Andy Fleming272cc702008-10-30 16:41:01 -05001714
1715 list_for_each(entry, &mmc_devices) {
1716 m = list_entry(entry, struct mmc, link);
1717
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001718 if (m->has_init)
1719 mmc_type = IS_SD(m) ? "SD" : "eMMC";
1720 else
1721 mmc_type = NULL;
1722
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001723 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Przemyslaw Marczak34dd9282015-02-20 12:29:27 +01001724 if (mmc_type)
1725 printf(" (%s)", mmc_type);
Andy Fleming272cc702008-10-30 16:41:01 -05001726
Lubomir Popove75eaf12014-11-11 12:25:42 +02001727 if (entry->next != &mmc_devices) {
1728 printf("%c", separator);
1729 if (separator != '\n')
1730 puts (" ");
1731 }
Andy Fleming272cc702008-10-30 16:41:01 -05001732 }
1733
1734 printf("\n");
1735}
1736
Paul Burton56196822013-09-04 16:12:25 +01001737#else
1738void print_mmc_devices(char separator) { }
1739#endif
1740
Lei Wenea6ebe22011-05-02 16:26:25 +00001741int get_mmc_num(void)
1742{
1743 return cur_dev_num;
1744}
1745
Che-Liang Chioue9550442012-11-28 15:21:13 +00001746void mmc_set_preinit(struct mmc *mmc, int preinit)
1747{
1748 mmc->preinit = preinit;
1749}
1750
1751static void do_preinit(void)
1752{
1753 struct mmc *m;
1754 struct list_head *entry;
1755
1756 list_for_each(entry, &mmc_devices) {
1757 m = list_entry(entry, struct mmc, link);
1758
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08001759#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
1760 mmc_set_preinit(m, 1);
1761#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001762 if (m->preinit)
1763 mmc_start_init(m);
1764 }
1765}
1766
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001767#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
1768static int mmc_probe(bd_t *bis)
1769{
1770 return 0;
1771}
1772#elif defined(CONFIG_DM_MMC)
1773static int mmc_probe(bd_t *bis)
1774{
1775 int ret;
1776 struct uclass *uc;
1777 struct udevice *m;
1778
1779 ret = uclass_get(UCLASS_MMC, &uc);
1780 if (ret)
1781 return ret;
1782
1783 uclass_foreach_dev(m, uc) {
1784 ret = device_probe(m);
1785 if (ret)
1786 printf("%s - probe failed: %d\n", m->name, ret);
1787 }
1788
1789 return 0;
1790}
1791#else
1792static int mmc_probe(bd_t *bis)
1793{
1794 if (board_mmc_init(bis) < 0)
1795 cpu_mmc_init(bis);
1796
1797 return 0;
1798}
1799#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00001800
Andy Fleming272cc702008-10-30 16:41:01 -05001801int mmc_initialize(bd_t *bis)
1802{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001803 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001804 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02001805 if (initialized) /* Avoid initializing mmc multiple times */
1806 return 0;
1807 initialized = 1;
1808
Andy Fleming272cc702008-10-30 16:41:01 -05001809 INIT_LIST_HEAD (&mmc_devices);
1810 cur_dev_num = 0;
1811
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06001812 ret = mmc_probe(bis);
1813 if (ret)
1814 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001815
Ying Zhangbb0dc102013-08-16 15:16:11 +08001816#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05001817 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08001818#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001819
Che-Liang Chioue9550442012-11-28 15:21:13 +00001820 do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05001821 return 0;
1822}
Amar3690d6d2013-04-27 11:42:58 +05301823
1824#ifdef CONFIG_SUPPORT_EMMC_BOOT
1825/*
1826 * This function changes the size of boot partition and the size of rpmb
1827 * partition present on EMMC devices.
1828 *
1829 * Input Parameters:
1830 * struct *mmc: pointer for the mmc device strcuture
1831 * bootsize: size of boot partition
1832 * rpmbsize: size of rpmb partition
1833 *
1834 * Returns 0 on success.
1835 */
1836
1837int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1838 unsigned long rpmbsize)
1839{
1840 int err;
1841 struct mmc_cmd cmd;
1842
1843 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1844 cmd.cmdidx = MMC_CMD_RES_MAN;
1845 cmd.resp_type = MMC_RSP_R1b;
1846 cmd.cmdarg = MMC_CMD62_ARG1;
1847
1848 err = mmc_send_cmd(mmc, &cmd, NULL);
1849 if (err) {
1850 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1851 return err;
1852 }
1853
1854 /* Boot partition changing mode */
1855 cmd.cmdidx = MMC_CMD_RES_MAN;
1856 cmd.resp_type = MMC_RSP_R1b;
1857 cmd.cmdarg = MMC_CMD62_ARG2;
1858
1859 err = mmc_send_cmd(mmc, &cmd, NULL);
1860 if (err) {
1861 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1862 return err;
1863 }
1864 /* boot partition size is multiple of 128KB */
1865 bootsize = (bootsize * 1024) / 128;
1866
1867 /* Arg: boot partition size */
1868 cmd.cmdidx = MMC_CMD_RES_MAN;
1869 cmd.resp_type = MMC_RSP_R1b;
1870 cmd.cmdarg = bootsize;
1871
1872 err = mmc_send_cmd(mmc, &cmd, NULL);
1873 if (err) {
1874 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1875 return err;
1876 }
1877 /* RPMB partition size is multiple of 128KB */
1878 rpmbsize = (rpmbsize * 1024) / 128;
1879 /* Arg: RPMB partition size */
1880 cmd.cmdidx = MMC_CMD_RES_MAN;
1881 cmd.resp_type = MMC_RSP_R1b;
1882 cmd.cmdarg = rpmbsize;
1883
1884 err = mmc_send_cmd(mmc, &cmd, NULL);
1885 if (err) {
1886 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1887 return err;
1888 }
1889 return 0;
1890}
1891
1892/*
Tom Rini5a99b9d2014-02-05 10:24:22 -05001893 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1894 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1895 * and BOOT_MODE.
1896 *
1897 * Returns 0 on success.
1898 */
1899int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1900{
1901 int err;
1902
1903 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1904 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1905 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1906 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1907
1908 if (err)
1909 return err;
1910 return 0;
1911}
1912
1913/*
Tom Rini792970b2014-02-05 10:24:21 -05001914 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1915 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1916 * PARTITION_ACCESS.
1917 *
1918 * Returns 0 on success.
1919 */
1920int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1921{
1922 int err;
1923
1924 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1925 EXT_CSD_BOOT_ACK(ack) |
1926 EXT_CSD_BOOT_PART_NUM(part_num) |
1927 EXT_CSD_PARTITION_ACCESS(access));
1928
1929 if (err)
1930 return err;
1931 return 0;
1932}
Tom Rini33ace362014-02-07 14:15:20 -05001933
1934/*
1935 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1936 * for enable. Note that this is a write-once field for non-zero values.
1937 *
1938 * Returns 0 on success.
1939 */
1940int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1941{
1942 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1943 enable);
1944}
Amar3690d6d2013-04-27 11:42:58 +05301945#endif