blob: 2a1ba6e51dc9cbf7a5c91f7a64bf298e2ca9691b [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;
Jean-Jacques Hiblot05384772019-07-02 10:53:58 +0200961 int retry = 3;
Lei Wenbc897b12011-05-02 16:26:26 +0000962
Jean-Jacques Hiblot05384772019-07-02 10:53:58 +0200963 do {
964 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
965 EXT_CSD_PART_CONF,
966 (mmc->part_config & ~PART_ACCESS_MASK)
967 | (part_num & PART_ACCESS_MASK));
968 } while (ret && retry--);
Stephen Warrenf866a462013-06-11 15:14:01 -0600969
Peter Bigot6dc93e72014-09-02 18:31:23 -0500970 /*
971 * Set the capacity if the switch succeeded or was intended
972 * to return to representing the raw device.
973 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700974 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500975 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600976 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700977 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500978
979 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000980}
981
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100982#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100983int mmc_hwpart_config(struct mmc *mmc,
984 const struct mmc_hwpart_conf *conf,
985 enum mmc_hwpart_conf_mode mode)
986{
987 u8 part_attrs = 0;
988 u32 enh_size_mult;
989 u32 enh_start_addr;
990 u32 gp_size_mult[4];
991 u32 max_enh_size_mult;
992 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100993 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100994 int i, pidx, err;
995 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
996
997 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
998 return -EINVAL;
999
1000 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001001 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001002 return -EMEDIUMTYPE;
1003 }
1004
1005 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001006 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001007 return -EMEDIUMTYPE;
1008 }
1009
1010 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001011 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001012 return -EMEDIUMTYPE;
1013 }
1014
1015 /* check partition alignment and total enhanced size */
1016 if (conf->user.enh_size) {
1017 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1018 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001019 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001020 "size aligned\n");
1021 return -EINVAL;
1022 }
1023 part_attrs |= EXT_CSD_ENH_USR;
1024 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1025 if (mmc->high_capacity) {
1026 enh_start_addr = conf->user.enh_start;
1027 } else {
1028 enh_start_addr = (conf->user.enh_start << 9);
1029 }
1030 } else {
1031 enh_size_mult = 0;
1032 enh_start_addr = 0;
1033 }
1034 tot_enh_size_mult += enh_size_mult;
1035
1036 for (pidx = 0; pidx < 4; pidx++) {
1037 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001038 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001039 "aligned\n", pidx+1);
1040 return -EINVAL;
1041 }
1042 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1043 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1044 part_attrs |= EXT_CSD_ENH_GP(pidx);
1045 tot_enh_size_mult += gp_size_mult[pidx];
1046 }
1047 }
1048
1049 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001050 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001051 return -EMEDIUMTYPE;
1052 }
1053
1054 err = mmc_send_ext_csd(mmc, ext_csd);
1055 if (err)
1056 return err;
1057
1058 max_enh_size_mult =
1059 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1060 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1061 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1062 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001063 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001064 tot_enh_size_mult, max_enh_size_mult);
1065 return -EMEDIUMTYPE;
1066 }
1067
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001068 /* The default value of EXT_CSD_WR_REL_SET is device
1069 * dependent, the values can only be changed if the
1070 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1071 * changed only once and before partitioning is completed. */
1072 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1073 if (conf->user.wr_rel_change) {
1074 if (conf->user.wr_rel_set)
1075 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1076 else
1077 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1078 }
1079 for (pidx = 0; pidx < 4; pidx++) {
1080 if (conf->gp_part[pidx].wr_rel_change) {
1081 if (conf->gp_part[pidx].wr_rel_set)
1082 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1083 else
1084 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1085 }
1086 }
1087
1088 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1089 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1090 puts("Card does not support host controlled partition write "
1091 "reliability settings\n");
1092 return -EMEDIUMTYPE;
1093 }
1094
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001095 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1096 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001097 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001098 return -EPERM;
1099 }
1100
1101 if (mode == MMC_HWPART_CONF_CHECK)
1102 return 0;
1103
1104 /* Partitioning requires high-capacity size definitions */
1105 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1106 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1107 EXT_CSD_ERASE_GROUP_DEF, 1);
1108
1109 if (err)
1110 return err;
1111
1112 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1113
1114 /* update erase group size to be high-capacity */
1115 mmc->erase_grp_size =
1116 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1117
1118 }
1119
1120 /* all OK, write the configuration */
1121 for (i = 0; i < 4; i++) {
1122 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1123 EXT_CSD_ENH_START_ADDR+i,
1124 (enh_start_addr >> (i*8)) & 0xFF);
1125 if (err)
1126 return err;
1127 }
1128 for (i = 0; i < 3; i++) {
1129 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1130 EXT_CSD_ENH_SIZE_MULT+i,
1131 (enh_size_mult >> (i*8)) & 0xFF);
1132 if (err)
1133 return err;
1134 }
1135 for (pidx = 0; pidx < 4; pidx++) {
1136 for (i = 0; i < 3; i++) {
1137 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1138 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1139 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1140 if (err)
1141 return err;
1142 }
1143 }
1144 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1145 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1146 if (err)
1147 return err;
1148
1149 if (mode == MMC_HWPART_CONF_SET)
1150 return 0;
1151
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001152 /* The WR_REL_SET is a write-once register but shall be
1153 * written before setting PART_SETTING_COMPLETED. As it is
1154 * write-once we can only write it when completing the
1155 * partitioning. */
1156 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1157 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1158 EXT_CSD_WR_REL_SET, wr_rel_set);
1159 if (err)
1160 return err;
1161 }
1162
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001163 /* Setting PART_SETTING_COMPLETED confirms the partition
1164 * configuration but it only becomes effective after power
1165 * cycle, so we do not adjust the partition related settings
1166 * in the mmc struct. */
1167
1168 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1169 EXT_CSD_PARTITION_SETTING,
1170 EXT_CSD_PARTITION_SETTING_COMPLETED);
1171 if (err)
1172 return err;
1173
1174 return 0;
1175}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001176#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001177
Simon Glasse7881d82017-07-29 11:35:31 -06001178#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001179int mmc_getcd(struct mmc *mmc)
1180{
1181 int cd;
1182
1183 cd = board_mmc_getcd(mmc);
1184
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001185 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001186 if (mmc->cfg->ops->getcd)
1187 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001188 else
1189 cd = 1;
1190 }
Thierry Reding48972d92012-01-02 01:15:37 +00001191
1192 return cd;
1193}
Simon Glass8ca51e52016-06-12 23:30:22 -06001194#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001195
Marek Vasut62d77ce2018-04-15 00:37:11 +02001196#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001197static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001198{
1199 struct mmc_cmd cmd;
1200 struct mmc_data data;
1201
1202 /* Switch the frequency */
1203 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1204 cmd.resp_type = MMC_RSP_R1;
1205 cmd.cmdarg = (mode << 31) | 0xffffff;
1206 cmd.cmdarg &= ~(0xf << (group * 4));
1207 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001208
1209 data.dest = (char *)resp;
1210 data.blocksize = 64;
1211 data.blocks = 1;
1212 data.flags = MMC_DATA_READ;
1213
1214 return mmc_send_cmd(mmc, &cmd, &data);
1215}
1216
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001217static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001218{
1219 int err;
1220 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301221 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1222 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001223 struct mmc_data data;
1224 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001225#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001226 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001227#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001228
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +01001229 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001230
Thomas Choud52ebf12010-12-24 13:12:21 +00001231 if (mmc_host_is_spi(mmc))
1232 return 0;
1233
Andy Fleming272cc702008-10-30 16:41:01 -05001234 /* Read the SCR to find out if this card supports higher speeds */
1235 cmd.cmdidx = MMC_CMD_APP_CMD;
1236 cmd.resp_type = MMC_RSP_R1;
1237 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001238
1239 err = mmc_send_cmd(mmc, &cmd, NULL);
1240
1241 if (err)
1242 return err;
1243
1244 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1245 cmd.resp_type = MMC_RSP_R1;
1246 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001247
1248 timeout = 3;
1249
1250retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001251 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001252 data.blocksize = 8;
1253 data.blocks = 1;
1254 data.flags = MMC_DATA_READ;
1255
1256 err = mmc_send_cmd(mmc, &cmd, &data);
1257
1258 if (err) {
1259 if (timeout--)
1260 goto retry_scr;
1261
1262 return err;
1263 }
1264
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001265 mmc->scr[0] = __be32_to_cpu(scr[0]);
1266 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001267
1268 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001269 case 0:
1270 mmc->version = SD_VERSION_1_0;
1271 break;
1272 case 1:
1273 mmc->version = SD_VERSION_1_10;
1274 break;
1275 case 2:
1276 mmc->version = SD_VERSION_2;
1277 if ((mmc->scr[0] >> 15) & 0x1)
1278 mmc->version = SD_VERSION_3;
1279 break;
1280 default:
1281 mmc->version = SD_VERSION_1_0;
1282 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001283 }
1284
Alagu Sankarb44c7082010-05-12 15:08:24 +05301285 if (mmc->scr[0] & SD_DATA_4BIT)
1286 mmc->card_caps |= MMC_MODE_4BIT;
1287
Andy Fleming272cc702008-10-30 16:41:01 -05001288 /* Version 1.0 doesn't support switching */
1289 if (mmc->version == SD_VERSION_1_0)
1290 return 0;
1291
1292 timeout = 4;
1293 while (timeout--) {
1294 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001295 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001296
1297 if (err)
1298 return err;
1299
1300 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001301 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001302 break;
1303 }
1304
Andy Fleming272cc702008-10-30 16:41:01 -05001305 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001306 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1307 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001308
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001309#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001310 /* Version before 3.0 don't support UHS modes */
1311 if (mmc->version < SD_VERSION_3)
1312 return 0;
1313
1314 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1315 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1316 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1317 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1318 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1319 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1320 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1321 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1322 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1323 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1324 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001325#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001326
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001327 return 0;
1328}
1329
1330static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1331{
1332 int err;
1333
1334 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001335 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001336
Marek Vasutcf345762018-11-18 03:25:08 +01001337 /* SD version 1.00 and 1.01 does not support CMD 6 */
1338 if (mmc->version == SD_VERSION_1_0)
1339 return 0;
1340
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001341 switch (mode) {
1342 case SD_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001343 speed = UHS_SDR12_BUS_SPEED;
1344 break;
1345 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001346 speed = HIGH_SPEED_BUS_SPEED;
1347 break;
1348#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1349 case UHS_SDR12:
1350 speed = UHS_SDR12_BUS_SPEED;
1351 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001352 case UHS_SDR25:
1353 speed = UHS_SDR25_BUS_SPEED;
1354 break;
1355 case UHS_SDR50:
1356 speed = UHS_SDR50_BUS_SPEED;
1357 break;
1358 case UHS_DDR50:
1359 speed = UHS_DDR50_BUS_SPEED;
1360 break;
1361 case UHS_SDR104:
1362 speed = UHS_SDR104_BUS_SPEED;
1363 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001364#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001365 default:
1366 return -EINVAL;
1367 }
1368
1369 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001370 if (err)
1371 return err;
1372
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001373 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001374 return -ENOTSUPP;
1375
1376 return 0;
1377}
1378
Marek Vasutec360e62018-04-15 00:36:45 +02001379static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001380{
1381 int err;
1382 struct mmc_cmd cmd;
1383
1384 if ((w != 4) && (w != 1))
1385 return -EINVAL;
1386
1387 cmd.cmdidx = MMC_CMD_APP_CMD;
1388 cmd.resp_type = MMC_RSP_R1;
1389 cmd.cmdarg = mmc->rca << 16;
1390
1391 err = mmc_send_cmd(mmc, &cmd, NULL);
1392 if (err)
1393 return err;
1394
1395 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1396 cmd.resp_type = MMC_RSP_R1;
1397 if (w == 4)
1398 cmd.cmdarg = 2;
1399 else if (w == 1)
1400 cmd.cmdarg = 0;
1401 err = mmc_send_cmd(mmc, &cmd, NULL);
1402 if (err)
1403 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001404
1405 return 0;
1406}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001407#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001408
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001409#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001410static int sd_read_ssr(struct mmc *mmc)
1411{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001412 static const unsigned int sd_au_size[] = {
1413 0, SZ_16K / 512, SZ_32K / 512,
1414 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1415 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1416 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1417 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1418 SZ_64M / 512,
1419 };
Peng Fan3697e592016-09-01 11:13:38 +08001420 int err, i;
1421 struct mmc_cmd cmd;
1422 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1423 struct mmc_data data;
1424 int timeout = 3;
1425 unsigned int au, eo, et, es;
1426
1427 cmd.cmdidx = MMC_CMD_APP_CMD;
1428 cmd.resp_type = MMC_RSP_R1;
1429 cmd.cmdarg = mmc->rca << 16;
1430
1431 err = mmc_send_cmd(mmc, &cmd, NULL);
1432 if (err)
1433 return err;
1434
1435 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1436 cmd.resp_type = MMC_RSP_R1;
1437 cmd.cmdarg = 0;
1438
1439retry_ssr:
1440 data.dest = (char *)ssr;
1441 data.blocksize = 64;
1442 data.blocks = 1;
1443 data.flags = MMC_DATA_READ;
1444
1445 err = mmc_send_cmd(mmc, &cmd, &data);
1446 if (err) {
1447 if (timeout--)
1448 goto retry_ssr;
1449
1450 return err;
1451 }
1452
1453 for (i = 0; i < 16; i++)
1454 ssr[i] = be32_to_cpu(ssr[i]);
1455
1456 au = (ssr[2] >> 12) & 0xF;
1457 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1458 mmc->ssr.au = sd_au_size[au];
1459 es = (ssr[3] >> 24) & 0xFF;
1460 es |= (ssr[2] & 0xFF) << 8;
1461 et = (ssr[3] >> 18) & 0x3F;
1462 if (es && et) {
1463 eo = (ssr[3] >> 16) & 0x3;
1464 mmc->ssr.erase_timeout = (et * 1000) / es;
1465 mmc->ssr.erase_offset = eo * 1000;
1466 }
1467 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001468 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001469 }
1470
1471 return 0;
1472}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001473#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001474/* frequency bases */
1475/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001476static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001477 10000,
1478 100000,
1479 1000000,
1480 10000000,
1481};
1482
1483/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1484 * to platforms without floating point.
1485 */
Simon Glass61fe0762016-05-14 14:02:57 -06001486static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001487 0, /* reserved */
1488 10,
1489 12,
1490 13,
1491 15,
1492 20,
1493 25,
1494 30,
1495 35,
1496 40,
1497 45,
1498 50,
1499 55,
1500 60,
1501 70,
1502 80,
1503};
1504
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001505static inline int bus_width(uint cap)
1506{
1507 if (cap == MMC_MODE_8BIT)
1508 return 8;
1509 if (cap == MMC_MODE_4BIT)
1510 return 4;
1511 if (cap == MMC_MODE_1BIT)
1512 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001513 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001514 return 0;
1515}
1516
Simon Glasse7881d82017-07-29 11:35:31 -06001517#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001518#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001519static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1520{
1521 return -ENOTSUPP;
1522}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001523#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001524
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001525static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001526{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001527 int ret = 0;
1528
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001529 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001530 ret = mmc->cfg->ops->set_ios(mmc);
1531
1532 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001533}
Simon Glass8ca51e52016-06-12 23:30:22 -06001534#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001535
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001536int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001537{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001538 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001539 if (clock > mmc->cfg->f_max)
1540 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001541
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001542 if (clock < mmc->cfg->f_min)
1543 clock = mmc->cfg->f_min;
1544 }
Andy Fleming272cc702008-10-30 16:41:01 -05001545
1546 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001547 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001548
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001549 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1550
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001551 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001552}
1553
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001554static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001555{
1556 mmc->bus_width = width;
1557
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001558 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001559}
1560
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001561#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1562/*
1563 * helper function to display the capabilities in a human
1564 * friendly manner. The capabilities include bus width and
1565 * supported modes.
1566 */
1567void mmc_dump_capabilities(const char *text, uint caps)
1568{
1569 enum bus_mode mode;
1570
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001571 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001572 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001573 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001574 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001575 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001576 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001577 pr_debug("1, ");
1578 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001579 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1580 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001581 pr_debug("%s, ", mmc_mode_name(mode));
1582 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001583}
1584#endif
1585
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001586struct mode_width_tuning {
1587 enum bus_mode mode;
1588 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001589#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001590 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001591#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001592};
1593
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001594#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001595int mmc_voltage_to_mv(enum mmc_voltage voltage)
1596{
1597 switch (voltage) {
1598 case MMC_SIGNAL_VOLTAGE_000: return 0;
1599 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1600 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1601 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1602 }
1603 return -EINVAL;
1604}
1605
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001606static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1607{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001608 int err;
1609
1610 if (mmc->signal_voltage == signal_voltage)
1611 return 0;
1612
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001613 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001614 err = mmc_set_ios(mmc);
1615 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001616 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001617
1618 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001619}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001620#else
1621static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1622{
1623 return 0;
1624}
1625#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001626
Marek Vasut62d77ce2018-04-15 00:37:11 +02001627#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001628static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001629#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1630#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001631 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001632 .mode = UHS_SDR104,
1633 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1634 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1635 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001636#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001637 {
1638 .mode = UHS_SDR50,
1639 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1640 },
1641 {
1642 .mode = UHS_DDR50,
1643 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1644 },
1645 {
1646 .mode = UHS_SDR25,
1647 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1648 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001649#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001650 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001651 .mode = SD_HS,
1652 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1653 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001654#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001655 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001656 .mode = UHS_SDR12,
1657 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1658 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001659#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001660 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001661 .mode = SD_LEGACY,
1662 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1663 }
1664};
1665
1666#define for_each_sd_mode_by_pref(caps, mwt) \
1667 for (mwt = sd_modes_by_pref;\
1668 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1669 mwt++) \
1670 if (caps & MMC_CAP(mwt->mode))
1671
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001672static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001673{
1674 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001675 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1676 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001677#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001678 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001679#else
1680 bool uhs_en = false;
1681#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001682 uint caps;
1683
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001684#ifdef DEBUG
1685 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001686 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001687#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001688
Anup Patelf49ff792019-07-08 04:10:43 +00001689 if (mmc_host_is_spi(mmc)) {
1690 mmc_set_bus_width(mmc, 1);
1691 mmc_select_mode(mmc, SD_LEGACY);
1692 mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
1693 return 0;
1694 }
1695
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001696 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001697 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001698
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001699 if (!uhs_en)
1700 caps &= ~UHS_CAPS;
1701
1702 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001703 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001704
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001705 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001706 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001707 pr_debug("trying mode %s width %d (at %d MHz)\n",
1708 mmc_mode_name(mwt->mode),
1709 bus_width(*w),
1710 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001711
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001712 /* configure the bus width (card + host) */
1713 err = sd_select_bus_width(mmc, bus_width(*w));
1714 if (err)
1715 goto error;
1716 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001717
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001718 /* configure the bus mode (card) */
1719 err = sd_set_card_speed(mmc, mwt->mode);
1720 if (err)
1721 goto error;
1722
1723 /* configure the bus mode (host) */
1724 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001725 mmc_set_clock(mmc, mmc->tran_speed,
1726 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001727
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001728#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001729 /* execute tuning if needed */
1730 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1731 err = mmc_execute_tuning(mmc,
1732 mwt->tuning);
1733 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001734 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001735 goto error;
1736 }
1737 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001738#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001739
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001740#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001741 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001742 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001743 pr_warn("unable to read ssr\n");
1744#endif
1745 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001746 return 0;
1747
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001748error:
1749 /* revert to a safer bus speed */
1750 mmc_select_mode(mmc, SD_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001751 mmc_set_clock(mmc, mmc->tran_speed,
1752 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001753 }
1754 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001755 }
1756
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001757 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001758 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001759}
1760
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001761/*
1762 * read the compare the part of ext csd that is constant.
1763 * This can be used to check that the transfer is working
1764 * as expected.
1765 */
1766static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1767{
1768 int err;
1769 const u8 *ext_csd = mmc->ext_csd;
1770 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1771
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001772 if (mmc->version < MMC_VERSION_4)
1773 return 0;
1774
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001775 err = mmc_send_ext_csd(mmc, test_csd);
1776 if (err)
1777 return err;
1778
1779 /* Only compare read only fields */
1780 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1781 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1782 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1783 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1784 ext_csd[EXT_CSD_REV]
1785 == test_csd[EXT_CSD_REV] &&
1786 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1787 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1788 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1789 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1790 return 0;
1791
1792 return -EBADMSG;
1793}
1794
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001795#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001796static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1797 uint32_t allowed_mask)
1798{
1799 u32 card_mask = 0;
1800
1801 switch (mode) {
Peng Fan3dd26262018-08-10 14:07:54 +08001802 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001803 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001804 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1805 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001806 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001807 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1808 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001809 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1810 break;
1811 case MMC_DDR_52:
1812 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1813 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1814 MMC_SIGNAL_VOLTAGE_180;
1815 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1816 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1817 break;
1818 default:
1819 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1820 break;
1821 }
1822
1823 while (card_mask & allowed_mask) {
1824 enum mmc_voltage best_match;
1825
1826 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1827 if (!mmc_set_signal_voltage(mmc, best_match))
1828 return 0;
1829
1830 allowed_mask &= ~best_match;
1831 }
1832
1833 return -ENOTSUPP;
1834}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001835#else
1836static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1837 uint32_t allowed_mask)
1838{
1839 return 0;
1840}
1841#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001842
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001843static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan3dd26262018-08-10 14:07:54 +08001844#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1845 {
1846 .mode = MMC_HS_400,
1847 .widths = MMC_MODE_8BIT,
1848 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1849 },
1850#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001851#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001852 {
1853 .mode = MMC_HS_200,
1854 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001855 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001856 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001857#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001858 {
1859 .mode = MMC_DDR_52,
1860 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1861 },
1862 {
1863 .mode = MMC_HS_52,
1864 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1865 },
1866 {
1867 .mode = MMC_HS,
1868 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1869 },
1870 {
1871 .mode = MMC_LEGACY,
1872 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1873 }
1874};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001875
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001876#define for_each_mmc_mode_by_pref(caps, mwt) \
1877 for (mwt = mmc_modes_by_pref;\
1878 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1879 mwt++) \
1880 if (caps & MMC_CAP(mwt->mode))
1881
1882static const struct ext_csd_bus_width {
1883 uint cap;
1884 bool is_ddr;
1885 uint ext_csd_bits;
1886} ext_csd_bus_width[] = {
1887 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1888 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1889 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1890 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1891 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1892};
1893
Peng Fan3dd26262018-08-10 14:07:54 +08001894#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1895static int mmc_select_hs400(struct mmc *mmc)
1896{
1897 int err;
1898
1899 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001900 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001901 if (err)
1902 return err;
1903
1904 /* configure the bus mode (host) */
1905 mmc_select_mode(mmc, MMC_HS_200);
1906 mmc_set_clock(mmc, mmc->tran_speed, false);
1907
1908 /* execute tuning if needed */
1909 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1910 if (err) {
1911 debug("tuning failed\n");
1912 return err;
1913 }
1914
1915 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001916 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001917
1918 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1919 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1920 if (err)
1921 return err;
1922
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001923 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001924 if (err)
1925 return err;
1926
1927 mmc_select_mode(mmc, MMC_HS_400);
1928 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1929 if (err)
1930 return err;
1931
1932 return 0;
1933}
1934#else
1935static int mmc_select_hs400(struct mmc *mmc)
1936{
1937 return -ENOTSUPP;
1938}
1939#endif
1940
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001941#define for_each_supported_width(caps, ddr, ecbv) \
1942 for (ecbv = ext_csd_bus_width;\
1943 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1944 ecbv++) \
1945 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1946
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001947static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001948{
1949 int err;
1950 const struct mode_width_tuning *mwt;
1951 const struct ext_csd_bus_width *ecbw;
1952
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001953#ifdef DEBUG
1954 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001955 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001956#endif
1957
Anup Patelf49ff792019-07-08 04:10:43 +00001958 if (mmc_host_is_spi(mmc)) {
1959 mmc_set_bus_width(mmc, 1);
1960 mmc_select_mode(mmc, MMC_LEGACY);
1961 mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
1962 return 0;
1963 }
1964
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001965 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001966 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001967
1968 /* Only version 4 of MMC supports wider bus widths */
1969 if (mmc->version < MMC_VERSION_4)
1970 return 0;
1971
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001972 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001973 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001974 return -ENOTSUPP;
1975 }
1976
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001977#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
1978 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1979 /*
1980 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
1981 * before doing anything else, since a transition from either of
1982 * the HS200/HS400 mode directly to legacy mode is not supported.
1983 */
1984 if (mmc->selected_mode == MMC_HS_200 ||
1985 mmc->selected_mode == MMC_HS_400)
1986 mmc_set_card_speed(mmc, MMC_HS, true);
1987 else
1988#endif
1989 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001990
1991 for_each_mmc_mode_by_pref(card_caps, mwt) {
1992 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001993 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001994 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001995 pr_debug("trying mode %s width %d (at %d MHz)\n",
1996 mmc_mode_name(mwt->mode),
1997 bus_width(ecbw->cap),
1998 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001999 old_voltage = mmc->signal_voltage;
2000 err = mmc_set_lowest_voltage(mmc, mwt->mode,
2001 MMC_ALL_SIGNAL_VOLTAGE);
2002 if (err)
2003 continue;
2004
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002005 /* configure the bus width (card + host) */
2006 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2007 EXT_CSD_BUS_WIDTH,
2008 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
2009 if (err)
2010 goto error;
2011 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
2012
Peng Fan3dd26262018-08-10 14:07:54 +08002013 if (mwt->mode == MMC_HS_400) {
2014 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002015 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08002016 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002017 goto error;
2018 }
Peng Fan3dd26262018-08-10 14:07:54 +08002019 } else {
2020 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002021 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002022 if (err)
2023 goto error;
2024
2025 /*
2026 * configure the bus width AND the ddr mode
2027 * (card). The host side will be taken care
2028 * of in the next step
2029 */
2030 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2031 err = mmc_switch(mmc,
2032 EXT_CSD_CMD_SET_NORMAL,
2033 EXT_CSD_BUS_WIDTH,
2034 ecbw->ext_csd_bits);
2035 if (err)
2036 goto error;
2037 }
2038
2039 /* configure the bus mode (host) */
2040 mmc_select_mode(mmc, mwt->mode);
2041 mmc_set_clock(mmc, mmc->tran_speed,
2042 MMC_CLK_ENABLE);
2043#ifdef MMC_SUPPORTS_TUNING
2044
2045 /* execute tuning if needed */
2046 if (mwt->tuning) {
2047 err = mmc_execute_tuning(mmc,
2048 mwt->tuning);
2049 if (err) {
2050 pr_debug("tuning failed\n");
2051 goto error;
2052 }
2053 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002054#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002055 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002056
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002057 /* do a transfer to check the configuration */
2058 err = mmc_read_and_compare_ext_csd(mmc);
2059 if (!err)
2060 return 0;
2061error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002062 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002063 /* if an error occured, revert to a safer bus mode */
2064 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2065 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2066 mmc_select_mode(mmc, MMC_LEGACY);
2067 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002068 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002069 }
2070
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002071 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002072
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002073 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002074}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002075#endif
2076
2077#if CONFIG_IS_ENABLED(MMC_TINY)
2078DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2079#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002080
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002081static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002082{
2083 int err, i;
2084 u64 capacity;
2085 bool has_parts = false;
2086 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002087 static const u32 mmc_versions[] = {
2088 MMC_VERSION_4,
2089 MMC_VERSION_4_1,
2090 MMC_VERSION_4_2,
2091 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002092 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002093 MMC_VERSION_4_41,
2094 MMC_VERSION_4_5,
2095 MMC_VERSION_5_0,
2096 MMC_VERSION_5_1
2097 };
2098
Marek Vasut62d77ce2018-04-15 00:37:11 +02002099#if CONFIG_IS_ENABLED(MMC_TINY)
2100 u8 *ext_csd = ext_csd_bkup;
2101
2102 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2103 return 0;
2104
2105 if (!mmc->ext_csd)
2106 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2107
2108 err = mmc_send_ext_csd(mmc, ext_csd);
2109 if (err)
2110 goto error;
2111
2112 /* store the ext csd for future reference */
2113 if (!mmc->ext_csd)
2114 mmc->ext_csd = ext_csd;
2115#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002116 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002117
2118 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2119 return 0;
2120
2121 /* check ext_csd version and capacity */
2122 err = mmc_send_ext_csd(mmc, ext_csd);
2123 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002124 goto error;
2125
2126 /* store the ext csd for future reference */
2127 if (!mmc->ext_csd)
2128 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2129 if (!mmc->ext_csd)
2130 return -ENOMEM;
2131 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002132#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002133 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002134 return -EINVAL;
2135
2136 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2137
2138 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002139 /*
2140 * According to the JEDEC Standard, the value of
2141 * ext_csd's capacity is valid if the value is more
2142 * than 2GB
2143 */
2144 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2145 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2146 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2147 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2148 capacity *= MMC_MAX_BLOCK_LEN;
2149 if ((capacity >> 20) > 2 * 1024)
2150 mmc->capacity_user = capacity;
2151 }
2152
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +02002153 if (mmc->version >= MMC_VERSION_4_5)
2154 mmc->gen_cmd6_time = ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
2155
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002156 /* The partition data may be non-zero but it is only
2157 * effective if PARTITION_SETTING_COMPLETED is set in
2158 * EXT_CSD, so ignore any data if this bit is not set,
2159 * except for enabling the high-capacity group size
2160 * definition (see below).
2161 */
2162 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2163 EXT_CSD_PARTITION_SETTING_COMPLETED);
2164
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +02002165 mmc->part_switch_time = ext_csd[EXT_CSD_PART_SWITCH_TIME];
2166 /* Some eMMC set the value too low so set a minimum */
2167 if (mmc->part_switch_time < MMC_MIN_PART_SWITCH_TIME && mmc->part_switch_time)
2168 mmc->part_switch_time = MMC_MIN_PART_SWITCH_TIME;
2169
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002170 /* store the partition info of emmc */
2171 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2172 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2173 ext_csd[EXT_CSD_BOOT_MULT])
2174 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2175 if (part_completed &&
2176 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2177 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2178
2179 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2180
2181 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2182
2183 for (i = 0; i < 4; i++) {
2184 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2185 uint mult = (ext_csd[idx + 2] << 16) +
2186 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2187 if (mult)
2188 has_parts = true;
2189 if (!part_completed)
2190 continue;
2191 mmc->capacity_gp[i] = mult;
2192 mmc->capacity_gp[i] *=
2193 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2194 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2195 mmc->capacity_gp[i] <<= 19;
2196 }
2197
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002198#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002199 if (part_completed) {
2200 mmc->enh_user_size =
2201 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2202 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2203 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2204 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2205 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2206 mmc->enh_user_size <<= 19;
2207 mmc->enh_user_start =
2208 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2209 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2210 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2211 ext_csd[EXT_CSD_ENH_START_ADDR];
2212 if (mmc->high_capacity)
2213 mmc->enh_user_start <<= 9;
2214 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002215#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002216
2217 /*
2218 * Host needs to enable ERASE_GRP_DEF bit if device is
2219 * partitioned. This bit will be lost every time after a reset
2220 * or power off. This will affect erase size.
2221 */
2222 if (part_completed)
2223 has_parts = true;
2224 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2225 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2226 has_parts = true;
2227 if (has_parts) {
2228 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2229 EXT_CSD_ERASE_GROUP_DEF, 1);
2230
2231 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002232 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002233
2234 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2235 }
2236
2237 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002238#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002239 /* Read out group size from ext_csd */
2240 mmc->erase_grp_size =
2241 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002242#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002243 /*
2244 * if high capacity and partition setting completed
2245 * SEC_COUNT is valid even if it is smaller than 2 GiB
2246 * JEDEC Standard JESD84-B45, 6.2.4
2247 */
2248 if (mmc->high_capacity && part_completed) {
2249 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2250 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2251 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2252 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2253 capacity *= MMC_MAX_BLOCK_LEN;
2254 mmc->capacity_user = capacity;
2255 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002256 }
2257#if CONFIG_IS_ENABLED(MMC_WRITE)
2258 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002259 /* Calculate the group size from the csd value. */
2260 int erase_gsz, erase_gmul;
2261
2262 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2263 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2264 mmc->erase_grp_size = (erase_gsz + 1)
2265 * (erase_gmul + 1);
2266 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002267#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002268#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002269 mmc->hc_wp_grp_size = 1024
2270 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2271 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002272#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002273
2274 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2275
2276 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002277error:
2278 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002279#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002280 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002281#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002282 mmc->ext_csd = NULL;
2283 }
2284 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002285}
2286
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002287static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002288{
Stephen Warrenf866a462013-06-11 15:14:01 -06002289 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002290 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002291 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002292 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002293 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002294
Thomas Choud52ebf12010-12-24 13:12:21 +00002295#ifdef CONFIG_MMC_SPI_CRC_ON
2296 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2297 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2298 cmd.resp_type = MMC_RSP_R1;
2299 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002300 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002301 if (err)
2302 return err;
2303 }
2304#endif
2305
Andy Fleming272cc702008-10-30 16:41:01 -05002306 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002307 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2308 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002309 cmd.resp_type = MMC_RSP_R2;
2310 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002311
2312 err = mmc_send_cmd(mmc, &cmd, NULL);
2313
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002314#ifdef CONFIG_MMC_QUIRKS
2315 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2316 int retries = 4;
2317 /*
2318 * It has been seen that SEND_CID may fail on the first
2319 * attempt, let's try a few more time
2320 */
2321 do {
2322 err = mmc_send_cmd(mmc, &cmd, NULL);
2323 if (!err)
2324 break;
2325 } while (retries--);
2326 }
2327#endif
2328
Andy Fleming272cc702008-10-30 16:41:01 -05002329 if (err)
2330 return err;
2331
2332 memcpy(mmc->cid, cmd.response, 16);
2333
2334 /*
2335 * For MMC cards, set the Relative Address.
2336 * For SD cards, get the Relatvie Address.
2337 * This also puts the cards into Standby State
2338 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002339 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2340 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2341 cmd.cmdarg = mmc->rca << 16;
2342 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002343
Thomas Choud52ebf12010-12-24 13:12:21 +00002344 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002345
Thomas Choud52ebf12010-12-24 13:12:21 +00002346 if (err)
2347 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002348
Thomas Choud52ebf12010-12-24 13:12:21 +00002349 if (IS_SD(mmc))
2350 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2351 }
Andy Fleming272cc702008-10-30 16:41:01 -05002352
2353 /* Get the Card-Specific Data */
2354 cmd.cmdidx = MMC_CMD_SEND_CSD;
2355 cmd.resp_type = MMC_RSP_R2;
2356 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002357
2358 err = mmc_send_cmd(mmc, &cmd, NULL);
2359
2360 if (err)
2361 return err;
2362
Rabin Vincent998be3d2009-04-05 13:30:56 +05302363 mmc->csd[0] = cmd.response[0];
2364 mmc->csd[1] = cmd.response[1];
2365 mmc->csd[2] = cmd.response[2];
2366 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002367
2368 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302369 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002370
2371 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002372 case 0:
2373 mmc->version = MMC_VERSION_1_2;
2374 break;
2375 case 1:
2376 mmc->version = MMC_VERSION_1_4;
2377 break;
2378 case 2:
2379 mmc->version = MMC_VERSION_2_2;
2380 break;
2381 case 3:
2382 mmc->version = MMC_VERSION_3;
2383 break;
2384 case 4:
2385 mmc->version = MMC_VERSION_4;
2386 break;
2387 default:
2388 mmc->version = MMC_VERSION_1_2;
2389 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002390 }
2391 }
2392
2393 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302394 freq = fbase[(cmd.response[0] & 0x7)];
2395 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002396
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002397 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002398 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002399
Markus Niebelab711882013-12-16 13:40:46 +01002400 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302401 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002402#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002403
2404 if (IS_SD(mmc))
2405 mmc->write_bl_len = mmc->read_bl_len;
2406 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302407 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002408#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002409
2410 if (mmc->high_capacity) {
2411 csize = (mmc->csd[1] & 0x3f) << 16
2412 | (mmc->csd[2] & 0xffff0000) >> 16;
2413 cmult = 8;
2414 } else {
2415 csize = (mmc->csd[1] & 0x3ff) << 2
2416 | (mmc->csd[2] & 0xc0000000) >> 30;
2417 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2418 }
2419
Stephen Warrenf866a462013-06-11 15:14:01 -06002420 mmc->capacity_user = (csize + 1) << (cmult + 2);
2421 mmc->capacity_user *= mmc->read_bl_len;
2422 mmc->capacity_boot = 0;
2423 mmc->capacity_rpmb = 0;
2424 for (i = 0; i < 4; i++)
2425 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002426
Simon Glass8bfa1952013-04-03 08:54:30 +00002427 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2428 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002429
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002430#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002431 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2432 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002433#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002434
Markus Niebelab711882013-12-16 13:40:46 +01002435 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2436 cmd.cmdidx = MMC_CMD_SET_DSR;
2437 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2438 cmd.resp_type = MMC_RSP_NONE;
2439 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002440 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002441 }
2442
Andy Fleming272cc702008-10-30 16:41:01 -05002443 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002444 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2445 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002446 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002447 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002448 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002449
Thomas Choud52ebf12010-12-24 13:12:21 +00002450 if (err)
2451 return err;
2452 }
Andy Fleming272cc702008-10-30 16:41:01 -05002453
Lei Wene6f99a52011-06-22 17:03:31 +00002454 /*
2455 * For SD, its erase group is always one sector
2456 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002457#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002458 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002459#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002460 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002461
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002462 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002463 if (err)
2464 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302465
Simon Glassc40fdca2016-05-01 13:52:35 -06002466 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002467 if (err)
2468 return err;
2469
Marek Vasut62d77ce2018-04-15 00:37:11 +02002470#if CONFIG_IS_ENABLED(MMC_TINY)
2471 mmc_set_clock(mmc, mmc->legacy_speed, false);
2472 mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
2473 mmc_set_bus_width(mmc, 1);
2474#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002475 if (IS_SD(mmc)) {
2476 err = sd_get_capabilities(mmc);
2477 if (err)
2478 return err;
2479 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2480 } else {
2481 err = mmc_get_capabilities(mmc);
2482 if (err)
2483 return err;
2484 mmc_select_mode_and_width(mmc, mmc->card_caps);
2485 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002486#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002487 if (err)
2488 return err;
2489
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002490 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002491
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002492 /* Fix the block length for DDR mode */
2493 if (mmc->ddr_mode) {
2494 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002495#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002496 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002497#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002498 }
2499
Andy Fleming272cc702008-10-30 16:41:01 -05002500 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002501 bdesc = mmc_get_blk_desc(mmc);
2502 bdesc->lun = 0;
2503 bdesc->hwpart = 0;
2504 bdesc->type = 0;
2505 bdesc->blksz = mmc->read_bl_len;
2506 bdesc->log2blksz = LOG2(bdesc->blksz);
2507 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002508#if !defined(CONFIG_SPL_BUILD) || \
2509 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
2510 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002511 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002512 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2513 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002514 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002515 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2516 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2517 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002518 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002519 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002520#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002521 bdesc->vendor[0] = 0;
2522 bdesc->product[0] = 0;
2523 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002524#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002525
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002526#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2527 part_init(bdesc);
2528#endif
2529
Andy Fleming272cc702008-10-30 16:41:01 -05002530 return 0;
2531}
2532
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002533static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002534{
2535 struct mmc_cmd cmd;
2536 int err;
2537
2538 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2539 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002540 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002541 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002542
2543 err = mmc_send_cmd(mmc, &cmd, NULL);
2544
2545 if (err)
2546 return err;
2547
Rabin Vincent998be3d2009-04-05 13:30:56 +05302548 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002549 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002550 else
2551 mmc->version = SD_VERSION_2;
2552
2553 return 0;
2554}
2555
Simon Glassc4d660d2017-07-04 13:31:19 -06002556#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002557/* board-specific MMC power initializations. */
2558__weak void board_mmc_power_init(void)
2559{
2560}
Simon Glass05cbeb72017-04-22 19:10:56 -06002561#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002562
Peng Fan2051aef2016-10-11 15:08:43 +08002563static int mmc_power_init(struct mmc *mmc)
2564{
Simon Glassc4d660d2017-07-04 13:31:19 -06002565#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002566#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002567 int ret;
2568
2569 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002570 &mmc->vmmc_supply);
2571 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002572 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002573
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002574 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2575 &mmc->vqmmc_supply);
2576 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002577 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002578#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002579#else /* !CONFIG_DM_MMC */
2580 /*
2581 * Driver model should use a regulator, as above, rather than calling
2582 * out to board code.
2583 */
2584 board_mmc_power_init();
2585#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002586 return 0;
2587}
2588
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002589/*
2590 * put the host in the initial state:
2591 * - turn on Vdd (card power supply)
2592 * - configure the bus width and clock to minimal values
2593 */
2594static void mmc_set_initial_state(struct mmc *mmc)
2595{
2596 int err;
2597
2598 /* First try to set 3.3V. If it fails set to 1.8V */
2599 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2600 if (err != 0)
2601 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2602 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002603 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002604
2605 mmc_select_mode(mmc, MMC_LEGACY);
2606 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002607 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002608}
2609
2610static int mmc_power_on(struct mmc *mmc)
2611{
2612#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2613 if (mmc->vmmc_supply) {
2614 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2615
2616 if (ret) {
2617 puts("Error enabling VMMC supply\n");
2618 return ret;
2619 }
2620 }
2621#endif
2622 return 0;
2623}
2624
2625static int mmc_power_off(struct mmc *mmc)
2626{
Jaehoon Chung65117182018-01-26 19:25:29 +09002627 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002628#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2629 if (mmc->vmmc_supply) {
2630 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2631
2632 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002633 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002634 return ret;
2635 }
2636 }
2637#endif
2638 return 0;
2639}
2640
2641static int mmc_power_cycle(struct mmc *mmc)
2642{
2643 int ret;
2644
2645 ret = mmc_power_off(mmc);
2646 if (ret)
2647 return ret;
2648 /*
2649 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2650 * to be on the safer side.
2651 */
2652 udelay(2000);
2653 return mmc_power_on(mmc);
2654}
2655
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002656int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002657{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002658 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002659 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002660
Lei Wenbc897b12011-05-02 16:26:26 +00002661 if (mmc->has_init)
2662 return 0;
2663
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002664#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2665 mmc_adapter_card_type_ident();
2666#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002667 err = mmc_power_init(mmc);
2668 if (err)
2669 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002670
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002671#ifdef CONFIG_MMC_QUIRKS
2672 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
2673 MMC_QUIRK_RETRY_SEND_CID;
2674#endif
2675
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002676 err = mmc_power_cycle(mmc);
2677 if (err) {
2678 /*
2679 * if power cycling is not supported, we should not try
2680 * to use the UHS modes, because we wouldn't be able to
2681 * recover from an error during the UHS initialization.
2682 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002683 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002684 uhs_en = false;
2685 mmc->host_caps &= ~UHS_CAPS;
2686 err = mmc_power_on(mmc);
2687 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002688 if (err)
2689 return err;
2690
Simon Glasse7881d82017-07-29 11:35:31 -06002691#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002692 /* The device has already been probed ready for use */
2693#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002694 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002695 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002696 if (err)
2697 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002698#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002699 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002700
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002701retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002702 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002703
Andy Fleming272cc702008-10-30 16:41:01 -05002704 /* Reset the Card */
2705 err = mmc_go_idle(mmc);
2706
2707 if (err)
2708 return err;
2709
Lei Wenbc897b12011-05-02 16:26:26 +00002710 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002711 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002712
Andy Fleming272cc702008-10-30 16:41:01 -05002713 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002714 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002715
Andy Fleming272cc702008-10-30 16:41:01 -05002716 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002717 err = sd_send_op_cond(mmc, uhs_en);
2718 if (err && uhs_en) {
2719 uhs_en = false;
2720 mmc_power_cycle(mmc);
2721 goto retry;
2722 }
Andy Fleming272cc702008-10-30 16:41:01 -05002723
2724 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002725 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002726 err = mmc_send_op_cond(mmc);
2727
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002728 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002729#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002730 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002731#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002732 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002733 }
2734 }
2735
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002736 return err;
2737}
2738
2739int mmc_start_init(struct mmc *mmc)
2740{
2741 bool no_card;
2742 int err = 0;
2743
2744 /*
2745 * all hosts are capable of 1 bit bus-width and able to use the legacy
2746 * timings.
2747 */
2748 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
2749 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
2750
2751#if !defined(CONFIG_MMC_BROKEN_CD)
2752 /* we pretend there's no card when init is NULL */
2753 no_card = mmc_getcd(mmc) == 0;
2754#else
2755 no_card = 0;
2756#endif
2757#if !CONFIG_IS_ENABLED(DM_MMC)
2758 no_card = no_card || (mmc->cfg->ops->init == NULL);
2759#endif
2760 if (no_card) {
2761 mmc->has_init = 0;
2762#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2763 pr_err("MMC: no card present\n");
2764#endif
2765 return -ENOMEDIUM;
2766 }
2767
2768 err = mmc_get_op_cond(mmc);
2769
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002770 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002771 mmc->init_in_progress = 1;
2772
2773 return err;
2774}
2775
2776static int mmc_complete_init(struct mmc *mmc)
2777{
2778 int err = 0;
2779
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002780 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002781 if (mmc->op_cond_pending)
2782 err = mmc_complete_op_cond(mmc);
2783
2784 if (!err)
2785 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002786 if (err)
2787 mmc->has_init = 0;
2788 else
2789 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002790 return err;
2791}
2792
2793int mmc_init(struct mmc *mmc)
2794{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002795 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302796 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002797#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002798 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002799
Simon Glass33fb2112016-05-01 13:52:41 -06002800 upriv->mmc = mmc;
2801#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002802 if (mmc->has_init)
2803 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002804
2805 start = get_timer(0);
2806
Che-Liang Chioue9550442012-11-28 15:21:13 +00002807 if (!mmc->init_in_progress)
2808 err = mmc_start_init(mmc);
2809
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002810 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002811 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002812 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002813 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002814
Lei Wenbc897b12011-05-02 16:26:26 +00002815 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002816}
2817
Marek Vasutfceea992019-01-29 04:45:51 +01002818#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2819 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2820 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2821int mmc_deinit(struct mmc *mmc)
2822{
2823 u32 caps_filtered;
2824
2825 if (!mmc->has_init)
2826 return 0;
2827
2828 if (IS_SD(mmc)) {
2829 caps_filtered = mmc->card_caps &
2830 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2831 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2832 MMC_CAP(UHS_SDR104));
2833
2834 return sd_select_mode_and_width(mmc, caps_filtered);
2835 } else {
2836 caps_filtered = mmc->card_caps &
2837 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2838
2839 return mmc_select_mode_and_width(mmc, caps_filtered);
2840 }
2841}
2842#endif
2843
Markus Niebelab711882013-12-16 13:40:46 +01002844int mmc_set_dsr(struct mmc *mmc, u16 val)
2845{
2846 mmc->dsr = val;
2847 return 0;
2848}
2849
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002850/* CPU-specific MMC initializations */
2851__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002852{
2853 return -1;
2854}
2855
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002856/* board-specific MMC initializations. */
2857__weak int board_mmc_init(bd_t *bis)
2858{
2859 return -1;
2860}
Andy Fleming272cc702008-10-30 16:41:01 -05002861
Che-Liang Chioue9550442012-11-28 15:21:13 +00002862void mmc_set_preinit(struct mmc *mmc, int preinit)
2863{
2864 mmc->preinit = preinit;
2865}
2866
Faiz Abbas8a856db2018-02-12 19:35:24 +05302867#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002868static int mmc_probe(bd_t *bis)
2869{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002870 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002871 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002872 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002873
2874 ret = uclass_get(UCLASS_MMC, &uc);
2875 if (ret)
2876 return ret;
2877
Simon Glass4a1db6d2015-12-29 05:22:49 -07002878 /*
2879 * Try to add them in sequence order. Really with driver model we
2880 * should allow holes, but the current MMC list does not allow that.
2881 * So if we request 0, 1, 3 we will get 0, 1, 2.
2882 */
2883 for (i = 0; ; i++) {
2884 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2885 if (ret == -ENODEV)
2886 break;
2887 }
2888 uclass_foreach_dev(dev, uc) {
2889 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002890 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002891 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002892 }
2893
2894 return 0;
2895}
2896#else
2897static int mmc_probe(bd_t *bis)
2898{
2899 if (board_mmc_init(bis) < 0)
2900 cpu_mmc_init(bis);
2901
2902 return 0;
2903}
2904#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002905
Andy Fleming272cc702008-10-30 16:41:01 -05002906int mmc_initialize(bd_t *bis)
2907{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002908 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002909 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002910 if (initialized) /* Avoid initializing mmc multiple times */
2911 return 0;
2912 initialized = 1;
2913
Simon Glassc4d660d2017-07-04 13:31:19 -06002914#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002915#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002916 mmc_list_init();
2917#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002918#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002919 ret = mmc_probe(bis);
2920 if (ret)
2921 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002922
Ying Zhangbb0dc102013-08-16 15:16:11 +08002923#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002924 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002925#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002926
Simon Glassc40fdca2016-05-01 13:52:35 -06002927 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002928 return 0;
2929}
Tomas Melincd3d4882016-11-25 11:01:03 +02002930
2931#ifdef CONFIG_CMD_BKOPS_ENABLE
2932int mmc_set_bkops_enable(struct mmc *mmc)
2933{
2934 int err;
2935 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2936
2937 err = mmc_send_ext_csd(mmc, ext_csd);
2938 if (err) {
2939 puts("Could not get ext_csd register values\n");
2940 return err;
2941 }
2942
2943 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2944 puts("Background operations not supported on device\n");
2945 return -EMEDIUMTYPE;
2946 }
2947
2948 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2949 puts("Background operations already enabled\n");
2950 return 0;
2951 }
2952
2953 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2954 if (err) {
2955 puts("Failed to enable manual background operations\n");
2956 return err;
2957 }
2958
2959 puts("Enabled manual background operations\n");
2960
2961 return 0;
2962}
2963#endif