blob: 709733747abcb896c064afb03edb74c7f608ad4c [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Fleming272cc702008-10-30 16:41:01 -05002/*
3 * Copyright 2008, Freescale Semiconductor, Inc
4 * Andy Fleming
5 *
6 * Based vaguely on the Linux code
Andy Fleming272cc702008-10-30 16:41:01 -05007 */
8
9#include <config.h>
10#include <common.h>
11#include <command.h>
Sjoerd Simons8e3332e2015-08-30 16:55:45 -060012#include <dm.h>
13#include <dm/device-internal.h>
Stephen Warrend4622df2014-05-23 12:47:06 -060014#include <errno.h>
Andy Fleming272cc702008-10-30 16:41:01 -050015#include <mmc.h>
16#include <part.h>
Peng Fan2051aef2016-10-11 15:08:43 +080017#include <power/regulator.h>
Andy Fleming272cc702008-10-30 16:41:01 -050018#include <malloc.h>
Simon Glasscf92e052015-09-02 17:24:58 -060019#include <memalign.h>
Andy Fleming272cc702008-10-30 16:41:01 -050020#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053021#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010022#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050023
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +020024#define DEFAULT_CMD6_TIMEOUT_MS 500
25
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +020026static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +020027static int mmc_power_cycle(struct mmc *mmc);
Marek Vasut62d77ce2018-04-15 00:37:11 +020028#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +020029static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
Marek Vasutb5b838f2016-12-01 02:06:33 +010030#endif
31
Simon Glasse7881d82017-07-29 11:35:31 -060032#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020033
34static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
35{
36 return -ENOSYS;
37}
38
Jeroen Hofstee750121c2014-07-12 21:24:08 +020039__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000040{
41 return -1;
42}
43
44int mmc_getwp(struct mmc *mmc)
45{
46 int wp;
47
48 wp = board_mmc_getwp(mmc);
49
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000050 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020051 if (mmc->cfg->ops->getwp)
52 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000053 else
54 wp = 0;
55 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000056
57 return wp;
58}
59
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020060__weak int board_mmc_getcd(struct mmc *mmc)
61{
Stefano Babic11fdade2010-02-05 15:04:43 +010062 return -1;
63}
Simon Glass8ca51e52016-06-12 23:30:22 -060064#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010065
Marek Vasut8635ff92012-03-15 18:41:35 +000066#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060067void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
68{
69 printf("CMD_SEND:%d\n", cmd->cmdidx);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010070 printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
Simon Glassc0c76eb2016-06-12 23:30:20 -060071}
72
73void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
74{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000075 int i;
76 u8 *ptr;
77
Bin Meng7863ce52016-03-17 21:53:14 -070078 if (ret) {
79 printf("\t\tRET\t\t\t %d\n", ret);
80 } else {
81 switch (cmd->resp_type) {
82 case MMC_RSP_NONE:
83 printf("\t\tMMC_RSP_NONE\n");
84 break;
85 case MMC_RSP_R1:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010086 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070087 cmd->response[0]);
88 break;
89 case MMC_RSP_R1b:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010090 printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070091 cmd->response[0]);
92 break;
93 case MMC_RSP_R2:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010094 printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070095 cmd->response[0]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010096 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070097 cmd->response[1]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010098 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070099 cmd->response[2]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100100 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700101 cmd->response[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000102 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -0700103 printf("\t\t\t\t\tDUMPING DATA\n");
104 for (i = 0; i < 4; i++) {
105 int j;
106 printf("\t\t\t\t\t%03d - ", i*4);
107 ptr = (u8 *)&cmd->response[i];
108 ptr += 3;
109 for (j = 0; j < 4; j++)
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100110 printf("%02x ", *ptr--);
Bin Meng7863ce52016-03-17 21:53:14 -0700111 printf("\n");
112 }
113 break;
114 case MMC_RSP_R3:
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100115 printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700116 cmd->response[0]);
117 break;
118 default:
119 printf("\t\tERROR MMC rsp not supported\n");
120 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700121 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000122 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600123}
124
125void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
126{
127 int status;
128
129 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
130 printf("CURR STATE:%d\n", status);
131}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000132#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600133
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200134#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
135const char *mmc_mode_name(enum bus_mode mode)
136{
137 static const char *const names[] = {
138 [MMC_LEGACY] = "MMC legacy",
139 [SD_LEGACY] = "SD Legacy",
140 [MMC_HS] = "MMC High Speed (26MHz)",
141 [SD_HS] = "SD High Speed (50MHz)",
142 [UHS_SDR12] = "UHS SDR12 (25MHz)",
143 [UHS_SDR25] = "UHS SDR25 (50MHz)",
144 [UHS_SDR50] = "UHS SDR50 (100MHz)",
145 [UHS_SDR104] = "UHS SDR104 (208MHz)",
146 [UHS_DDR50] = "UHS DDR50 (50MHz)",
147 [MMC_HS_52] = "MMC High Speed (52MHz)",
148 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
149 [MMC_HS_200] = "HS200 (200MHz)",
Peng Fan3dd26262018-08-10 14:07:54 +0800150 [MMC_HS_400] = "HS400 (200MHz)",
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200151 };
152
153 if (mode >= MMC_MODES_END)
154 return "Unknown mode";
155 else
156 return names[mode];
157}
158#endif
159
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200160static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
161{
162 static const int freqs[] = {
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900163 [MMC_LEGACY] = 25000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200164 [SD_LEGACY] = 25000000,
165 [MMC_HS] = 26000000,
166 [SD_HS] = 50000000,
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900167 [MMC_HS_52] = 52000000,
168 [MMC_DDR_52] = 52000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200169 [UHS_SDR12] = 25000000,
170 [UHS_SDR25] = 50000000,
171 [UHS_SDR50] = 100000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200172 [UHS_DDR50] = 50000000,
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100173 [UHS_SDR104] = 208000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200174 [MMC_HS_200] = 200000000,
Peng Fan3dd26262018-08-10 14:07:54 +0800175 [MMC_HS_400] = 200000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200176 };
177
178 if (mode == MMC_LEGACY)
179 return mmc->legacy_speed;
180 else if (mode >= MMC_MODES_END)
181 return 0;
182 else
183 return freqs[mode];
184}
185
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200186static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
187{
188 mmc->selected_mode = mode;
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200189 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200190 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900191 pr_debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
192 mmc->tran_speed / 1000000);
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200193 return 0;
194}
195
Simon Glasse7881d82017-07-29 11:35:31 -0600196#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassc0c76eb2016-06-12 23:30:20 -0600197int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
198{
199 int ret;
200
201 mmmc_trace_before_send(mmc, cmd);
202 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
203 mmmc_trace_after_send(mmc, cmd, ret);
204
Marek Vasut8635ff92012-03-15 18:41:35 +0000205 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500206}
Simon Glass8ca51e52016-06-12 23:30:22 -0600207#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500208
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200209int mmc_send_status(struct mmc *mmc, unsigned int *status)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000210{
211 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000212 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000213
214 cmd.cmdidx = MMC_CMD_SEND_STATUS;
215 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200216 if (!mmc_host_is_spi(mmc))
217 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000218
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200219 while (retries--) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000220 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000221 if (!err) {
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200222 mmc_trace_state(mmc, &cmd);
223 *status = cmd.response[0];
224 return 0;
225 }
226 }
227 mmc_trace_state(mmc, &cmd);
228 return -ECOMM;
229}
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200230
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200231int mmc_poll_for_busy(struct mmc *mmc, int timeout)
232{
233 unsigned int status;
234 int err;
235
Jean-Jacques Hiblotcd0b80e2019-07-02 10:53:53 +0200236 err = mmc_wait_dat0(mmc, 1, timeout);
237 if (err != -ENOSYS)
238 return err;
239
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200240 while (1) {
241 err = mmc_send_status(mmc, &status);
242 if (err)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000243 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000244
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200245 if ((status & MMC_STATUS_RDY_FOR_DATA) &&
246 (status & MMC_STATUS_CURR_STATE) !=
247 MMC_STATE_PRG)
248 break;
249
250 if (status & MMC_STATUS_MASK) {
251#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
252 pr_err("Status Error: 0x%08x\n", status);
253#endif
254 return -ECOMM;
255 }
256
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500257 if (timeout-- <= 0)
258 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000259
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500260 udelay(1000);
261 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000262
Jongman Heo5b0c9422012-06-03 21:32:13 +0000263 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100264#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100265 pr_err("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100266#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900267 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000268 }
269
270 return 0;
271}
272
Paul Burtonda61fa52013-09-09 15:30:26 +0100273int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500274{
275 struct mmc_cmd cmd;
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200276 int err;
Andy Fleming272cc702008-10-30 16:41:01 -0500277
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600278 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900279 return 0;
280
Andy Fleming272cc702008-10-30 16:41:01 -0500281 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
282 cmd.resp_type = MMC_RSP_R1;
283 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500284
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200285 err = mmc_send_cmd(mmc, &cmd, NULL);
286
287#ifdef CONFIG_MMC_QUIRKS
288 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
289 int retries = 4;
290 /*
291 * It has been seen that SET_BLOCKLEN may fail on the first
292 * attempt, let's try a few more time
293 */
294 do {
295 err = mmc_send_cmd(mmc, &cmd, NULL);
296 if (!err)
297 break;
298 } while (retries--);
299 }
300#endif
301
302 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500303}
304
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100305#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200306static const u8 tuning_blk_pattern_4bit[] = {
307 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
308 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
309 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
310 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
311 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
312 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
313 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
314 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
315};
316
317static const u8 tuning_blk_pattern_8bit[] = {
318 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
319 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
320 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
321 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
322 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
323 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
324 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
325 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
326 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
327 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
328 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
329 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
330 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
331 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
332 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
333 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
334};
335
336int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
337{
338 struct mmc_cmd cmd;
339 struct mmc_data data;
340 const u8 *tuning_block_pattern;
341 int size, err;
342
343 if (mmc->bus_width == 8) {
344 tuning_block_pattern = tuning_blk_pattern_8bit;
345 size = sizeof(tuning_blk_pattern_8bit);
346 } else if (mmc->bus_width == 4) {
347 tuning_block_pattern = tuning_blk_pattern_4bit;
348 size = sizeof(tuning_blk_pattern_4bit);
349 } else {
350 return -EINVAL;
351 }
352
353 ALLOC_CACHE_ALIGN_BUFFER(u8, data_buf, size);
354
355 cmd.cmdidx = opcode;
356 cmd.cmdarg = 0;
357 cmd.resp_type = MMC_RSP_R1;
358
359 data.dest = (void *)data_buf;
360 data.blocks = 1;
361 data.blocksize = size;
362 data.flags = MMC_DATA_READ;
363
364 err = mmc_send_cmd(mmc, &cmd, &data);
365 if (err)
366 return err;
367
368 if (memcmp(data_buf, tuning_block_pattern, size))
369 return -EIO;
370
371 return 0;
372}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100373#endif
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200374
Sascha Silbeff8fef52013-06-14 13:07:25 +0200375static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000376 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500377{
378 struct mmc_cmd cmd;
379 struct mmc_data data;
380
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700381 if (blkcnt > 1)
382 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
383 else
384 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500385
386 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700387 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500388 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700389 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500390
391 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500392
393 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700394 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500395 data.blocksize = mmc->read_bl_len;
396 data.flags = MMC_DATA_READ;
397
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700398 if (mmc_send_cmd(mmc, &cmd, &data))
399 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500400
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700401 if (blkcnt > 1) {
402 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
403 cmd.cmdarg = 0;
404 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700405 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100406#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100407 pr_err("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100408#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700409 return 0;
410 }
Andy Fleming272cc702008-10-30 16:41:01 -0500411 }
412
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700413 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500414}
415
Simon Glassc4d660d2017-07-04 13:31:19 -0600416#if CONFIG_IS_ENABLED(BLK)
Simon Glass7dba0b92016-06-12 23:30:15 -0600417ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600418#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600419ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
420 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600421#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500422{
Simon Glassc4d660d2017-07-04 13:31:19 -0600423#if CONFIG_IS_ENABLED(BLK)
Simon Glass33fb2112016-05-01 13:52:41 -0600424 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
425#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700426 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700427 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700428 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500429
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700430 if (blkcnt == 0)
431 return 0;
432
433 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500434 if (!mmc)
435 return 0;
436
Marek Vasutb5b838f2016-12-01 02:06:33 +0100437 if (CONFIG_IS_ENABLED(MMC_TINY))
438 err = mmc_switch_part(mmc, block_dev->hwpart);
439 else
440 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
441
Stephen Warren873cc1d2015-12-07 11:38:49 -0700442 if (err < 0)
443 return 0;
444
Simon Glassc40fdca2016-05-01 13:52:35 -0600445 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100446#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100447 pr_err("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
448 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100449#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800450 return 0;
451 }
Andy Fleming272cc702008-10-30 16:41:01 -0500452
Simon Glass11692992015-06-23 15:38:50 -0600453 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900454 pr_debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500455 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600456 }
Andy Fleming272cc702008-10-30 16:41:01 -0500457
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700458 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200459 cur = (blocks_todo > mmc->cfg->b_max) ?
460 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600461 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900462 pr_debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700463 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600464 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700465 blocks_todo -= cur;
466 start += cur;
467 dst += cur * mmc->read_bl_len;
468 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500469
470 return blkcnt;
471}
472
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000473static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500474{
475 struct mmc_cmd cmd;
476 int err;
477
478 udelay(1000);
479
480 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
481 cmd.cmdarg = 0;
482 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500483
484 err = mmc_send_cmd(mmc, &cmd, NULL);
485
486 if (err)
487 return err;
488
489 udelay(2000);
490
491 return 0;
492}
493
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100494#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200495static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
496{
497 struct mmc_cmd cmd;
498 int err = 0;
499
500 /*
501 * Send CMD11 only if the request is to switch the card to
502 * 1.8V signalling.
503 */
504 if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
505 return mmc_set_signal_voltage(mmc, signal_voltage);
506
507 cmd.cmdidx = SD_CMD_SWITCH_UHS18V;
508 cmd.cmdarg = 0;
509 cmd.resp_type = MMC_RSP_R1;
510
511 err = mmc_send_cmd(mmc, &cmd, NULL);
512 if (err)
513 return err;
514
515 if (!mmc_host_is_spi(mmc) && (cmd.response[0] & MMC_STATUS_ERROR))
516 return -EIO;
517
518 /*
519 * The card should drive cmd and dat[0:3] low immediately
520 * after the response of cmd11, but wait 100 us to be sure
521 */
522 err = mmc_wait_dat0(mmc, 0, 100);
523 if (err == -ENOSYS)
524 udelay(100);
525 else if (err)
526 return -ETIMEDOUT;
527
528 /*
529 * During a signal voltage level switch, the clock must be gated
530 * for 5 ms according to the SD spec
531 */
Jaehoon Chung65117182018-01-26 19:25:29 +0900532 mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200533
534 err = mmc_set_signal_voltage(mmc, signal_voltage);
535 if (err)
536 return err;
537
538 /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
539 mdelay(10);
Jaehoon Chung65117182018-01-26 19:25:29 +0900540 mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200541
542 /*
543 * Failure to switch is indicated by the card holding
544 * dat[0:3] low. Wait for at least 1 ms according to spec
545 */
546 err = mmc_wait_dat0(mmc, 1, 1000);
547 if (err == -ENOSYS)
548 udelay(1000);
549 else if (err)
550 return -ETIMEDOUT;
551
552 return 0;
553}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100554#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200555
556static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
Andy Fleming272cc702008-10-30 16:41:01 -0500557{
558 int timeout = 1000;
559 int err;
560 struct mmc_cmd cmd;
561
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500562 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500563 cmd.cmdidx = MMC_CMD_APP_CMD;
564 cmd.resp_type = MMC_RSP_R1;
565 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500566
567 err = mmc_send_cmd(mmc, &cmd, NULL);
568
569 if (err)
570 return err;
571
572 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
573 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100574
575 /*
576 * Most cards do not answer if some reserved bits
577 * in the ocr are set. However, Some controller
578 * can set bit 7 (reserved for low voltages), but
579 * how to manage low voltages SD card is not yet
580 * specified.
581 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000582 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200583 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500584
585 if (mmc->version == SD_VERSION_2)
586 cmd.cmdarg |= OCR_HCS;
587
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200588 if (uhs_en)
589 cmd.cmdarg |= OCR_S18R;
590
Andy Fleming272cc702008-10-30 16:41:01 -0500591 err = mmc_send_cmd(mmc, &cmd, NULL);
592
593 if (err)
594 return err;
595
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500596 if (cmd.response[0] & OCR_BUSY)
597 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500598
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500599 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900600 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500601
602 udelay(1000);
603 }
Andy Fleming272cc702008-10-30 16:41:01 -0500604
605 if (mmc->version != SD_VERSION_2)
606 mmc->version = SD_VERSION_1_0;
607
Thomas Choud52ebf12010-12-24 13:12:21 +0000608 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
609 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
610 cmd.resp_type = MMC_RSP_R3;
611 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000612
613 err = mmc_send_cmd(mmc, &cmd, NULL);
614
615 if (err)
616 return err;
617 }
618
Rabin Vincent998be3d2009-04-05 13:30:56 +0530619 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500620
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100621#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200622 if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x41000000)
623 == 0x41000000) {
624 err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
625 if (err)
626 return err;
627 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100628#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200629
Andy Fleming272cc702008-10-30 16:41:01 -0500630 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
631 mmc->rca = 0;
632
633 return 0;
634}
635
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500636static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500637{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500638 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500639 int err;
640
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500641 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
642 cmd.resp_type = MMC_RSP_R3;
643 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500644 if (use_arg && !mmc_host_is_spi(mmc))
645 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200646 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500647 (mmc->ocr & OCR_VOLTAGE_MASK)) |
648 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000649
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500650 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000651 if (err)
652 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500653 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000654 return 0;
655}
656
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200657static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000658{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000659 int err, i;
660
Andy Fleming272cc702008-10-30 16:41:01 -0500661 /* Some cards seem to need this */
662 mmc_go_idle(mmc);
663
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000664 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000665 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500666 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500667 if (err)
668 return err;
669
Che-Liang Chioue9550442012-11-28 15:21:13 +0000670 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500671 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500672 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000673 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500674 mmc->op_cond_pending = 1;
675 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000676}
Andy Fleming272cc702008-10-30 16:41:01 -0500677
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200678static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000679{
680 struct mmc_cmd cmd;
681 int timeout = 1000;
Vipul Kumar36332b62018-05-03 12:20:54 +0530682 ulong start;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000683 int err;
684
685 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500686 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lud188b112016-08-02 15:33:18 +0800687 /* Some cards seem to need this */
688 mmc_go_idle(mmc);
689
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500690 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500691 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500692 err = mmc_send_op_cond_iter(mmc, 1);
693 if (err)
694 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500695 if (mmc->ocr & OCR_BUSY)
696 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500697 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900698 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500699 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500700 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500701 }
Andy Fleming272cc702008-10-30 16:41:01 -0500702
Thomas Choud52ebf12010-12-24 13:12:21 +0000703 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
704 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
705 cmd.resp_type = MMC_RSP_R3;
706 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000707
708 err = mmc_send_cmd(mmc, &cmd, NULL);
709
710 if (err)
711 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500712
713 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000714 }
715
Andy Fleming272cc702008-10-30 16:41:01 -0500716 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500717
718 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700719 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500720
721 return 0;
722}
723
724
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000725static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500726{
727 struct mmc_cmd cmd;
728 struct mmc_data data;
729 int err;
730
731 /* Get the Card Status Register */
732 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
733 cmd.resp_type = MMC_RSP_R1;
734 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500735
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000736 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500737 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000738 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500739 data.flags = MMC_DATA_READ;
740
741 err = mmc_send_cmd(mmc, &cmd, &data);
742
743 return err;
744}
745
Marek Vasut68925502019-02-06 11:34:27 +0100746static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
747 bool send_status)
Andy Fleming272cc702008-10-30 16:41:01 -0500748{
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200749 unsigned int status, start;
Andy Fleming272cc702008-10-30 16:41:01 -0500750 struct mmc_cmd cmd;
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200751 int timeout = DEFAULT_CMD6_TIMEOUT_MS;
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200752 bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
753 (index == EXT_CSD_PART_CONF);
Maxime Riparda9003dc2016-11-04 16:18:08 +0100754 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000755 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500756
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200757 if (mmc->gen_cmd6_time)
758 timeout = mmc->gen_cmd6_time * 10;
759
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200760 if (is_part_switch && mmc->part_switch_time)
761 timeout = mmc->part_switch_time * 10;
762
Andy Fleming272cc702008-10-30 16:41:01 -0500763 cmd.cmdidx = MMC_CMD_SWITCH;
764 cmd.resp_type = MMC_RSP_R1b;
765 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000766 (index << 16) |
767 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500768
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200769 do {
Maxime Riparda9003dc2016-11-04 16:18:08 +0100770 ret = mmc_send_cmd(mmc, &cmd, NULL);
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200771 } while (ret && retries-- > 0);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000772
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200773 if (ret)
774 return ret;
775
776 start = get_timer(0);
777
778 /* poll dat0 for rdy/buys status */
779 ret = mmc_wait_dat0(mmc, 1, timeout);
780 if (ret && ret != -ENOSYS)
781 return ret;
782
783 /*
784 * In cases when not allowed to poll by using CMD13 or because we aren't
785 * capable of polling by using mmc_wait_dat0, then rely on waiting the
786 * stated timeout to be sufficient.
787 */
788 if (ret == -ENOSYS && !send_status)
789 mdelay(timeout);
790
791 /* Finally wait until the card is ready or indicates a failure
792 * to switch. It doesn't hurt to use CMD13 here even if send_status
793 * is false, because by now (after 'timeout' ms) the bus should be
794 * reliable.
795 */
796 do {
797 ret = mmc_send_status(mmc, &status);
798
799 if (!ret && (status & MMC_STATUS_SWITCH_ERROR)) {
800 pr_debug("switch failed %d/%d/0x%x !\n", set, index,
801 value);
802 return -EIO;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100803 }
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200804 if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
Marek Vasut68925502019-02-06 11:34:27 +0100805 return 0;
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200806 udelay(100);
807 } while (get_timer(start) < timeout);
Marek Vasut68925502019-02-06 11:34:27 +0100808
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200809 return -ETIMEDOUT;
Andy Fleming272cc702008-10-30 16:41:01 -0500810}
811
Marek Vasut68925502019-02-06 11:34:27 +0100812int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
813{
814 return __mmc_switch(mmc, set, index, value, true);
815}
816
Marek Vasut62d77ce2018-04-15 00:37:11 +0200817#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100818static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
819 bool hsdowngrade)
Andy Fleming272cc702008-10-30 16:41:01 -0500820{
Andy Fleming272cc702008-10-30 16:41:01 -0500821 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200822 int speed_bits;
823
824 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
825
826 switch (mode) {
827 case MMC_HS:
828 case MMC_HS_52:
829 case MMC_DDR_52:
830 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200831 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100832#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200833 case MMC_HS_200:
834 speed_bits = EXT_CSD_TIMING_HS200;
835 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100836#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800837#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
838 case MMC_HS_400:
839 speed_bits = EXT_CSD_TIMING_HS400;
840 break;
841#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200842 case MMC_LEGACY:
843 speed_bits = EXT_CSD_TIMING_LEGACY;
844 break;
845 default:
846 return -EINVAL;
847 }
Marek Vasut68925502019-02-06 11:34:27 +0100848
849 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
850 speed_bits, !hsdowngrade);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200851 if (err)
852 return err;
853
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100854#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
855 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
856 /*
857 * In case the eMMC is in HS200/HS400 mode and we are downgrading
858 * to HS mode, the card clock are still running much faster than
859 * the supported HS mode clock, so we can not reliably read out
860 * Extended CSD. Reconfigure the controller to run at HS mode.
861 */
862 if (hsdowngrade) {
863 mmc_select_mode(mmc, MMC_HS);
864 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
865 }
866#endif
867
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200868 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
869 /* Now check to see that it worked */
870 err = mmc_send_ext_csd(mmc, test_csd);
871 if (err)
872 return err;
873
874 /* No high-speed support */
875 if (!test_csd[EXT_CSD_HS_TIMING])
876 return -ENOTSUPP;
877 }
878
879 return 0;
880}
881
882static int mmc_get_capabilities(struct mmc *mmc)
883{
884 u8 *ext_csd = mmc->ext_csd;
885 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500886
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +0100887 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -0500888
Thomas Choud52ebf12010-12-24 13:12:21 +0000889 if (mmc_host_is_spi(mmc))
890 return 0;
891
Andy Fleming272cc702008-10-30 16:41:01 -0500892 /* Only version 4 supports high-speed */
893 if (mmc->version < MMC_VERSION_4)
894 return 0;
895
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200896 if (!ext_csd) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100897 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200898 return -ENOTSUPP;
899 }
900
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600901 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
902
Peng Fan3dd26262018-08-10 14:07:54 +0800903 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +0200904 mmc->cardtype = cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500905
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100906#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200907 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
908 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
909 mmc->card_caps |= MMC_MODE_HS200;
910 }
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100911#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800912#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
913 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
914 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
915 mmc->card_caps |= MMC_MODE_HS400;
916 }
917#endif
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900918 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200919 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900920 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200921 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900922 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200923 if (cardtype & EXT_CSD_CARD_TYPE_26)
924 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500925
926 return 0;
927}
Marek Vasut62d77ce2018-04-15 00:37:11 +0200928#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500929
Stephen Warrenf866a462013-06-11 15:14:01 -0600930static int mmc_set_capacity(struct mmc *mmc, int part_num)
931{
932 switch (part_num) {
933 case 0:
934 mmc->capacity = mmc->capacity_user;
935 break;
936 case 1:
937 case 2:
938 mmc->capacity = mmc->capacity_boot;
939 break;
940 case 3:
941 mmc->capacity = mmc->capacity_rpmb;
942 break;
943 case 4:
944 case 5:
945 case 6:
946 case 7:
947 mmc->capacity = mmc->capacity_gp[part_num - 4];
948 break;
949 default:
950 return -1;
951 }
952
Simon Glassc40fdca2016-05-01 13:52:35 -0600953 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600954
955 return 0;
956}
957
Simon Glass7dba0b92016-06-12 23:30:15 -0600958int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000959{
Stephen Warrenf866a462013-06-11 15:14:01 -0600960 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000961
Stephen Warrenf866a462013-06-11 15:14:01 -0600962 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
963 (mmc->part_config & ~PART_ACCESS_MASK)
964 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600965
Peter Bigot6dc93e72014-09-02 18:31:23 -0500966 /*
967 * Set the capacity if the switch succeeded or was intended
968 * to return to representing the raw device.
969 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700970 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500971 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600972 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700973 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500974
975 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000976}
977
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100978#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100979int mmc_hwpart_config(struct mmc *mmc,
980 const struct mmc_hwpart_conf *conf,
981 enum mmc_hwpart_conf_mode mode)
982{
983 u8 part_attrs = 0;
984 u32 enh_size_mult;
985 u32 enh_start_addr;
986 u32 gp_size_mult[4];
987 u32 max_enh_size_mult;
988 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100989 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100990 int i, pidx, err;
991 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
992
993 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
994 return -EINVAL;
995
996 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100997 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100998 return -EMEDIUMTYPE;
999 }
1000
1001 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001002 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001003 return -EMEDIUMTYPE;
1004 }
1005
1006 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001007 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001008 return -EMEDIUMTYPE;
1009 }
1010
1011 /* check partition alignment and total enhanced size */
1012 if (conf->user.enh_size) {
1013 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1014 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001015 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001016 "size aligned\n");
1017 return -EINVAL;
1018 }
1019 part_attrs |= EXT_CSD_ENH_USR;
1020 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1021 if (mmc->high_capacity) {
1022 enh_start_addr = conf->user.enh_start;
1023 } else {
1024 enh_start_addr = (conf->user.enh_start << 9);
1025 }
1026 } else {
1027 enh_size_mult = 0;
1028 enh_start_addr = 0;
1029 }
1030 tot_enh_size_mult += enh_size_mult;
1031
1032 for (pidx = 0; pidx < 4; pidx++) {
1033 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001034 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001035 "aligned\n", pidx+1);
1036 return -EINVAL;
1037 }
1038 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1039 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1040 part_attrs |= EXT_CSD_ENH_GP(pidx);
1041 tot_enh_size_mult += gp_size_mult[pidx];
1042 }
1043 }
1044
1045 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001046 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001047 return -EMEDIUMTYPE;
1048 }
1049
1050 err = mmc_send_ext_csd(mmc, ext_csd);
1051 if (err)
1052 return err;
1053
1054 max_enh_size_mult =
1055 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1056 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1057 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1058 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001059 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001060 tot_enh_size_mult, max_enh_size_mult);
1061 return -EMEDIUMTYPE;
1062 }
1063
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001064 /* The default value of EXT_CSD_WR_REL_SET is device
1065 * dependent, the values can only be changed if the
1066 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1067 * changed only once and before partitioning is completed. */
1068 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1069 if (conf->user.wr_rel_change) {
1070 if (conf->user.wr_rel_set)
1071 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1072 else
1073 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1074 }
1075 for (pidx = 0; pidx < 4; pidx++) {
1076 if (conf->gp_part[pidx].wr_rel_change) {
1077 if (conf->gp_part[pidx].wr_rel_set)
1078 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1079 else
1080 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1081 }
1082 }
1083
1084 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1085 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1086 puts("Card does not support host controlled partition write "
1087 "reliability settings\n");
1088 return -EMEDIUMTYPE;
1089 }
1090
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001091 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1092 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001093 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001094 return -EPERM;
1095 }
1096
1097 if (mode == MMC_HWPART_CONF_CHECK)
1098 return 0;
1099
1100 /* Partitioning requires high-capacity size definitions */
1101 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1102 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1103 EXT_CSD_ERASE_GROUP_DEF, 1);
1104
1105 if (err)
1106 return err;
1107
1108 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1109
1110 /* update erase group size to be high-capacity */
1111 mmc->erase_grp_size =
1112 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1113
1114 }
1115
1116 /* all OK, write the configuration */
1117 for (i = 0; i < 4; i++) {
1118 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1119 EXT_CSD_ENH_START_ADDR+i,
1120 (enh_start_addr >> (i*8)) & 0xFF);
1121 if (err)
1122 return err;
1123 }
1124 for (i = 0; i < 3; i++) {
1125 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1126 EXT_CSD_ENH_SIZE_MULT+i,
1127 (enh_size_mult >> (i*8)) & 0xFF);
1128 if (err)
1129 return err;
1130 }
1131 for (pidx = 0; pidx < 4; pidx++) {
1132 for (i = 0; i < 3; i++) {
1133 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1134 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1135 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1136 if (err)
1137 return err;
1138 }
1139 }
1140 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1141 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1142 if (err)
1143 return err;
1144
1145 if (mode == MMC_HWPART_CONF_SET)
1146 return 0;
1147
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001148 /* The WR_REL_SET is a write-once register but shall be
1149 * written before setting PART_SETTING_COMPLETED. As it is
1150 * write-once we can only write it when completing the
1151 * partitioning. */
1152 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1153 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1154 EXT_CSD_WR_REL_SET, wr_rel_set);
1155 if (err)
1156 return err;
1157 }
1158
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001159 /* Setting PART_SETTING_COMPLETED confirms the partition
1160 * configuration but it only becomes effective after power
1161 * cycle, so we do not adjust the partition related settings
1162 * in the mmc struct. */
1163
1164 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1165 EXT_CSD_PARTITION_SETTING,
1166 EXT_CSD_PARTITION_SETTING_COMPLETED);
1167 if (err)
1168 return err;
1169
1170 return 0;
1171}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001172#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001173
Simon Glasse7881d82017-07-29 11:35:31 -06001174#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001175int mmc_getcd(struct mmc *mmc)
1176{
1177 int cd;
1178
1179 cd = board_mmc_getcd(mmc);
1180
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001181 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001182 if (mmc->cfg->ops->getcd)
1183 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001184 else
1185 cd = 1;
1186 }
Thierry Reding48972d92012-01-02 01:15:37 +00001187
1188 return cd;
1189}
Simon Glass8ca51e52016-06-12 23:30:22 -06001190#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001191
Marek Vasut62d77ce2018-04-15 00:37:11 +02001192#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001193static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001194{
1195 struct mmc_cmd cmd;
1196 struct mmc_data data;
1197
1198 /* Switch the frequency */
1199 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1200 cmd.resp_type = MMC_RSP_R1;
1201 cmd.cmdarg = (mode << 31) | 0xffffff;
1202 cmd.cmdarg &= ~(0xf << (group * 4));
1203 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001204
1205 data.dest = (char *)resp;
1206 data.blocksize = 64;
1207 data.blocks = 1;
1208 data.flags = MMC_DATA_READ;
1209
1210 return mmc_send_cmd(mmc, &cmd, &data);
1211}
1212
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001213static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001214{
1215 int err;
1216 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301217 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1218 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001219 struct mmc_data data;
1220 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001221#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001222 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001223#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001224
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +01001225 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001226
Thomas Choud52ebf12010-12-24 13:12:21 +00001227 if (mmc_host_is_spi(mmc))
1228 return 0;
1229
Andy Fleming272cc702008-10-30 16:41:01 -05001230 /* Read the SCR to find out if this card supports higher speeds */
1231 cmd.cmdidx = MMC_CMD_APP_CMD;
1232 cmd.resp_type = MMC_RSP_R1;
1233 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001234
1235 err = mmc_send_cmd(mmc, &cmd, NULL);
1236
1237 if (err)
1238 return err;
1239
1240 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1241 cmd.resp_type = MMC_RSP_R1;
1242 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001243
1244 timeout = 3;
1245
1246retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001247 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001248 data.blocksize = 8;
1249 data.blocks = 1;
1250 data.flags = MMC_DATA_READ;
1251
1252 err = mmc_send_cmd(mmc, &cmd, &data);
1253
1254 if (err) {
1255 if (timeout--)
1256 goto retry_scr;
1257
1258 return err;
1259 }
1260
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001261 mmc->scr[0] = __be32_to_cpu(scr[0]);
1262 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001263
1264 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001265 case 0:
1266 mmc->version = SD_VERSION_1_0;
1267 break;
1268 case 1:
1269 mmc->version = SD_VERSION_1_10;
1270 break;
1271 case 2:
1272 mmc->version = SD_VERSION_2;
1273 if ((mmc->scr[0] >> 15) & 0x1)
1274 mmc->version = SD_VERSION_3;
1275 break;
1276 default:
1277 mmc->version = SD_VERSION_1_0;
1278 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001279 }
1280
Alagu Sankarb44c7082010-05-12 15:08:24 +05301281 if (mmc->scr[0] & SD_DATA_4BIT)
1282 mmc->card_caps |= MMC_MODE_4BIT;
1283
Andy Fleming272cc702008-10-30 16:41:01 -05001284 /* Version 1.0 doesn't support switching */
1285 if (mmc->version == SD_VERSION_1_0)
1286 return 0;
1287
1288 timeout = 4;
1289 while (timeout--) {
1290 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001291 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001292
1293 if (err)
1294 return err;
1295
1296 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001297 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001298 break;
1299 }
1300
Andy Fleming272cc702008-10-30 16:41:01 -05001301 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001302 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1303 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001304
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001305#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001306 /* Version before 3.0 don't support UHS modes */
1307 if (mmc->version < SD_VERSION_3)
1308 return 0;
1309
1310 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1311 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1312 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1313 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1314 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1315 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1316 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1317 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1318 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1319 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1320 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001321#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001322
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001323 return 0;
1324}
1325
1326static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1327{
1328 int err;
1329
1330 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001331 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001332
Marek Vasutcf345762018-11-18 03:25:08 +01001333 /* SD version 1.00 and 1.01 does not support CMD 6 */
1334 if (mmc->version == SD_VERSION_1_0)
1335 return 0;
1336
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001337 switch (mode) {
1338 case SD_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001339 speed = UHS_SDR12_BUS_SPEED;
1340 break;
1341 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001342 speed = HIGH_SPEED_BUS_SPEED;
1343 break;
1344#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1345 case UHS_SDR12:
1346 speed = UHS_SDR12_BUS_SPEED;
1347 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001348 case UHS_SDR25:
1349 speed = UHS_SDR25_BUS_SPEED;
1350 break;
1351 case UHS_SDR50:
1352 speed = UHS_SDR50_BUS_SPEED;
1353 break;
1354 case UHS_DDR50:
1355 speed = UHS_DDR50_BUS_SPEED;
1356 break;
1357 case UHS_SDR104:
1358 speed = UHS_SDR104_BUS_SPEED;
1359 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001360#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001361 default:
1362 return -EINVAL;
1363 }
1364
1365 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001366 if (err)
1367 return err;
1368
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001369 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001370 return -ENOTSUPP;
1371
1372 return 0;
1373}
1374
Marek Vasutec360e62018-04-15 00:36:45 +02001375static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001376{
1377 int err;
1378 struct mmc_cmd cmd;
1379
1380 if ((w != 4) && (w != 1))
1381 return -EINVAL;
1382
1383 cmd.cmdidx = MMC_CMD_APP_CMD;
1384 cmd.resp_type = MMC_RSP_R1;
1385 cmd.cmdarg = mmc->rca << 16;
1386
1387 err = mmc_send_cmd(mmc, &cmd, NULL);
1388 if (err)
1389 return err;
1390
1391 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1392 cmd.resp_type = MMC_RSP_R1;
1393 if (w == 4)
1394 cmd.cmdarg = 2;
1395 else if (w == 1)
1396 cmd.cmdarg = 0;
1397 err = mmc_send_cmd(mmc, &cmd, NULL);
1398 if (err)
1399 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001400
1401 return 0;
1402}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001403#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001404
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001405#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001406static int sd_read_ssr(struct mmc *mmc)
1407{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001408 static const unsigned int sd_au_size[] = {
1409 0, SZ_16K / 512, SZ_32K / 512,
1410 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1411 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1412 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1413 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1414 SZ_64M / 512,
1415 };
Peng Fan3697e592016-09-01 11:13:38 +08001416 int err, i;
1417 struct mmc_cmd cmd;
1418 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1419 struct mmc_data data;
1420 int timeout = 3;
1421 unsigned int au, eo, et, es;
1422
1423 cmd.cmdidx = MMC_CMD_APP_CMD;
1424 cmd.resp_type = MMC_RSP_R1;
1425 cmd.cmdarg = mmc->rca << 16;
1426
1427 err = mmc_send_cmd(mmc, &cmd, NULL);
1428 if (err)
1429 return err;
1430
1431 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1432 cmd.resp_type = MMC_RSP_R1;
1433 cmd.cmdarg = 0;
1434
1435retry_ssr:
1436 data.dest = (char *)ssr;
1437 data.blocksize = 64;
1438 data.blocks = 1;
1439 data.flags = MMC_DATA_READ;
1440
1441 err = mmc_send_cmd(mmc, &cmd, &data);
1442 if (err) {
1443 if (timeout--)
1444 goto retry_ssr;
1445
1446 return err;
1447 }
1448
1449 for (i = 0; i < 16; i++)
1450 ssr[i] = be32_to_cpu(ssr[i]);
1451
1452 au = (ssr[2] >> 12) & 0xF;
1453 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1454 mmc->ssr.au = sd_au_size[au];
1455 es = (ssr[3] >> 24) & 0xFF;
1456 es |= (ssr[2] & 0xFF) << 8;
1457 et = (ssr[3] >> 18) & 0x3F;
1458 if (es && et) {
1459 eo = (ssr[3] >> 16) & 0x3;
1460 mmc->ssr.erase_timeout = (et * 1000) / es;
1461 mmc->ssr.erase_offset = eo * 1000;
1462 }
1463 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001464 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001465 }
1466
1467 return 0;
1468}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001469#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001470/* frequency bases */
1471/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001472static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001473 10000,
1474 100000,
1475 1000000,
1476 10000000,
1477};
1478
1479/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1480 * to platforms without floating point.
1481 */
Simon Glass61fe0762016-05-14 14:02:57 -06001482static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001483 0, /* reserved */
1484 10,
1485 12,
1486 13,
1487 15,
1488 20,
1489 25,
1490 30,
1491 35,
1492 40,
1493 45,
1494 50,
1495 55,
1496 60,
1497 70,
1498 80,
1499};
1500
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001501static inline int bus_width(uint cap)
1502{
1503 if (cap == MMC_MODE_8BIT)
1504 return 8;
1505 if (cap == MMC_MODE_4BIT)
1506 return 4;
1507 if (cap == MMC_MODE_1BIT)
1508 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001509 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001510 return 0;
1511}
1512
Simon Glasse7881d82017-07-29 11:35:31 -06001513#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001514#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001515static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1516{
1517 return -ENOTSUPP;
1518}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001519#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001520
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001521static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001522{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001523 int ret = 0;
1524
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001525 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001526 ret = mmc->cfg->ops->set_ios(mmc);
1527
1528 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001529}
Simon Glass8ca51e52016-06-12 23:30:22 -06001530#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001531
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001532int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001533{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001534 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001535 if (clock > mmc->cfg->f_max)
1536 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001537
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001538 if (clock < mmc->cfg->f_min)
1539 clock = mmc->cfg->f_min;
1540 }
Andy Fleming272cc702008-10-30 16:41:01 -05001541
1542 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001543 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001544
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001545 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1546
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001547 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001548}
1549
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001550static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001551{
1552 mmc->bus_width = width;
1553
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001554 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001555}
1556
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001557#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1558/*
1559 * helper function to display the capabilities in a human
1560 * friendly manner. The capabilities include bus width and
1561 * supported modes.
1562 */
1563void mmc_dump_capabilities(const char *text, uint caps)
1564{
1565 enum bus_mode mode;
1566
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001567 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001568 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001569 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001570 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001571 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001572 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001573 pr_debug("1, ");
1574 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001575 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1576 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001577 pr_debug("%s, ", mmc_mode_name(mode));
1578 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001579}
1580#endif
1581
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001582struct mode_width_tuning {
1583 enum bus_mode mode;
1584 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001585#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001586 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001587#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001588};
1589
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001590#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001591int mmc_voltage_to_mv(enum mmc_voltage voltage)
1592{
1593 switch (voltage) {
1594 case MMC_SIGNAL_VOLTAGE_000: return 0;
1595 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1596 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1597 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1598 }
1599 return -EINVAL;
1600}
1601
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001602static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1603{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001604 int err;
1605
1606 if (mmc->signal_voltage == signal_voltage)
1607 return 0;
1608
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001609 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001610 err = mmc_set_ios(mmc);
1611 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001612 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001613
1614 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001615}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001616#else
1617static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1618{
1619 return 0;
1620}
1621#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001622
Marek Vasut62d77ce2018-04-15 00:37:11 +02001623#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001624static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001625#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1626#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001627 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001628 .mode = UHS_SDR104,
1629 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1630 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1631 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001632#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001633 {
1634 .mode = UHS_SDR50,
1635 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1636 },
1637 {
1638 .mode = UHS_DDR50,
1639 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1640 },
1641 {
1642 .mode = UHS_SDR25,
1643 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1644 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001645#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001646 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001647 .mode = SD_HS,
1648 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1649 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001650#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001651 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001652 .mode = UHS_SDR12,
1653 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1654 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001655#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001656 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001657 .mode = SD_LEGACY,
1658 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1659 }
1660};
1661
1662#define for_each_sd_mode_by_pref(caps, mwt) \
1663 for (mwt = sd_modes_by_pref;\
1664 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1665 mwt++) \
1666 if (caps & MMC_CAP(mwt->mode))
1667
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001668static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001669{
1670 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001671 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1672 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001673#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001674 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001675#else
1676 bool uhs_en = false;
1677#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001678 uint caps;
1679
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001680#ifdef DEBUG
1681 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001682 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001683#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001684
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001685 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001686 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001687
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001688 if (!uhs_en)
1689 caps &= ~UHS_CAPS;
1690
1691 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001692 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001693
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001694 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001695 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001696 pr_debug("trying mode %s width %d (at %d MHz)\n",
1697 mmc_mode_name(mwt->mode),
1698 bus_width(*w),
1699 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001700
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001701 /* configure the bus width (card + host) */
1702 err = sd_select_bus_width(mmc, bus_width(*w));
1703 if (err)
1704 goto error;
1705 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001706
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001707 /* configure the bus mode (card) */
1708 err = sd_set_card_speed(mmc, mwt->mode);
1709 if (err)
1710 goto error;
1711
1712 /* configure the bus mode (host) */
1713 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001714 mmc_set_clock(mmc, mmc->tran_speed,
1715 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001716
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001717#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001718 /* execute tuning if needed */
1719 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1720 err = mmc_execute_tuning(mmc,
1721 mwt->tuning);
1722 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001723 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001724 goto error;
1725 }
1726 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001727#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001728
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001729#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001730 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001731 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001732 pr_warn("unable to read ssr\n");
1733#endif
1734 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001735 return 0;
1736
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001737error:
1738 /* revert to a safer bus speed */
1739 mmc_select_mode(mmc, SD_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001740 mmc_set_clock(mmc, mmc->tran_speed,
1741 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001742 }
1743 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001744 }
1745
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001746 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001747 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001748}
1749
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001750/*
1751 * read the compare the part of ext csd that is constant.
1752 * This can be used to check that the transfer is working
1753 * as expected.
1754 */
1755static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1756{
1757 int err;
1758 const u8 *ext_csd = mmc->ext_csd;
1759 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1760
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001761 if (mmc->version < MMC_VERSION_4)
1762 return 0;
1763
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001764 err = mmc_send_ext_csd(mmc, test_csd);
1765 if (err)
1766 return err;
1767
1768 /* Only compare read only fields */
1769 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1770 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1771 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1772 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1773 ext_csd[EXT_CSD_REV]
1774 == test_csd[EXT_CSD_REV] &&
1775 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1776 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1777 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1778 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1779 return 0;
1780
1781 return -EBADMSG;
1782}
1783
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001784#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001785static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1786 uint32_t allowed_mask)
1787{
1788 u32 card_mask = 0;
1789
1790 switch (mode) {
Peng Fan3dd26262018-08-10 14:07:54 +08001791 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001792 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001793 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1794 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001795 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001796 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1797 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001798 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1799 break;
1800 case MMC_DDR_52:
1801 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1802 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1803 MMC_SIGNAL_VOLTAGE_180;
1804 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1805 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1806 break;
1807 default:
1808 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1809 break;
1810 }
1811
1812 while (card_mask & allowed_mask) {
1813 enum mmc_voltage best_match;
1814
1815 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1816 if (!mmc_set_signal_voltage(mmc, best_match))
1817 return 0;
1818
1819 allowed_mask &= ~best_match;
1820 }
1821
1822 return -ENOTSUPP;
1823}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001824#else
1825static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1826 uint32_t allowed_mask)
1827{
1828 return 0;
1829}
1830#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001831
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001832static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan3dd26262018-08-10 14:07:54 +08001833#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1834 {
1835 .mode = MMC_HS_400,
1836 .widths = MMC_MODE_8BIT,
1837 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1838 },
1839#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001840#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001841 {
1842 .mode = MMC_HS_200,
1843 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001844 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001845 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001846#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001847 {
1848 .mode = MMC_DDR_52,
1849 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1850 },
1851 {
1852 .mode = MMC_HS_52,
1853 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1854 },
1855 {
1856 .mode = MMC_HS,
1857 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1858 },
1859 {
1860 .mode = MMC_LEGACY,
1861 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1862 }
1863};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001864
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001865#define for_each_mmc_mode_by_pref(caps, mwt) \
1866 for (mwt = mmc_modes_by_pref;\
1867 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1868 mwt++) \
1869 if (caps & MMC_CAP(mwt->mode))
1870
1871static const struct ext_csd_bus_width {
1872 uint cap;
1873 bool is_ddr;
1874 uint ext_csd_bits;
1875} ext_csd_bus_width[] = {
1876 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1877 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1878 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1879 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1880 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1881};
1882
Peng Fan3dd26262018-08-10 14:07:54 +08001883#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1884static int mmc_select_hs400(struct mmc *mmc)
1885{
1886 int err;
1887
1888 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001889 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001890 if (err)
1891 return err;
1892
1893 /* configure the bus mode (host) */
1894 mmc_select_mode(mmc, MMC_HS_200);
1895 mmc_set_clock(mmc, mmc->tran_speed, false);
1896
1897 /* execute tuning if needed */
1898 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1899 if (err) {
1900 debug("tuning failed\n");
1901 return err;
1902 }
1903
1904 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001905 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001906
1907 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1908 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1909 if (err)
1910 return err;
1911
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001912 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001913 if (err)
1914 return err;
1915
1916 mmc_select_mode(mmc, MMC_HS_400);
1917 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1918 if (err)
1919 return err;
1920
1921 return 0;
1922}
1923#else
1924static int mmc_select_hs400(struct mmc *mmc)
1925{
1926 return -ENOTSUPP;
1927}
1928#endif
1929
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001930#define for_each_supported_width(caps, ddr, ecbv) \
1931 for (ecbv = ext_csd_bus_width;\
1932 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1933 ecbv++) \
1934 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1935
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001936static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001937{
1938 int err;
1939 const struct mode_width_tuning *mwt;
1940 const struct ext_csd_bus_width *ecbw;
1941
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001942#ifdef DEBUG
1943 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001944 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001945#endif
1946
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001947 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001948 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001949
1950 /* Only version 4 of MMC supports wider bus widths */
1951 if (mmc->version < MMC_VERSION_4)
1952 return 0;
1953
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001954 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001955 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001956 return -ENOTSUPP;
1957 }
1958
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001959#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
1960 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1961 /*
1962 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
1963 * before doing anything else, since a transition from either of
1964 * the HS200/HS400 mode directly to legacy mode is not supported.
1965 */
1966 if (mmc->selected_mode == MMC_HS_200 ||
1967 mmc->selected_mode == MMC_HS_400)
1968 mmc_set_card_speed(mmc, MMC_HS, true);
1969 else
1970#endif
1971 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001972
1973 for_each_mmc_mode_by_pref(card_caps, mwt) {
1974 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001975 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001976 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001977 pr_debug("trying mode %s width %d (at %d MHz)\n",
1978 mmc_mode_name(mwt->mode),
1979 bus_width(ecbw->cap),
1980 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001981 old_voltage = mmc->signal_voltage;
1982 err = mmc_set_lowest_voltage(mmc, mwt->mode,
1983 MMC_ALL_SIGNAL_VOLTAGE);
1984 if (err)
1985 continue;
1986
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001987 /* configure the bus width (card + host) */
1988 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1989 EXT_CSD_BUS_WIDTH,
1990 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
1991 if (err)
1992 goto error;
1993 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
1994
Peng Fan3dd26262018-08-10 14:07:54 +08001995 if (mwt->mode == MMC_HS_400) {
1996 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001997 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08001998 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001999 goto error;
2000 }
Peng Fan3dd26262018-08-10 14:07:54 +08002001 } else {
2002 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002003 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002004 if (err)
2005 goto error;
2006
2007 /*
2008 * configure the bus width AND the ddr mode
2009 * (card). The host side will be taken care
2010 * of in the next step
2011 */
2012 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2013 err = mmc_switch(mmc,
2014 EXT_CSD_CMD_SET_NORMAL,
2015 EXT_CSD_BUS_WIDTH,
2016 ecbw->ext_csd_bits);
2017 if (err)
2018 goto error;
2019 }
2020
2021 /* configure the bus mode (host) */
2022 mmc_select_mode(mmc, mwt->mode);
2023 mmc_set_clock(mmc, mmc->tran_speed,
2024 MMC_CLK_ENABLE);
2025#ifdef MMC_SUPPORTS_TUNING
2026
2027 /* execute tuning if needed */
2028 if (mwt->tuning) {
2029 err = mmc_execute_tuning(mmc,
2030 mwt->tuning);
2031 if (err) {
2032 pr_debug("tuning failed\n");
2033 goto error;
2034 }
2035 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002036#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002037 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002038
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002039 /* do a transfer to check the configuration */
2040 err = mmc_read_and_compare_ext_csd(mmc);
2041 if (!err)
2042 return 0;
2043error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002044 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002045 /* if an error occured, revert to a safer bus mode */
2046 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2047 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2048 mmc_select_mode(mmc, MMC_LEGACY);
2049 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002050 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002051 }
2052
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002053 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002054
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002055 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002056}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002057#endif
2058
2059#if CONFIG_IS_ENABLED(MMC_TINY)
2060DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2061#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002062
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002063static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002064{
2065 int err, i;
2066 u64 capacity;
2067 bool has_parts = false;
2068 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002069 static const u32 mmc_versions[] = {
2070 MMC_VERSION_4,
2071 MMC_VERSION_4_1,
2072 MMC_VERSION_4_2,
2073 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002074 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002075 MMC_VERSION_4_41,
2076 MMC_VERSION_4_5,
2077 MMC_VERSION_5_0,
2078 MMC_VERSION_5_1
2079 };
2080
Marek Vasut62d77ce2018-04-15 00:37:11 +02002081#if CONFIG_IS_ENABLED(MMC_TINY)
2082 u8 *ext_csd = ext_csd_bkup;
2083
2084 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2085 return 0;
2086
2087 if (!mmc->ext_csd)
2088 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2089
2090 err = mmc_send_ext_csd(mmc, ext_csd);
2091 if (err)
2092 goto error;
2093
2094 /* store the ext csd for future reference */
2095 if (!mmc->ext_csd)
2096 mmc->ext_csd = ext_csd;
2097#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002098 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002099
2100 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2101 return 0;
2102
2103 /* check ext_csd version and capacity */
2104 err = mmc_send_ext_csd(mmc, ext_csd);
2105 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002106 goto error;
2107
2108 /* store the ext csd for future reference */
2109 if (!mmc->ext_csd)
2110 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2111 if (!mmc->ext_csd)
2112 return -ENOMEM;
2113 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002114#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002115 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002116 return -EINVAL;
2117
2118 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2119
2120 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002121 /*
2122 * According to the JEDEC Standard, the value of
2123 * ext_csd's capacity is valid if the value is more
2124 * than 2GB
2125 */
2126 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2127 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2128 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2129 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2130 capacity *= MMC_MAX_BLOCK_LEN;
2131 if ((capacity >> 20) > 2 * 1024)
2132 mmc->capacity_user = capacity;
2133 }
2134
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +02002135 if (mmc->version >= MMC_VERSION_4_5)
2136 mmc->gen_cmd6_time = ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
2137
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002138 /* The partition data may be non-zero but it is only
2139 * effective if PARTITION_SETTING_COMPLETED is set in
2140 * EXT_CSD, so ignore any data if this bit is not set,
2141 * except for enabling the high-capacity group size
2142 * definition (see below).
2143 */
2144 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2145 EXT_CSD_PARTITION_SETTING_COMPLETED);
2146
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +02002147 mmc->part_switch_time = ext_csd[EXT_CSD_PART_SWITCH_TIME];
2148 /* Some eMMC set the value too low so set a minimum */
2149 if (mmc->part_switch_time < MMC_MIN_PART_SWITCH_TIME && mmc->part_switch_time)
2150 mmc->part_switch_time = MMC_MIN_PART_SWITCH_TIME;
2151
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002152 /* store the partition info of emmc */
2153 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2154 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2155 ext_csd[EXT_CSD_BOOT_MULT])
2156 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2157 if (part_completed &&
2158 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2159 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2160
2161 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2162
2163 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2164
2165 for (i = 0; i < 4; i++) {
2166 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2167 uint mult = (ext_csd[idx + 2] << 16) +
2168 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2169 if (mult)
2170 has_parts = true;
2171 if (!part_completed)
2172 continue;
2173 mmc->capacity_gp[i] = mult;
2174 mmc->capacity_gp[i] *=
2175 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2176 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2177 mmc->capacity_gp[i] <<= 19;
2178 }
2179
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002180#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002181 if (part_completed) {
2182 mmc->enh_user_size =
2183 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2184 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2185 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2186 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2187 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2188 mmc->enh_user_size <<= 19;
2189 mmc->enh_user_start =
2190 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2191 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2192 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2193 ext_csd[EXT_CSD_ENH_START_ADDR];
2194 if (mmc->high_capacity)
2195 mmc->enh_user_start <<= 9;
2196 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002197#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002198
2199 /*
2200 * Host needs to enable ERASE_GRP_DEF bit if device is
2201 * partitioned. This bit will be lost every time after a reset
2202 * or power off. This will affect erase size.
2203 */
2204 if (part_completed)
2205 has_parts = true;
2206 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2207 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2208 has_parts = true;
2209 if (has_parts) {
2210 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2211 EXT_CSD_ERASE_GROUP_DEF, 1);
2212
2213 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002214 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002215
2216 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2217 }
2218
2219 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002220#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002221 /* Read out group size from ext_csd */
2222 mmc->erase_grp_size =
2223 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002224#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002225 /*
2226 * if high capacity and partition setting completed
2227 * SEC_COUNT is valid even if it is smaller than 2 GiB
2228 * JEDEC Standard JESD84-B45, 6.2.4
2229 */
2230 if (mmc->high_capacity && part_completed) {
2231 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2232 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2233 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2234 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2235 capacity *= MMC_MAX_BLOCK_LEN;
2236 mmc->capacity_user = capacity;
2237 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002238 }
2239#if CONFIG_IS_ENABLED(MMC_WRITE)
2240 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002241 /* Calculate the group size from the csd value. */
2242 int erase_gsz, erase_gmul;
2243
2244 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2245 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2246 mmc->erase_grp_size = (erase_gsz + 1)
2247 * (erase_gmul + 1);
2248 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002249#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002250#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002251 mmc->hc_wp_grp_size = 1024
2252 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2253 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002254#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002255
2256 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2257
2258 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002259error:
2260 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002261#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002262 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002263#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002264 mmc->ext_csd = NULL;
2265 }
2266 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002267}
2268
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002269static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002270{
Stephen Warrenf866a462013-06-11 15:14:01 -06002271 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002272 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002273 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002274 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002275 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002276
Thomas Choud52ebf12010-12-24 13:12:21 +00002277#ifdef CONFIG_MMC_SPI_CRC_ON
2278 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2279 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2280 cmd.resp_type = MMC_RSP_R1;
2281 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002282 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002283 if (err)
2284 return err;
2285 }
2286#endif
2287
Andy Fleming272cc702008-10-30 16:41:01 -05002288 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002289 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2290 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002291 cmd.resp_type = MMC_RSP_R2;
2292 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002293
2294 err = mmc_send_cmd(mmc, &cmd, NULL);
2295
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002296#ifdef CONFIG_MMC_QUIRKS
2297 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2298 int retries = 4;
2299 /*
2300 * It has been seen that SEND_CID may fail on the first
2301 * attempt, let's try a few more time
2302 */
2303 do {
2304 err = mmc_send_cmd(mmc, &cmd, NULL);
2305 if (!err)
2306 break;
2307 } while (retries--);
2308 }
2309#endif
2310
Andy Fleming272cc702008-10-30 16:41:01 -05002311 if (err)
2312 return err;
2313
2314 memcpy(mmc->cid, cmd.response, 16);
2315
2316 /*
2317 * For MMC cards, set the Relative Address.
2318 * For SD cards, get the Relatvie Address.
2319 * This also puts the cards into Standby State
2320 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002321 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2322 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2323 cmd.cmdarg = mmc->rca << 16;
2324 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002325
Thomas Choud52ebf12010-12-24 13:12:21 +00002326 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002327
Thomas Choud52ebf12010-12-24 13:12:21 +00002328 if (err)
2329 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002330
Thomas Choud52ebf12010-12-24 13:12:21 +00002331 if (IS_SD(mmc))
2332 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2333 }
Andy Fleming272cc702008-10-30 16:41:01 -05002334
2335 /* Get the Card-Specific Data */
2336 cmd.cmdidx = MMC_CMD_SEND_CSD;
2337 cmd.resp_type = MMC_RSP_R2;
2338 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002339
2340 err = mmc_send_cmd(mmc, &cmd, NULL);
2341
2342 if (err)
2343 return err;
2344
Rabin Vincent998be3d2009-04-05 13:30:56 +05302345 mmc->csd[0] = cmd.response[0];
2346 mmc->csd[1] = cmd.response[1];
2347 mmc->csd[2] = cmd.response[2];
2348 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002349
2350 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302351 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002352
2353 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002354 case 0:
2355 mmc->version = MMC_VERSION_1_2;
2356 break;
2357 case 1:
2358 mmc->version = MMC_VERSION_1_4;
2359 break;
2360 case 2:
2361 mmc->version = MMC_VERSION_2_2;
2362 break;
2363 case 3:
2364 mmc->version = MMC_VERSION_3;
2365 break;
2366 case 4:
2367 mmc->version = MMC_VERSION_4;
2368 break;
2369 default:
2370 mmc->version = MMC_VERSION_1_2;
2371 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002372 }
2373 }
2374
2375 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302376 freq = fbase[(cmd.response[0] & 0x7)];
2377 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002378
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002379 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002380 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002381
Markus Niebelab711882013-12-16 13:40:46 +01002382 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302383 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002384#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002385
2386 if (IS_SD(mmc))
2387 mmc->write_bl_len = mmc->read_bl_len;
2388 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302389 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002390#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002391
2392 if (mmc->high_capacity) {
2393 csize = (mmc->csd[1] & 0x3f) << 16
2394 | (mmc->csd[2] & 0xffff0000) >> 16;
2395 cmult = 8;
2396 } else {
2397 csize = (mmc->csd[1] & 0x3ff) << 2
2398 | (mmc->csd[2] & 0xc0000000) >> 30;
2399 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2400 }
2401
Stephen Warrenf866a462013-06-11 15:14:01 -06002402 mmc->capacity_user = (csize + 1) << (cmult + 2);
2403 mmc->capacity_user *= mmc->read_bl_len;
2404 mmc->capacity_boot = 0;
2405 mmc->capacity_rpmb = 0;
2406 for (i = 0; i < 4; i++)
2407 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002408
Simon Glass8bfa1952013-04-03 08:54:30 +00002409 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2410 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002411
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002412#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002413 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2414 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002415#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002416
Markus Niebelab711882013-12-16 13:40:46 +01002417 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2418 cmd.cmdidx = MMC_CMD_SET_DSR;
2419 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2420 cmd.resp_type = MMC_RSP_NONE;
2421 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002422 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002423 }
2424
Andy Fleming272cc702008-10-30 16:41:01 -05002425 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002426 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2427 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002428 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002429 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002430 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002431
Thomas Choud52ebf12010-12-24 13:12:21 +00002432 if (err)
2433 return err;
2434 }
Andy Fleming272cc702008-10-30 16:41:01 -05002435
Lei Wene6f99a52011-06-22 17:03:31 +00002436 /*
2437 * For SD, its erase group is always one sector
2438 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002439#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002440 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002441#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002442 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002443
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002444 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002445 if (err)
2446 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302447
Simon Glassc40fdca2016-05-01 13:52:35 -06002448 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002449 if (err)
2450 return err;
2451
Marek Vasut62d77ce2018-04-15 00:37:11 +02002452#if CONFIG_IS_ENABLED(MMC_TINY)
2453 mmc_set_clock(mmc, mmc->legacy_speed, false);
2454 mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
2455 mmc_set_bus_width(mmc, 1);
2456#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002457 if (IS_SD(mmc)) {
2458 err = sd_get_capabilities(mmc);
2459 if (err)
2460 return err;
2461 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2462 } else {
2463 err = mmc_get_capabilities(mmc);
2464 if (err)
2465 return err;
2466 mmc_select_mode_and_width(mmc, mmc->card_caps);
2467 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002468#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002469 if (err)
2470 return err;
2471
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002472 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002473
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002474 /* Fix the block length for DDR mode */
2475 if (mmc->ddr_mode) {
2476 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002477#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002478 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002479#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002480 }
2481
Andy Fleming272cc702008-10-30 16:41:01 -05002482 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002483 bdesc = mmc_get_blk_desc(mmc);
2484 bdesc->lun = 0;
2485 bdesc->hwpart = 0;
2486 bdesc->type = 0;
2487 bdesc->blksz = mmc->read_bl_len;
2488 bdesc->log2blksz = LOG2(bdesc->blksz);
2489 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002490#if !defined(CONFIG_SPL_BUILD) || \
2491 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
2492 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002493 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002494 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2495 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002496 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002497 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2498 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2499 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002500 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002501 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002502#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002503 bdesc->vendor[0] = 0;
2504 bdesc->product[0] = 0;
2505 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002506#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002507
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002508#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2509 part_init(bdesc);
2510#endif
2511
Andy Fleming272cc702008-10-30 16:41:01 -05002512 return 0;
2513}
2514
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002515static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002516{
2517 struct mmc_cmd cmd;
2518 int err;
2519
2520 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2521 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002522 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002523 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002524
2525 err = mmc_send_cmd(mmc, &cmd, NULL);
2526
2527 if (err)
2528 return err;
2529
Rabin Vincent998be3d2009-04-05 13:30:56 +05302530 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002531 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002532 else
2533 mmc->version = SD_VERSION_2;
2534
2535 return 0;
2536}
2537
Simon Glassc4d660d2017-07-04 13:31:19 -06002538#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002539/* board-specific MMC power initializations. */
2540__weak void board_mmc_power_init(void)
2541{
2542}
Simon Glass05cbeb72017-04-22 19:10:56 -06002543#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002544
Peng Fan2051aef2016-10-11 15:08:43 +08002545static int mmc_power_init(struct mmc *mmc)
2546{
Simon Glassc4d660d2017-07-04 13:31:19 -06002547#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002548#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002549 int ret;
2550
2551 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002552 &mmc->vmmc_supply);
2553 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002554 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002555
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002556 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2557 &mmc->vqmmc_supply);
2558 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002559 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002560#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002561#else /* !CONFIG_DM_MMC */
2562 /*
2563 * Driver model should use a regulator, as above, rather than calling
2564 * out to board code.
2565 */
2566 board_mmc_power_init();
2567#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002568 return 0;
2569}
2570
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002571/*
2572 * put the host in the initial state:
2573 * - turn on Vdd (card power supply)
2574 * - configure the bus width and clock to minimal values
2575 */
2576static void mmc_set_initial_state(struct mmc *mmc)
2577{
2578 int err;
2579
2580 /* First try to set 3.3V. If it fails set to 1.8V */
2581 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2582 if (err != 0)
2583 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2584 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002585 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002586
2587 mmc_select_mode(mmc, MMC_LEGACY);
2588 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002589 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002590}
2591
2592static int mmc_power_on(struct mmc *mmc)
2593{
2594#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2595 if (mmc->vmmc_supply) {
2596 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2597
2598 if (ret) {
2599 puts("Error enabling VMMC supply\n");
2600 return ret;
2601 }
2602 }
2603#endif
2604 return 0;
2605}
2606
2607static int mmc_power_off(struct mmc *mmc)
2608{
Jaehoon Chung65117182018-01-26 19:25:29 +09002609 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002610#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2611 if (mmc->vmmc_supply) {
2612 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2613
2614 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002615 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002616 return ret;
2617 }
2618 }
2619#endif
2620 return 0;
2621}
2622
2623static int mmc_power_cycle(struct mmc *mmc)
2624{
2625 int ret;
2626
2627 ret = mmc_power_off(mmc);
2628 if (ret)
2629 return ret;
2630 /*
2631 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2632 * to be on the safer side.
2633 */
2634 udelay(2000);
2635 return mmc_power_on(mmc);
2636}
2637
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002638int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002639{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002640 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002641 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002642
Lei Wenbc897b12011-05-02 16:26:26 +00002643 if (mmc->has_init)
2644 return 0;
2645
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002646#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2647 mmc_adapter_card_type_ident();
2648#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002649 err = mmc_power_init(mmc);
2650 if (err)
2651 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002652
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002653#ifdef CONFIG_MMC_QUIRKS
2654 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
2655 MMC_QUIRK_RETRY_SEND_CID;
2656#endif
2657
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002658 err = mmc_power_cycle(mmc);
2659 if (err) {
2660 /*
2661 * if power cycling is not supported, we should not try
2662 * to use the UHS modes, because we wouldn't be able to
2663 * recover from an error during the UHS initialization.
2664 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002665 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002666 uhs_en = false;
2667 mmc->host_caps &= ~UHS_CAPS;
2668 err = mmc_power_on(mmc);
2669 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002670 if (err)
2671 return err;
2672
Simon Glasse7881d82017-07-29 11:35:31 -06002673#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002674 /* The device has already been probed ready for use */
2675#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002676 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002677 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002678 if (err)
2679 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002680#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002681 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002682
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002683retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002684 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002685
Andy Fleming272cc702008-10-30 16:41:01 -05002686 /* Reset the Card */
2687 err = mmc_go_idle(mmc);
2688
2689 if (err)
2690 return err;
2691
Lei Wenbc897b12011-05-02 16:26:26 +00002692 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002693 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002694
Andy Fleming272cc702008-10-30 16:41:01 -05002695 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002696 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002697
Andy Fleming272cc702008-10-30 16:41:01 -05002698 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002699 err = sd_send_op_cond(mmc, uhs_en);
2700 if (err && uhs_en) {
2701 uhs_en = false;
2702 mmc_power_cycle(mmc);
2703 goto retry;
2704 }
Andy Fleming272cc702008-10-30 16:41:01 -05002705
2706 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002707 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002708 err = mmc_send_op_cond(mmc);
2709
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002710 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002711#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002712 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002713#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002714 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002715 }
2716 }
2717
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002718 return err;
2719}
2720
2721int mmc_start_init(struct mmc *mmc)
2722{
2723 bool no_card;
2724 int err = 0;
2725
2726 /*
2727 * all hosts are capable of 1 bit bus-width and able to use the legacy
2728 * timings.
2729 */
2730 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
2731 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
2732
2733#if !defined(CONFIG_MMC_BROKEN_CD)
2734 /* we pretend there's no card when init is NULL */
2735 no_card = mmc_getcd(mmc) == 0;
2736#else
2737 no_card = 0;
2738#endif
2739#if !CONFIG_IS_ENABLED(DM_MMC)
2740 no_card = no_card || (mmc->cfg->ops->init == NULL);
2741#endif
2742 if (no_card) {
2743 mmc->has_init = 0;
2744#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2745 pr_err("MMC: no card present\n");
2746#endif
2747 return -ENOMEDIUM;
2748 }
2749
2750 err = mmc_get_op_cond(mmc);
2751
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002752 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002753 mmc->init_in_progress = 1;
2754
2755 return err;
2756}
2757
2758static int mmc_complete_init(struct mmc *mmc)
2759{
2760 int err = 0;
2761
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002762 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002763 if (mmc->op_cond_pending)
2764 err = mmc_complete_op_cond(mmc);
2765
2766 if (!err)
2767 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002768 if (err)
2769 mmc->has_init = 0;
2770 else
2771 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002772 return err;
2773}
2774
2775int mmc_init(struct mmc *mmc)
2776{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002777 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302778 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002779#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002780 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002781
Simon Glass33fb2112016-05-01 13:52:41 -06002782 upriv->mmc = mmc;
2783#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002784 if (mmc->has_init)
2785 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002786
2787 start = get_timer(0);
2788
Che-Liang Chioue9550442012-11-28 15:21:13 +00002789 if (!mmc->init_in_progress)
2790 err = mmc_start_init(mmc);
2791
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002792 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002793 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002794 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002795 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002796
Lei Wenbc897b12011-05-02 16:26:26 +00002797 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002798}
2799
Marek Vasutfceea992019-01-29 04:45:51 +01002800#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2801 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2802 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2803int mmc_deinit(struct mmc *mmc)
2804{
2805 u32 caps_filtered;
2806
2807 if (!mmc->has_init)
2808 return 0;
2809
2810 if (IS_SD(mmc)) {
2811 caps_filtered = mmc->card_caps &
2812 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2813 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2814 MMC_CAP(UHS_SDR104));
2815
2816 return sd_select_mode_and_width(mmc, caps_filtered);
2817 } else {
2818 caps_filtered = mmc->card_caps &
2819 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2820
2821 return mmc_select_mode_and_width(mmc, caps_filtered);
2822 }
2823}
2824#endif
2825
Markus Niebelab711882013-12-16 13:40:46 +01002826int mmc_set_dsr(struct mmc *mmc, u16 val)
2827{
2828 mmc->dsr = val;
2829 return 0;
2830}
2831
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002832/* CPU-specific MMC initializations */
2833__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002834{
2835 return -1;
2836}
2837
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002838/* board-specific MMC initializations. */
2839__weak int board_mmc_init(bd_t *bis)
2840{
2841 return -1;
2842}
Andy Fleming272cc702008-10-30 16:41:01 -05002843
Che-Liang Chioue9550442012-11-28 15:21:13 +00002844void mmc_set_preinit(struct mmc *mmc, int preinit)
2845{
2846 mmc->preinit = preinit;
2847}
2848
Faiz Abbas8a856db2018-02-12 19:35:24 +05302849#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002850static int mmc_probe(bd_t *bis)
2851{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002852 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002853 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002854 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002855
2856 ret = uclass_get(UCLASS_MMC, &uc);
2857 if (ret)
2858 return ret;
2859
Simon Glass4a1db6d2015-12-29 05:22:49 -07002860 /*
2861 * Try to add them in sequence order. Really with driver model we
2862 * should allow holes, but the current MMC list does not allow that.
2863 * So if we request 0, 1, 3 we will get 0, 1, 2.
2864 */
2865 for (i = 0; ; i++) {
2866 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2867 if (ret == -ENODEV)
2868 break;
2869 }
2870 uclass_foreach_dev(dev, uc) {
2871 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002872 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002873 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002874 }
2875
2876 return 0;
2877}
2878#else
2879static int mmc_probe(bd_t *bis)
2880{
2881 if (board_mmc_init(bis) < 0)
2882 cpu_mmc_init(bis);
2883
2884 return 0;
2885}
2886#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002887
Andy Fleming272cc702008-10-30 16:41:01 -05002888int mmc_initialize(bd_t *bis)
2889{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002890 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002891 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002892 if (initialized) /* Avoid initializing mmc multiple times */
2893 return 0;
2894 initialized = 1;
2895
Simon Glassc4d660d2017-07-04 13:31:19 -06002896#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002897#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002898 mmc_list_init();
2899#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002900#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002901 ret = mmc_probe(bis);
2902 if (ret)
2903 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002904
Ying Zhangbb0dc102013-08-16 15:16:11 +08002905#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002906 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002907#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002908
Simon Glassc40fdca2016-05-01 13:52:35 -06002909 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002910 return 0;
2911}
Tomas Melincd3d4882016-11-25 11:01:03 +02002912
2913#ifdef CONFIG_CMD_BKOPS_ENABLE
2914int mmc_set_bkops_enable(struct mmc *mmc)
2915{
2916 int err;
2917 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2918
2919 err = mmc_send_ext_csd(mmc, ext_csd);
2920 if (err) {
2921 puts("Could not get ext_csd register values\n");
2922 return err;
2923 }
2924
2925 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2926 puts("Background operations not supported on device\n");
2927 return -EMEDIUMTYPE;
2928 }
2929
2930 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2931 puts("Background operations already enabled\n");
2932 return 0;
2933 }
2934
2935 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2936 if (err) {
2937 puts("Failed to enable manual background operations\n");
2938 return err;
2939 }
2940
2941 puts("Enabled manual background operations\n");
2942
2943 return 0;
2944}
2945#endif