blob: d59cce611e4f5707081460c726dc53e4990e3c02 [file] [log] [blame]
Andy Fleming272cc702008-10-30 16:41:01 -05001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Based vaguely on the Linux code
6 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Andy Fleming272cc702008-10-30 16:41:01 -05008 */
9
10#include <config.h>
11#include <common.h>
12#include <command.h>
Sjoerd Simons8e3332e2015-08-30 16:55:45 -060013#include <dm.h>
14#include <dm/device-internal.h>
Stephen Warrend4622df2014-05-23 12:47:06 -060015#include <errno.h>
Andy Fleming272cc702008-10-30 16:41:01 -050016#include <mmc.h>
17#include <part.h>
Peng Fan2051aef2016-10-11 15:08:43 +080018#include <power/regulator.h>
Andy Fleming272cc702008-10-30 16:41:01 -050019#include <malloc.h>
Simon Glasscf92e052015-09-02 17:24:58 -060020#include <memalign.h>
Andy Fleming272cc702008-10-30 16:41:01 -050021#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053022#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010023#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050024
Peng Fan3697e592016-09-01 11:13:38 +080025static const unsigned int sd_au_size[] = {
26 0, SZ_16K / 512, SZ_32K / 512,
27 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
28 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
29 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
30 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512,
31};
32
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +020033static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +020034static int mmc_power_cycle(struct mmc *mmc);
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +020035
Marek Vasutb5b838f2016-12-01 02:06:33 +010036#if CONFIG_IS_ENABLED(MMC_TINY)
37static struct mmc mmc_static;
38struct mmc *find_mmc_device(int dev_num)
39{
40 return &mmc_static;
41}
42
43void mmc_do_preinit(void)
44{
45 struct mmc *m = &mmc_static;
46#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
47 mmc_set_preinit(m, 1);
48#endif
49 if (m->preinit)
50 mmc_start_init(m);
51}
52
53struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
54{
55 return &mmc->block_dev;
56}
57#endif
58
Simon Glasse7881d82017-07-29 11:35:31 -060059#if !CONFIG_IS_ENABLED(DM_MMC)
Jeroen Hofstee750121c2014-07-12 21:24:08 +020060__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000061{
62 return -1;
63}
64
65int mmc_getwp(struct mmc *mmc)
66{
67 int wp;
68
69 wp = board_mmc_getwp(mmc);
70
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000071 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020072 if (mmc->cfg->ops->getwp)
73 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000074 else
75 wp = 0;
76 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000077
78 return wp;
79}
80
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020081__weak int board_mmc_getcd(struct mmc *mmc)
82{
Stefano Babic11fdade2010-02-05 15:04:43 +010083 return -1;
84}
Simon Glass8ca51e52016-06-12 23:30:22 -060085#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010086
Marek Vasut8635ff92012-03-15 18:41:35 +000087#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060088void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
89{
90 printf("CMD_SEND:%d\n", cmd->cmdidx);
91 printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
92}
93
94void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
95{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000096 int i;
97 u8 *ptr;
98
Bin Meng7863ce52016-03-17 21:53:14 -070099 if (ret) {
100 printf("\t\tRET\t\t\t %d\n", ret);
101 } else {
102 switch (cmd->resp_type) {
103 case MMC_RSP_NONE:
104 printf("\t\tMMC_RSP_NONE\n");
105 break;
106 case MMC_RSP_R1:
107 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
108 cmd->response[0]);
109 break;
110 case MMC_RSP_R1b:
111 printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
112 cmd->response[0]);
113 break;
114 case MMC_RSP_R2:
115 printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
116 cmd->response[0]);
117 printf("\t\t \t\t 0x%08X \n",
118 cmd->response[1]);
119 printf("\t\t \t\t 0x%08X \n",
120 cmd->response[2]);
121 printf("\t\t \t\t 0x%08X \n",
122 cmd->response[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000123 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -0700124 printf("\t\t\t\t\tDUMPING DATA\n");
125 for (i = 0; i < 4; i++) {
126 int j;
127 printf("\t\t\t\t\t%03d - ", i*4);
128 ptr = (u8 *)&cmd->response[i];
129 ptr += 3;
130 for (j = 0; j < 4; j++)
131 printf("%02X ", *ptr--);
132 printf("\n");
133 }
134 break;
135 case MMC_RSP_R3:
136 printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
137 cmd->response[0]);
138 break;
139 default:
140 printf("\t\tERROR MMC rsp not supported\n");
141 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700142 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000143 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600144}
145
146void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
147{
148 int status;
149
150 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
151 printf("CURR STATE:%d\n", status);
152}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000153#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600154
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200155#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
156const char *mmc_mode_name(enum bus_mode mode)
157{
158 static const char *const names[] = {
159 [MMC_LEGACY] = "MMC legacy",
160 [SD_LEGACY] = "SD Legacy",
161 [MMC_HS] = "MMC High Speed (26MHz)",
162 [SD_HS] = "SD High Speed (50MHz)",
163 [UHS_SDR12] = "UHS SDR12 (25MHz)",
164 [UHS_SDR25] = "UHS SDR25 (50MHz)",
165 [UHS_SDR50] = "UHS SDR50 (100MHz)",
166 [UHS_SDR104] = "UHS SDR104 (208MHz)",
167 [UHS_DDR50] = "UHS DDR50 (50MHz)",
168 [MMC_HS_52] = "MMC High Speed (52MHz)",
169 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
170 [MMC_HS_200] = "HS200 (200MHz)",
171 };
172
173 if (mode >= MMC_MODES_END)
174 return "Unknown mode";
175 else
176 return names[mode];
177}
178#endif
179
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200180static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
181{
182 static const int freqs[] = {
183 [SD_LEGACY] = 25000000,
184 [MMC_HS] = 26000000,
185 [SD_HS] = 50000000,
186 [UHS_SDR12] = 25000000,
187 [UHS_SDR25] = 50000000,
188 [UHS_SDR50] = 100000000,
189 [UHS_SDR104] = 208000000,
190 [UHS_DDR50] = 50000000,
191 [MMC_HS_52] = 52000000,
192 [MMC_DDR_52] = 52000000,
193 [MMC_HS_200] = 200000000,
194 };
195
196 if (mode == MMC_LEGACY)
197 return mmc->legacy_speed;
198 else if (mode >= MMC_MODES_END)
199 return 0;
200 else
201 return freqs[mode];
202}
203
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200204static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
205{
206 mmc->selected_mode = mode;
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200207 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200208 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200209 debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
210 mmc->tran_speed / 1000000);
211 return 0;
212}
213
Simon Glasse7881d82017-07-29 11:35:31 -0600214#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassc0c76eb2016-06-12 23:30:20 -0600215int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
216{
217 int ret;
218
219 mmmc_trace_before_send(mmc, cmd);
220 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
221 mmmc_trace_after_send(mmc, cmd, ret);
222
Marek Vasut8635ff92012-03-15 18:41:35 +0000223 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500224}
Simon Glass8ca51e52016-06-12 23:30:22 -0600225#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500226
Paul Burtonda61fa52013-09-09 15:30:26 +0100227int mmc_send_status(struct mmc *mmc, int timeout)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000228{
229 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000230 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000231
232 cmd.cmdidx = MMC_CMD_SEND_STATUS;
233 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200234 if (!mmc_host_is_spi(mmc))
235 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000236
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500237 while (1) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000238 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000239 if (!err) {
240 if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
241 (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
242 MMC_STATE_PRG)
243 break;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200244
245 if (cmd.response[0] & MMC_STATUS_MASK) {
Paul Burton56196822013-09-04 16:12:25 +0100246#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jan Kloetzked617c422012-02-05 22:29:12 +0000247 printf("Status Error: 0x%08X\n",
248 cmd.response[0]);
Paul Burton56196822013-09-04 16:12:25 +0100249#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900250 return -ECOMM;
Jan Kloetzked617c422012-02-05 22:29:12 +0000251 }
252 } else if (--retries < 0)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000253 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000254
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500255 if (timeout-- <= 0)
256 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000257
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500258 udelay(1000);
259 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000260
Simon Glassc0c76eb2016-06-12 23:30:20 -0600261 mmc_trace_state(mmc, &cmd);
Jongman Heo5b0c9422012-06-03 21:32:13 +0000262 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100263#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000264 printf("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100265#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900266 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000267 }
268
269 return 0;
270}
271
Paul Burtonda61fa52013-09-09 15:30:26 +0100272int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500273{
274 struct mmc_cmd cmd;
275
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600276 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900277 return 0;
278
Andy Fleming272cc702008-10-30 16:41:01 -0500279 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
280 cmd.resp_type = MMC_RSP_R1;
281 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500282
283 return mmc_send_cmd(mmc, &cmd, NULL);
284}
285
Sascha Silbeff8fef52013-06-14 13:07:25 +0200286static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000287 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500288{
289 struct mmc_cmd cmd;
290 struct mmc_data data;
291
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700292 if (blkcnt > 1)
293 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
294 else
295 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500296
297 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700298 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500299 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700300 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500301
302 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500303
304 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700305 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500306 data.blocksize = mmc->read_bl_len;
307 data.flags = MMC_DATA_READ;
308
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700309 if (mmc_send_cmd(mmc, &cmd, &data))
310 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500311
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700312 if (blkcnt > 1) {
313 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
314 cmd.cmdarg = 0;
315 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700316 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100317#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700318 printf("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100319#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700320 return 0;
321 }
Andy Fleming272cc702008-10-30 16:41:01 -0500322 }
323
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700324 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500325}
326
Simon Glassc4d660d2017-07-04 13:31:19 -0600327#if CONFIG_IS_ENABLED(BLK)
Simon Glass7dba0b92016-06-12 23:30:15 -0600328ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600329#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600330ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
331 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600332#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500333{
Simon Glassc4d660d2017-07-04 13:31:19 -0600334#if CONFIG_IS_ENABLED(BLK)
Simon Glass33fb2112016-05-01 13:52:41 -0600335 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
336#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700337 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700338 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700339 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500340
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700341 if (blkcnt == 0)
342 return 0;
343
344 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500345 if (!mmc)
346 return 0;
347
Marek Vasutb5b838f2016-12-01 02:06:33 +0100348 if (CONFIG_IS_ENABLED(MMC_TINY))
349 err = mmc_switch_part(mmc, block_dev->hwpart);
350 else
351 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
352
Stephen Warren873cc1d2015-12-07 11:38:49 -0700353 if (err < 0)
354 return 0;
355
Simon Glassc40fdca2016-05-01 13:52:35 -0600356 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100357#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Sascha Silbeff8fef52013-06-14 13:07:25 +0200358 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
Simon Glassc40fdca2016-05-01 13:52:35 -0600359 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100360#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800361 return 0;
362 }
Andy Fleming272cc702008-10-30 16:41:01 -0500363
Simon Glass11692992015-06-23 15:38:50 -0600364 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
365 debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500366 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600367 }
Andy Fleming272cc702008-10-30 16:41:01 -0500368
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700369 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200370 cur = (blocks_todo > mmc->cfg->b_max) ?
371 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600372 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
373 debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700374 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600375 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700376 blocks_todo -= cur;
377 start += cur;
378 dst += cur * mmc->read_bl_len;
379 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500380
381 return blkcnt;
382}
383
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000384static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500385{
386 struct mmc_cmd cmd;
387 int err;
388
389 udelay(1000);
390
391 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
392 cmd.cmdarg = 0;
393 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500394
395 err = mmc_send_cmd(mmc, &cmd, NULL);
396
397 if (err)
398 return err;
399
400 udelay(2000);
401
402 return 0;
403}
404
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000405static int sd_send_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500406{
407 int timeout = 1000;
408 int err;
409 struct mmc_cmd cmd;
410
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500411 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500412 cmd.cmdidx = MMC_CMD_APP_CMD;
413 cmd.resp_type = MMC_RSP_R1;
414 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500415
416 err = mmc_send_cmd(mmc, &cmd, NULL);
417
418 if (err)
419 return err;
420
421 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
422 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100423
424 /*
425 * Most cards do not answer if some reserved bits
426 * in the ocr are set. However, Some controller
427 * can set bit 7 (reserved for low voltages), but
428 * how to manage low voltages SD card is not yet
429 * specified.
430 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000431 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200432 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500433
434 if (mmc->version == SD_VERSION_2)
435 cmd.cmdarg |= OCR_HCS;
436
437 err = mmc_send_cmd(mmc, &cmd, NULL);
438
439 if (err)
440 return err;
441
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500442 if (cmd.response[0] & OCR_BUSY)
443 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500444
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500445 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900446 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500447
448 udelay(1000);
449 }
Andy Fleming272cc702008-10-30 16:41:01 -0500450
451 if (mmc->version != SD_VERSION_2)
452 mmc->version = SD_VERSION_1_0;
453
Thomas Choud52ebf12010-12-24 13:12:21 +0000454 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
455 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
456 cmd.resp_type = MMC_RSP_R3;
457 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000458
459 err = mmc_send_cmd(mmc, &cmd, NULL);
460
461 if (err)
462 return err;
463 }
464
Rabin Vincent998be3d2009-04-05 13:30:56 +0530465 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500466
467 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
468 mmc->rca = 0;
469
470 return 0;
471}
472
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500473static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500474{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500475 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500476 int err;
477
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500478 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
479 cmd.resp_type = MMC_RSP_R3;
480 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500481 if (use_arg && !mmc_host_is_spi(mmc))
482 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200483 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500484 (mmc->ocr & OCR_VOLTAGE_MASK)) |
485 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000486
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500487 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000488 if (err)
489 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500490 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000491 return 0;
492}
493
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200494static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000495{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000496 int err, i;
497
Andy Fleming272cc702008-10-30 16:41:01 -0500498 /* Some cards seem to need this */
499 mmc_go_idle(mmc);
500
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000501 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000502 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500503 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500504 if (err)
505 return err;
506
Che-Liang Chioue9550442012-11-28 15:21:13 +0000507 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500508 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500509 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000510 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500511 mmc->op_cond_pending = 1;
512 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000513}
Andy Fleming272cc702008-10-30 16:41:01 -0500514
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200515static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000516{
517 struct mmc_cmd cmd;
518 int timeout = 1000;
519 uint start;
520 int err;
521
522 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500523 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lud188b112016-08-02 15:33:18 +0800524 /* Some cards seem to need this */
525 mmc_go_idle(mmc);
526
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500527 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500528 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500529 err = mmc_send_op_cond_iter(mmc, 1);
530 if (err)
531 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500532 if (mmc->ocr & OCR_BUSY)
533 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500534 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900535 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500536 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500537 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500538 }
Andy Fleming272cc702008-10-30 16:41:01 -0500539
Thomas Choud52ebf12010-12-24 13:12:21 +0000540 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
541 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
542 cmd.resp_type = MMC_RSP_R3;
543 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000544
545 err = mmc_send_cmd(mmc, &cmd, NULL);
546
547 if (err)
548 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500549
550 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000551 }
552
Andy Fleming272cc702008-10-30 16:41:01 -0500553 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500554
555 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700556 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500557
558 return 0;
559}
560
561
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000562static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500563{
564 struct mmc_cmd cmd;
565 struct mmc_data data;
566 int err;
567
568 /* Get the Card Status Register */
569 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
570 cmd.resp_type = MMC_RSP_R1;
571 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500572
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000573 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500574 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000575 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500576 data.flags = MMC_DATA_READ;
577
578 err = mmc_send_cmd(mmc, &cmd, &data);
579
580 return err;
581}
582
Simon Glassc40704f2016-06-12 23:30:18 -0600583int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
Andy Fleming272cc702008-10-30 16:41:01 -0500584{
585 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000586 int timeout = 1000;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100587 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000588 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500589
590 cmd.cmdidx = MMC_CMD_SWITCH;
591 cmd.resp_type = MMC_RSP_R1b;
592 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000593 (index << 16) |
594 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500595
Maxime Riparda9003dc2016-11-04 16:18:08 +0100596 while (retries > 0) {
597 ret = mmc_send_cmd(mmc, &cmd, NULL);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000598
Maxime Riparda9003dc2016-11-04 16:18:08 +0100599 /* Waiting for the ready status */
600 if (!ret) {
601 ret = mmc_send_status(mmc, timeout);
602 return ret;
603 }
604
605 retries--;
606 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000607
608 return ret;
609
Andy Fleming272cc702008-10-30 16:41:01 -0500610}
611
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200612static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
Andy Fleming272cc702008-10-30 16:41:01 -0500613{
Andy Fleming272cc702008-10-30 16:41:01 -0500614 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200615 int speed_bits;
616
617 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
618
619 switch (mode) {
620 case MMC_HS:
621 case MMC_HS_52:
622 case MMC_DDR_52:
623 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200624 break;
625 case MMC_HS_200:
626 speed_bits = EXT_CSD_TIMING_HS200;
627 break;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200628 case MMC_LEGACY:
629 speed_bits = EXT_CSD_TIMING_LEGACY;
630 break;
631 default:
632 return -EINVAL;
633 }
634 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
635 speed_bits);
636 if (err)
637 return err;
638
639 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
640 /* Now check to see that it worked */
641 err = mmc_send_ext_csd(mmc, test_csd);
642 if (err)
643 return err;
644
645 /* No high-speed support */
646 if (!test_csd[EXT_CSD_HS_TIMING])
647 return -ENOTSUPP;
648 }
649
650 return 0;
651}
652
653static int mmc_get_capabilities(struct mmc *mmc)
654{
655 u8 *ext_csd = mmc->ext_csd;
656 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500657
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200658 mmc->card_caps = MMC_MODE_1BIT;
Andy Fleming272cc702008-10-30 16:41:01 -0500659
Thomas Choud52ebf12010-12-24 13:12:21 +0000660 if (mmc_host_is_spi(mmc))
661 return 0;
662
Andy Fleming272cc702008-10-30 16:41:01 -0500663 /* Only version 4 supports high-speed */
664 if (mmc->version < MMC_VERSION_4)
665 return 0;
666
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200667 if (!ext_csd) {
668 printf("No ext_csd found!\n"); /* this should enver happen */
669 return -ENOTSUPP;
670 }
671
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600672 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
673
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200674 cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
Andy Fleming272cc702008-10-30 16:41:01 -0500675
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200676 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
677 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
678 mmc->card_caps |= MMC_MODE_HS200;
679 }
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900680 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200681 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900682 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200683 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900684 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200685 if (cardtype & EXT_CSD_CARD_TYPE_26)
686 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500687
688 return 0;
689}
690
Stephen Warrenf866a462013-06-11 15:14:01 -0600691static int mmc_set_capacity(struct mmc *mmc, int part_num)
692{
693 switch (part_num) {
694 case 0:
695 mmc->capacity = mmc->capacity_user;
696 break;
697 case 1:
698 case 2:
699 mmc->capacity = mmc->capacity_boot;
700 break;
701 case 3:
702 mmc->capacity = mmc->capacity_rpmb;
703 break;
704 case 4:
705 case 5:
706 case 6:
707 case 7:
708 mmc->capacity = mmc->capacity_gp[part_num - 4];
709 break;
710 default:
711 return -1;
712 }
713
Simon Glassc40fdca2016-05-01 13:52:35 -0600714 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600715
716 return 0;
717}
718
Simon Glass7dba0b92016-06-12 23:30:15 -0600719int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000720{
Stephen Warrenf866a462013-06-11 15:14:01 -0600721 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000722
Stephen Warrenf866a462013-06-11 15:14:01 -0600723 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
724 (mmc->part_config & ~PART_ACCESS_MASK)
725 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600726
Peter Bigot6dc93e72014-09-02 18:31:23 -0500727 /*
728 * Set the capacity if the switch succeeded or was intended
729 * to return to representing the raw device.
730 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700731 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500732 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600733 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700734 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500735
736 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000737}
738
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100739int mmc_hwpart_config(struct mmc *mmc,
740 const struct mmc_hwpart_conf *conf,
741 enum mmc_hwpart_conf_mode mode)
742{
743 u8 part_attrs = 0;
744 u32 enh_size_mult;
745 u32 enh_start_addr;
746 u32 gp_size_mult[4];
747 u32 max_enh_size_mult;
748 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100749 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100750 int i, pidx, err;
751 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
752
753 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
754 return -EINVAL;
755
756 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
757 printf("eMMC >= 4.4 required for enhanced user data area\n");
758 return -EMEDIUMTYPE;
759 }
760
761 if (!(mmc->part_support & PART_SUPPORT)) {
762 printf("Card does not support partitioning\n");
763 return -EMEDIUMTYPE;
764 }
765
766 if (!mmc->hc_wp_grp_size) {
767 printf("Card does not define HC WP group size\n");
768 return -EMEDIUMTYPE;
769 }
770
771 /* check partition alignment and total enhanced size */
772 if (conf->user.enh_size) {
773 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
774 conf->user.enh_start % mmc->hc_wp_grp_size) {
775 printf("User data enhanced area not HC WP group "
776 "size aligned\n");
777 return -EINVAL;
778 }
779 part_attrs |= EXT_CSD_ENH_USR;
780 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
781 if (mmc->high_capacity) {
782 enh_start_addr = conf->user.enh_start;
783 } else {
784 enh_start_addr = (conf->user.enh_start << 9);
785 }
786 } else {
787 enh_size_mult = 0;
788 enh_start_addr = 0;
789 }
790 tot_enh_size_mult += enh_size_mult;
791
792 for (pidx = 0; pidx < 4; pidx++) {
793 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
794 printf("GP%i partition not HC WP group size "
795 "aligned\n", pidx+1);
796 return -EINVAL;
797 }
798 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
799 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
800 part_attrs |= EXT_CSD_ENH_GP(pidx);
801 tot_enh_size_mult += gp_size_mult[pidx];
802 }
803 }
804
805 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
806 printf("Card does not support enhanced attribute\n");
807 return -EMEDIUMTYPE;
808 }
809
810 err = mmc_send_ext_csd(mmc, ext_csd);
811 if (err)
812 return err;
813
814 max_enh_size_mult =
815 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
816 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
817 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
818 if (tot_enh_size_mult > max_enh_size_mult) {
819 printf("Total enhanced size exceeds maximum (%u > %u)\n",
820 tot_enh_size_mult, max_enh_size_mult);
821 return -EMEDIUMTYPE;
822 }
823
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100824 /* The default value of EXT_CSD_WR_REL_SET is device
825 * dependent, the values can only be changed if the
826 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
827 * changed only once and before partitioning is completed. */
828 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
829 if (conf->user.wr_rel_change) {
830 if (conf->user.wr_rel_set)
831 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
832 else
833 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
834 }
835 for (pidx = 0; pidx < 4; pidx++) {
836 if (conf->gp_part[pidx].wr_rel_change) {
837 if (conf->gp_part[pidx].wr_rel_set)
838 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
839 else
840 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
841 }
842 }
843
844 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
845 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
846 puts("Card does not support host controlled partition write "
847 "reliability settings\n");
848 return -EMEDIUMTYPE;
849 }
850
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100851 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
852 EXT_CSD_PARTITION_SETTING_COMPLETED) {
853 printf("Card already partitioned\n");
854 return -EPERM;
855 }
856
857 if (mode == MMC_HWPART_CONF_CHECK)
858 return 0;
859
860 /* Partitioning requires high-capacity size definitions */
861 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
862 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
863 EXT_CSD_ERASE_GROUP_DEF, 1);
864
865 if (err)
866 return err;
867
868 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
869
870 /* update erase group size to be high-capacity */
871 mmc->erase_grp_size =
872 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
873
874 }
875
876 /* all OK, write the configuration */
877 for (i = 0; i < 4; i++) {
878 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
879 EXT_CSD_ENH_START_ADDR+i,
880 (enh_start_addr >> (i*8)) & 0xFF);
881 if (err)
882 return err;
883 }
884 for (i = 0; i < 3; i++) {
885 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
886 EXT_CSD_ENH_SIZE_MULT+i,
887 (enh_size_mult >> (i*8)) & 0xFF);
888 if (err)
889 return err;
890 }
891 for (pidx = 0; pidx < 4; pidx++) {
892 for (i = 0; i < 3; i++) {
893 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
894 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
895 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
896 if (err)
897 return err;
898 }
899 }
900 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
901 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
902 if (err)
903 return err;
904
905 if (mode == MMC_HWPART_CONF_SET)
906 return 0;
907
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100908 /* The WR_REL_SET is a write-once register but shall be
909 * written before setting PART_SETTING_COMPLETED. As it is
910 * write-once we can only write it when completing the
911 * partitioning. */
912 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
913 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
914 EXT_CSD_WR_REL_SET, wr_rel_set);
915 if (err)
916 return err;
917 }
918
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100919 /* Setting PART_SETTING_COMPLETED confirms the partition
920 * configuration but it only becomes effective after power
921 * cycle, so we do not adjust the partition related settings
922 * in the mmc struct. */
923
924 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
925 EXT_CSD_PARTITION_SETTING,
926 EXT_CSD_PARTITION_SETTING_COMPLETED);
927 if (err)
928 return err;
929
930 return 0;
931}
932
Simon Glasse7881d82017-07-29 11:35:31 -0600933#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +0000934int mmc_getcd(struct mmc *mmc)
935{
936 int cd;
937
938 cd = board_mmc_getcd(mmc);
939
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000940 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200941 if (mmc->cfg->ops->getcd)
942 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +0000943 else
944 cd = 1;
945 }
Thierry Reding48972d92012-01-02 01:15:37 +0000946
947 return cd;
948}
Simon Glass8ca51e52016-06-12 23:30:22 -0600949#endif
Thierry Reding48972d92012-01-02 01:15:37 +0000950
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000951static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -0500952{
953 struct mmc_cmd cmd;
954 struct mmc_data data;
955
956 /* Switch the frequency */
957 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
958 cmd.resp_type = MMC_RSP_R1;
959 cmd.cmdarg = (mode << 31) | 0xffffff;
960 cmd.cmdarg &= ~(0xf << (group * 4));
961 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -0500962
963 data.dest = (char *)resp;
964 data.blocksize = 64;
965 data.blocks = 1;
966 data.flags = MMC_DATA_READ;
967
968 return mmc_send_cmd(mmc, &cmd, &data);
969}
970
971
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200972static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500973{
974 int err;
975 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +0530976 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
977 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -0500978 struct mmc_data data;
979 int timeout;
980
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200981 mmc->card_caps = MMC_MODE_1BIT;
Andy Fleming272cc702008-10-30 16:41:01 -0500982
Thomas Choud52ebf12010-12-24 13:12:21 +0000983 if (mmc_host_is_spi(mmc))
984 return 0;
985
Andy Fleming272cc702008-10-30 16:41:01 -0500986 /* Read the SCR to find out if this card supports higher speeds */
987 cmd.cmdidx = MMC_CMD_APP_CMD;
988 cmd.resp_type = MMC_RSP_R1;
989 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -0500990
991 err = mmc_send_cmd(mmc, &cmd, NULL);
992
993 if (err)
994 return err;
995
996 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
997 cmd.resp_type = MMC_RSP_R1;
998 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500999
1000 timeout = 3;
1001
1002retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001003 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001004 data.blocksize = 8;
1005 data.blocks = 1;
1006 data.flags = MMC_DATA_READ;
1007
1008 err = mmc_send_cmd(mmc, &cmd, &data);
1009
1010 if (err) {
1011 if (timeout--)
1012 goto retry_scr;
1013
1014 return err;
1015 }
1016
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001017 mmc->scr[0] = __be32_to_cpu(scr[0]);
1018 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001019
1020 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001021 case 0:
1022 mmc->version = SD_VERSION_1_0;
1023 break;
1024 case 1:
1025 mmc->version = SD_VERSION_1_10;
1026 break;
1027 case 2:
1028 mmc->version = SD_VERSION_2;
1029 if ((mmc->scr[0] >> 15) & 0x1)
1030 mmc->version = SD_VERSION_3;
1031 break;
1032 default:
1033 mmc->version = SD_VERSION_1_0;
1034 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001035 }
1036
Alagu Sankarb44c7082010-05-12 15:08:24 +05301037 if (mmc->scr[0] & SD_DATA_4BIT)
1038 mmc->card_caps |= MMC_MODE_4BIT;
1039
Andy Fleming272cc702008-10-30 16:41:01 -05001040 /* Version 1.0 doesn't support switching */
1041 if (mmc->version == SD_VERSION_1_0)
1042 return 0;
1043
1044 timeout = 4;
1045 while (timeout--) {
1046 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001047 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001048
1049 if (err)
1050 return err;
1051
1052 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001053 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001054 break;
1055 }
1056
Andy Fleming272cc702008-10-30 16:41:01 -05001057 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001058 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1059 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001060
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001061 return 0;
1062}
1063
1064static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1065{
1066 int err;
1067
1068 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001069
Anton staaff781dd32011-10-03 13:54:59 +00001070 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001071 if (err)
1072 return err;
1073
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001074 if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) != 0x01000000)
1075 return -ENOTSUPP;
1076
1077 return 0;
1078}
1079
1080int sd_select_bus_width(struct mmc *mmc, int w)
1081{
1082 int err;
1083 struct mmc_cmd cmd;
1084
1085 if ((w != 4) && (w != 1))
1086 return -EINVAL;
1087
1088 cmd.cmdidx = MMC_CMD_APP_CMD;
1089 cmd.resp_type = MMC_RSP_R1;
1090 cmd.cmdarg = mmc->rca << 16;
1091
1092 err = mmc_send_cmd(mmc, &cmd, NULL);
1093 if (err)
1094 return err;
1095
1096 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1097 cmd.resp_type = MMC_RSP_R1;
1098 if (w == 4)
1099 cmd.cmdarg = 2;
1100 else if (w == 1)
1101 cmd.cmdarg = 0;
1102 err = mmc_send_cmd(mmc, &cmd, NULL);
1103 if (err)
1104 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001105
1106 return 0;
1107}
1108
Peng Fan3697e592016-09-01 11:13:38 +08001109static int sd_read_ssr(struct mmc *mmc)
1110{
1111 int err, i;
1112 struct mmc_cmd cmd;
1113 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1114 struct mmc_data data;
1115 int timeout = 3;
1116 unsigned int au, eo, et, es;
1117
1118 cmd.cmdidx = MMC_CMD_APP_CMD;
1119 cmd.resp_type = MMC_RSP_R1;
1120 cmd.cmdarg = mmc->rca << 16;
1121
1122 err = mmc_send_cmd(mmc, &cmd, NULL);
1123 if (err)
1124 return err;
1125
1126 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1127 cmd.resp_type = MMC_RSP_R1;
1128 cmd.cmdarg = 0;
1129
1130retry_ssr:
1131 data.dest = (char *)ssr;
1132 data.blocksize = 64;
1133 data.blocks = 1;
1134 data.flags = MMC_DATA_READ;
1135
1136 err = mmc_send_cmd(mmc, &cmd, &data);
1137 if (err) {
1138 if (timeout--)
1139 goto retry_ssr;
1140
1141 return err;
1142 }
1143
1144 for (i = 0; i < 16; i++)
1145 ssr[i] = be32_to_cpu(ssr[i]);
1146
1147 au = (ssr[2] >> 12) & 0xF;
1148 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1149 mmc->ssr.au = sd_au_size[au];
1150 es = (ssr[3] >> 24) & 0xFF;
1151 es |= (ssr[2] & 0xFF) << 8;
1152 et = (ssr[3] >> 18) & 0x3F;
1153 if (es && et) {
1154 eo = (ssr[3] >> 16) & 0x3;
1155 mmc->ssr.erase_timeout = (et * 1000) / es;
1156 mmc->ssr.erase_offset = eo * 1000;
1157 }
1158 } else {
1159 debug("Invalid Allocation Unit Size.\n");
1160 }
1161
1162 return 0;
1163}
1164
Andy Fleming272cc702008-10-30 16:41:01 -05001165/* frequency bases */
1166/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001167static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001168 10000,
1169 100000,
1170 1000000,
1171 10000000,
1172};
1173
1174/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1175 * to platforms without floating point.
1176 */
Simon Glass61fe0762016-05-14 14:02:57 -06001177static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001178 0, /* reserved */
1179 10,
1180 12,
1181 13,
1182 15,
1183 20,
1184 25,
1185 30,
1186 35,
1187 40,
1188 45,
1189 50,
1190 55,
1191 60,
1192 70,
1193 80,
1194};
1195
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001196static inline int bus_width(uint cap)
1197{
1198 if (cap == MMC_MODE_8BIT)
1199 return 8;
1200 if (cap == MMC_MODE_4BIT)
1201 return 4;
1202 if (cap == MMC_MODE_1BIT)
1203 return 1;
1204 printf("invalid bus witdh capability 0x%x\n", cap);
1205 return 0;
1206}
1207
Simon Glasse7881d82017-07-29 11:35:31 -06001208#if !CONFIG_IS_ENABLED(DM_MMC)
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001209static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1210{
1211 return -ENOTSUPP;
1212}
1213
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02001214static void mmc_send_init_stream(struct mmc *mmc)
1215{
1216}
1217
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001218static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001219{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001220 int ret = 0;
1221
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001222 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001223 ret = mmc->cfg->ops->set_ios(mmc);
1224
1225 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001226}
Simon Glass8ca51e52016-06-12 23:30:22 -06001227#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001228
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001229int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001230{
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001231 if (clock > mmc->cfg->f_max)
1232 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001233
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001234 if (clock < mmc->cfg->f_min)
1235 clock = mmc->cfg->f_min;
Andy Fleming272cc702008-10-30 16:41:01 -05001236
1237 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001238 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001239
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001240 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001241}
1242
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001243static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001244{
1245 mmc->bus_width = width;
1246
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001247 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001248}
1249
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001250#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1251/*
1252 * helper function to display the capabilities in a human
1253 * friendly manner. The capabilities include bus width and
1254 * supported modes.
1255 */
1256void mmc_dump_capabilities(const char *text, uint caps)
1257{
1258 enum bus_mode mode;
1259
1260 printf("%s: widths [", text);
1261 if (caps & MMC_MODE_8BIT)
1262 printf("8, ");
1263 if (caps & MMC_MODE_4BIT)
1264 printf("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001265 if (caps & MMC_MODE_1BIT)
1266 printf("1, ");
1267 printf("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001268 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1269 if (MMC_CAP(mode) & caps)
1270 printf("%s, ", mmc_mode_name(mode));
1271 printf("\b\b]\n");
1272}
1273#endif
1274
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001275struct mode_width_tuning {
1276 enum bus_mode mode;
1277 uint widths;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001278 uint tuning;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001279};
1280
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001281static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1282{
1283 mmc->signal_voltage = signal_voltage;
1284 return mmc_set_ios(mmc);
1285}
1286
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001287static const struct mode_width_tuning sd_modes_by_pref[] = {
1288 {
1289 .mode = SD_HS,
1290 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1291 },
1292 {
1293 .mode = SD_LEGACY,
1294 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1295 }
1296};
1297
1298#define for_each_sd_mode_by_pref(caps, mwt) \
1299 for (mwt = sd_modes_by_pref;\
1300 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1301 mwt++) \
1302 if (caps & MMC_CAP(mwt->mode))
1303
1304static int sd_select_mode_and_width(struct mmc *mmc)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001305{
1306 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001307 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1308 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001309
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001310 err = sd_get_capabilities(mmc);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001311 if (err)
1312 return err;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001313 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001314 mmc->card_caps &= (mmc->cfg->host_caps | MMC_MODE_1BIT);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001315
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001316 for_each_sd_mode_by_pref(mmc->card_caps, mwt) {
1317 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001318
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001319 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
1320 if (*w & mmc->card_caps & mwt->widths) {
1321 debug("trying mode %s width %d (at %d MHz)\n",
1322 mmc_mode_name(mwt->mode),
1323 bus_width(*w),
1324 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001325
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001326 /* configure the bus width (card + host) */
1327 err = sd_select_bus_width(mmc, bus_width(*w));
1328 if (err)
1329 goto error;
1330 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001331
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001332 /* configure the bus mode (card) */
1333 err = sd_set_card_speed(mmc, mwt->mode);
1334 if (err)
1335 goto error;
1336
1337 /* configure the bus mode (host) */
1338 mmc_select_mode(mmc, mwt->mode);
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001339 mmc_set_clock(mmc, mmc->tran_speed, false);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001340
1341 err = sd_read_ssr(mmc);
1342 if (!err)
1343 return 0;
1344
1345 printf("bad ssr\n");
1346
1347error:
1348 /* revert to a safer bus speed */
1349 mmc_select_mode(mmc, SD_LEGACY);
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001350 mmc_set_clock(mmc, mmc->tran_speed, false);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001351 }
1352 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001353 }
1354
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001355 printf("unable to select a mode\n");
1356 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001357}
1358
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001359/*
1360 * read the compare the part of ext csd that is constant.
1361 * This can be used to check that the transfer is working
1362 * as expected.
1363 */
1364static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1365{
1366 int err;
1367 const u8 *ext_csd = mmc->ext_csd;
1368 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1369
1370 err = mmc_send_ext_csd(mmc, test_csd);
1371 if (err)
1372 return err;
1373
1374 /* Only compare read only fields */
1375 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1376 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1377 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1378 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1379 ext_csd[EXT_CSD_REV]
1380 == test_csd[EXT_CSD_REV] &&
1381 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1382 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1383 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1384 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1385 return 0;
1386
1387 return -EBADMSG;
1388}
1389
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001390static const struct mode_width_tuning mmc_modes_by_pref[] = {
1391 {
1392 .mode = MMC_HS_200,
1393 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001394 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001395 },
1396 {
1397 .mode = MMC_DDR_52,
1398 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1399 },
1400 {
1401 .mode = MMC_HS_52,
1402 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1403 },
1404 {
1405 .mode = MMC_HS,
1406 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1407 },
1408 {
1409 .mode = MMC_LEGACY,
1410 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1411 }
1412};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001413
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001414#define for_each_mmc_mode_by_pref(caps, mwt) \
1415 for (mwt = mmc_modes_by_pref;\
1416 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1417 mwt++) \
1418 if (caps & MMC_CAP(mwt->mode))
1419
1420static const struct ext_csd_bus_width {
1421 uint cap;
1422 bool is_ddr;
1423 uint ext_csd_bits;
1424} ext_csd_bus_width[] = {
1425 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1426 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1427 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1428 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1429 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1430};
1431
1432#define for_each_supported_width(caps, ddr, ecbv) \
1433 for (ecbv = ext_csd_bus_width;\
1434 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1435 ecbv++) \
1436 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1437
1438static int mmc_select_mode_and_width(struct mmc *mmc)
1439{
1440 int err;
1441 const struct mode_width_tuning *mwt;
1442 const struct ext_csd_bus_width *ecbw;
1443
1444 err = mmc_get_capabilities(mmc);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001445 if (err)
1446 return err;
1447
1448 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001449 mmc->card_caps &= (mmc->cfg->host_caps | MMC_MODE_1BIT);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001450
1451 /* Only version 4 of MMC supports wider bus widths */
1452 if (mmc->version < MMC_VERSION_4)
1453 return 0;
1454
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001455 if (!mmc->ext_csd) {
1456 debug("No ext_csd found!\n"); /* this should enver happen */
1457 return -ENOTSUPP;
1458 }
1459
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001460 for_each_mmc_mode_by_pref(mmc->card_caps, mwt) {
1461 for_each_supported_width(mmc->card_caps & mwt->widths,
1462 mmc_is_mode_ddr(mwt->mode), ecbw) {
1463 debug("trying mode %s width %d (at %d MHz)\n",
1464 mmc_mode_name(mwt->mode),
1465 bus_width(ecbw->cap),
1466 mmc_mode2freq(mmc, mwt->mode) / 1000000);
1467 /* configure the bus width (card + host) */
1468 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1469 EXT_CSD_BUS_WIDTH,
1470 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
1471 if (err)
1472 goto error;
1473 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
1474
1475 /* configure the bus speed (card) */
1476 err = mmc_set_card_speed(mmc, mwt->mode);
1477 if (err)
1478 goto error;
1479
1480 /*
1481 * configure the bus width AND the ddr mode (card)
1482 * The host side will be taken care of in the next step
1483 */
1484 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
1485 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1486 EXT_CSD_BUS_WIDTH,
1487 ecbw->ext_csd_bits);
1488 if (err)
1489 goto error;
1490 }
1491
1492 /* configure the bus mode (host) */
1493 mmc_select_mode(mmc, mwt->mode);
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001494 mmc_set_clock(mmc, mmc->tran_speed, false);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001495
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001496 /* execute tuning if needed */
1497 if (mwt->tuning) {
1498 err = mmc_execute_tuning(mmc, mwt->tuning);
1499 if (err) {
1500 debug("tuning failed\n");
1501 goto error;
1502 }
1503 }
1504
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001505 /* do a transfer to check the configuration */
1506 err = mmc_read_and_compare_ext_csd(mmc);
1507 if (!err)
1508 return 0;
1509error:
1510 /* if an error occured, revert to a safer bus mode */
1511 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1512 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
1513 mmc_select_mode(mmc, MMC_LEGACY);
1514 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001515 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001516 }
1517
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001518 printf("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001519
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001520 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001521}
1522
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001523static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02001524{
1525 int err, i;
1526 u64 capacity;
1527 bool has_parts = false;
1528 bool part_completed;
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001529 u8 *ext_csd;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02001530
1531 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
1532 return 0;
1533
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001534 ext_csd = malloc_cache_aligned(MMC_MAX_BLOCK_LEN);
1535 if (!ext_csd)
1536 return -ENOMEM;
1537
1538 mmc->ext_csd = ext_csd;
1539
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02001540 /* check ext_csd version and capacity */
1541 err = mmc_send_ext_csd(mmc, ext_csd);
1542 if (err)
1543 return err;
1544 if (ext_csd[EXT_CSD_REV] >= 2) {
1545 /*
1546 * According to the JEDEC Standard, the value of
1547 * ext_csd's capacity is valid if the value is more
1548 * than 2GB
1549 */
1550 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
1551 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
1552 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
1553 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
1554 capacity *= MMC_MAX_BLOCK_LEN;
1555 if ((capacity >> 20) > 2 * 1024)
1556 mmc->capacity_user = capacity;
1557 }
1558
1559 switch (ext_csd[EXT_CSD_REV]) {
1560 case 1:
1561 mmc->version = MMC_VERSION_4_1;
1562 break;
1563 case 2:
1564 mmc->version = MMC_VERSION_4_2;
1565 break;
1566 case 3:
1567 mmc->version = MMC_VERSION_4_3;
1568 break;
1569 case 5:
1570 mmc->version = MMC_VERSION_4_41;
1571 break;
1572 case 6:
1573 mmc->version = MMC_VERSION_4_5;
1574 break;
1575 case 7:
1576 mmc->version = MMC_VERSION_5_0;
1577 break;
1578 case 8:
1579 mmc->version = MMC_VERSION_5_1;
1580 break;
1581 }
1582
1583 /* The partition data may be non-zero but it is only
1584 * effective if PARTITION_SETTING_COMPLETED is set in
1585 * EXT_CSD, so ignore any data if this bit is not set,
1586 * except for enabling the high-capacity group size
1587 * definition (see below).
1588 */
1589 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
1590 EXT_CSD_PARTITION_SETTING_COMPLETED);
1591
1592 /* store the partition info of emmc */
1593 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
1594 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
1595 ext_csd[EXT_CSD_BOOT_MULT])
1596 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
1597 if (part_completed &&
1598 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
1599 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
1600
1601 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
1602
1603 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
1604
1605 for (i = 0; i < 4; i++) {
1606 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
1607 uint mult = (ext_csd[idx + 2] << 16) +
1608 (ext_csd[idx + 1] << 8) + ext_csd[idx];
1609 if (mult)
1610 has_parts = true;
1611 if (!part_completed)
1612 continue;
1613 mmc->capacity_gp[i] = mult;
1614 mmc->capacity_gp[i] *=
1615 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1616 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1617 mmc->capacity_gp[i] <<= 19;
1618 }
1619
1620 if (part_completed) {
1621 mmc->enh_user_size =
1622 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
1623 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
1624 ext_csd[EXT_CSD_ENH_SIZE_MULT];
1625 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
1626 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1627 mmc->enh_user_size <<= 19;
1628 mmc->enh_user_start =
1629 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
1630 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
1631 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
1632 ext_csd[EXT_CSD_ENH_START_ADDR];
1633 if (mmc->high_capacity)
1634 mmc->enh_user_start <<= 9;
1635 }
1636
1637 /*
1638 * Host needs to enable ERASE_GRP_DEF bit if device is
1639 * partitioned. This bit will be lost every time after a reset
1640 * or power off. This will affect erase size.
1641 */
1642 if (part_completed)
1643 has_parts = true;
1644 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
1645 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
1646 has_parts = true;
1647 if (has_parts) {
1648 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1649 EXT_CSD_ERASE_GROUP_DEF, 1);
1650
1651 if (err)
1652 return err;
1653
1654 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1655 }
1656
1657 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
1658 /* Read out group size from ext_csd */
1659 mmc->erase_grp_size =
1660 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1661 /*
1662 * if high capacity and partition setting completed
1663 * SEC_COUNT is valid even if it is smaller than 2 GiB
1664 * JEDEC Standard JESD84-B45, 6.2.4
1665 */
1666 if (mmc->high_capacity && part_completed) {
1667 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
1668 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
1669 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
1670 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1671 capacity *= MMC_MAX_BLOCK_LEN;
1672 mmc->capacity_user = capacity;
1673 }
1674 } else {
1675 /* Calculate the group size from the csd value. */
1676 int erase_gsz, erase_gmul;
1677
1678 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
1679 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
1680 mmc->erase_grp_size = (erase_gsz + 1)
1681 * (erase_gmul + 1);
1682 }
1683
1684 mmc->hc_wp_grp_size = 1024
1685 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1686 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1687
1688 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1689
1690 return 0;
1691}
1692
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001693static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001694{
Stephen Warrenf866a462013-06-11 15:14:01 -06001695 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05001696 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02001697 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05001698 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06001699 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05001700
Thomas Choud52ebf12010-12-24 13:12:21 +00001701#ifdef CONFIG_MMC_SPI_CRC_ON
1702 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
1703 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
1704 cmd.resp_type = MMC_RSP_R1;
1705 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001706 err = mmc_send_cmd(mmc, &cmd, NULL);
1707
1708 if (err)
1709 return err;
1710 }
1711#endif
1712
Andy Fleming272cc702008-10-30 16:41:01 -05001713 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001714 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
1715 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05001716 cmd.resp_type = MMC_RSP_R2;
1717 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001718
1719 err = mmc_send_cmd(mmc, &cmd, NULL);
1720
1721 if (err)
1722 return err;
1723
1724 memcpy(mmc->cid, cmd.response, 16);
1725
1726 /*
1727 * For MMC cards, set the Relative Address.
1728 * For SD cards, get the Relatvie Address.
1729 * This also puts the cards into Standby State
1730 */
Thomas Choud52ebf12010-12-24 13:12:21 +00001731 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1732 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
1733 cmd.cmdarg = mmc->rca << 16;
1734 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05001735
Thomas Choud52ebf12010-12-24 13:12:21 +00001736 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001737
Thomas Choud52ebf12010-12-24 13:12:21 +00001738 if (err)
1739 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001740
Thomas Choud52ebf12010-12-24 13:12:21 +00001741 if (IS_SD(mmc))
1742 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
1743 }
Andy Fleming272cc702008-10-30 16:41:01 -05001744
1745 /* Get the Card-Specific Data */
1746 cmd.cmdidx = MMC_CMD_SEND_CSD;
1747 cmd.resp_type = MMC_RSP_R2;
1748 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001749
1750 err = mmc_send_cmd(mmc, &cmd, NULL);
1751
1752 if (err)
1753 return err;
1754
Rabin Vincent998be3d2009-04-05 13:30:56 +05301755 mmc->csd[0] = cmd.response[0];
1756 mmc->csd[1] = cmd.response[1];
1757 mmc->csd[2] = cmd.response[2];
1758 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05001759
1760 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301761 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05001762
1763 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07001764 case 0:
1765 mmc->version = MMC_VERSION_1_2;
1766 break;
1767 case 1:
1768 mmc->version = MMC_VERSION_1_4;
1769 break;
1770 case 2:
1771 mmc->version = MMC_VERSION_2_2;
1772 break;
1773 case 3:
1774 mmc->version = MMC_VERSION_3;
1775 break;
1776 case 4:
1777 mmc->version = MMC_VERSION_4;
1778 break;
1779 default:
1780 mmc->version = MMC_VERSION_1_2;
1781 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001782 }
1783 }
1784
1785 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05301786 freq = fbase[(cmd.response[0] & 0x7)];
1787 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05001788
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02001789 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02001790 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001791
Markus Niebelab711882013-12-16 13:40:46 +01001792 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05301793 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001794
1795 if (IS_SD(mmc))
1796 mmc->write_bl_len = mmc->read_bl_len;
1797 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05301798 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Andy Fleming272cc702008-10-30 16:41:01 -05001799
1800 if (mmc->high_capacity) {
1801 csize = (mmc->csd[1] & 0x3f) << 16
1802 | (mmc->csd[2] & 0xffff0000) >> 16;
1803 cmult = 8;
1804 } else {
1805 csize = (mmc->csd[1] & 0x3ff) << 2
1806 | (mmc->csd[2] & 0xc0000000) >> 30;
1807 cmult = (mmc->csd[2] & 0x00038000) >> 15;
1808 }
1809
Stephen Warrenf866a462013-06-11 15:14:01 -06001810 mmc->capacity_user = (csize + 1) << (cmult + 2);
1811 mmc->capacity_user *= mmc->read_bl_len;
1812 mmc->capacity_boot = 0;
1813 mmc->capacity_rpmb = 0;
1814 for (i = 0; i < 4; i++)
1815 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001816
Simon Glass8bfa1952013-04-03 08:54:30 +00001817 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
1818 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001819
Simon Glass8bfa1952013-04-03 08:54:30 +00001820 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
1821 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05001822
Markus Niebelab711882013-12-16 13:40:46 +01001823 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
1824 cmd.cmdidx = MMC_CMD_SET_DSR;
1825 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
1826 cmd.resp_type = MMC_RSP_NONE;
1827 if (mmc_send_cmd(mmc, &cmd, NULL))
1828 printf("MMC: SET_DSR failed\n");
1829 }
1830
Andy Fleming272cc702008-10-30 16:41:01 -05001831 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00001832 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
1833 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00001834 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00001835 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00001836 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05001837
Thomas Choud52ebf12010-12-24 13:12:21 +00001838 if (err)
1839 return err;
1840 }
Andy Fleming272cc702008-10-30 16:41:01 -05001841
Lei Wene6f99a52011-06-22 17:03:31 +00001842 /*
1843 * For SD, its erase group is always one sector
1844 */
1845 mmc->erase_grp_size = 1;
Lei Wenbc897b12011-05-02 16:26:26 +00001846 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00001847
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001848 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02001849 if (err)
1850 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05301851
Simon Glassc40fdca2016-05-01 13:52:35 -06001852 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06001853 if (err)
1854 return err;
1855
Andy Fleming272cc702008-10-30 16:41:01 -05001856 if (IS_SD(mmc))
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001857 err = sd_select_mode_and_width(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001858 else
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001859 err = mmc_select_mode_and_width(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001860
1861 if (err)
1862 return err;
1863
Jaehoon Chungad5fd922012-03-26 21:16:03 +00001864
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06001865 /* Fix the block length for DDR mode */
1866 if (mmc->ddr_mode) {
1867 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
1868 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
1869 }
1870
Andy Fleming272cc702008-10-30 16:41:01 -05001871 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06001872 bdesc = mmc_get_blk_desc(mmc);
1873 bdesc->lun = 0;
1874 bdesc->hwpart = 0;
1875 bdesc->type = 0;
1876 bdesc->blksz = mmc->read_bl_len;
1877 bdesc->log2blksz = LOG2(bdesc->blksz);
1878 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01001879#if !defined(CONFIG_SPL_BUILD) || \
1880 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
1881 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06001882 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00001883 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
1884 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001885 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001886 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
1887 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
1888 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06001889 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00001890 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01001891#else
Simon Glassc40fdca2016-05-01 13:52:35 -06001892 bdesc->vendor[0] = 0;
1893 bdesc->product[0] = 0;
1894 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01001895#endif
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001896#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
Simon Glassc40fdca2016-05-01 13:52:35 -06001897 part_init(bdesc);
Mikhail Kshevetskiy122efd42012-07-09 08:53:38 +00001898#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001899
1900 return 0;
1901}
1902
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001903static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001904{
1905 struct mmc_cmd cmd;
1906 int err;
1907
1908 cmd.cmdidx = SD_CMD_SEND_IF_COND;
1909 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001910 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05001911 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05001912
1913 err = mmc_send_cmd(mmc, &cmd, NULL);
1914
1915 if (err)
1916 return err;
1917
Rabin Vincent998be3d2009-04-05 13:30:56 +05301918 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09001919 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05001920 else
1921 mmc->version = SD_VERSION_2;
1922
1923 return 0;
1924}
1925
Simon Glassc4d660d2017-07-04 13:31:19 -06001926#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001927/* board-specific MMC power initializations. */
1928__weak void board_mmc_power_init(void)
1929{
1930}
Simon Glass05cbeb72017-04-22 19:10:56 -06001931#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01001932
Peng Fan2051aef2016-10-11 15:08:43 +08001933static int mmc_power_init(struct mmc *mmc)
1934{
Simon Glassc4d660d2017-07-04 13:31:19 -06001935#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02001936#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08001937 int ret;
1938
1939 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02001940 &mmc->vmmc_supply);
1941 if (ret)
Jaehoon Chung288db7c2016-10-24 15:22:22 +09001942 debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08001943
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02001944 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
1945 &mmc->vqmmc_supply);
1946 if (ret)
1947 debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08001948#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06001949#else /* !CONFIG_DM_MMC */
1950 /*
1951 * Driver model should use a regulator, as above, rather than calling
1952 * out to board code.
1953 */
1954 board_mmc_power_init();
1955#endif
Peng Fan2051aef2016-10-11 15:08:43 +08001956 return 0;
1957}
1958
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02001959/*
1960 * put the host in the initial state:
1961 * - turn on Vdd (card power supply)
1962 * - configure the bus width and clock to minimal values
1963 */
1964static void mmc_set_initial_state(struct mmc *mmc)
1965{
1966 int err;
1967
1968 /* First try to set 3.3V. If it fails set to 1.8V */
1969 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
1970 if (err != 0)
1971 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
1972 if (err != 0)
1973 printf("mmc: failed to set signal voltage\n");
1974
1975 mmc_select_mode(mmc, MMC_LEGACY);
1976 mmc_set_bus_width(mmc, 1);
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001977 mmc_set_clock(mmc, 0, false);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02001978}
1979
1980static int mmc_power_on(struct mmc *mmc)
1981{
1982#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
1983 if (mmc->vmmc_supply) {
1984 int ret = regulator_set_enable(mmc->vmmc_supply, true);
1985
1986 if (ret) {
1987 puts("Error enabling VMMC supply\n");
1988 return ret;
1989 }
1990 }
1991#endif
1992 return 0;
1993}
1994
1995static int mmc_power_off(struct mmc *mmc)
1996{
Kishon Vijay Abraham I2e7410d2017-09-21 16:30:04 +02001997 mmc_set_clock(mmc, 1, true);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02001998#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
1999 if (mmc->vmmc_supply) {
2000 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2001
2002 if (ret) {
2003 puts("Error disabling VMMC supply\n");
2004 return ret;
2005 }
2006 }
2007#endif
2008 return 0;
2009}
2010
2011static int mmc_power_cycle(struct mmc *mmc)
2012{
2013 int ret;
2014
2015 ret = mmc_power_off(mmc);
2016 if (ret)
2017 return ret;
2018 /*
2019 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2020 * to be on the safer side.
2021 */
2022 udelay(2000);
2023 return mmc_power_on(mmc);
2024}
2025
Che-Liang Chioue9550442012-11-28 15:21:13 +00002026int mmc_start_init(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002027{
Simon Glass8ca51e52016-06-12 23:30:22 -06002028 bool no_card;
Macpaul Linafd59322011-11-14 23:35:39 +00002029 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002030
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002031 /* we pretend there's no card when init is NULL */
Simon Glass8ca51e52016-06-12 23:30:22 -06002032 no_card = mmc_getcd(mmc) == 0;
Simon Glasse7881d82017-07-29 11:35:31 -06002033#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002034 no_card = no_card || (mmc->cfg->ops->init == NULL);
2035#endif
2036 if (no_card) {
Thierry Reding48972d92012-01-02 01:15:37 +00002037 mmc->has_init = 0;
Paul Burton56196822013-09-04 16:12:25 +01002038#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Thierry Reding48972d92012-01-02 01:15:37 +00002039 printf("MMC: no card present\n");
Paul Burton56196822013-09-04 16:12:25 +01002040#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002041 return -ENOMEDIUM;
Thierry Reding48972d92012-01-02 01:15:37 +00002042 }
2043
Lei Wenbc897b12011-05-02 16:26:26 +00002044 if (mmc->has_init)
2045 return 0;
2046
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002047#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2048 mmc_adapter_card_type_ident();
2049#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002050 err = mmc_power_init(mmc);
2051 if (err)
2052 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002053
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002054 err = mmc_power_on(mmc);
2055 if (err)
2056 return err;
2057
Simon Glasse7881d82017-07-29 11:35:31 -06002058#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002059 /* The device has already been probed ready for use */
2060#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002061 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002062 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002063 if (err)
2064 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002065#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002066 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002067
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002068 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002069 mmc_send_init_stream(mmc);
2070
Andy Fleming272cc702008-10-30 16:41:01 -05002071 /* Reset the Card */
2072 err = mmc_go_idle(mmc);
2073
2074 if (err)
2075 return err;
2076
Lei Wenbc897b12011-05-02 16:26:26 +00002077 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002078 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002079
Andy Fleming272cc702008-10-30 16:41:01 -05002080 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002081 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002082
Andy Fleming272cc702008-10-30 16:41:01 -05002083 /* Now try to get the SD card's operating condition */
2084 err = sd_send_op_cond(mmc);
2085
2086 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002087 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002088 err = mmc_send_op_cond(mmc);
2089
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002090 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002091#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Andy Fleming272cc702008-10-30 16:41:01 -05002092 printf("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002093#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002094 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002095 }
2096 }
2097
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002098 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002099 mmc->init_in_progress = 1;
2100
2101 return err;
2102}
2103
2104static int mmc_complete_init(struct mmc *mmc)
2105{
2106 int err = 0;
2107
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002108 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002109 if (mmc->op_cond_pending)
2110 err = mmc_complete_op_cond(mmc);
2111
2112 if (!err)
2113 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002114 if (err)
2115 mmc->has_init = 0;
2116 else
2117 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002118 return err;
2119}
2120
2121int mmc_init(struct mmc *mmc)
2122{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002123 int err = 0;
Marek Vasutce9eca92016-12-01 02:06:32 +01002124 __maybe_unused unsigned start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002125#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002126 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002127
Simon Glass33fb2112016-05-01 13:52:41 -06002128 upriv->mmc = mmc;
2129#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002130 if (mmc->has_init)
2131 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002132
2133 start = get_timer(0);
2134
Che-Liang Chioue9550442012-11-28 15:21:13 +00002135 if (!mmc->init_in_progress)
2136 err = mmc_start_init(mmc);
2137
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002138 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002139 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002140 if (err)
2141 printf("%s: %d, time %lu\n", __func__, err, get_timer(start));
2142
Lei Wenbc897b12011-05-02 16:26:26 +00002143 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002144}
2145
Markus Niebelab711882013-12-16 13:40:46 +01002146int mmc_set_dsr(struct mmc *mmc, u16 val)
2147{
2148 mmc->dsr = val;
2149 return 0;
2150}
2151
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002152/* CPU-specific MMC initializations */
2153__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002154{
2155 return -1;
2156}
2157
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002158/* board-specific MMC initializations. */
2159__weak int board_mmc_init(bd_t *bis)
2160{
2161 return -1;
2162}
Andy Fleming272cc702008-10-30 16:41:01 -05002163
Che-Liang Chioue9550442012-11-28 15:21:13 +00002164void mmc_set_preinit(struct mmc *mmc, int preinit)
2165{
2166 mmc->preinit = preinit;
2167}
2168
Simon Glassc4d660d2017-07-04 13:31:19 -06002169#if CONFIG_IS_ENABLED(DM_MMC) && defined(CONFIG_SPL_BUILD)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002170static int mmc_probe(bd_t *bis)
2171{
2172 return 0;
2173}
Simon Glassc4d660d2017-07-04 13:31:19 -06002174#elif CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002175static int mmc_probe(bd_t *bis)
2176{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002177 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002178 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002179 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002180
2181 ret = uclass_get(UCLASS_MMC, &uc);
2182 if (ret)
2183 return ret;
2184
Simon Glass4a1db6d2015-12-29 05:22:49 -07002185 /*
2186 * Try to add them in sequence order. Really with driver model we
2187 * should allow holes, but the current MMC list does not allow that.
2188 * So if we request 0, 1, 3 we will get 0, 1, 2.
2189 */
2190 for (i = 0; ; i++) {
2191 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2192 if (ret == -ENODEV)
2193 break;
2194 }
2195 uclass_foreach_dev(dev, uc) {
2196 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002197 if (ret)
Simon Glass4a1db6d2015-12-29 05:22:49 -07002198 printf("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002199 }
2200
2201 return 0;
2202}
2203#else
2204static int mmc_probe(bd_t *bis)
2205{
2206 if (board_mmc_init(bis) < 0)
2207 cpu_mmc_init(bis);
2208
2209 return 0;
2210}
2211#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002212
Andy Fleming272cc702008-10-30 16:41:01 -05002213int mmc_initialize(bd_t *bis)
2214{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002215 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002216 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002217 if (initialized) /* Avoid initializing mmc multiple times */
2218 return 0;
2219 initialized = 1;
2220
Simon Glassc4d660d2017-07-04 13:31:19 -06002221#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002222#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002223 mmc_list_init();
2224#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002225#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002226 ret = mmc_probe(bis);
2227 if (ret)
2228 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002229
Ying Zhangbb0dc102013-08-16 15:16:11 +08002230#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002231 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002232#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002233
Simon Glassc40fdca2016-05-01 13:52:35 -06002234 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002235 return 0;
2236}
Tomas Melincd3d4882016-11-25 11:01:03 +02002237
2238#ifdef CONFIG_CMD_BKOPS_ENABLE
2239int mmc_set_bkops_enable(struct mmc *mmc)
2240{
2241 int err;
2242 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2243
2244 err = mmc_send_ext_csd(mmc, ext_csd);
2245 if (err) {
2246 puts("Could not get ext_csd register values\n");
2247 return err;
2248 }
2249
2250 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2251 puts("Background operations not supported on device\n");
2252 return -EMEDIUMTYPE;
2253 }
2254
2255 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2256 puts("Background operations already enabled\n");
2257 return 0;
2258 }
2259
2260 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2261 if (err) {
2262 puts("Failed to enable manual background operations\n");
2263 return err;
2264 }
2265
2266 puts("Enabled manual background operations\n");
2267
2268 return 0;
2269}
2270#endif