blob: ff56c3dd67dd361a6a934364c2df13ac109c25f6 [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{
749 struct mmc_cmd cmd;
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200750 int timeout = DEFAULT_CMD6_TIMEOUT_MS;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100751 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000752 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500753
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200754 if (mmc->gen_cmd6_time)
755 timeout = mmc->gen_cmd6_time * 10;
756
Andy Fleming272cc702008-10-30 16:41:01 -0500757 cmd.cmdidx = MMC_CMD_SWITCH;
758 cmd.resp_type = MMC_RSP_R1b;
759 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000760 (index << 16) |
761 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500762
Maxime Riparda9003dc2016-11-04 16:18:08 +0100763 while (retries > 0) {
764 ret = mmc_send_cmd(mmc, &cmd, NULL);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000765
Marek Vasut68925502019-02-06 11:34:27 +0100766 if (ret) {
767 retries--;
768 continue;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100769 }
770
Marek Vasut68925502019-02-06 11:34:27 +0100771 if (!send_status) {
772 mdelay(50);
773 return 0;
774 }
775
776 /* Waiting for the ready status */
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200777 return mmc_poll_for_busy(mmc, timeout);
Maxime Riparda9003dc2016-11-04 16:18:08 +0100778 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000779
780 return ret;
781
Andy Fleming272cc702008-10-30 16:41:01 -0500782}
783
Marek Vasut68925502019-02-06 11:34:27 +0100784int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
785{
786 return __mmc_switch(mmc, set, index, value, true);
787}
788
Marek Vasut62d77ce2018-04-15 00:37:11 +0200789#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100790static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
791 bool hsdowngrade)
Andy Fleming272cc702008-10-30 16:41:01 -0500792{
Andy Fleming272cc702008-10-30 16:41:01 -0500793 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200794 int speed_bits;
795
796 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
797
798 switch (mode) {
799 case MMC_HS:
800 case MMC_HS_52:
801 case MMC_DDR_52:
802 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200803 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100804#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200805 case MMC_HS_200:
806 speed_bits = EXT_CSD_TIMING_HS200;
807 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100808#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800809#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
810 case MMC_HS_400:
811 speed_bits = EXT_CSD_TIMING_HS400;
812 break;
813#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200814 case MMC_LEGACY:
815 speed_bits = EXT_CSD_TIMING_LEGACY;
816 break;
817 default:
818 return -EINVAL;
819 }
Marek Vasut68925502019-02-06 11:34:27 +0100820
821 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
822 speed_bits, !hsdowngrade);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200823 if (err)
824 return err;
825
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100826#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
827 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
828 /*
829 * In case the eMMC is in HS200/HS400 mode and we are downgrading
830 * to HS mode, the card clock are still running much faster than
831 * the supported HS mode clock, so we can not reliably read out
832 * Extended CSD. Reconfigure the controller to run at HS mode.
833 */
834 if (hsdowngrade) {
835 mmc_select_mode(mmc, MMC_HS);
836 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
837 }
838#endif
839
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200840 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
841 /* Now check to see that it worked */
842 err = mmc_send_ext_csd(mmc, test_csd);
843 if (err)
844 return err;
845
846 /* No high-speed support */
847 if (!test_csd[EXT_CSD_HS_TIMING])
848 return -ENOTSUPP;
849 }
850
851 return 0;
852}
853
854static int mmc_get_capabilities(struct mmc *mmc)
855{
856 u8 *ext_csd = mmc->ext_csd;
857 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500858
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +0100859 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -0500860
Thomas Choud52ebf12010-12-24 13:12:21 +0000861 if (mmc_host_is_spi(mmc))
862 return 0;
863
Andy Fleming272cc702008-10-30 16:41:01 -0500864 /* Only version 4 supports high-speed */
865 if (mmc->version < MMC_VERSION_4)
866 return 0;
867
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200868 if (!ext_csd) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100869 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200870 return -ENOTSUPP;
871 }
872
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600873 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
874
Peng Fan3dd26262018-08-10 14:07:54 +0800875 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +0200876 mmc->cardtype = cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500877
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100878#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200879 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
880 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
881 mmc->card_caps |= MMC_MODE_HS200;
882 }
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100883#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800884#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
885 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
886 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
887 mmc->card_caps |= MMC_MODE_HS400;
888 }
889#endif
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900890 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200891 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900892 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200893 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900894 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200895 if (cardtype & EXT_CSD_CARD_TYPE_26)
896 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500897
898 return 0;
899}
Marek Vasut62d77ce2018-04-15 00:37:11 +0200900#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500901
Stephen Warrenf866a462013-06-11 15:14:01 -0600902static int mmc_set_capacity(struct mmc *mmc, int part_num)
903{
904 switch (part_num) {
905 case 0:
906 mmc->capacity = mmc->capacity_user;
907 break;
908 case 1:
909 case 2:
910 mmc->capacity = mmc->capacity_boot;
911 break;
912 case 3:
913 mmc->capacity = mmc->capacity_rpmb;
914 break;
915 case 4:
916 case 5:
917 case 6:
918 case 7:
919 mmc->capacity = mmc->capacity_gp[part_num - 4];
920 break;
921 default:
922 return -1;
923 }
924
Simon Glassc40fdca2016-05-01 13:52:35 -0600925 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600926
927 return 0;
928}
929
Marek Vasut72119aa2019-05-31 15:22:44 +0200930#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200931static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
932{
933 int forbidden = 0;
934 bool change = false;
935
936 if (part_num & PART_ACCESS_MASK)
Marek Vasut72119aa2019-05-31 15:22:44 +0200937 forbidden = MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200938
939 if (MMC_CAP(mmc->selected_mode) & forbidden) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900940 pr_debug("selected mode (%s) is forbidden for part %d\n",
941 mmc_mode_name(mmc->selected_mode), part_num);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200942 change = true;
943 } else if (mmc->selected_mode != mmc->best_mode) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900944 pr_debug("selected mode is not optimal\n");
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200945 change = true;
946 }
947
948 if (change)
949 return mmc_select_mode_and_width(mmc,
950 mmc->card_caps & ~forbidden);
951
952 return 0;
953}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100954#else
955static inline int mmc_boot_part_access_chk(struct mmc *mmc,
956 unsigned int part_num)
957{
958 return 0;
959}
960#endif
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200961
Simon Glass7dba0b92016-06-12 23:30:15 -0600962int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000963{
Stephen Warrenf866a462013-06-11 15:14:01 -0600964 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000965
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200966 ret = mmc_boot_part_access_chk(mmc, part_num);
967 if (ret)
968 return ret;
969
Stephen Warrenf866a462013-06-11 15:14:01 -0600970 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
971 (mmc->part_config & ~PART_ACCESS_MASK)
972 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600973
Peter Bigot6dc93e72014-09-02 18:31:23 -0500974 /*
975 * Set the capacity if the switch succeeded or was intended
976 * to return to representing the raw device.
977 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700978 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500979 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600980 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700981 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500982
983 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000984}
985
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100986#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100987int mmc_hwpart_config(struct mmc *mmc,
988 const struct mmc_hwpart_conf *conf,
989 enum mmc_hwpart_conf_mode mode)
990{
991 u8 part_attrs = 0;
992 u32 enh_size_mult;
993 u32 enh_start_addr;
994 u32 gp_size_mult[4];
995 u32 max_enh_size_mult;
996 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100997 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100998 int i, pidx, err;
999 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1000
1001 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
1002 return -EINVAL;
1003
1004 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001005 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001006 return -EMEDIUMTYPE;
1007 }
1008
1009 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001010 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001011 return -EMEDIUMTYPE;
1012 }
1013
1014 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001015 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001016 return -EMEDIUMTYPE;
1017 }
1018
1019 /* check partition alignment and total enhanced size */
1020 if (conf->user.enh_size) {
1021 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1022 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001023 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001024 "size aligned\n");
1025 return -EINVAL;
1026 }
1027 part_attrs |= EXT_CSD_ENH_USR;
1028 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1029 if (mmc->high_capacity) {
1030 enh_start_addr = conf->user.enh_start;
1031 } else {
1032 enh_start_addr = (conf->user.enh_start << 9);
1033 }
1034 } else {
1035 enh_size_mult = 0;
1036 enh_start_addr = 0;
1037 }
1038 tot_enh_size_mult += enh_size_mult;
1039
1040 for (pidx = 0; pidx < 4; pidx++) {
1041 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001042 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001043 "aligned\n", pidx+1);
1044 return -EINVAL;
1045 }
1046 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1047 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1048 part_attrs |= EXT_CSD_ENH_GP(pidx);
1049 tot_enh_size_mult += gp_size_mult[pidx];
1050 }
1051 }
1052
1053 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001054 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001055 return -EMEDIUMTYPE;
1056 }
1057
1058 err = mmc_send_ext_csd(mmc, ext_csd);
1059 if (err)
1060 return err;
1061
1062 max_enh_size_mult =
1063 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1064 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1065 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1066 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001067 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001068 tot_enh_size_mult, max_enh_size_mult);
1069 return -EMEDIUMTYPE;
1070 }
1071
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001072 /* The default value of EXT_CSD_WR_REL_SET is device
1073 * dependent, the values can only be changed if the
1074 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1075 * changed only once and before partitioning is completed. */
1076 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1077 if (conf->user.wr_rel_change) {
1078 if (conf->user.wr_rel_set)
1079 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1080 else
1081 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1082 }
1083 for (pidx = 0; pidx < 4; pidx++) {
1084 if (conf->gp_part[pidx].wr_rel_change) {
1085 if (conf->gp_part[pidx].wr_rel_set)
1086 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1087 else
1088 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1089 }
1090 }
1091
1092 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1093 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1094 puts("Card does not support host controlled partition write "
1095 "reliability settings\n");
1096 return -EMEDIUMTYPE;
1097 }
1098
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001099 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1100 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001101 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001102 return -EPERM;
1103 }
1104
1105 if (mode == MMC_HWPART_CONF_CHECK)
1106 return 0;
1107
1108 /* Partitioning requires high-capacity size definitions */
1109 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1110 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1111 EXT_CSD_ERASE_GROUP_DEF, 1);
1112
1113 if (err)
1114 return err;
1115
1116 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1117
1118 /* update erase group size to be high-capacity */
1119 mmc->erase_grp_size =
1120 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1121
1122 }
1123
1124 /* all OK, write the configuration */
1125 for (i = 0; i < 4; i++) {
1126 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1127 EXT_CSD_ENH_START_ADDR+i,
1128 (enh_start_addr >> (i*8)) & 0xFF);
1129 if (err)
1130 return err;
1131 }
1132 for (i = 0; i < 3; i++) {
1133 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1134 EXT_CSD_ENH_SIZE_MULT+i,
1135 (enh_size_mult >> (i*8)) & 0xFF);
1136 if (err)
1137 return err;
1138 }
1139 for (pidx = 0; pidx < 4; pidx++) {
1140 for (i = 0; i < 3; i++) {
1141 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1142 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1143 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1144 if (err)
1145 return err;
1146 }
1147 }
1148 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1149 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1150 if (err)
1151 return err;
1152
1153 if (mode == MMC_HWPART_CONF_SET)
1154 return 0;
1155
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001156 /* The WR_REL_SET is a write-once register but shall be
1157 * written before setting PART_SETTING_COMPLETED. As it is
1158 * write-once we can only write it when completing the
1159 * partitioning. */
1160 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1161 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1162 EXT_CSD_WR_REL_SET, wr_rel_set);
1163 if (err)
1164 return err;
1165 }
1166
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001167 /* Setting PART_SETTING_COMPLETED confirms the partition
1168 * configuration but it only becomes effective after power
1169 * cycle, so we do not adjust the partition related settings
1170 * in the mmc struct. */
1171
1172 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1173 EXT_CSD_PARTITION_SETTING,
1174 EXT_CSD_PARTITION_SETTING_COMPLETED);
1175 if (err)
1176 return err;
1177
1178 return 0;
1179}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001180#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001181
Simon Glasse7881d82017-07-29 11:35:31 -06001182#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001183int mmc_getcd(struct mmc *mmc)
1184{
1185 int cd;
1186
1187 cd = board_mmc_getcd(mmc);
1188
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001189 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001190 if (mmc->cfg->ops->getcd)
1191 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001192 else
1193 cd = 1;
1194 }
Thierry Reding48972d92012-01-02 01:15:37 +00001195
1196 return cd;
1197}
Simon Glass8ca51e52016-06-12 23:30:22 -06001198#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001199
Marek Vasut62d77ce2018-04-15 00:37:11 +02001200#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001201static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001202{
1203 struct mmc_cmd cmd;
1204 struct mmc_data data;
1205
1206 /* Switch the frequency */
1207 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1208 cmd.resp_type = MMC_RSP_R1;
1209 cmd.cmdarg = (mode << 31) | 0xffffff;
1210 cmd.cmdarg &= ~(0xf << (group * 4));
1211 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001212
1213 data.dest = (char *)resp;
1214 data.blocksize = 64;
1215 data.blocks = 1;
1216 data.flags = MMC_DATA_READ;
1217
1218 return mmc_send_cmd(mmc, &cmd, &data);
1219}
1220
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001221static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001222{
1223 int err;
1224 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301225 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1226 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001227 struct mmc_data data;
1228 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001229#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001230 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001231#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001232
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +01001233 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001234
Thomas Choud52ebf12010-12-24 13:12:21 +00001235 if (mmc_host_is_spi(mmc))
1236 return 0;
1237
Andy Fleming272cc702008-10-30 16:41:01 -05001238 /* Read the SCR to find out if this card supports higher speeds */
1239 cmd.cmdidx = MMC_CMD_APP_CMD;
1240 cmd.resp_type = MMC_RSP_R1;
1241 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001242
1243 err = mmc_send_cmd(mmc, &cmd, NULL);
1244
1245 if (err)
1246 return err;
1247
1248 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1249 cmd.resp_type = MMC_RSP_R1;
1250 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001251
1252 timeout = 3;
1253
1254retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001255 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001256 data.blocksize = 8;
1257 data.blocks = 1;
1258 data.flags = MMC_DATA_READ;
1259
1260 err = mmc_send_cmd(mmc, &cmd, &data);
1261
1262 if (err) {
1263 if (timeout--)
1264 goto retry_scr;
1265
1266 return err;
1267 }
1268
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001269 mmc->scr[0] = __be32_to_cpu(scr[0]);
1270 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001271
1272 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001273 case 0:
1274 mmc->version = SD_VERSION_1_0;
1275 break;
1276 case 1:
1277 mmc->version = SD_VERSION_1_10;
1278 break;
1279 case 2:
1280 mmc->version = SD_VERSION_2;
1281 if ((mmc->scr[0] >> 15) & 0x1)
1282 mmc->version = SD_VERSION_3;
1283 break;
1284 default:
1285 mmc->version = SD_VERSION_1_0;
1286 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001287 }
1288
Alagu Sankarb44c7082010-05-12 15:08:24 +05301289 if (mmc->scr[0] & SD_DATA_4BIT)
1290 mmc->card_caps |= MMC_MODE_4BIT;
1291
Andy Fleming272cc702008-10-30 16:41:01 -05001292 /* Version 1.0 doesn't support switching */
1293 if (mmc->version == SD_VERSION_1_0)
1294 return 0;
1295
1296 timeout = 4;
1297 while (timeout--) {
1298 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001299 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001300
1301 if (err)
1302 return err;
1303
1304 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001305 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001306 break;
1307 }
1308
Andy Fleming272cc702008-10-30 16:41:01 -05001309 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001310 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1311 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001312
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001313#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001314 /* Version before 3.0 don't support UHS modes */
1315 if (mmc->version < SD_VERSION_3)
1316 return 0;
1317
1318 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1319 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1320 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1321 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1322 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1323 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1324 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1325 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1326 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1327 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1328 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001329#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001330
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001331 return 0;
1332}
1333
1334static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1335{
1336 int err;
1337
1338 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001339 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001340
Marek Vasutcf345762018-11-18 03:25:08 +01001341 /* SD version 1.00 and 1.01 does not support CMD 6 */
1342 if (mmc->version == SD_VERSION_1_0)
1343 return 0;
1344
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001345 switch (mode) {
1346 case SD_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001347 speed = UHS_SDR12_BUS_SPEED;
1348 break;
1349 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001350 speed = HIGH_SPEED_BUS_SPEED;
1351 break;
1352#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1353 case UHS_SDR12:
1354 speed = UHS_SDR12_BUS_SPEED;
1355 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001356 case UHS_SDR25:
1357 speed = UHS_SDR25_BUS_SPEED;
1358 break;
1359 case UHS_SDR50:
1360 speed = UHS_SDR50_BUS_SPEED;
1361 break;
1362 case UHS_DDR50:
1363 speed = UHS_DDR50_BUS_SPEED;
1364 break;
1365 case UHS_SDR104:
1366 speed = UHS_SDR104_BUS_SPEED;
1367 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001368#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001369 default:
1370 return -EINVAL;
1371 }
1372
1373 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001374 if (err)
1375 return err;
1376
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001377 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001378 return -ENOTSUPP;
1379
1380 return 0;
1381}
1382
Marek Vasutec360e62018-04-15 00:36:45 +02001383static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001384{
1385 int err;
1386 struct mmc_cmd cmd;
1387
1388 if ((w != 4) && (w != 1))
1389 return -EINVAL;
1390
1391 cmd.cmdidx = MMC_CMD_APP_CMD;
1392 cmd.resp_type = MMC_RSP_R1;
1393 cmd.cmdarg = mmc->rca << 16;
1394
1395 err = mmc_send_cmd(mmc, &cmd, NULL);
1396 if (err)
1397 return err;
1398
1399 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1400 cmd.resp_type = MMC_RSP_R1;
1401 if (w == 4)
1402 cmd.cmdarg = 2;
1403 else if (w == 1)
1404 cmd.cmdarg = 0;
1405 err = mmc_send_cmd(mmc, &cmd, NULL);
1406 if (err)
1407 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001408
1409 return 0;
1410}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001411#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001412
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001413#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001414static int sd_read_ssr(struct mmc *mmc)
1415{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001416 static const unsigned int sd_au_size[] = {
1417 0, SZ_16K / 512, SZ_32K / 512,
1418 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1419 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1420 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1421 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1422 SZ_64M / 512,
1423 };
Peng Fan3697e592016-09-01 11:13:38 +08001424 int err, i;
1425 struct mmc_cmd cmd;
1426 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1427 struct mmc_data data;
1428 int timeout = 3;
1429 unsigned int au, eo, et, es;
1430
1431 cmd.cmdidx = MMC_CMD_APP_CMD;
1432 cmd.resp_type = MMC_RSP_R1;
1433 cmd.cmdarg = mmc->rca << 16;
1434
1435 err = mmc_send_cmd(mmc, &cmd, NULL);
1436 if (err)
1437 return err;
1438
1439 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1440 cmd.resp_type = MMC_RSP_R1;
1441 cmd.cmdarg = 0;
1442
1443retry_ssr:
1444 data.dest = (char *)ssr;
1445 data.blocksize = 64;
1446 data.blocks = 1;
1447 data.flags = MMC_DATA_READ;
1448
1449 err = mmc_send_cmd(mmc, &cmd, &data);
1450 if (err) {
1451 if (timeout--)
1452 goto retry_ssr;
1453
1454 return err;
1455 }
1456
1457 for (i = 0; i < 16; i++)
1458 ssr[i] = be32_to_cpu(ssr[i]);
1459
1460 au = (ssr[2] >> 12) & 0xF;
1461 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1462 mmc->ssr.au = sd_au_size[au];
1463 es = (ssr[3] >> 24) & 0xFF;
1464 es |= (ssr[2] & 0xFF) << 8;
1465 et = (ssr[3] >> 18) & 0x3F;
1466 if (es && et) {
1467 eo = (ssr[3] >> 16) & 0x3;
1468 mmc->ssr.erase_timeout = (et * 1000) / es;
1469 mmc->ssr.erase_offset = eo * 1000;
1470 }
1471 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001472 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001473 }
1474
1475 return 0;
1476}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001477#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001478/* frequency bases */
1479/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001480static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001481 10000,
1482 100000,
1483 1000000,
1484 10000000,
1485};
1486
1487/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1488 * to platforms without floating point.
1489 */
Simon Glass61fe0762016-05-14 14:02:57 -06001490static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001491 0, /* reserved */
1492 10,
1493 12,
1494 13,
1495 15,
1496 20,
1497 25,
1498 30,
1499 35,
1500 40,
1501 45,
1502 50,
1503 55,
1504 60,
1505 70,
1506 80,
1507};
1508
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001509static inline int bus_width(uint cap)
1510{
1511 if (cap == MMC_MODE_8BIT)
1512 return 8;
1513 if (cap == MMC_MODE_4BIT)
1514 return 4;
1515 if (cap == MMC_MODE_1BIT)
1516 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001517 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001518 return 0;
1519}
1520
Simon Glasse7881d82017-07-29 11:35:31 -06001521#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001522#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001523static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1524{
1525 return -ENOTSUPP;
1526}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001527#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001528
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001529static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001530{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001531 int ret = 0;
1532
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001533 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001534 ret = mmc->cfg->ops->set_ios(mmc);
1535
1536 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001537}
Simon Glass8ca51e52016-06-12 23:30:22 -06001538#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001539
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001540int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001541{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001542 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001543 if (clock > mmc->cfg->f_max)
1544 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001545
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001546 if (clock < mmc->cfg->f_min)
1547 clock = mmc->cfg->f_min;
1548 }
Andy Fleming272cc702008-10-30 16:41:01 -05001549
1550 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001551 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001552
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001553 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1554
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001555 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001556}
1557
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001558static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001559{
1560 mmc->bus_width = width;
1561
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001562 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001563}
1564
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001565#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1566/*
1567 * helper function to display the capabilities in a human
1568 * friendly manner. The capabilities include bus width and
1569 * supported modes.
1570 */
1571void mmc_dump_capabilities(const char *text, uint caps)
1572{
1573 enum bus_mode mode;
1574
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001575 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001576 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001577 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001578 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001579 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001580 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001581 pr_debug("1, ");
1582 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001583 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1584 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001585 pr_debug("%s, ", mmc_mode_name(mode));
1586 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001587}
1588#endif
1589
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001590struct mode_width_tuning {
1591 enum bus_mode mode;
1592 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001593#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001594 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001595#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001596};
1597
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001598#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001599int mmc_voltage_to_mv(enum mmc_voltage voltage)
1600{
1601 switch (voltage) {
1602 case MMC_SIGNAL_VOLTAGE_000: return 0;
1603 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1604 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1605 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1606 }
1607 return -EINVAL;
1608}
1609
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001610static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1611{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001612 int err;
1613
1614 if (mmc->signal_voltage == signal_voltage)
1615 return 0;
1616
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001617 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001618 err = mmc_set_ios(mmc);
1619 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001620 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001621
1622 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001623}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001624#else
1625static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1626{
1627 return 0;
1628}
1629#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001630
Marek Vasut62d77ce2018-04-15 00:37:11 +02001631#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001632static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001633#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1634#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001635 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001636 .mode = UHS_SDR104,
1637 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1638 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1639 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001640#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001641 {
1642 .mode = UHS_SDR50,
1643 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1644 },
1645 {
1646 .mode = UHS_DDR50,
1647 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1648 },
1649 {
1650 .mode = UHS_SDR25,
1651 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1652 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001653#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001654 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001655 .mode = SD_HS,
1656 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1657 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001658#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001659 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001660 .mode = UHS_SDR12,
1661 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1662 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001663#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001664 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001665 .mode = SD_LEGACY,
1666 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1667 }
1668};
1669
1670#define for_each_sd_mode_by_pref(caps, mwt) \
1671 for (mwt = sd_modes_by_pref;\
1672 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1673 mwt++) \
1674 if (caps & MMC_CAP(mwt->mode))
1675
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001676static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001677{
1678 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001679 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1680 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001681#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001682 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001683#else
1684 bool uhs_en = false;
1685#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001686 uint caps;
1687
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001688#ifdef DEBUG
1689 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001690 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001691#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001692
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001693 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001694 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001695
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001696 if (!uhs_en)
1697 caps &= ~UHS_CAPS;
1698
1699 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001700 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001701
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001702 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001703 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001704 pr_debug("trying mode %s width %d (at %d MHz)\n",
1705 mmc_mode_name(mwt->mode),
1706 bus_width(*w),
1707 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001708
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001709 /* configure the bus width (card + host) */
1710 err = sd_select_bus_width(mmc, bus_width(*w));
1711 if (err)
1712 goto error;
1713 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001714
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001715 /* configure the bus mode (card) */
1716 err = sd_set_card_speed(mmc, mwt->mode);
1717 if (err)
1718 goto error;
1719
1720 /* configure the bus mode (host) */
1721 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001722 mmc_set_clock(mmc, mmc->tran_speed,
1723 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001724
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001725#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001726 /* execute tuning if needed */
1727 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1728 err = mmc_execute_tuning(mmc,
1729 mwt->tuning);
1730 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001731 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001732 goto error;
1733 }
1734 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001735#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001736
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001737#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001738 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001739 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001740 pr_warn("unable to read ssr\n");
1741#endif
1742 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001743 return 0;
1744
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001745error:
1746 /* revert to a safer bus speed */
1747 mmc_select_mode(mmc, SD_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001748 mmc_set_clock(mmc, mmc->tran_speed,
1749 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001750 }
1751 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001752 }
1753
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001754 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001755 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001756}
1757
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001758/*
1759 * read the compare the part of ext csd that is constant.
1760 * This can be used to check that the transfer is working
1761 * as expected.
1762 */
1763static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1764{
1765 int err;
1766 const u8 *ext_csd = mmc->ext_csd;
1767 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1768
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001769 if (mmc->version < MMC_VERSION_4)
1770 return 0;
1771
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001772 err = mmc_send_ext_csd(mmc, test_csd);
1773 if (err)
1774 return err;
1775
1776 /* Only compare read only fields */
1777 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1778 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1779 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1780 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1781 ext_csd[EXT_CSD_REV]
1782 == test_csd[EXT_CSD_REV] &&
1783 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1784 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1785 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1786 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1787 return 0;
1788
1789 return -EBADMSG;
1790}
1791
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001792#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001793static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1794 uint32_t allowed_mask)
1795{
1796 u32 card_mask = 0;
1797
1798 switch (mode) {
Peng Fan3dd26262018-08-10 14:07:54 +08001799 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001800 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001801 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1802 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001803 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001804 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1805 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001806 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1807 break;
1808 case MMC_DDR_52:
1809 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1810 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1811 MMC_SIGNAL_VOLTAGE_180;
1812 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1813 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1814 break;
1815 default:
1816 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1817 break;
1818 }
1819
1820 while (card_mask & allowed_mask) {
1821 enum mmc_voltage best_match;
1822
1823 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1824 if (!mmc_set_signal_voltage(mmc, best_match))
1825 return 0;
1826
1827 allowed_mask &= ~best_match;
1828 }
1829
1830 return -ENOTSUPP;
1831}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001832#else
1833static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1834 uint32_t allowed_mask)
1835{
1836 return 0;
1837}
1838#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001839
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001840static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan3dd26262018-08-10 14:07:54 +08001841#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1842 {
1843 .mode = MMC_HS_400,
1844 .widths = MMC_MODE_8BIT,
1845 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1846 },
1847#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001848#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001849 {
1850 .mode = MMC_HS_200,
1851 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001852 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001853 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001854#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001855 {
1856 .mode = MMC_DDR_52,
1857 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1858 },
1859 {
1860 .mode = MMC_HS_52,
1861 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1862 },
1863 {
1864 .mode = MMC_HS,
1865 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1866 },
1867 {
1868 .mode = MMC_LEGACY,
1869 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1870 }
1871};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001872
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001873#define for_each_mmc_mode_by_pref(caps, mwt) \
1874 for (mwt = mmc_modes_by_pref;\
1875 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1876 mwt++) \
1877 if (caps & MMC_CAP(mwt->mode))
1878
1879static const struct ext_csd_bus_width {
1880 uint cap;
1881 bool is_ddr;
1882 uint ext_csd_bits;
1883} ext_csd_bus_width[] = {
1884 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1885 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1886 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1887 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1888 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1889};
1890
Peng Fan3dd26262018-08-10 14:07:54 +08001891#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1892static int mmc_select_hs400(struct mmc *mmc)
1893{
1894 int err;
1895
1896 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001897 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001898 if (err)
1899 return err;
1900
1901 /* configure the bus mode (host) */
1902 mmc_select_mode(mmc, MMC_HS_200);
1903 mmc_set_clock(mmc, mmc->tran_speed, false);
1904
1905 /* execute tuning if needed */
1906 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1907 if (err) {
1908 debug("tuning failed\n");
1909 return err;
1910 }
1911
1912 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001913 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001914
1915 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1916 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1917 if (err)
1918 return err;
1919
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001920 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001921 if (err)
1922 return err;
1923
1924 mmc_select_mode(mmc, MMC_HS_400);
1925 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1926 if (err)
1927 return err;
1928
1929 return 0;
1930}
1931#else
1932static int mmc_select_hs400(struct mmc *mmc)
1933{
1934 return -ENOTSUPP;
1935}
1936#endif
1937
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001938#define for_each_supported_width(caps, ddr, ecbv) \
1939 for (ecbv = ext_csd_bus_width;\
1940 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1941 ecbv++) \
1942 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1943
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001944static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001945{
1946 int err;
1947 const struct mode_width_tuning *mwt;
1948 const struct ext_csd_bus_width *ecbw;
1949
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001950#ifdef DEBUG
1951 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001952 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001953#endif
1954
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001955 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001956 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001957
1958 /* Only version 4 of MMC supports wider bus widths */
1959 if (mmc->version < MMC_VERSION_4)
1960 return 0;
1961
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001962 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001963 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001964 return -ENOTSUPP;
1965 }
1966
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001967#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
1968 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1969 /*
1970 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
1971 * before doing anything else, since a transition from either of
1972 * the HS200/HS400 mode directly to legacy mode is not supported.
1973 */
1974 if (mmc->selected_mode == MMC_HS_200 ||
1975 mmc->selected_mode == MMC_HS_400)
1976 mmc_set_card_speed(mmc, MMC_HS, true);
1977 else
1978#endif
1979 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001980
1981 for_each_mmc_mode_by_pref(card_caps, mwt) {
1982 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001983 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001984 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001985 pr_debug("trying mode %s width %d (at %d MHz)\n",
1986 mmc_mode_name(mwt->mode),
1987 bus_width(ecbw->cap),
1988 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001989 old_voltage = mmc->signal_voltage;
1990 err = mmc_set_lowest_voltage(mmc, mwt->mode,
1991 MMC_ALL_SIGNAL_VOLTAGE);
1992 if (err)
1993 continue;
1994
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001995 /* configure the bus width (card + host) */
1996 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1997 EXT_CSD_BUS_WIDTH,
1998 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
1999 if (err)
2000 goto error;
2001 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
2002
Peng Fan3dd26262018-08-10 14:07:54 +08002003 if (mwt->mode == MMC_HS_400) {
2004 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002005 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08002006 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002007 goto error;
2008 }
Peng Fan3dd26262018-08-10 14:07:54 +08002009 } else {
2010 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002011 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002012 if (err)
2013 goto error;
2014
2015 /*
2016 * configure the bus width AND the ddr mode
2017 * (card). The host side will be taken care
2018 * of in the next step
2019 */
2020 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2021 err = mmc_switch(mmc,
2022 EXT_CSD_CMD_SET_NORMAL,
2023 EXT_CSD_BUS_WIDTH,
2024 ecbw->ext_csd_bits);
2025 if (err)
2026 goto error;
2027 }
2028
2029 /* configure the bus mode (host) */
2030 mmc_select_mode(mmc, mwt->mode);
2031 mmc_set_clock(mmc, mmc->tran_speed,
2032 MMC_CLK_ENABLE);
2033#ifdef MMC_SUPPORTS_TUNING
2034
2035 /* execute tuning if needed */
2036 if (mwt->tuning) {
2037 err = mmc_execute_tuning(mmc,
2038 mwt->tuning);
2039 if (err) {
2040 pr_debug("tuning failed\n");
2041 goto error;
2042 }
2043 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002044#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002045 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002046
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002047 /* do a transfer to check the configuration */
2048 err = mmc_read_and_compare_ext_csd(mmc);
2049 if (!err)
2050 return 0;
2051error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002052 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002053 /* if an error occured, revert to a safer bus mode */
2054 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2055 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2056 mmc_select_mode(mmc, MMC_LEGACY);
2057 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002058 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002059 }
2060
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002061 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002062
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002063 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002064}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002065#endif
2066
2067#if CONFIG_IS_ENABLED(MMC_TINY)
2068DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2069#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002070
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002071static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002072{
2073 int err, i;
2074 u64 capacity;
2075 bool has_parts = false;
2076 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002077 static const u32 mmc_versions[] = {
2078 MMC_VERSION_4,
2079 MMC_VERSION_4_1,
2080 MMC_VERSION_4_2,
2081 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002082 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002083 MMC_VERSION_4_41,
2084 MMC_VERSION_4_5,
2085 MMC_VERSION_5_0,
2086 MMC_VERSION_5_1
2087 };
2088
Marek Vasut62d77ce2018-04-15 00:37:11 +02002089#if CONFIG_IS_ENABLED(MMC_TINY)
2090 u8 *ext_csd = ext_csd_bkup;
2091
2092 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2093 return 0;
2094
2095 if (!mmc->ext_csd)
2096 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2097
2098 err = mmc_send_ext_csd(mmc, ext_csd);
2099 if (err)
2100 goto error;
2101
2102 /* store the ext csd for future reference */
2103 if (!mmc->ext_csd)
2104 mmc->ext_csd = ext_csd;
2105#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002106 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002107
2108 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2109 return 0;
2110
2111 /* check ext_csd version and capacity */
2112 err = mmc_send_ext_csd(mmc, ext_csd);
2113 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002114 goto error;
2115
2116 /* store the ext csd for future reference */
2117 if (!mmc->ext_csd)
2118 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2119 if (!mmc->ext_csd)
2120 return -ENOMEM;
2121 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002122#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002123 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002124 return -EINVAL;
2125
2126 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2127
2128 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002129 /*
2130 * According to the JEDEC Standard, the value of
2131 * ext_csd's capacity is valid if the value is more
2132 * than 2GB
2133 */
2134 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2135 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2136 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2137 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2138 capacity *= MMC_MAX_BLOCK_LEN;
2139 if ((capacity >> 20) > 2 * 1024)
2140 mmc->capacity_user = capacity;
2141 }
2142
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +02002143 if (mmc->version >= MMC_VERSION_4_5)
2144 mmc->gen_cmd6_time = ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
2145
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002146 /* The partition data may be non-zero but it is only
2147 * effective if PARTITION_SETTING_COMPLETED is set in
2148 * EXT_CSD, so ignore any data if this bit is not set,
2149 * except for enabling the high-capacity group size
2150 * definition (see below).
2151 */
2152 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2153 EXT_CSD_PARTITION_SETTING_COMPLETED);
2154
2155 /* store the partition info of emmc */
2156 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2157 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2158 ext_csd[EXT_CSD_BOOT_MULT])
2159 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2160 if (part_completed &&
2161 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2162 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2163
2164 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2165
2166 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2167
2168 for (i = 0; i < 4; i++) {
2169 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2170 uint mult = (ext_csd[idx + 2] << 16) +
2171 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2172 if (mult)
2173 has_parts = true;
2174 if (!part_completed)
2175 continue;
2176 mmc->capacity_gp[i] = mult;
2177 mmc->capacity_gp[i] *=
2178 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2179 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2180 mmc->capacity_gp[i] <<= 19;
2181 }
2182
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002183#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002184 if (part_completed) {
2185 mmc->enh_user_size =
2186 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2187 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2188 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2189 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2190 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2191 mmc->enh_user_size <<= 19;
2192 mmc->enh_user_start =
2193 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2194 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2195 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2196 ext_csd[EXT_CSD_ENH_START_ADDR];
2197 if (mmc->high_capacity)
2198 mmc->enh_user_start <<= 9;
2199 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002200#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002201
2202 /*
2203 * Host needs to enable ERASE_GRP_DEF bit if device is
2204 * partitioned. This bit will be lost every time after a reset
2205 * or power off. This will affect erase size.
2206 */
2207 if (part_completed)
2208 has_parts = true;
2209 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2210 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2211 has_parts = true;
2212 if (has_parts) {
2213 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2214 EXT_CSD_ERASE_GROUP_DEF, 1);
2215
2216 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002217 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002218
2219 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2220 }
2221
2222 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002223#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002224 /* Read out group size from ext_csd */
2225 mmc->erase_grp_size =
2226 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002227#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002228 /*
2229 * if high capacity and partition setting completed
2230 * SEC_COUNT is valid even if it is smaller than 2 GiB
2231 * JEDEC Standard JESD84-B45, 6.2.4
2232 */
2233 if (mmc->high_capacity && part_completed) {
2234 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2235 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2236 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2237 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2238 capacity *= MMC_MAX_BLOCK_LEN;
2239 mmc->capacity_user = capacity;
2240 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002241 }
2242#if CONFIG_IS_ENABLED(MMC_WRITE)
2243 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002244 /* Calculate the group size from the csd value. */
2245 int erase_gsz, erase_gmul;
2246
2247 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2248 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2249 mmc->erase_grp_size = (erase_gsz + 1)
2250 * (erase_gmul + 1);
2251 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002252#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002253#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002254 mmc->hc_wp_grp_size = 1024
2255 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2256 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002257#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002258
2259 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2260
2261 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002262error:
2263 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002264#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002265 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002266#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002267 mmc->ext_csd = NULL;
2268 }
2269 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002270}
2271
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002272static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002273{
Stephen Warrenf866a462013-06-11 15:14:01 -06002274 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002275 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002276 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002277 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002278 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002279
Thomas Choud52ebf12010-12-24 13:12:21 +00002280#ifdef CONFIG_MMC_SPI_CRC_ON
2281 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2282 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2283 cmd.resp_type = MMC_RSP_R1;
2284 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002285 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002286 if (err)
2287 return err;
2288 }
2289#endif
2290
Andy Fleming272cc702008-10-30 16:41:01 -05002291 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002292 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2293 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002294 cmd.resp_type = MMC_RSP_R2;
2295 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002296
2297 err = mmc_send_cmd(mmc, &cmd, NULL);
2298
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002299#ifdef CONFIG_MMC_QUIRKS
2300 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2301 int retries = 4;
2302 /*
2303 * It has been seen that SEND_CID may fail on the first
2304 * attempt, let's try a few more time
2305 */
2306 do {
2307 err = mmc_send_cmd(mmc, &cmd, NULL);
2308 if (!err)
2309 break;
2310 } while (retries--);
2311 }
2312#endif
2313
Andy Fleming272cc702008-10-30 16:41:01 -05002314 if (err)
2315 return err;
2316
2317 memcpy(mmc->cid, cmd.response, 16);
2318
2319 /*
2320 * For MMC cards, set the Relative Address.
2321 * For SD cards, get the Relatvie Address.
2322 * This also puts the cards into Standby State
2323 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002324 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2325 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2326 cmd.cmdarg = mmc->rca << 16;
2327 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002328
Thomas Choud52ebf12010-12-24 13:12:21 +00002329 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002330
Thomas Choud52ebf12010-12-24 13:12:21 +00002331 if (err)
2332 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002333
Thomas Choud52ebf12010-12-24 13:12:21 +00002334 if (IS_SD(mmc))
2335 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2336 }
Andy Fleming272cc702008-10-30 16:41:01 -05002337
2338 /* Get the Card-Specific Data */
2339 cmd.cmdidx = MMC_CMD_SEND_CSD;
2340 cmd.resp_type = MMC_RSP_R2;
2341 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002342
2343 err = mmc_send_cmd(mmc, &cmd, NULL);
2344
2345 if (err)
2346 return err;
2347
Rabin Vincent998be3d2009-04-05 13:30:56 +05302348 mmc->csd[0] = cmd.response[0];
2349 mmc->csd[1] = cmd.response[1];
2350 mmc->csd[2] = cmd.response[2];
2351 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002352
2353 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302354 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002355
2356 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002357 case 0:
2358 mmc->version = MMC_VERSION_1_2;
2359 break;
2360 case 1:
2361 mmc->version = MMC_VERSION_1_4;
2362 break;
2363 case 2:
2364 mmc->version = MMC_VERSION_2_2;
2365 break;
2366 case 3:
2367 mmc->version = MMC_VERSION_3;
2368 break;
2369 case 4:
2370 mmc->version = MMC_VERSION_4;
2371 break;
2372 default:
2373 mmc->version = MMC_VERSION_1_2;
2374 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002375 }
2376 }
2377
2378 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302379 freq = fbase[(cmd.response[0] & 0x7)];
2380 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002381
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002382 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002383 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002384
Markus Niebelab711882013-12-16 13:40:46 +01002385 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302386 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002387#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002388
2389 if (IS_SD(mmc))
2390 mmc->write_bl_len = mmc->read_bl_len;
2391 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302392 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002393#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002394
2395 if (mmc->high_capacity) {
2396 csize = (mmc->csd[1] & 0x3f) << 16
2397 | (mmc->csd[2] & 0xffff0000) >> 16;
2398 cmult = 8;
2399 } else {
2400 csize = (mmc->csd[1] & 0x3ff) << 2
2401 | (mmc->csd[2] & 0xc0000000) >> 30;
2402 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2403 }
2404
Stephen Warrenf866a462013-06-11 15:14:01 -06002405 mmc->capacity_user = (csize + 1) << (cmult + 2);
2406 mmc->capacity_user *= mmc->read_bl_len;
2407 mmc->capacity_boot = 0;
2408 mmc->capacity_rpmb = 0;
2409 for (i = 0; i < 4; i++)
2410 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002411
Simon Glass8bfa1952013-04-03 08:54:30 +00002412 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2413 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002414
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002415#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002416 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2417 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002418#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002419
Markus Niebelab711882013-12-16 13:40:46 +01002420 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2421 cmd.cmdidx = MMC_CMD_SET_DSR;
2422 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2423 cmd.resp_type = MMC_RSP_NONE;
2424 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002425 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002426 }
2427
Andy Fleming272cc702008-10-30 16:41:01 -05002428 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002429 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2430 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002431 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002432 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002433 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002434
Thomas Choud52ebf12010-12-24 13:12:21 +00002435 if (err)
2436 return err;
2437 }
Andy Fleming272cc702008-10-30 16:41:01 -05002438
Lei Wene6f99a52011-06-22 17:03:31 +00002439 /*
2440 * For SD, its erase group is always one sector
2441 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002442#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002443 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002444#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002445 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002446
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002447 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002448 if (err)
2449 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302450
Simon Glassc40fdca2016-05-01 13:52:35 -06002451 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002452 if (err)
2453 return err;
2454
Marek Vasut62d77ce2018-04-15 00:37:11 +02002455#if CONFIG_IS_ENABLED(MMC_TINY)
2456 mmc_set_clock(mmc, mmc->legacy_speed, false);
2457 mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
2458 mmc_set_bus_width(mmc, 1);
2459#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002460 if (IS_SD(mmc)) {
2461 err = sd_get_capabilities(mmc);
2462 if (err)
2463 return err;
2464 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2465 } else {
2466 err = mmc_get_capabilities(mmc);
2467 if (err)
2468 return err;
2469 mmc_select_mode_and_width(mmc, mmc->card_caps);
2470 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002471#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002472 if (err)
2473 return err;
2474
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002475 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002476
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002477 /* Fix the block length for DDR mode */
2478 if (mmc->ddr_mode) {
2479 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002480#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002481 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002482#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002483 }
2484
Andy Fleming272cc702008-10-30 16:41:01 -05002485 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002486 bdesc = mmc_get_blk_desc(mmc);
2487 bdesc->lun = 0;
2488 bdesc->hwpart = 0;
2489 bdesc->type = 0;
2490 bdesc->blksz = mmc->read_bl_len;
2491 bdesc->log2blksz = LOG2(bdesc->blksz);
2492 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002493#if !defined(CONFIG_SPL_BUILD) || \
2494 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
2495 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002496 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002497 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2498 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002499 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002500 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2501 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2502 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002503 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002504 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002505#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002506 bdesc->vendor[0] = 0;
2507 bdesc->product[0] = 0;
2508 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002509#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002510
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002511#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2512 part_init(bdesc);
2513#endif
2514
Andy Fleming272cc702008-10-30 16:41:01 -05002515 return 0;
2516}
2517
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002518static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002519{
2520 struct mmc_cmd cmd;
2521 int err;
2522
2523 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2524 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002525 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002526 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002527
2528 err = mmc_send_cmd(mmc, &cmd, NULL);
2529
2530 if (err)
2531 return err;
2532
Rabin Vincent998be3d2009-04-05 13:30:56 +05302533 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002534 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002535 else
2536 mmc->version = SD_VERSION_2;
2537
2538 return 0;
2539}
2540
Simon Glassc4d660d2017-07-04 13:31:19 -06002541#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002542/* board-specific MMC power initializations. */
2543__weak void board_mmc_power_init(void)
2544{
2545}
Simon Glass05cbeb72017-04-22 19:10:56 -06002546#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002547
Peng Fan2051aef2016-10-11 15:08:43 +08002548static int mmc_power_init(struct mmc *mmc)
2549{
Simon Glassc4d660d2017-07-04 13:31:19 -06002550#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002551#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002552 int ret;
2553
2554 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002555 &mmc->vmmc_supply);
2556 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002557 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002558
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002559 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2560 &mmc->vqmmc_supply);
2561 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002562 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002563#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002564#else /* !CONFIG_DM_MMC */
2565 /*
2566 * Driver model should use a regulator, as above, rather than calling
2567 * out to board code.
2568 */
2569 board_mmc_power_init();
2570#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002571 return 0;
2572}
2573
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002574/*
2575 * put the host in the initial state:
2576 * - turn on Vdd (card power supply)
2577 * - configure the bus width and clock to minimal values
2578 */
2579static void mmc_set_initial_state(struct mmc *mmc)
2580{
2581 int err;
2582
2583 /* First try to set 3.3V. If it fails set to 1.8V */
2584 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2585 if (err != 0)
2586 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2587 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002588 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002589
2590 mmc_select_mode(mmc, MMC_LEGACY);
2591 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002592 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002593}
2594
2595static int mmc_power_on(struct mmc *mmc)
2596{
2597#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2598 if (mmc->vmmc_supply) {
2599 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2600
2601 if (ret) {
2602 puts("Error enabling VMMC supply\n");
2603 return ret;
2604 }
2605 }
2606#endif
2607 return 0;
2608}
2609
2610static int mmc_power_off(struct mmc *mmc)
2611{
Jaehoon Chung65117182018-01-26 19:25:29 +09002612 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002613#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2614 if (mmc->vmmc_supply) {
2615 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2616
2617 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002618 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002619 return ret;
2620 }
2621 }
2622#endif
2623 return 0;
2624}
2625
2626static int mmc_power_cycle(struct mmc *mmc)
2627{
2628 int ret;
2629
2630 ret = mmc_power_off(mmc);
2631 if (ret)
2632 return ret;
2633 /*
2634 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2635 * to be on the safer side.
2636 */
2637 udelay(2000);
2638 return mmc_power_on(mmc);
2639}
2640
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002641int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002642{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002643 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002644 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002645
Lei Wenbc897b12011-05-02 16:26:26 +00002646 if (mmc->has_init)
2647 return 0;
2648
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002649#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2650 mmc_adapter_card_type_ident();
2651#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002652 err = mmc_power_init(mmc);
2653 if (err)
2654 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002655
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002656#ifdef CONFIG_MMC_QUIRKS
2657 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
2658 MMC_QUIRK_RETRY_SEND_CID;
2659#endif
2660
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002661 err = mmc_power_cycle(mmc);
2662 if (err) {
2663 /*
2664 * if power cycling is not supported, we should not try
2665 * to use the UHS modes, because we wouldn't be able to
2666 * recover from an error during the UHS initialization.
2667 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002668 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002669 uhs_en = false;
2670 mmc->host_caps &= ~UHS_CAPS;
2671 err = mmc_power_on(mmc);
2672 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002673 if (err)
2674 return err;
2675
Simon Glasse7881d82017-07-29 11:35:31 -06002676#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002677 /* The device has already been probed ready for use */
2678#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002679 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002680 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002681 if (err)
2682 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002683#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002684 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002685
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002686retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002687 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002688
Andy Fleming272cc702008-10-30 16:41:01 -05002689 /* Reset the Card */
2690 err = mmc_go_idle(mmc);
2691
2692 if (err)
2693 return err;
2694
Lei Wenbc897b12011-05-02 16:26:26 +00002695 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002696 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002697
Andy Fleming272cc702008-10-30 16:41:01 -05002698 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002699 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002700
Andy Fleming272cc702008-10-30 16:41:01 -05002701 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002702 err = sd_send_op_cond(mmc, uhs_en);
2703 if (err && uhs_en) {
2704 uhs_en = false;
2705 mmc_power_cycle(mmc);
2706 goto retry;
2707 }
Andy Fleming272cc702008-10-30 16:41:01 -05002708
2709 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002710 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002711 err = mmc_send_op_cond(mmc);
2712
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002713 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002714#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002715 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002716#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002717 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002718 }
2719 }
2720
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002721 return err;
2722}
2723
2724int mmc_start_init(struct mmc *mmc)
2725{
2726 bool no_card;
2727 int err = 0;
2728
2729 /*
2730 * all hosts are capable of 1 bit bus-width and able to use the legacy
2731 * timings.
2732 */
2733 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
2734 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
2735
2736#if !defined(CONFIG_MMC_BROKEN_CD)
2737 /* we pretend there's no card when init is NULL */
2738 no_card = mmc_getcd(mmc) == 0;
2739#else
2740 no_card = 0;
2741#endif
2742#if !CONFIG_IS_ENABLED(DM_MMC)
2743 no_card = no_card || (mmc->cfg->ops->init == NULL);
2744#endif
2745 if (no_card) {
2746 mmc->has_init = 0;
2747#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2748 pr_err("MMC: no card present\n");
2749#endif
2750 return -ENOMEDIUM;
2751 }
2752
2753 err = mmc_get_op_cond(mmc);
2754
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002755 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002756 mmc->init_in_progress = 1;
2757
2758 return err;
2759}
2760
2761static int mmc_complete_init(struct mmc *mmc)
2762{
2763 int err = 0;
2764
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002765 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002766 if (mmc->op_cond_pending)
2767 err = mmc_complete_op_cond(mmc);
2768
2769 if (!err)
2770 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002771 if (err)
2772 mmc->has_init = 0;
2773 else
2774 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002775 return err;
2776}
2777
2778int mmc_init(struct mmc *mmc)
2779{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002780 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302781 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002782#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002783 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002784
Simon Glass33fb2112016-05-01 13:52:41 -06002785 upriv->mmc = mmc;
2786#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002787 if (mmc->has_init)
2788 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002789
2790 start = get_timer(0);
2791
Che-Liang Chioue9550442012-11-28 15:21:13 +00002792 if (!mmc->init_in_progress)
2793 err = mmc_start_init(mmc);
2794
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002795 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002796 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002797 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002798 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002799
Lei Wenbc897b12011-05-02 16:26:26 +00002800 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002801}
2802
Marek Vasutfceea992019-01-29 04:45:51 +01002803#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2804 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2805 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2806int mmc_deinit(struct mmc *mmc)
2807{
2808 u32 caps_filtered;
2809
2810 if (!mmc->has_init)
2811 return 0;
2812
2813 if (IS_SD(mmc)) {
2814 caps_filtered = mmc->card_caps &
2815 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2816 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2817 MMC_CAP(UHS_SDR104));
2818
2819 return sd_select_mode_and_width(mmc, caps_filtered);
2820 } else {
2821 caps_filtered = mmc->card_caps &
2822 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2823
2824 return mmc_select_mode_and_width(mmc, caps_filtered);
2825 }
2826}
2827#endif
2828
Markus Niebelab711882013-12-16 13:40:46 +01002829int mmc_set_dsr(struct mmc *mmc, u16 val)
2830{
2831 mmc->dsr = val;
2832 return 0;
2833}
2834
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002835/* CPU-specific MMC initializations */
2836__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002837{
2838 return -1;
2839}
2840
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002841/* board-specific MMC initializations. */
2842__weak int board_mmc_init(bd_t *bis)
2843{
2844 return -1;
2845}
Andy Fleming272cc702008-10-30 16:41:01 -05002846
Che-Liang Chioue9550442012-11-28 15:21:13 +00002847void mmc_set_preinit(struct mmc *mmc, int preinit)
2848{
2849 mmc->preinit = preinit;
2850}
2851
Faiz Abbas8a856db2018-02-12 19:35:24 +05302852#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002853static int mmc_probe(bd_t *bis)
2854{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002855 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002856 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002857 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002858
2859 ret = uclass_get(UCLASS_MMC, &uc);
2860 if (ret)
2861 return ret;
2862
Simon Glass4a1db6d2015-12-29 05:22:49 -07002863 /*
2864 * Try to add them in sequence order. Really with driver model we
2865 * should allow holes, but the current MMC list does not allow that.
2866 * So if we request 0, 1, 3 we will get 0, 1, 2.
2867 */
2868 for (i = 0; ; i++) {
2869 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2870 if (ret == -ENODEV)
2871 break;
2872 }
2873 uclass_foreach_dev(dev, uc) {
2874 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002875 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002876 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002877 }
2878
2879 return 0;
2880}
2881#else
2882static int mmc_probe(bd_t *bis)
2883{
2884 if (board_mmc_init(bis) < 0)
2885 cpu_mmc_init(bis);
2886
2887 return 0;
2888}
2889#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002890
Andy Fleming272cc702008-10-30 16:41:01 -05002891int mmc_initialize(bd_t *bis)
2892{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002893 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002894 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002895 if (initialized) /* Avoid initializing mmc multiple times */
2896 return 0;
2897 initialized = 1;
2898
Simon Glassc4d660d2017-07-04 13:31:19 -06002899#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002900#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002901 mmc_list_init();
2902#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002903#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002904 ret = mmc_probe(bis);
2905 if (ret)
2906 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002907
Ying Zhangbb0dc102013-08-16 15:16:11 +08002908#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002909 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002910#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002911
Simon Glassc40fdca2016-05-01 13:52:35 -06002912 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002913 return 0;
2914}
Tomas Melincd3d4882016-11-25 11:01:03 +02002915
2916#ifdef CONFIG_CMD_BKOPS_ENABLE
2917int mmc_set_bkops_enable(struct mmc *mmc)
2918{
2919 int err;
2920 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2921
2922 err = mmc_send_ext_csd(mmc, ext_csd);
2923 if (err) {
2924 puts("Could not get ext_csd register values\n");
2925 return err;
2926 }
2927
2928 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2929 puts("Background operations not supported on device\n");
2930 return -EMEDIUMTYPE;
2931 }
2932
2933 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2934 puts("Background operations already enabled\n");
2935 return 0;
2936 }
2937
2938 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2939 if (err) {
2940 puts("Failed to enable manual background operations\n");
2941 return err;
2942 }
2943
2944 puts("Enabled manual background operations\n");
2945
2946 return 0;
2947}
2948#endif