blob: bb9014dc064296daacd7c548a427dcacac6420c4 [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>
13#include <mmc.h>
14#include <part.h>
15#include <malloc.h>
16#include <linux/list.h>
Rabin Vincent69d4e2c2009-04-05 13:30:54 +053017#include <div64.h>
Paul Burton8d30cc92013-09-09 15:30:26 +010018#include "mmc_private.h"
Andy Flemingad347bb2008-10-30 16:41:01 -050019
20static struct list_head mmc_devices;
21static int cur_dev_num = -1;
22
Nikita Kiryanov020f2612012-12-03 02:19:46 +000023int __weak board_mmc_getwp(struct mmc *mmc)
24{
25 return -1;
26}
27
28int mmc_getwp(struct mmc *mmc)
29{
30 int wp;
31
32 wp = board_mmc_getwp(mmc);
33
Peter Korsgaardf7b15102013-03-21 04:00:03 +000034 if (wp < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +020035 if (mmc->cfg->ops->getwp)
36 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +000037 else
38 wp = 0;
39 }
Nikita Kiryanov020f2612012-12-03 02:19:46 +000040
41 return wp;
42}
43
Thierry Redingd7aebf42012-01-02 01:15:36 +000044int __board_mmc_getcd(struct mmc *mmc) {
Stefano Babic6e00edf2010-02-05 15:04:43 +010045 return -1;
46}
47
Thierry Redingd7aebf42012-01-02 01:15:36 +000048int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
Stefano Babic6e00edf2010-02-05 15:04:43 +010049 alias("__board_mmc_getcd")));
50
Paul Burton8d30cc92013-09-09 15:30:26 +010051int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
Andy Flemingad347bb2008-10-30 16:41:01 -050052{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000053 int ret;
Marek Vasutdccb6082012-03-15 18:41:35 +000054
Marek Vasutdccb6082012-03-15 18:41:35 +000055#ifdef CONFIG_MMC_TRACE
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000056 int i;
57 u8 *ptr;
58
59 printf("CMD_SEND:%d\n", cmd->cmdidx);
60 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
Pantelis Antoniou2c850462014-03-11 19:34:20 +020061 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000062 switch (cmd->resp_type) {
63 case MMC_RSP_NONE:
64 printf("\t\tMMC_RSP_NONE\n");
65 break;
66 case MMC_RSP_R1:
67 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
68 cmd->response[0]);
69 break;
70 case MMC_RSP_R1b:
71 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
72 cmd->response[0]);
73 break;
74 case MMC_RSP_R2:
75 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
76 cmd->response[0]);
77 printf("\t\t \t\t 0x%08X \n",
78 cmd->response[1]);
79 printf("\t\t \t\t 0x%08X \n",
80 cmd->response[2]);
81 printf("\t\t \t\t 0x%08X \n",
82 cmd->response[3]);
83 printf("\n");
84 printf("\t\t\t\t\tDUMPING DATA\n");
85 for (i = 0; i < 4; i++) {
86 int j;
87 printf("\t\t\t\t\t%03d - ", i*4);
Dirk Behmec9cb4a92012-03-08 02:35:34 +000088 ptr = (u8 *)&cmd->response[i];
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000089 ptr += 3;
90 for (j = 0; j < 4; j++)
91 printf("%02X ", *ptr--);
92 printf("\n");
93 }
94 break;
95 case MMC_RSP_R3:
96 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
97 cmd->response[0]);
98 break;
99 default:
100 printf("\t\tERROR MMC rsp not supported\n");
101 break;
102 }
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000103#else
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200104 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000105#endif
Marek Vasutdccb6082012-03-15 18:41:35 +0000106 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500107}
108
Paul Burton8d30cc92013-09-09 15:30:26 +0100109int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000110{
111 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000112 int err, retries = 5;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000113#ifdef CONFIG_MMC_TRACE
114 int status;
115#endif
116
117 cmd.cmdidx = MMC_CMD_SEND_STATUS;
118 cmd.resp_type = MMC_RSP_R1;
Marek Vasutc4427392011-08-10 09:24:48 +0200119 if (!mmc_host_is_spi(mmc))
120 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000121
122 do {
123 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-02-05 22:29:12 +0000124 if (!err) {
125 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
126 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
127 MMC_STATE_PRG)
128 break;
129 else if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100130#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzke31789322012-02-05 22:29:12 +0000131 printf("Status Error: 0x%08X\n",
132 cmd.response[0]);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100133#endif
Jan Kloetzke31789322012-02-05 22:29:12 +0000134 return COMM_ERR;
135 }
136 } else if (--retries < 0)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000137 return err;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000138
139 udelay(1000);
140
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000141 } while (timeout--);
142
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000143#ifdef CONFIG_MMC_TRACE
144 status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
145 printf("CURR STATE:%d\n", status);
146#endif
Jongman Heo1be00d92012-06-03 21:32:13 +0000147 if (timeout <= 0) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100148#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000149 printf("Timeout waiting card ready\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100150#endif
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000151 return TIMEOUT;
152 }
Andrew Gabbasove80682f2014-04-03 04:34:32 -0500153 if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
154 return SWITCH_ERR;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000155
156 return 0;
157}
158
Paul Burton8d30cc92013-09-09 15:30:26 +0100159int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500160{
161 struct mmc_cmd cmd;
162
163 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
164 cmd.resp_type = MMC_RSP_R1;
165 cmd.cmdarg = len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500166
167 return mmc_send_cmd(mmc, &cmd, NULL);
168}
169
170struct mmc *find_mmc_device(int dev_num)
171{
172 struct mmc *m;
173 struct list_head *entry;
174
175 list_for_each(entry, &mmc_devices) {
176 m = list_entry(entry, struct mmc, link);
177
178 if (m->block_dev.dev == dev_num)
179 return m;
180 }
181
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100182#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -0500183 printf("MMC Device %d not found\n", dev_num);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100184#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500185
186 return NULL;
187}
188
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200189static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000190 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500191{
192 struct mmc_cmd cmd;
193 struct mmc_data data;
194
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700195 if (blkcnt > 1)
196 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
197 else
198 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500199
200 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700201 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500202 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700203 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500204
205 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500206
207 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700208 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500209 data.blocksize = mmc->read_bl_len;
210 data.flags = MMC_DATA_READ;
211
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700212 if (mmc_send_cmd(mmc, &cmd, &data))
213 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500214
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700215 if (blkcnt > 1) {
216 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
217 cmd.cmdarg = 0;
218 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700219 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100220#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700221 printf("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100222#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700223 return 0;
224 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500225 }
226
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700227 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500228}
229
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200230static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
Andy Flemingad347bb2008-10-30 16:41:01 -0500231{
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700232 lbaint_t cur, blocks_todo = blkcnt;
233
234 if (blkcnt == 0)
235 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500236
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700237 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500238 if (!mmc)
239 return 0;
240
Lei Wene1cc9c82010-09-13 22:07:27 +0800241 if ((start + blkcnt) > mmc->block_dev.lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100242#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200243 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Lei Wene1cc9c82010-09-13 22:07:27 +0800244 start + blkcnt, mmc->block_dev.lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100245#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800246 return 0;
247 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500248
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700249 if (mmc_set_blocklen(mmc, mmc->read_bl_len))
Andy Flemingad347bb2008-10-30 16:41:01 -0500250 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500251
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700252 do {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200253 cur = (blocks_todo > mmc->cfg->b_max) ?
254 mmc->cfg->b_max : blocks_todo;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700255 if(mmc_read_blocks(mmc, dst, start, cur) != cur)
256 return 0;
257 blocks_todo -= cur;
258 start += cur;
259 dst += cur * mmc->read_bl_len;
260 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500261
262 return blkcnt;
263}
264
Kim Phillips87ea3892012-10-29 13:34:43 +0000265static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500266{
267 struct mmc_cmd cmd;
268 int err;
269
270 udelay(1000);
271
272 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
273 cmd.cmdarg = 0;
274 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500275
276 err = mmc_send_cmd(mmc, &cmd, NULL);
277
278 if (err)
279 return err;
280
281 udelay(2000);
282
283 return 0;
284}
285
Kim Phillips87ea3892012-10-29 13:34:43 +0000286static int sd_send_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500287{
288 int timeout = 1000;
289 int err;
290 struct mmc_cmd cmd;
291
292 do {
293 cmd.cmdidx = MMC_CMD_APP_CMD;
294 cmd.resp_type = MMC_RSP_R1;
295 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500296
297 err = mmc_send_cmd(mmc, &cmd, NULL);
298
299 if (err)
300 return err;
301
302 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
303 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100304
305 /*
306 * Most cards do not answer if some reserved bits
307 * in the ocr are set. However, Some controller
308 * can set bit 7 (reserved for low voltages), but
309 * how to manage low voltages SD card is not yet
310 * specified.
311 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000312 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200313 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500314
315 if (mmc->version == SD_VERSION_2)
316 cmd.cmdarg |= OCR_HCS;
317
318 err = mmc_send_cmd(mmc, &cmd, NULL);
319
320 if (err)
321 return err;
322
323 udelay(1000);
324 } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
325
326 if (timeout <= 0)
327 return UNUSABLE_ERR;
328
329 if (mmc->version != SD_VERSION_2)
330 mmc->version = SD_VERSION_1_0;
331
Thomas Chou1254c3d2010-12-24 13:12:21 +0000332 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
333 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
334 cmd.resp_type = MMC_RSP_R3;
335 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000336
337 err = mmc_send_cmd(mmc, &cmd, NULL);
338
339 if (err)
340 return err;
341 }
342
Rabin Vincentb6eed942009-04-05 13:30:56 +0530343 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500344
345 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
346 mmc->rca = 0;
347
348 return 0;
349}
350
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000351/* We pass in the cmd since otherwise the init seems to fail */
352static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
353 int use_arg)
Andy Flemingad347bb2008-10-30 16:41:01 -0500354{
Andy Flemingad347bb2008-10-30 16:41:01 -0500355 int err;
356
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000357 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
358 cmd->resp_type = MMC_RSP_R3;
359 cmd->cmdarg = 0;
360 if (use_arg && !mmc_host_is_spi(mmc)) {
361 cmd->cmdarg =
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200362 (mmc->cfg->voltages &
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000363 (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
364 (mmc->op_cond_response & OCR_ACCESS_MODE);
365
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200366 if (mmc->cfg->host_caps & MMC_MODE_HC)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000367 cmd->cmdarg |= OCR_HCS;
368 }
369 err = mmc_send_cmd(mmc, cmd, NULL);
370 if (err)
371 return err;
372 mmc->op_cond_response = cmd->response[0];
373 return 0;
374}
375
376int mmc_send_op_cond(struct mmc *mmc)
377{
378 struct mmc_cmd cmd;
379 int err, i;
380
Andy Flemingad347bb2008-10-30 16:41:01 -0500381 /* Some cards seem to need this */
382 mmc_go_idle(mmc);
383
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000384 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000385 mmc->op_cond_pending = 1;
386 for (i = 0; i < 2; i++) {
387 err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
388 if (err)
389 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200390
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000391 /* exit if not busy (flag seems to be inverted) */
392 if (mmc->op_cond_response & OCR_BUSY)
393 return 0;
394 }
395 return IN_PROGRESS;
396}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200397
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000398int mmc_complete_op_cond(struct mmc *mmc)
399{
400 struct mmc_cmd cmd;
401 int timeout = 1000;
402 uint start;
403 int err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200404
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000405 mmc->op_cond_pending = 0;
406 start = get_timer(0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500407 do {
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000408 err = mmc_send_op_cond_iter(mmc, &cmd, 1);
Andy Flemingad347bb2008-10-30 16:41:01 -0500409 if (err)
410 return err;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000411 if (get_timer(start) > timeout)
412 return UNUSABLE_ERR;
413 udelay(100);
414 } while (!(mmc->op_cond_response & OCR_BUSY));
Andy Flemingad347bb2008-10-30 16:41:01 -0500415
Thomas Chou1254c3d2010-12-24 13:12:21 +0000416 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
417 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
418 cmd.resp_type = MMC_RSP_R3;
419 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000420
421 err = mmc_send_cmd(mmc, &cmd, NULL);
422
423 if (err)
424 return err;
425 }
426
Andy Flemingad347bb2008-10-30 16:41:01 -0500427 mmc->version = MMC_VERSION_UNKNOWN;
Rabin Vincentb6eed942009-04-05 13:30:56 +0530428 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500429
430 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700431 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500432
433 return 0;
434}
435
436
Kim Phillips87ea3892012-10-29 13:34:43 +0000437static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500438{
439 struct mmc_cmd cmd;
440 struct mmc_data data;
441 int err;
442
443 /* Get the Card Status Register */
444 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
445 cmd.resp_type = MMC_RSP_R1;
446 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500447
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000448 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500449 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000450 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500451 data.flags = MMC_DATA_READ;
452
453 err = mmc_send_cmd(mmc, &cmd, &data);
454
455 return err;
456}
457
458
Kim Phillips87ea3892012-10-29 13:34:43 +0000459static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Flemingad347bb2008-10-30 16:41:01 -0500460{
461 struct mmc_cmd cmd;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000462 int timeout = 1000;
463 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500464
465 cmd.cmdidx = MMC_CMD_SWITCH;
466 cmd.resp_type = MMC_RSP_R1b;
467 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000468 (index << 16) |
469 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500470
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000471 ret = mmc_send_cmd(mmc, &cmd, NULL);
472
473 /* Waiting for the ready status */
Jan Kloetzke4e929dd2012-02-05 22:29:11 +0000474 if (!ret)
475 ret = mmc_send_status(mmc, timeout);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000476
477 return ret;
478
Andy Flemingad347bb2008-10-30 16:41:01 -0500479}
480
Kim Phillips87ea3892012-10-29 13:34:43 +0000481static int mmc_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500482{
Simon Glassa09c2b72013-04-03 08:54:30 +0000483 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Andy Flemingad347bb2008-10-30 16:41:01 -0500484 char cardtype;
485 int err;
486
487 mmc->card_caps = 0;
488
Thomas Chou1254c3d2010-12-24 13:12:21 +0000489 if (mmc_host_is_spi(mmc))
490 return 0;
491
Andy Flemingad347bb2008-10-30 16:41:01 -0500492 /* Only version 4 supports high-speed */
493 if (mmc->version < MMC_VERSION_4)
494 return 0;
495
Andy Flemingad347bb2008-10-30 16:41:01 -0500496 err = mmc_send_ext_csd(mmc, ext_csd);
497
498 if (err)
499 return err;
500
Lei Wen217467f2011-10-03 20:35:10 +0000501 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500502
503 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
504
505 if (err)
Andrew Gabbasove80682f2014-04-03 04:34:32 -0500506 return err == SWITCH_ERR ? 0 : err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500507
508 /* Now check to see that it worked */
509 err = mmc_send_ext_csd(mmc, ext_csd);
510
511 if (err)
512 return err;
513
514 /* No high-speed support */
Lei Wen217467f2011-10-03 20:35:10 +0000515 if (!ext_csd[EXT_CSD_HS_TIMING])
Andy Flemingad347bb2008-10-30 16:41:01 -0500516 return 0;
517
518 /* High Speed is set, there are two types: 52MHz and 26MHz */
519 if (cardtype & MMC_HS_52MHZ)
520 mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
521 else
522 mmc->card_caps |= MMC_MODE_HS;
523
524 return 0;
525}
526
Stephen Warrene315ae82013-06-11 15:14:01 -0600527static int mmc_set_capacity(struct mmc *mmc, int part_num)
528{
529 switch (part_num) {
530 case 0:
531 mmc->capacity = mmc->capacity_user;
532 break;
533 case 1:
534 case 2:
535 mmc->capacity = mmc->capacity_boot;
536 break;
537 case 3:
538 mmc->capacity = mmc->capacity_rpmb;
539 break;
540 case 4:
541 case 5:
542 case 6:
543 case 7:
544 mmc->capacity = mmc->capacity_gp[part_num - 4];
545 break;
546 default:
547 return -1;
548 }
549
550 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
551
552 return 0;
553}
554
Lei Wen31b99802011-05-02 16:26:26 +0000555int mmc_switch_part(int dev_num, unsigned int part_num)
556{
557 struct mmc *mmc = find_mmc_device(dev_num);
Stephen Warrene315ae82013-06-11 15:14:01 -0600558 int ret;
Lei Wen31b99802011-05-02 16:26:26 +0000559
560 if (!mmc)
561 return -1;
562
Stephen Warrene315ae82013-06-11 15:14:01 -0600563 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
564 (mmc->part_config & ~PART_ACCESS_MASK)
565 | (part_num & PART_ACCESS_MASK));
566 if (ret)
567 return ret;
568
569 return mmc_set_capacity(mmc, part_num);
Lei Wen31b99802011-05-02 16:26:26 +0000570}
571
Thierry Redingb9c8b772012-01-02 01:15:37 +0000572int mmc_getcd(struct mmc *mmc)
573{
574 int cd;
575
576 cd = board_mmc_getcd(mmc);
577
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000578 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200579 if (mmc->cfg->ops->getcd)
580 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +0000581 else
582 cd = 1;
583 }
Thierry Redingb9c8b772012-01-02 01:15:37 +0000584
585 return cd;
586}
587
Kim Phillips87ea3892012-10-29 13:34:43 +0000588static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -0500589{
590 struct mmc_cmd cmd;
591 struct mmc_data data;
592
593 /* Switch the frequency */
594 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
595 cmd.resp_type = MMC_RSP_R1;
596 cmd.cmdarg = (mode << 31) | 0xffffff;
597 cmd.cmdarg &= ~(0xf << (group * 4));
598 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -0500599
600 data.dest = (char *)resp;
601 data.blocksize = 64;
602 data.blocks = 1;
603 data.flags = MMC_DATA_READ;
604
605 return mmc_send_cmd(mmc, &cmd, &data);
606}
607
608
Kim Phillips87ea3892012-10-29 13:34:43 +0000609static int sd_change_freq(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500610{
611 int err;
612 struct mmc_cmd cmd;
Anton staaf9b00f0d2011-10-03 13:54:59 +0000613 ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
614 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -0500615 struct mmc_data data;
616 int timeout;
617
618 mmc->card_caps = 0;
619
Thomas Chou1254c3d2010-12-24 13:12:21 +0000620 if (mmc_host_is_spi(mmc))
621 return 0;
622
Andy Flemingad347bb2008-10-30 16:41:01 -0500623 /* Read the SCR to find out if this card supports higher speeds */
624 cmd.cmdidx = MMC_CMD_APP_CMD;
625 cmd.resp_type = MMC_RSP_R1;
626 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500627
628 err = mmc_send_cmd(mmc, &cmd, NULL);
629
630 if (err)
631 return err;
632
633 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
634 cmd.resp_type = MMC_RSP_R1;
635 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500636
637 timeout = 3;
638
639retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +0000640 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -0500641 data.blocksize = 8;
642 data.blocks = 1;
643 data.flags = MMC_DATA_READ;
644
645 err = mmc_send_cmd(mmc, &cmd, &data);
646
647 if (err) {
648 if (timeout--)
649 goto retry_scr;
650
651 return err;
652 }
653
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300654 mmc->scr[0] = __be32_to_cpu(scr[0]);
655 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -0500656
657 switch ((mmc->scr[0] >> 24) & 0xf) {
658 case 0:
659 mmc->version = SD_VERSION_1_0;
660 break;
661 case 1:
662 mmc->version = SD_VERSION_1_10;
663 break;
664 case 2:
665 mmc->version = SD_VERSION_2;
Jaehoon Chungd552bd12013-01-29 22:58:16 +0000666 if ((mmc->scr[0] >> 15) & 0x1)
667 mmc->version = SD_VERSION_3;
Andy Flemingad347bb2008-10-30 16:41:01 -0500668 break;
669 default:
670 mmc->version = SD_VERSION_1_0;
671 break;
672 }
673
Alagu Sankar24bb5ab2010-05-12 15:08:24 +0530674 if (mmc->scr[0] & SD_DATA_4BIT)
675 mmc->card_caps |= MMC_MODE_4BIT;
676
Andy Flemingad347bb2008-10-30 16:41:01 -0500677 /* Version 1.0 doesn't support switching */
678 if (mmc->version == SD_VERSION_1_0)
679 return 0;
680
681 timeout = 4;
682 while (timeout--) {
683 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +0000684 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500685
686 if (err)
687 return err;
688
689 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300690 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -0500691 break;
692 }
693
Andy Flemingad347bb2008-10-30 16:41:01 -0500694 /* If high-speed isn't supported, we return */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300695 if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
Andy Flemingad347bb2008-10-30 16:41:01 -0500696 return 0;
697
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000698 /*
699 * If the host doesn't support SD_HIGHSPEED, do not switch card to
700 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
701 * This can avoid furthur problem when the card runs in different
702 * mode between the host.
703 */
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200704 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
705 (mmc->cfg->host_caps & MMC_MODE_HS)))
Macpaul Lin24e92ec2011-11-28 16:31:09 +0000706 return 0;
707
Anton staaf9b00f0d2011-10-03 13:54:59 +0000708 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -0500709
710 if (err)
711 return err;
712
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +0300713 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
Andy Flemingad347bb2008-10-30 16:41:01 -0500714 mmc->card_caps |= MMC_MODE_HS;
715
716 return 0;
717}
718
719/* frequency bases */
720/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000721static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500722 10000,
723 100000,
724 1000000,
725 10000000,
726};
727
728/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
729 * to platforms without floating point.
730 */
Mike Frysingerb588caf2010-10-20 01:15:53 +0000731static const int multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -0500732 0, /* reserved */
733 10,
734 12,
735 13,
736 15,
737 20,
738 25,
739 30,
740 35,
741 40,
742 45,
743 50,
744 55,
745 60,
746 70,
747 80,
748};
749
Kim Phillips87ea3892012-10-29 13:34:43 +0000750static void mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500751{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200752 if (mmc->cfg->ops->set_ios)
753 mmc->cfg->ops->set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -0500754}
755
756void mmc_set_clock(struct mmc *mmc, uint clock)
757{
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200758 if (clock > mmc->cfg->f_max)
759 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -0500760
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200761 if (clock < mmc->cfg->f_min)
762 clock = mmc->cfg->f_min;
Andy Flemingad347bb2008-10-30 16:41:01 -0500763
764 mmc->clock = clock;
765
766 mmc_set_ios(mmc);
767}
768
Kim Phillips87ea3892012-10-29 13:34:43 +0000769static void mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -0500770{
771 mmc->bus_width = width;
772
773 mmc_set_ios(mmc);
774}
775
Kim Phillips87ea3892012-10-29 13:34:43 +0000776static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500777{
Stephen Warrene315ae82013-06-11 15:14:01 -0600778 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -0500779 uint mult, freq;
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000780 u64 cmult, csize, capacity;
Andy Flemingad347bb2008-10-30 16:41:01 -0500781 struct mmc_cmd cmd;
Simon Glassa09c2b72013-04-03 08:54:30 +0000782 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
783 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000784 int timeout = 1000;
Andy Flemingad347bb2008-10-30 16:41:01 -0500785
Thomas Chou1254c3d2010-12-24 13:12:21 +0000786#ifdef CONFIG_MMC_SPI_CRC_ON
787 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
788 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
789 cmd.resp_type = MMC_RSP_R1;
790 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000791 err = mmc_send_cmd(mmc, &cmd, NULL);
792
793 if (err)
794 return err;
795 }
796#endif
797
Andy Flemingad347bb2008-10-30 16:41:01 -0500798 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000799 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
800 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -0500801 cmd.resp_type = MMC_RSP_R2;
802 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500803
804 err = mmc_send_cmd(mmc, &cmd, NULL);
805
806 if (err)
807 return err;
808
809 memcpy(mmc->cid, cmd.response, 16);
810
811 /*
812 * For MMC cards, set the Relative Address.
813 * For SD cards, get the Relatvie Address.
814 * This also puts the cards into Standby State
815 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000816 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
817 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
818 cmd.cmdarg = mmc->rca << 16;
819 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -0500820
Thomas Chou1254c3d2010-12-24 13:12:21 +0000821 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500822
Thomas Chou1254c3d2010-12-24 13:12:21 +0000823 if (err)
824 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500825
Thomas Chou1254c3d2010-12-24 13:12:21 +0000826 if (IS_SD(mmc))
827 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
828 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500829
830 /* Get the Card-Specific Data */
831 cmd.cmdidx = MMC_CMD_SEND_CSD;
832 cmd.resp_type = MMC_RSP_R2;
833 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -0500834
835 err = mmc_send_cmd(mmc, &cmd, NULL);
836
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000837 /* Waiting for the ready status */
838 mmc_send_status(mmc, timeout);
839
Andy Flemingad347bb2008-10-30 16:41:01 -0500840 if (err)
841 return err;
842
Rabin Vincentb6eed942009-04-05 13:30:56 +0530843 mmc->csd[0] = cmd.response[0];
844 mmc->csd[1] = cmd.response[1];
845 mmc->csd[2] = cmd.response[2];
846 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -0500847
848 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530849 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -0500850
851 switch (version) {
852 case 0:
853 mmc->version = MMC_VERSION_1_2;
854 break;
855 case 1:
856 mmc->version = MMC_VERSION_1_4;
857 break;
858 case 2:
859 mmc->version = MMC_VERSION_2_2;
860 break;
861 case 3:
862 mmc->version = MMC_VERSION_3;
863 break;
864 case 4:
865 mmc->version = MMC_VERSION_4;
866 break;
867 default:
868 mmc->version = MMC_VERSION_1_2;
869 break;
870 }
871 }
872
873 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +0530874 freq = fbase[(cmd.response[0] & 0x7)];
875 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -0500876
877 mmc->tran_speed = freq * mult;
878
Markus Niebel03951412013-12-16 13:40:46 +0100879 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +0530880 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500881
882 if (IS_SD(mmc))
883 mmc->write_bl_len = mmc->read_bl_len;
884 else
Rabin Vincentb6eed942009-04-05 13:30:56 +0530885 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Flemingad347bb2008-10-30 16:41:01 -0500886
887 if (mmc->high_capacity) {
888 csize = (mmc->csd[1] & 0x3f) << 16
889 | (mmc->csd[2] & 0xffff0000) >> 16;
890 cmult = 8;
891 } else {
892 csize = (mmc->csd[1] & 0x3ff) << 2
893 | (mmc->csd[2] & 0xc0000000) >> 30;
894 cmult = (mmc->csd[2] & 0x00038000) >> 15;
895 }
896
Stephen Warrene315ae82013-06-11 15:14:01 -0600897 mmc->capacity_user = (csize + 1) << (cmult + 2);
898 mmc->capacity_user *= mmc->read_bl_len;
899 mmc->capacity_boot = 0;
900 mmc->capacity_rpmb = 0;
901 for (i = 0; i < 4; i++)
902 mmc->capacity_gp[i] = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500903
Simon Glassa09c2b72013-04-03 08:54:30 +0000904 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
905 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500906
Simon Glassa09c2b72013-04-03 08:54:30 +0000907 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
908 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500909
Markus Niebel03951412013-12-16 13:40:46 +0100910 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
911 cmd.cmdidx = MMC_CMD_SET_DSR;
912 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
913 cmd.resp_type = MMC_RSP_NONE;
914 if (mmc_send_cmd(mmc, &cmd, NULL))
915 printf("MMC: SET_DSR failed\n");
916 }
917
Andy Flemingad347bb2008-10-30 16:41:01 -0500918 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000919 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
920 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +0000921 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000922 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000923 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -0500924
Thomas Chou1254c3d2010-12-24 13:12:21 +0000925 if (err)
926 return err;
927 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500928
Lei Wenea526762011-06-22 17:03:31 +0000929 /*
930 * For SD, its erase group is always one sector
931 */
932 mmc->erase_grp_size = 1;
Lei Wen31b99802011-05-02 16:26:26 +0000933 mmc->part_config = MMCPART_NOAVAILABLE;
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530934 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
935 /* check ext_csd version and capacity */
936 err = mmc_send_ext_csd(mmc, ext_csd);
Kim Phillips87ea3892012-10-29 13:34:43 +0000937 if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
Yoshihiro Shimoda7d88de52011-07-04 22:13:26 +0000938 /*
939 * According to the JEDEC Standard, the value of
940 * ext_csd's capacity is valid if the value is more
941 * than 2GB
942 */
Lei Wen217467f2011-10-03 20:35:10 +0000943 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
944 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
945 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
946 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
Simon Glassa09c2b72013-04-03 08:54:30 +0000947 capacity *= MMC_MAX_BLOCK_LEN;
Łukasz Majewski237823e2011-07-05 02:19:44 +0000948 if ((capacity >> 20) > 2 * 1024)
Stephen Warrene315ae82013-06-11 15:14:01 -0600949 mmc->capacity_user = capacity;
Sukumar Ghorai232293c2010-09-20 18:29:29 +0530950 }
Lei Wen31b99802011-05-02 16:26:26 +0000951
Jaehoon Chung6108ef62013-01-29 19:31:16 +0000952 switch (ext_csd[EXT_CSD_REV]) {
953 case 1:
954 mmc->version = MMC_VERSION_4_1;
955 break;
956 case 2:
957 mmc->version = MMC_VERSION_4_2;
958 break;
959 case 3:
960 mmc->version = MMC_VERSION_4_3;
961 break;
962 case 5:
963 mmc->version = MMC_VERSION_4_41;
964 break;
965 case 6:
966 mmc->version = MMC_VERSION_4_5;
967 break;
968 }
969
Lei Wenea526762011-06-22 17:03:31 +0000970 /*
Oliver Metzb3f14092013-10-01 20:32:07 +0200971 * Host needs to enable ERASE_GRP_DEF bit if device is
972 * partitioned. This bit will be lost every time after a reset
973 * or power off. This will affect erase size.
Lei Wenea526762011-06-22 17:03:31 +0000974 */
Oliver Metzb3f14092013-10-01 20:32:07 +0200975 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
976 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
977 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
978 EXT_CSD_ERASE_GROUP_DEF, 1);
979
980 if (err)
981 return err;
982
983 /* Read out group size from ext_csd */
Lei Wen217467f2011-10-03 20:35:10 +0000984 mmc->erase_grp_size =
Simon Glassa09c2b72013-04-03 08:54:30 +0000985 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
986 MMC_MAX_BLOCK_LEN * 1024;
987 } else {
Oliver Metzb3f14092013-10-01 20:32:07 +0200988 /* Calculate the group size from the csd value. */
Lei Wenea526762011-06-22 17:03:31 +0000989 int erase_gsz, erase_gmul;
990 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
991 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
992 mmc->erase_grp_size = (erase_gsz + 1)
993 * (erase_gmul + 1);
994 }
995
Lei Wen31b99802011-05-02 16:26:26 +0000996 /* store the partition info of emmc */
Stephen Warren009784c2012-07-30 10:55:43 +0000997 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
998 ext_csd[EXT_CSD_BOOT_MULT])
Lei Wen217467f2011-10-03 20:35:10 +0000999 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
Stephen Warrene315ae82013-06-11 15:14:01 -06001000
1001 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1002
1003 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1004
1005 for (i = 0; i < 4; i++) {
1006 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1007 mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
1008 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1009 mmc->capacity_gp[i] *=
1010 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1011 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1012 }
Sukumar Ghorai232293c2010-09-20 18:29:29 +05301013 }
1014
Stephen Warrene315ae82013-06-11 15:14:01 -06001015 err = mmc_set_capacity(mmc, mmc->part_num);
1016 if (err)
1017 return err;
1018
Andy Flemingad347bb2008-10-30 16:41:01 -05001019 if (IS_SD(mmc))
1020 err = sd_change_freq(mmc);
1021 else
1022 err = mmc_change_freq(mmc);
1023
1024 if (err)
1025 return err;
1026
1027 /* Restrict card's capabilities by what the host can do */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001028 mmc->card_caps &= mmc->cfg->host_caps;
Andy Flemingad347bb2008-10-30 16:41:01 -05001029
1030 if (IS_SD(mmc)) {
1031 if (mmc->card_caps & MMC_MODE_4BIT) {
1032 cmd.cmdidx = MMC_CMD_APP_CMD;
1033 cmd.resp_type = MMC_RSP_R1;
1034 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001035
1036 err = mmc_send_cmd(mmc, &cmd, NULL);
1037 if (err)
1038 return err;
1039
1040 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1041 cmd.resp_type = MMC_RSP_R1;
1042 cmd.cmdarg = 2;
Andy Flemingad347bb2008-10-30 16:41:01 -05001043 err = mmc_send_cmd(mmc, &cmd, NULL);
1044 if (err)
1045 return err;
1046
1047 mmc_set_bus_width(mmc, 4);
1048 }
1049
1050 if (mmc->card_caps & MMC_MODE_HS)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001051 mmc->tran_speed = 50000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001052 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001053 mmc->tran_speed = 25000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001054 } else {
Andy Flemingeb766ad2012-10-31 19:02:38 +00001055 int idx;
1056
1057 /* An array of possible bus widths in order of preference */
1058 static unsigned ext_csd_bits[] = {
1059 EXT_CSD_BUS_WIDTH_8,
1060 EXT_CSD_BUS_WIDTH_4,
1061 EXT_CSD_BUS_WIDTH_1,
1062 };
1063
1064 /* An array to map CSD bus widths to host cap bits */
1065 static unsigned ext_to_hostcaps[] = {
1066 [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
1067 [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
1068 };
1069
1070 /* An array to map chosen bus width to an integer */
1071 static unsigned widths[] = {
1072 8, 4, 1,
1073 };
1074
1075 for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
1076 unsigned int extw = ext_csd_bits[idx];
1077
1078 /*
1079 * Check to make sure the controller supports
1080 * this bus width, if it's more than 1
1081 */
1082 if (extw != EXT_CSD_BUS_WIDTH_1 &&
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001083 !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
Andy Flemingeb766ad2012-10-31 19:02:38 +00001084 continue;
1085
Andy Flemingad347bb2008-10-30 16:41:01 -05001086 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
Andy Flemingeb766ad2012-10-31 19:02:38 +00001087 EXT_CSD_BUS_WIDTH, extw);
Andy Flemingad347bb2008-10-30 16:41:01 -05001088
1089 if (err)
Lei Wen4f5a6a52011-10-03 20:35:11 +00001090 continue;
Andy Flemingad347bb2008-10-30 16:41:01 -05001091
Andy Flemingeb766ad2012-10-31 19:02:38 +00001092 mmc_set_bus_width(mmc, widths[idx]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001093
Lei Wen4f5a6a52011-10-03 20:35:11 +00001094 err = mmc_send_ext_csd(mmc, test_csd);
1095 if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
1096 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
1097 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
1098 == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
1099 && ext_csd[EXT_CSD_REV] \
1100 == test_csd[EXT_CSD_REV]
1101 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
1102 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1103 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
1104 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
Andy Flemingad347bb2008-10-30 16:41:01 -05001105
Andy Flemingeb766ad2012-10-31 19:02:38 +00001106 mmc->card_caps |= ext_to_hostcaps[extw];
Lei Wen4f5a6a52011-10-03 20:35:11 +00001107 break;
1108 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001109 }
1110
1111 if (mmc->card_caps & MMC_MODE_HS) {
1112 if (mmc->card_caps & MMC_MODE_HS_52MHz)
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001113 mmc->tran_speed = 52000000;
Andy Flemingad347bb2008-10-30 16:41:01 -05001114 else
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001115 mmc->tran_speed = 26000000;
1116 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001117 }
1118
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00001119 mmc_set_clock(mmc, mmc->tran_speed);
1120
Andy Flemingad347bb2008-10-30 16:41:01 -05001121 /* fill in device description */
1122 mmc->block_dev.lun = 0;
1123 mmc->block_dev.type = 0;
1124 mmc->block_dev.blksz = mmc->read_bl_len;
Egbert Eich2eec2ab2013-04-09 21:11:56 +00001125 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
Rabin Vincent69d4e2c2009-04-05 13:30:54 +05301126 mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001127#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Taylor Hutt7367ec22012-10-20 17:15:59 +00001128 sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
1129 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1130 (mmc->cid[3] >> 16) & 0xffff);
1131 sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
1132 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1133 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1134 (mmc->cid[2] >> 24) & 0xff);
1135 sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
1136 (mmc->cid[2] >> 16) & 0xf);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001137#else
1138 mmc->block_dev.vendor[0] = 0;
1139 mmc->block_dev.product[0] = 0;
1140 mmc->block_dev.revision[0] = 0;
1141#endif
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001142#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001143 init_part(&mmc->block_dev);
Mikhail Kshevetskiy5cbfa8e7a2012-07-09 08:53:38 +00001144#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001145
1146 return 0;
1147}
1148
Kim Phillips87ea3892012-10-29 13:34:43 +00001149static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001150{
1151 struct mmc_cmd cmd;
1152 int err;
1153
1154 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1155 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001156 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05001157 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05001158
1159 err = mmc_send_cmd(mmc, &cmd, NULL);
1160
1161 if (err)
1162 return err;
1163
Rabin Vincentb6eed942009-04-05 13:30:56 +05301164 if ((cmd.response[0] & 0xff) != 0xaa)
Andy Flemingad347bb2008-10-30 16:41:01 -05001165 return UNUSABLE_ERR;
1166 else
1167 mmc->version = SD_VERSION_2;
1168
1169 return 0;
1170}
1171
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001172/* not used any more */
1173int __deprecated mmc_register(struct mmc *mmc)
1174{
1175#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1176 printf("%s is deprecated! use mmc_create() instead.\n", __func__);
1177#endif
1178 return -1;
1179}
1180
1181struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
Andy Flemingad347bb2008-10-30 16:41:01 -05001182{
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001183 struct mmc *mmc;
1184
1185 /* quick validation */
1186 if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
1187 cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
1188 return NULL;
1189
1190 mmc = calloc(1, sizeof(*mmc));
1191 if (mmc == NULL)
1192 return NULL;
1193
1194 mmc->cfg = cfg;
1195 mmc->priv = priv;
1196
1197 /* the following chunk was mmc_register() */
1198
Markus Niebel03951412013-12-16 13:40:46 +01001199 /* Setup dsr related values */
1200 mmc->dsr_imp = 0;
1201 mmc->dsr = 0xffffffff;
Andy Flemingad347bb2008-10-30 16:41:01 -05001202 /* Setup the universal parts of the block interface just once */
1203 mmc->block_dev.if_type = IF_TYPE_MMC;
1204 mmc->block_dev.dev = cur_dev_num++;
1205 mmc->block_dev.removable = 1;
1206 mmc->block_dev.block_read = mmc_bread;
1207 mmc->block_dev.block_write = mmc_bwrite;
Lei Wenea526762011-06-22 17:03:31 +00001208 mmc->block_dev.block_erase = mmc_berase;
Andy Flemingad347bb2008-10-30 16:41:01 -05001209
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001210 /* setup initial part type */
1211 mmc->block_dev.part_type = mmc->cfg->part_type;
Andy Flemingad347bb2008-10-30 16:41:01 -05001212
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001213 INIT_LIST_HEAD(&mmc->link);
Andy Flemingad347bb2008-10-30 16:41:01 -05001214
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001215 list_add_tail(&mmc->link, &mmc_devices);
1216
1217 return mmc;
1218}
1219
1220void mmc_destroy(struct mmc *mmc)
1221{
1222 /* only freeing memory for now */
1223 free(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001224}
1225
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001226#ifdef CONFIG_PARTITIONS
Andy Flemingad347bb2008-10-30 16:41:01 -05001227block_dev_desc_t *mmc_get_dev(int dev)
1228{
1229 struct mmc *mmc = find_mmc_device(dev);
Benoît Thébaudeau6ce8aed2012-08-10 08:59:12 +00001230 if (!mmc || mmc_init(mmc))
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001231 return NULL;
Andy Flemingad347bb2008-10-30 16:41:01 -05001232
Łukasz Majewski65b04cf2012-04-19 02:39:18 +00001233 return &mmc->block_dev;
Andy Flemingad347bb2008-10-30 16:41:01 -05001234}
Matthew McClintock6252b4f2011-05-24 05:31:19 +00001235#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001236
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001237int mmc_start_init(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001238{
Macpaul Lin028bde12011-11-14 23:35:39 +00001239 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001240
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001241 /* we pretend there's no card when init is NULL */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001242 if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
Thierry Redingb9c8b772012-01-02 01:15:37 +00001243 mmc->has_init = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001244#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001245 printf("MMC: no card present\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001246#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +00001247 return NO_CARD_ERR;
1248 }
1249
Lei Wen31b99802011-05-02 16:26:26 +00001250 if (mmc->has_init)
1251 return 0;
1252
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02001253 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001254 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001255
1256 if (err)
1257 return err;
1258
Ilya Yanok8459aab2009-06-29 17:53:16 +04001259 mmc_set_bus_width(mmc, 1);
1260 mmc_set_clock(mmc, 1);
1261
Andy Flemingad347bb2008-10-30 16:41:01 -05001262 /* Reset the Card */
1263 err = mmc_go_idle(mmc);
1264
1265 if (err)
1266 return err;
1267
Lei Wen31b99802011-05-02 16:26:26 +00001268 /* The internal partition reset to user partition(0) at every CMD0*/
1269 mmc->part_num = 0;
1270
Andy Flemingad347bb2008-10-30 16:41:01 -05001271 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00001272 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001273
Andy Flemingad347bb2008-10-30 16:41:01 -05001274 /* Now try to get the SD card's operating condition */
1275 err = sd_send_op_cond(mmc);
1276
1277 /* If the command timed out, we check for an MMC card */
1278 if (err == TIMEOUT) {
1279 err = mmc_send_op_cond(mmc);
1280
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001281 if (err && err != IN_PROGRESS) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001282#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Flemingad347bb2008-10-30 16:41:01 -05001283 printf("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001284#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001285 return UNUSABLE_ERR;
1286 }
1287 }
1288
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001289 if (err == IN_PROGRESS)
1290 mmc->init_in_progress = 1;
1291
1292 return err;
1293}
1294
1295static int mmc_complete_init(struct mmc *mmc)
1296{
1297 int err = 0;
1298
1299 if (mmc->op_cond_pending)
1300 err = mmc_complete_op_cond(mmc);
1301
1302 if (!err)
1303 err = mmc_startup(mmc);
Lei Wen31b99802011-05-02 16:26:26 +00001304 if (err)
1305 mmc->has_init = 0;
1306 else
1307 mmc->has_init = 1;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001308 mmc->init_in_progress = 0;
Lei Wen31b99802011-05-02 16:26:26 +00001309 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001310}
1311
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001312int mmc_init(struct mmc *mmc)
1313{
1314 int err = IN_PROGRESS;
Mateusz Zalegada351782014-04-29 20:15:30 +02001315 unsigned start;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001316
1317 if (mmc->has_init)
1318 return 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02001319
1320 start = get_timer(0);
1321
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001322 if (!mmc->init_in_progress)
1323 err = mmc_start_init(mmc);
1324
1325 if (!err || err == IN_PROGRESS)
1326 err = mmc_complete_init(mmc);
1327 debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
1328 return err;
1329}
1330
Markus Niebel03951412013-12-16 13:40:46 +01001331int mmc_set_dsr(struct mmc *mmc, u16 val)
1332{
1333 mmc->dsr = val;
1334 return 0;
1335}
1336
Andy Flemingad347bb2008-10-30 16:41:01 -05001337/*
1338 * CPU and board-specific MMC initializations. Aliased function
1339 * signals caller to move on
1340 */
1341static int __def_mmc_init(bd_t *bis)
1342{
1343 return -1;
1344}
1345
Peter Tyser21d2cd22009-04-20 11:08:46 -05001346int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
1347int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
Andy Flemingad347bb2008-10-30 16:41:01 -05001348
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001349#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
1350
Andy Flemingad347bb2008-10-30 16:41:01 -05001351void print_mmc_devices(char separator)
1352{
1353 struct mmc *m;
1354 struct list_head *entry;
1355
1356 list_for_each(entry, &mmc_devices) {
1357 m = list_entry(entry, struct mmc, link);
1358
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001359 printf("%s: %d", m->cfg->name, m->block_dev.dev);
Andy Flemingad347bb2008-10-30 16:41:01 -05001360
1361 if (entry->next != &mmc_devices)
1362 printf("%c ", separator);
1363 }
1364
1365 printf("\n");
1366}
1367
Paul Burton6a7c5ba2013-09-04 16:12:25 +01001368#else
1369void print_mmc_devices(char separator) { }
1370#endif
1371
Lei Wend430d7c2011-05-02 16:26:25 +00001372int get_mmc_num(void)
1373{
1374 return cur_dev_num;
1375}
1376
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001377void mmc_set_preinit(struct mmc *mmc, int preinit)
1378{
1379 mmc->preinit = preinit;
1380}
1381
1382static void do_preinit(void)
1383{
1384 struct mmc *m;
1385 struct list_head *entry;
1386
1387 list_for_each(entry, &mmc_devices) {
1388 m = list_entry(entry, struct mmc, link);
1389
1390 if (m->preinit)
1391 mmc_start_init(m);
1392 }
1393}
1394
1395
Andy Flemingad347bb2008-10-30 16:41:01 -05001396int mmc_initialize(bd_t *bis)
1397{
1398 INIT_LIST_HEAD (&mmc_devices);
1399 cur_dev_num = 0;
1400
1401 if (board_mmc_init(bis) < 0)
1402 cpu_mmc_init(bis);
1403
Ying Zhang9ff70262013-08-16 15:16:11 +08001404#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05001405 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08001406#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001407
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00001408 do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05001409 return 0;
1410}
Amar1104e9b2013-04-27 11:42:58 +05301411
1412#ifdef CONFIG_SUPPORT_EMMC_BOOT
1413/*
1414 * This function changes the size of boot partition and the size of rpmb
1415 * partition present on EMMC devices.
1416 *
1417 * Input Parameters:
1418 * struct *mmc: pointer for the mmc device strcuture
1419 * bootsize: size of boot partition
1420 * rpmbsize: size of rpmb partition
1421 *
1422 * Returns 0 on success.
1423 */
1424
1425int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
1426 unsigned long rpmbsize)
1427{
1428 int err;
1429 struct mmc_cmd cmd;
1430
1431 /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
1432 cmd.cmdidx = MMC_CMD_RES_MAN;
1433 cmd.resp_type = MMC_RSP_R1b;
1434 cmd.cmdarg = MMC_CMD62_ARG1;
1435
1436 err = mmc_send_cmd(mmc, &cmd, NULL);
1437 if (err) {
1438 debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
1439 return err;
1440 }
1441
1442 /* Boot partition changing mode */
1443 cmd.cmdidx = MMC_CMD_RES_MAN;
1444 cmd.resp_type = MMC_RSP_R1b;
1445 cmd.cmdarg = MMC_CMD62_ARG2;
1446
1447 err = mmc_send_cmd(mmc, &cmd, NULL);
1448 if (err) {
1449 debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
1450 return err;
1451 }
1452 /* boot partition size is multiple of 128KB */
1453 bootsize = (bootsize * 1024) / 128;
1454
1455 /* Arg: boot partition size */
1456 cmd.cmdidx = MMC_CMD_RES_MAN;
1457 cmd.resp_type = MMC_RSP_R1b;
1458 cmd.cmdarg = bootsize;
1459
1460 err = mmc_send_cmd(mmc, &cmd, NULL);
1461 if (err) {
1462 debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
1463 return err;
1464 }
1465 /* RPMB partition size is multiple of 128KB */
1466 rpmbsize = (rpmbsize * 1024) / 128;
1467 /* Arg: RPMB partition size */
1468 cmd.cmdidx = MMC_CMD_RES_MAN;
1469 cmd.resp_type = MMC_RSP_R1b;
1470 cmd.cmdarg = rpmbsize;
1471
1472 err = mmc_send_cmd(mmc, &cmd, NULL);
1473 if (err) {
1474 debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
1475 return err;
1476 }
1477 return 0;
1478}
1479
1480/*
Tom Rini4cf854c2014-02-05 10:24:22 -05001481 * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
1482 * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
1483 * and BOOT_MODE.
1484 *
1485 * Returns 0 on success.
1486 */
1487int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1488{
1489 int err;
1490
1491 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
1492 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
1493 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
1494 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1495
1496 if (err)
1497 return err;
1498 return 0;
1499}
1500
1501/*
Tom Rinif8c6f792014-02-05 10:24:21 -05001502 * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
1503 * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
1504 * PARTITION_ACCESS.
1505 *
1506 * Returns 0 on success.
1507 */
1508int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
1509{
1510 int err;
1511
1512 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
1513 EXT_CSD_BOOT_ACK(ack) |
1514 EXT_CSD_BOOT_PART_NUM(part_num) |
1515 EXT_CSD_PARTITION_ACCESS(access));
1516
1517 if (err)
1518 return err;
1519 return 0;
1520}
Tom Rini35a3ea12014-02-07 14:15:20 -05001521
1522/*
1523 * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
1524 * for enable. Note that this is a write-once field for non-zero values.
1525 *
1526 * Returns 0 on success.
1527 */
1528int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
1529{
1530 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
1531 enable);
1532}
Amar1104e9b2013-04-27 11:42:58 +05301533#endif