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