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