blob: cec39a9acf40730099d3a0cb6f6ef81d61270e9a [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Fleming272cc702008-10-30 16:41:01 -05002/*
3 * Copyright 2008, Freescale Semiconductor, Inc
4 * Andy Fleming
5 *
6 * Based vaguely on the Linux code
Andy Fleming272cc702008-10-30 16:41:01 -05007 */
8
9#include <config.h>
10#include <common.h>
11#include <command.h>
Sjoerd Simons8e3332e2015-08-30 16:55:45 -060012#include <dm.h>
13#include <dm/device-internal.h>
Stephen Warrend4622df2014-05-23 12:47:06 -060014#include <errno.h>
Andy Fleming272cc702008-10-30 16:41:01 -050015#include <mmc.h>
16#include <part.h>
Peng Fan2051aef2016-10-11 15:08:43 +080017#include <power/regulator.h>
Andy Fleming272cc702008-10-30 16:41:01 -050018#include <malloc.h>
Simon Glasscf92e052015-09-02 17:24:58 -060019#include <memalign.h>
Andy Fleming272cc702008-10-30 16:41:01 -050020#include <linux/list.h>
Rabin Vincent9b1f9422009-04-05 13:30:54 +053021#include <div64.h>
Paul Burtonda61fa52013-09-09 15:30:26 +010022#include "mmc_private.h"
Andy Fleming272cc702008-10-30 16:41:01 -050023
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +020024#define DEFAULT_CMD6_TIMEOUT_MS 500
25
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +020026static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +020027static int mmc_power_cycle(struct mmc *mmc);
Marek Vasut62d77ce2018-04-15 00:37:11 +020028#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +020029static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
Marek Vasutb5b838f2016-12-01 02:06:33 +010030#endif
31
Simon Glasse7881d82017-07-29 11:35:31 -060032#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020033
34static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
35{
36 return -ENOSYS;
37}
38
Jeroen Hofstee750121c2014-07-12 21:24:08 +020039__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000040{
41 return -1;
42}
43
44int mmc_getwp(struct mmc *mmc)
45{
46 int wp;
47
48 wp = board_mmc_getwp(mmc);
49
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000050 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020051 if (mmc->cfg->ops->getwp)
52 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000053 else
54 wp = 0;
55 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000056
57 return wp;
58}
59
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020060__weak int board_mmc_getcd(struct mmc *mmc)
61{
Stefano Babic11fdade2010-02-05 15:04:43 +010062 return -1;
63}
Simon Glass8ca51e52016-06-12 23:30:22 -060064#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010065
Marek Vasut8635ff92012-03-15 18:41:35 +000066#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060067void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
68{
69 printf("CMD_SEND:%d\n", cmd->cmdidx);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010070 printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
Simon Glassc0c76eb2016-06-12 23:30:20 -060071}
72
73void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
74{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000075 int i;
76 u8 *ptr;
77
Bin Meng7863ce52016-03-17 21:53:14 -070078 if (ret) {
79 printf("\t\tRET\t\t\t %d\n", ret);
80 } else {
81 switch (cmd->resp_type) {
82 case MMC_RSP_NONE:
83 printf("\t\tMMC_RSP_NONE\n");
84 break;
85 case MMC_RSP_R1:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010086 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070087 cmd->response[0]);
88 break;
89 case MMC_RSP_R1b:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010090 printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070091 cmd->response[0]);
92 break;
93 case MMC_RSP_R2:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010094 printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070095 cmd->response[0]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010096 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070097 cmd->response[1]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010098 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070099 cmd->response[2]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100100 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700101 cmd->response[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000102 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -0700103 printf("\t\t\t\t\tDUMPING DATA\n");
104 for (i = 0; i < 4; i++) {
105 int j;
106 printf("\t\t\t\t\t%03d - ", i*4);
107 ptr = (u8 *)&cmd->response[i];
108 ptr += 3;
109 for (j = 0; j < 4; j++)
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100110 printf("%02x ", *ptr--);
Bin Meng7863ce52016-03-17 21:53:14 -0700111 printf("\n");
112 }
113 break;
114 case MMC_RSP_R3:
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100115 printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700116 cmd->response[0]);
117 break;
118 default:
119 printf("\t\tERROR MMC rsp not supported\n");
120 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700121 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000122 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600123}
124
125void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
126{
127 int status;
128
129 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
130 printf("CURR STATE:%d\n", status);
131}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000132#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600133
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200134#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
135const char *mmc_mode_name(enum bus_mode mode)
136{
137 static const char *const names[] = {
138 [MMC_LEGACY] = "MMC legacy",
139 [SD_LEGACY] = "SD Legacy",
140 [MMC_HS] = "MMC High Speed (26MHz)",
141 [SD_HS] = "SD High Speed (50MHz)",
142 [UHS_SDR12] = "UHS SDR12 (25MHz)",
143 [UHS_SDR25] = "UHS SDR25 (50MHz)",
144 [UHS_SDR50] = "UHS SDR50 (100MHz)",
145 [UHS_SDR104] = "UHS SDR104 (208MHz)",
146 [UHS_DDR50] = "UHS DDR50 (50MHz)",
147 [MMC_HS_52] = "MMC High Speed (52MHz)",
148 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
149 [MMC_HS_200] = "HS200 (200MHz)",
Peng Fan3dd26262018-08-10 14:07:54 +0800150 [MMC_HS_400] = "HS400 (200MHz)",
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200151 };
152
153 if (mode >= MMC_MODES_END)
154 return "Unknown mode";
155 else
156 return names[mode];
157}
158#endif
159
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200160static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
161{
162 static const int freqs[] = {
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900163 [MMC_LEGACY] = 25000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200164 [SD_LEGACY] = 25000000,
165 [MMC_HS] = 26000000,
166 [SD_HS] = 50000000,
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900167 [MMC_HS_52] = 52000000,
168 [MMC_DDR_52] = 52000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200169 [UHS_SDR12] = 25000000,
170 [UHS_SDR25] = 50000000,
171 [UHS_SDR50] = 100000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200172 [UHS_DDR50] = 50000000,
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100173 [UHS_SDR104] = 208000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200174 [MMC_HS_200] = 200000000,
Peng Fan3dd26262018-08-10 14:07:54 +0800175 [MMC_HS_400] = 200000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200176 };
177
178 if (mode == MMC_LEGACY)
179 return mmc->legacy_speed;
180 else if (mode >= MMC_MODES_END)
181 return 0;
182 else
183 return freqs[mode];
184}
185
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200186static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
187{
188 mmc->selected_mode = mode;
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200189 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200190 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900191 pr_debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
192 mmc->tran_speed / 1000000);
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200193 return 0;
194}
195
Simon Glasse7881d82017-07-29 11:35:31 -0600196#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassc0c76eb2016-06-12 23:30:20 -0600197int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
198{
199 int ret;
200
201 mmmc_trace_before_send(mmc, cmd);
202 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
203 mmmc_trace_after_send(mmc, cmd, ret);
204
Marek Vasut8635ff92012-03-15 18:41:35 +0000205 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500206}
Simon Glass8ca51e52016-06-12 23:30:22 -0600207#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500208
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200209int mmc_send_status(struct mmc *mmc, unsigned int *status)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000210{
211 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000212 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000213
214 cmd.cmdidx = MMC_CMD_SEND_STATUS;
215 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200216 if (!mmc_host_is_spi(mmc))
217 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000218
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200219 while (retries--) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000220 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000221 if (!err) {
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200222 mmc_trace_state(mmc, &cmd);
223 *status = cmd.response[0];
224 return 0;
225 }
226 }
227 mmc_trace_state(mmc, &cmd);
228 return -ECOMM;
229}
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200230
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200231int mmc_poll_for_busy(struct mmc *mmc, int timeout)
232{
233 unsigned int status;
234 int err;
235
Jean-Jacques Hiblotcd0b80e2019-07-02 10:53:53 +0200236 err = mmc_wait_dat0(mmc, 1, timeout);
237 if (err != -ENOSYS)
238 return err;
239
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200240 while (1) {
241 err = mmc_send_status(mmc, &status);
242 if (err)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000243 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000244
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200245 if ((status & MMC_STATUS_RDY_FOR_DATA) &&
246 (status & MMC_STATUS_CURR_STATE) !=
247 MMC_STATE_PRG)
248 break;
249
250 if (status & MMC_STATUS_MASK) {
251#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
252 pr_err("Status Error: 0x%08x\n", status);
253#endif
254 return -ECOMM;
255 }
256
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500257 if (timeout-- <= 0)
258 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000259
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500260 udelay(1000);
261 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000262
Jongman Heo5b0c9422012-06-03 21:32:13 +0000263 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100264#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100265 pr_err("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100266#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900267 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000268 }
269
270 return 0;
271}
272
Paul Burtonda61fa52013-09-09 15:30:26 +0100273int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500274{
275 struct mmc_cmd cmd;
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200276 int err;
Andy Fleming272cc702008-10-30 16:41:01 -0500277
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600278 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900279 return 0;
280
Andy Fleming272cc702008-10-30 16:41:01 -0500281 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
282 cmd.resp_type = MMC_RSP_R1;
283 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500284
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200285 err = mmc_send_cmd(mmc, &cmd, NULL);
286
287#ifdef CONFIG_MMC_QUIRKS
288 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
289 int retries = 4;
290 /*
291 * It has been seen that SET_BLOCKLEN may fail on the first
292 * attempt, let's try a few more time
293 */
294 do {
295 err = mmc_send_cmd(mmc, &cmd, NULL);
296 if (!err)
297 break;
298 } while (retries--);
299 }
300#endif
301
302 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500303}
304
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100305#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200306static const u8 tuning_blk_pattern_4bit[] = {
307 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
308 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
309 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
310 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
311 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
312 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
313 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
314 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
315};
316
317static const u8 tuning_blk_pattern_8bit[] = {
318 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
319 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
320 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
321 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
322 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
323 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
324 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
325 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
326 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
327 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
328 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
329 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
330 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
331 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
332 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
333 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
334};
335
336int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
337{
338 struct mmc_cmd cmd;
339 struct mmc_data data;
340 const u8 *tuning_block_pattern;
341 int size, err;
342
343 if (mmc->bus_width == 8) {
344 tuning_block_pattern = tuning_blk_pattern_8bit;
345 size = sizeof(tuning_blk_pattern_8bit);
346 } else if (mmc->bus_width == 4) {
347 tuning_block_pattern = tuning_blk_pattern_4bit;
348 size = sizeof(tuning_blk_pattern_4bit);
349 } else {
350 return -EINVAL;
351 }
352
353 ALLOC_CACHE_ALIGN_BUFFER(u8, data_buf, size);
354
355 cmd.cmdidx = opcode;
356 cmd.cmdarg = 0;
357 cmd.resp_type = MMC_RSP_R1;
358
359 data.dest = (void *)data_buf;
360 data.blocks = 1;
361 data.blocksize = size;
362 data.flags = MMC_DATA_READ;
363
364 err = mmc_send_cmd(mmc, &cmd, &data);
365 if (err)
366 return err;
367
368 if (memcmp(data_buf, tuning_block_pattern, size))
369 return -EIO;
370
371 return 0;
372}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100373#endif
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200374
Sascha Silbeff8fef52013-06-14 13:07:25 +0200375static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000376 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500377{
378 struct mmc_cmd cmd;
379 struct mmc_data data;
380
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700381 if (blkcnt > 1)
382 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
383 else
384 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500385
386 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700387 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500388 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700389 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500390
391 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500392
393 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700394 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500395 data.blocksize = mmc->read_bl_len;
396 data.flags = MMC_DATA_READ;
397
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700398 if (mmc_send_cmd(mmc, &cmd, &data))
399 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500400
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700401 if (blkcnt > 1) {
402 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
403 cmd.cmdarg = 0;
404 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700405 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100406#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100407 pr_err("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100408#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700409 return 0;
410 }
Andy Fleming272cc702008-10-30 16:41:01 -0500411 }
412
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700413 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500414}
415
Simon Glassc4d660d2017-07-04 13:31:19 -0600416#if CONFIG_IS_ENABLED(BLK)
Simon Glass7dba0b92016-06-12 23:30:15 -0600417ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600418#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600419ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
420 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600421#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500422{
Simon Glassc4d660d2017-07-04 13:31:19 -0600423#if CONFIG_IS_ENABLED(BLK)
Simon Glass33fb2112016-05-01 13:52:41 -0600424 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
425#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700426 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700427 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700428 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500429
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700430 if (blkcnt == 0)
431 return 0;
432
433 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500434 if (!mmc)
435 return 0;
436
Marek Vasutb5b838f2016-12-01 02:06:33 +0100437 if (CONFIG_IS_ENABLED(MMC_TINY))
438 err = mmc_switch_part(mmc, block_dev->hwpart);
439 else
440 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
441
Stephen Warren873cc1d2015-12-07 11:38:49 -0700442 if (err < 0)
443 return 0;
444
Simon Glassc40fdca2016-05-01 13:52:35 -0600445 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100446#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100447 pr_err("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
448 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100449#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800450 return 0;
451 }
Andy Fleming272cc702008-10-30 16:41:01 -0500452
Simon Glass11692992015-06-23 15:38:50 -0600453 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900454 pr_debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500455 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600456 }
Andy Fleming272cc702008-10-30 16:41:01 -0500457
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700458 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200459 cur = (blocks_todo > mmc->cfg->b_max) ?
460 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600461 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900462 pr_debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700463 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600464 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700465 blocks_todo -= cur;
466 start += cur;
467 dst += cur * mmc->read_bl_len;
468 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500469
470 return blkcnt;
471}
472
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000473static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500474{
475 struct mmc_cmd cmd;
476 int err;
477
478 udelay(1000);
479
480 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
481 cmd.cmdarg = 0;
482 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500483
484 err = mmc_send_cmd(mmc, &cmd, NULL);
485
486 if (err)
487 return err;
488
489 udelay(2000);
490
491 return 0;
492}
493
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100494#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200495static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
496{
497 struct mmc_cmd cmd;
498 int err = 0;
499
500 /*
501 * Send CMD11 only if the request is to switch the card to
502 * 1.8V signalling.
503 */
504 if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
505 return mmc_set_signal_voltage(mmc, signal_voltage);
506
507 cmd.cmdidx = SD_CMD_SWITCH_UHS18V;
508 cmd.cmdarg = 0;
509 cmd.resp_type = MMC_RSP_R1;
510
511 err = mmc_send_cmd(mmc, &cmd, NULL);
512 if (err)
513 return err;
514
515 if (!mmc_host_is_spi(mmc) && (cmd.response[0] & MMC_STATUS_ERROR))
516 return -EIO;
517
518 /*
519 * The card should drive cmd and dat[0:3] low immediately
520 * after the response of cmd11, but wait 100 us to be sure
521 */
522 err = mmc_wait_dat0(mmc, 0, 100);
523 if (err == -ENOSYS)
524 udelay(100);
525 else if (err)
526 return -ETIMEDOUT;
527
528 /*
529 * During a signal voltage level switch, the clock must be gated
530 * for 5 ms according to the SD spec
531 */
Jaehoon Chung65117182018-01-26 19:25:29 +0900532 mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200533
534 err = mmc_set_signal_voltage(mmc, signal_voltage);
535 if (err)
536 return err;
537
538 /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
539 mdelay(10);
Jaehoon Chung65117182018-01-26 19:25:29 +0900540 mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200541
542 /*
543 * Failure to switch is indicated by the card holding
544 * dat[0:3] low. Wait for at least 1 ms according to spec
545 */
546 err = mmc_wait_dat0(mmc, 1, 1000);
547 if (err == -ENOSYS)
548 udelay(1000);
549 else if (err)
550 return -ETIMEDOUT;
551
552 return 0;
553}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100554#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200555
556static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
Andy Fleming272cc702008-10-30 16:41:01 -0500557{
558 int timeout = 1000;
559 int err;
560 struct mmc_cmd cmd;
561
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500562 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500563 cmd.cmdidx = MMC_CMD_APP_CMD;
564 cmd.resp_type = MMC_RSP_R1;
565 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500566
567 err = mmc_send_cmd(mmc, &cmd, NULL);
568
569 if (err)
570 return err;
571
572 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
573 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100574
575 /*
576 * Most cards do not answer if some reserved bits
577 * in the ocr are set. However, Some controller
578 * can set bit 7 (reserved for low voltages), but
579 * how to manage low voltages SD card is not yet
580 * specified.
581 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000582 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200583 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500584
585 if (mmc->version == SD_VERSION_2)
586 cmd.cmdarg |= OCR_HCS;
587
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200588 if (uhs_en)
589 cmd.cmdarg |= OCR_S18R;
590
Andy Fleming272cc702008-10-30 16:41:01 -0500591 err = mmc_send_cmd(mmc, &cmd, NULL);
592
593 if (err)
594 return err;
595
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500596 if (cmd.response[0] & OCR_BUSY)
597 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500598
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500599 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900600 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500601
602 udelay(1000);
603 }
Andy Fleming272cc702008-10-30 16:41:01 -0500604
605 if (mmc->version != SD_VERSION_2)
606 mmc->version = SD_VERSION_1_0;
607
Thomas Choud52ebf12010-12-24 13:12:21 +0000608 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
609 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
610 cmd.resp_type = MMC_RSP_R3;
611 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000612
613 err = mmc_send_cmd(mmc, &cmd, NULL);
614
615 if (err)
616 return err;
617 }
618
Rabin Vincent998be3d2009-04-05 13:30:56 +0530619 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500620
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100621#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200622 if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x41000000)
623 == 0x41000000) {
624 err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
625 if (err)
626 return err;
627 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100628#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200629
Andy Fleming272cc702008-10-30 16:41:01 -0500630 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
631 mmc->rca = 0;
632
633 return 0;
634}
635
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500636static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500637{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500638 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500639 int err;
640
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500641 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
642 cmd.resp_type = MMC_RSP_R3;
643 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500644 if (use_arg && !mmc_host_is_spi(mmc))
645 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200646 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500647 (mmc->ocr & OCR_VOLTAGE_MASK)) |
648 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000649
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500650 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000651 if (err)
652 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500653 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000654 return 0;
655}
656
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200657static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000658{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000659 int err, i;
660
Andy Fleming272cc702008-10-30 16:41:01 -0500661 /* Some cards seem to need this */
662 mmc_go_idle(mmc);
663
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000664 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000665 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500666 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500667 if (err)
668 return err;
669
Che-Liang Chioue9550442012-11-28 15:21:13 +0000670 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500671 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500672 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000673 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500674 mmc->op_cond_pending = 1;
675 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000676}
Andy Fleming272cc702008-10-30 16:41:01 -0500677
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200678static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000679{
680 struct mmc_cmd cmd;
681 int timeout = 1000;
Vipul Kumar36332b62018-05-03 12:20:54 +0530682 ulong start;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000683 int err;
684
685 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500686 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lud188b112016-08-02 15:33:18 +0800687 /* Some cards seem to need this */
688 mmc_go_idle(mmc);
689
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500690 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500691 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500692 err = mmc_send_op_cond_iter(mmc, 1);
693 if (err)
694 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500695 if (mmc->ocr & OCR_BUSY)
696 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500697 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900698 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500699 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500700 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500701 }
Andy Fleming272cc702008-10-30 16:41:01 -0500702
Thomas Choud52ebf12010-12-24 13:12:21 +0000703 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
704 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
705 cmd.resp_type = MMC_RSP_R3;
706 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000707
708 err = mmc_send_cmd(mmc, &cmd, NULL);
709
710 if (err)
711 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500712
713 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000714 }
715
Andy Fleming272cc702008-10-30 16:41:01 -0500716 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500717
718 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700719 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500720
721 return 0;
722}
723
724
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000725static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500726{
727 struct mmc_cmd cmd;
728 struct mmc_data data;
729 int err;
730
731 /* Get the Card Status Register */
732 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
733 cmd.resp_type = MMC_RSP_R1;
734 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500735
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000736 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500737 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000738 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500739 data.flags = MMC_DATA_READ;
740
741 err = mmc_send_cmd(mmc, &cmd, &data);
742
743 return err;
744}
745
Marek Vasut68925502019-02-06 11:34:27 +0100746static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
747 bool send_status)
Andy Fleming272cc702008-10-30 16:41:01 -0500748{
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200749 unsigned int status, start;
Andy Fleming272cc702008-10-30 16:41:01 -0500750 struct mmc_cmd cmd;
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200751 int timeout = DEFAULT_CMD6_TIMEOUT_MS;
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200752 bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
753 (index == EXT_CSD_PART_CONF);
Maxime Riparda9003dc2016-11-04 16:18:08 +0100754 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000755 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500756
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200757 if (mmc->gen_cmd6_time)
758 timeout = mmc->gen_cmd6_time * 10;
759
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200760 if (is_part_switch && mmc->part_switch_time)
761 timeout = mmc->part_switch_time * 10;
762
Andy Fleming272cc702008-10-30 16:41:01 -0500763 cmd.cmdidx = MMC_CMD_SWITCH;
764 cmd.resp_type = MMC_RSP_R1b;
765 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000766 (index << 16) |
767 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500768
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200769 do {
Maxime Riparda9003dc2016-11-04 16:18:08 +0100770 ret = mmc_send_cmd(mmc, &cmd, NULL);
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200771 } while (ret && retries-- > 0);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000772
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200773 if (ret)
774 return ret;
775
776 start = get_timer(0);
777
778 /* poll dat0 for rdy/buys status */
779 ret = mmc_wait_dat0(mmc, 1, timeout);
780 if (ret && ret != -ENOSYS)
781 return ret;
782
783 /*
784 * In cases when not allowed to poll by using CMD13 or because we aren't
785 * capable of polling by using mmc_wait_dat0, then rely on waiting the
786 * stated timeout to be sufficient.
787 */
788 if (ret == -ENOSYS && !send_status)
789 mdelay(timeout);
790
791 /* Finally wait until the card is ready or indicates a failure
792 * to switch. It doesn't hurt to use CMD13 here even if send_status
793 * is false, because by now (after 'timeout' ms) the bus should be
794 * reliable.
795 */
796 do {
797 ret = mmc_send_status(mmc, &status);
798
799 if (!ret && (status & MMC_STATUS_SWITCH_ERROR)) {
800 pr_debug("switch failed %d/%d/0x%x !\n", set, index,
801 value);
802 return -EIO;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100803 }
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200804 if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
Marek Vasut68925502019-02-06 11:34:27 +0100805 return 0;
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200806 udelay(100);
807 } while (get_timer(start) < timeout);
Marek Vasut68925502019-02-06 11:34:27 +0100808
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200809 return -ETIMEDOUT;
Andy Fleming272cc702008-10-30 16:41:01 -0500810}
811
Marek Vasut68925502019-02-06 11:34:27 +0100812int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
813{
814 return __mmc_switch(mmc, set, index, value, true);
815}
816
Marek Vasut62d77ce2018-04-15 00:37:11 +0200817#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100818static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
819 bool hsdowngrade)
Andy Fleming272cc702008-10-30 16:41:01 -0500820{
Andy Fleming272cc702008-10-30 16:41:01 -0500821 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200822 int speed_bits;
823
824 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
825
826 switch (mode) {
827 case MMC_HS:
828 case MMC_HS_52:
829 case MMC_DDR_52:
830 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200831 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100832#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200833 case MMC_HS_200:
834 speed_bits = EXT_CSD_TIMING_HS200;
835 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100836#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800837#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
838 case MMC_HS_400:
839 speed_bits = EXT_CSD_TIMING_HS400;
840 break;
841#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200842 case MMC_LEGACY:
843 speed_bits = EXT_CSD_TIMING_LEGACY;
844 break;
845 default:
846 return -EINVAL;
847 }
Marek Vasut68925502019-02-06 11:34:27 +0100848
849 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
850 speed_bits, !hsdowngrade);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200851 if (err)
852 return err;
853
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100854#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
855 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
856 /*
857 * In case the eMMC is in HS200/HS400 mode and we are downgrading
858 * to HS mode, the card clock are still running much faster than
859 * the supported HS mode clock, so we can not reliably read out
860 * Extended CSD. Reconfigure the controller to run at HS mode.
861 */
862 if (hsdowngrade) {
863 mmc_select_mode(mmc, MMC_HS);
864 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
865 }
866#endif
867
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200868 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
869 /* Now check to see that it worked */
870 err = mmc_send_ext_csd(mmc, test_csd);
871 if (err)
872 return err;
873
874 /* No high-speed support */
875 if (!test_csd[EXT_CSD_HS_TIMING])
876 return -ENOTSUPP;
877 }
878
879 return 0;
880}
881
882static int mmc_get_capabilities(struct mmc *mmc)
883{
884 u8 *ext_csd = mmc->ext_csd;
885 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500886
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +0100887 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -0500888
Thomas Choud52ebf12010-12-24 13:12:21 +0000889 if (mmc_host_is_spi(mmc))
890 return 0;
891
Andy Fleming272cc702008-10-30 16:41:01 -0500892 /* Only version 4 supports high-speed */
893 if (mmc->version < MMC_VERSION_4)
894 return 0;
895
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200896 if (!ext_csd) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100897 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200898 return -ENOTSUPP;
899 }
900
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600901 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
902
Peng Fan3dd26262018-08-10 14:07:54 +0800903 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +0200904 mmc->cardtype = cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500905
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100906#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200907 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
908 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
909 mmc->card_caps |= MMC_MODE_HS200;
910 }
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100911#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800912#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
913 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
914 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
915 mmc->card_caps |= MMC_MODE_HS400;
916 }
917#endif
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900918 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200919 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900920 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200921 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900922 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200923 if (cardtype & EXT_CSD_CARD_TYPE_26)
924 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500925
926 return 0;
927}
Marek Vasut62d77ce2018-04-15 00:37:11 +0200928#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500929
Stephen Warrenf866a462013-06-11 15:14:01 -0600930static int mmc_set_capacity(struct mmc *mmc, int part_num)
931{
932 switch (part_num) {
933 case 0:
934 mmc->capacity = mmc->capacity_user;
935 break;
936 case 1:
937 case 2:
938 mmc->capacity = mmc->capacity_boot;
939 break;
940 case 3:
941 mmc->capacity = mmc->capacity_rpmb;
942 break;
943 case 4:
944 case 5:
945 case 6:
946 case 7:
947 mmc->capacity = mmc->capacity_gp[part_num - 4];
948 break;
949 default:
950 return -1;
951 }
952
Simon Glassc40fdca2016-05-01 13:52:35 -0600953 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600954
955 return 0;
956}
957
Simon Glass7dba0b92016-06-12 23:30:15 -0600958int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000959{
Stephen Warrenf866a462013-06-11 15:14:01 -0600960 int ret;
Jean-Jacques Hiblot05384772019-07-02 10:53:58 +0200961 int retry = 3;
Lei Wenbc897b12011-05-02 16:26:26 +0000962
Jean-Jacques Hiblot05384772019-07-02 10:53:58 +0200963 do {
964 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
965 EXT_CSD_PART_CONF,
966 (mmc->part_config & ~PART_ACCESS_MASK)
967 | (part_num & PART_ACCESS_MASK));
968 } while (ret && retry--);
Stephen Warrenf866a462013-06-11 15:14:01 -0600969
Peter Bigot6dc93e72014-09-02 18:31:23 -0500970 /*
971 * Set the capacity if the switch succeeded or was intended
972 * to return to representing the raw device.
973 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700974 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500975 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600976 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700977 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500978
979 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000980}
981
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100982#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100983int mmc_hwpart_config(struct mmc *mmc,
984 const struct mmc_hwpart_conf *conf,
985 enum mmc_hwpart_conf_mode mode)
986{
987 u8 part_attrs = 0;
988 u32 enh_size_mult;
989 u32 enh_start_addr;
990 u32 gp_size_mult[4];
991 u32 max_enh_size_mult;
992 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100993 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100994 int i, pidx, err;
995 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
996
997 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
998 return -EINVAL;
999
1000 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001001 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001002 return -EMEDIUMTYPE;
1003 }
1004
1005 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001006 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001007 return -EMEDIUMTYPE;
1008 }
1009
1010 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001011 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001012 return -EMEDIUMTYPE;
1013 }
1014
1015 /* check partition alignment and total enhanced size */
1016 if (conf->user.enh_size) {
1017 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1018 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001019 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001020 "size aligned\n");
1021 return -EINVAL;
1022 }
1023 part_attrs |= EXT_CSD_ENH_USR;
1024 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1025 if (mmc->high_capacity) {
1026 enh_start_addr = conf->user.enh_start;
1027 } else {
1028 enh_start_addr = (conf->user.enh_start << 9);
1029 }
1030 } else {
1031 enh_size_mult = 0;
1032 enh_start_addr = 0;
1033 }
1034 tot_enh_size_mult += enh_size_mult;
1035
1036 for (pidx = 0; pidx < 4; pidx++) {
1037 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001038 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001039 "aligned\n", pidx+1);
1040 return -EINVAL;
1041 }
1042 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1043 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1044 part_attrs |= EXT_CSD_ENH_GP(pidx);
1045 tot_enh_size_mult += gp_size_mult[pidx];
1046 }
1047 }
1048
1049 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001050 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001051 return -EMEDIUMTYPE;
1052 }
1053
1054 err = mmc_send_ext_csd(mmc, ext_csd);
1055 if (err)
1056 return err;
1057
1058 max_enh_size_mult =
1059 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1060 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1061 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1062 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001063 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001064 tot_enh_size_mult, max_enh_size_mult);
1065 return -EMEDIUMTYPE;
1066 }
1067
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001068 /* The default value of EXT_CSD_WR_REL_SET is device
1069 * dependent, the values can only be changed if the
1070 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1071 * changed only once and before partitioning is completed. */
1072 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1073 if (conf->user.wr_rel_change) {
1074 if (conf->user.wr_rel_set)
1075 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1076 else
1077 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1078 }
1079 for (pidx = 0; pidx < 4; pidx++) {
1080 if (conf->gp_part[pidx].wr_rel_change) {
1081 if (conf->gp_part[pidx].wr_rel_set)
1082 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1083 else
1084 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1085 }
1086 }
1087
1088 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1089 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1090 puts("Card does not support host controlled partition write "
1091 "reliability settings\n");
1092 return -EMEDIUMTYPE;
1093 }
1094
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001095 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1096 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001097 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001098 return -EPERM;
1099 }
1100
1101 if (mode == MMC_HWPART_CONF_CHECK)
1102 return 0;
1103
1104 /* Partitioning requires high-capacity size definitions */
1105 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1106 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1107 EXT_CSD_ERASE_GROUP_DEF, 1);
1108
1109 if (err)
1110 return err;
1111
1112 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1113
1114 /* update erase group size to be high-capacity */
1115 mmc->erase_grp_size =
1116 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1117
1118 }
1119
1120 /* all OK, write the configuration */
1121 for (i = 0; i < 4; i++) {
1122 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1123 EXT_CSD_ENH_START_ADDR+i,
1124 (enh_start_addr >> (i*8)) & 0xFF);
1125 if (err)
1126 return err;
1127 }
1128 for (i = 0; i < 3; i++) {
1129 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1130 EXT_CSD_ENH_SIZE_MULT+i,
1131 (enh_size_mult >> (i*8)) & 0xFF);
1132 if (err)
1133 return err;
1134 }
1135 for (pidx = 0; pidx < 4; pidx++) {
1136 for (i = 0; i < 3; i++) {
1137 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1138 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1139 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1140 if (err)
1141 return err;
1142 }
1143 }
1144 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1145 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1146 if (err)
1147 return err;
1148
1149 if (mode == MMC_HWPART_CONF_SET)
1150 return 0;
1151
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001152 /* The WR_REL_SET is a write-once register but shall be
1153 * written before setting PART_SETTING_COMPLETED. As it is
1154 * write-once we can only write it when completing the
1155 * partitioning. */
1156 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1157 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1158 EXT_CSD_WR_REL_SET, wr_rel_set);
1159 if (err)
1160 return err;
1161 }
1162
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001163 /* Setting PART_SETTING_COMPLETED confirms the partition
1164 * configuration but it only becomes effective after power
1165 * cycle, so we do not adjust the partition related settings
1166 * in the mmc struct. */
1167
1168 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1169 EXT_CSD_PARTITION_SETTING,
1170 EXT_CSD_PARTITION_SETTING_COMPLETED);
1171 if (err)
1172 return err;
1173
1174 return 0;
1175}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001176#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001177
Simon Glasse7881d82017-07-29 11:35:31 -06001178#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001179int mmc_getcd(struct mmc *mmc)
1180{
1181 int cd;
1182
1183 cd = board_mmc_getcd(mmc);
1184
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001185 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001186 if (mmc->cfg->ops->getcd)
1187 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001188 else
1189 cd = 1;
1190 }
Thierry Reding48972d92012-01-02 01:15:37 +00001191
1192 return cd;
1193}
Simon Glass8ca51e52016-06-12 23:30:22 -06001194#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001195
Marek Vasut62d77ce2018-04-15 00:37:11 +02001196#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001197static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001198{
1199 struct mmc_cmd cmd;
1200 struct mmc_data data;
1201
1202 /* Switch the frequency */
1203 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1204 cmd.resp_type = MMC_RSP_R1;
1205 cmd.cmdarg = (mode << 31) | 0xffffff;
1206 cmd.cmdarg &= ~(0xf << (group * 4));
1207 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001208
1209 data.dest = (char *)resp;
1210 data.blocksize = 64;
1211 data.blocks = 1;
1212 data.flags = MMC_DATA_READ;
1213
1214 return mmc_send_cmd(mmc, &cmd, &data);
1215}
1216
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001217static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001218{
1219 int err;
1220 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301221 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1222 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001223 struct mmc_data data;
1224 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001225#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001226 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001227#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001228
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +01001229 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001230
Thomas Choud52ebf12010-12-24 13:12:21 +00001231 if (mmc_host_is_spi(mmc))
1232 return 0;
1233
Andy Fleming272cc702008-10-30 16:41:01 -05001234 /* Read the SCR to find out if this card supports higher speeds */
1235 cmd.cmdidx = MMC_CMD_APP_CMD;
1236 cmd.resp_type = MMC_RSP_R1;
1237 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001238
1239 err = mmc_send_cmd(mmc, &cmd, NULL);
1240
1241 if (err)
1242 return err;
1243
1244 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1245 cmd.resp_type = MMC_RSP_R1;
1246 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001247
1248 timeout = 3;
1249
1250retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001251 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001252 data.blocksize = 8;
1253 data.blocks = 1;
1254 data.flags = MMC_DATA_READ;
1255
1256 err = mmc_send_cmd(mmc, &cmd, &data);
1257
1258 if (err) {
1259 if (timeout--)
1260 goto retry_scr;
1261
1262 return err;
1263 }
1264
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001265 mmc->scr[0] = __be32_to_cpu(scr[0]);
1266 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001267
1268 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001269 case 0:
1270 mmc->version = SD_VERSION_1_0;
1271 break;
1272 case 1:
1273 mmc->version = SD_VERSION_1_10;
1274 break;
1275 case 2:
1276 mmc->version = SD_VERSION_2;
1277 if ((mmc->scr[0] >> 15) & 0x1)
1278 mmc->version = SD_VERSION_3;
1279 break;
1280 default:
1281 mmc->version = SD_VERSION_1_0;
1282 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001283 }
1284
Alagu Sankarb44c7082010-05-12 15:08:24 +05301285 if (mmc->scr[0] & SD_DATA_4BIT)
1286 mmc->card_caps |= MMC_MODE_4BIT;
1287
Andy Fleming272cc702008-10-30 16:41:01 -05001288 /* Version 1.0 doesn't support switching */
1289 if (mmc->version == SD_VERSION_1_0)
1290 return 0;
1291
1292 timeout = 4;
1293 while (timeout--) {
1294 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001295 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001296
1297 if (err)
1298 return err;
1299
1300 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001301 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001302 break;
1303 }
1304
Andy Fleming272cc702008-10-30 16:41:01 -05001305 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001306 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1307 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001308
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001309#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001310 /* Version before 3.0 don't support UHS modes */
1311 if (mmc->version < SD_VERSION_3)
1312 return 0;
1313
1314 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1315 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1316 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1317 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1318 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1319 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1320 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1321 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1322 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1323 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1324 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001325#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001326
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001327 return 0;
1328}
1329
1330static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1331{
1332 int err;
1333
1334 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001335 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001336
Marek Vasutcf345762018-11-18 03:25:08 +01001337 /* SD version 1.00 and 1.01 does not support CMD 6 */
1338 if (mmc->version == SD_VERSION_1_0)
1339 return 0;
1340
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001341 switch (mode) {
1342 case SD_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001343 speed = UHS_SDR12_BUS_SPEED;
1344 break;
1345 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001346 speed = HIGH_SPEED_BUS_SPEED;
1347 break;
1348#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1349 case UHS_SDR12:
1350 speed = UHS_SDR12_BUS_SPEED;
1351 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001352 case UHS_SDR25:
1353 speed = UHS_SDR25_BUS_SPEED;
1354 break;
1355 case UHS_SDR50:
1356 speed = UHS_SDR50_BUS_SPEED;
1357 break;
1358 case UHS_DDR50:
1359 speed = UHS_DDR50_BUS_SPEED;
1360 break;
1361 case UHS_SDR104:
1362 speed = UHS_SDR104_BUS_SPEED;
1363 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001364#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001365 default:
1366 return -EINVAL;
1367 }
1368
1369 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001370 if (err)
1371 return err;
1372
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001373 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001374 return -ENOTSUPP;
1375
1376 return 0;
1377}
1378
Marek Vasutec360e62018-04-15 00:36:45 +02001379static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001380{
1381 int err;
1382 struct mmc_cmd cmd;
1383
1384 if ((w != 4) && (w != 1))
1385 return -EINVAL;
1386
1387 cmd.cmdidx = MMC_CMD_APP_CMD;
1388 cmd.resp_type = MMC_RSP_R1;
1389 cmd.cmdarg = mmc->rca << 16;
1390
1391 err = mmc_send_cmd(mmc, &cmd, NULL);
1392 if (err)
1393 return err;
1394
1395 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1396 cmd.resp_type = MMC_RSP_R1;
1397 if (w == 4)
1398 cmd.cmdarg = 2;
1399 else if (w == 1)
1400 cmd.cmdarg = 0;
1401 err = mmc_send_cmd(mmc, &cmd, NULL);
1402 if (err)
1403 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001404
1405 return 0;
1406}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001407#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001408
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001409#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001410static int sd_read_ssr(struct mmc *mmc)
1411{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001412 static const unsigned int sd_au_size[] = {
1413 0, SZ_16K / 512, SZ_32K / 512,
1414 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1415 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1416 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1417 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1418 SZ_64M / 512,
1419 };
Peng Fan3697e592016-09-01 11:13:38 +08001420 int err, i;
1421 struct mmc_cmd cmd;
1422 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1423 struct mmc_data data;
1424 int timeout = 3;
1425 unsigned int au, eo, et, es;
1426
1427 cmd.cmdidx = MMC_CMD_APP_CMD;
1428 cmd.resp_type = MMC_RSP_R1;
1429 cmd.cmdarg = mmc->rca << 16;
1430
1431 err = mmc_send_cmd(mmc, &cmd, NULL);
1432 if (err)
1433 return err;
1434
1435 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1436 cmd.resp_type = MMC_RSP_R1;
1437 cmd.cmdarg = 0;
1438
1439retry_ssr:
1440 data.dest = (char *)ssr;
1441 data.blocksize = 64;
1442 data.blocks = 1;
1443 data.flags = MMC_DATA_READ;
1444
1445 err = mmc_send_cmd(mmc, &cmd, &data);
1446 if (err) {
1447 if (timeout--)
1448 goto retry_ssr;
1449
1450 return err;
1451 }
1452
1453 for (i = 0; i < 16; i++)
1454 ssr[i] = be32_to_cpu(ssr[i]);
1455
1456 au = (ssr[2] >> 12) & 0xF;
1457 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1458 mmc->ssr.au = sd_au_size[au];
1459 es = (ssr[3] >> 24) & 0xFF;
1460 es |= (ssr[2] & 0xFF) << 8;
1461 et = (ssr[3] >> 18) & 0x3F;
1462 if (es && et) {
1463 eo = (ssr[3] >> 16) & 0x3;
1464 mmc->ssr.erase_timeout = (et * 1000) / es;
1465 mmc->ssr.erase_offset = eo * 1000;
1466 }
1467 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001468 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001469 }
1470
1471 return 0;
1472}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001473#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001474/* frequency bases */
1475/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001476static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001477 10000,
1478 100000,
1479 1000000,
1480 10000000,
1481};
1482
1483/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1484 * to platforms without floating point.
1485 */
Simon Glass61fe0762016-05-14 14:02:57 -06001486static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001487 0, /* reserved */
1488 10,
1489 12,
1490 13,
1491 15,
1492 20,
1493 25,
1494 30,
1495 35,
1496 40,
1497 45,
1498 50,
1499 55,
1500 60,
1501 70,
1502 80,
1503};
1504
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001505static inline int bus_width(uint cap)
1506{
1507 if (cap == MMC_MODE_8BIT)
1508 return 8;
1509 if (cap == MMC_MODE_4BIT)
1510 return 4;
1511 if (cap == MMC_MODE_1BIT)
1512 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001513 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001514 return 0;
1515}
1516
Simon Glasse7881d82017-07-29 11:35:31 -06001517#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001518#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001519static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1520{
1521 return -ENOTSUPP;
1522}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001523#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001524
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001525static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001526{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001527 int ret = 0;
1528
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001529 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001530 ret = mmc->cfg->ops->set_ios(mmc);
1531
1532 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001533}
Simon Glass8ca51e52016-06-12 23:30:22 -06001534#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001535
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001536int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001537{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001538 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001539 if (clock > mmc->cfg->f_max)
1540 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001541
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001542 if (clock < mmc->cfg->f_min)
1543 clock = mmc->cfg->f_min;
1544 }
Andy Fleming272cc702008-10-30 16:41:01 -05001545
1546 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001547 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001548
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001549 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1550
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001551 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001552}
1553
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001554static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001555{
1556 mmc->bus_width = width;
1557
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001558 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001559}
1560
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001561#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1562/*
1563 * helper function to display the capabilities in a human
1564 * friendly manner. The capabilities include bus width and
1565 * supported modes.
1566 */
1567void mmc_dump_capabilities(const char *text, uint caps)
1568{
1569 enum bus_mode mode;
1570
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001571 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001572 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001573 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001574 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001575 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001576 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001577 pr_debug("1, ");
1578 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001579 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1580 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001581 pr_debug("%s, ", mmc_mode_name(mode));
1582 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001583}
1584#endif
1585
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001586struct mode_width_tuning {
1587 enum bus_mode mode;
1588 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001589#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001590 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001591#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001592};
1593
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001594#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001595int mmc_voltage_to_mv(enum mmc_voltage voltage)
1596{
1597 switch (voltage) {
1598 case MMC_SIGNAL_VOLTAGE_000: return 0;
1599 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1600 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1601 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1602 }
1603 return -EINVAL;
1604}
1605
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001606static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1607{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001608 int err;
1609
1610 if (mmc->signal_voltage == signal_voltage)
1611 return 0;
1612
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001613 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001614 err = mmc_set_ios(mmc);
1615 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001616 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001617
1618 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001619}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001620#else
1621static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1622{
1623 return 0;
1624}
1625#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001626
Marek Vasut62d77ce2018-04-15 00:37:11 +02001627#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001628static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001629#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1630#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001631 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001632 .mode = UHS_SDR104,
1633 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1634 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1635 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001636#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001637 {
1638 .mode = UHS_SDR50,
1639 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1640 },
1641 {
1642 .mode = UHS_DDR50,
1643 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1644 },
1645 {
1646 .mode = UHS_SDR25,
1647 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1648 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001649#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001650 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001651 .mode = SD_HS,
1652 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1653 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001654#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001655 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001656 .mode = UHS_SDR12,
1657 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1658 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001659#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001660 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001661 .mode = SD_LEGACY,
1662 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1663 }
1664};
1665
1666#define for_each_sd_mode_by_pref(caps, mwt) \
1667 for (mwt = sd_modes_by_pref;\
1668 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1669 mwt++) \
1670 if (caps & MMC_CAP(mwt->mode))
1671
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001672static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001673{
1674 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001675 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1676 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001677#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001678 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001679#else
1680 bool uhs_en = false;
1681#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001682 uint caps;
1683
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001684#ifdef DEBUG
1685 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001686 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001687#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001688
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001689 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001690 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001691
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001692 if (!uhs_en)
1693 caps &= ~UHS_CAPS;
1694
1695 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001696 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001697
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001698 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001699 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001700 pr_debug("trying mode %s width %d (at %d MHz)\n",
1701 mmc_mode_name(mwt->mode),
1702 bus_width(*w),
1703 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001704
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001705 /* configure the bus width (card + host) */
1706 err = sd_select_bus_width(mmc, bus_width(*w));
1707 if (err)
1708 goto error;
1709 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001710
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001711 /* configure the bus mode (card) */
1712 err = sd_set_card_speed(mmc, mwt->mode);
1713 if (err)
1714 goto error;
1715
1716 /* configure the bus mode (host) */
1717 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001718 mmc_set_clock(mmc, mmc->tran_speed,
1719 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001720
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001721#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001722 /* execute tuning if needed */
1723 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1724 err = mmc_execute_tuning(mmc,
1725 mwt->tuning);
1726 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001727 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001728 goto error;
1729 }
1730 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001731#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001732
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001733#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001734 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001735 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001736 pr_warn("unable to read ssr\n");
1737#endif
1738 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001739 return 0;
1740
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001741error:
1742 /* revert to a safer bus speed */
1743 mmc_select_mode(mmc, SD_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001744 mmc_set_clock(mmc, mmc->tran_speed,
1745 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001746 }
1747 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001748 }
1749
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001750 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001751 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001752}
1753
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001754/*
1755 * read the compare the part of ext csd that is constant.
1756 * This can be used to check that the transfer is working
1757 * as expected.
1758 */
1759static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1760{
1761 int err;
1762 const u8 *ext_csd = mmc->ext_csd;
1763 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1764
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001765 if (mmc->version < MMC_VERSION_4)
1766 return 0;
1767
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001768 err = mmc_send_ext_csd(mmc, test_csd);
1769 if (err)
1770 return err;
1771
1772 /* Only compare read only fields */
1773 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1774 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1775 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1776 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1777 ext_csd[EXT_CSD_REV]
1778 == test_csd[EXT_CSD_REV] &&
1779 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1780 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1781 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1782 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1783 return 0;
1784
1785 return -EBADMSG;
1786}
1787
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001788#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001789static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1790 uint32_t allowed_mask)
1791{
1792 u32 card_mask = 0;
1793
1794 switch (mode) {
Peng Fan3dd26262018-08-10 14:07:54 +08001795 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001796 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001797 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1798 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001799 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001800 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1801 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001802 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1803 break;
1804 case MMC_DDR_52:
1805 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1806 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1807 MMC_SIGNAL_VOLTAGE_180;
1808 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1809 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1810 break;
1811 default:
1812 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1813 break;
1814 }
1815
1816 while (card_mask & allowed_mask) {
1817 enum mmc_voltage best_match;
1818
1819 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1820 if (!mmc_set_signal_voltage(mmc, best_match))
1821 return 0;
1822
1823 allowed_mask &= ~best_match;
1824 }
1825
1826 return -ENOTSUPP;
1827}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001828#else
1829static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1830 uint32_t allowed_mask)
1831{
1832 return 0;
1833}
1834#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001835
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001836static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan3dd26262018-08-10 14:07:54 +08001837#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1838 {
1839 .mode = MMC_HS_400,
1840 .widths = MMC_MODE_8BIT,
1841 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1842 },
1843#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001844#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001845 {
1846 .mode = MMC_HS_200,
1847 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001848 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001849 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001850#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001851 {
1852 .mode = MMC_DDR_52,
1853 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1854 },
1855 {
1856 .mode = MMC_HS_52,
1857 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1858 },
1859 {
1860 .mode = MMC_HS,
1861 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1862 },
1863 {
1864 .mode = MMC_LEGACY,
1865 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1866 }
1867};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001868
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001869#define for_each_mmc_mode_by_pref(caps, mwt) \
1870 for (mwt = mmc_modes_by_pref;\
1871 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1872 mwt++) \
1873 if (caps & MMC_CAP(mwt->mode))
1874
1875static const struct ext_csd_bus_width {
1876 uint cap;
1877 bool is_ddr;
1878 uint ext_csd_bits;
1879} ext_csd_bus_width[] = {
1880 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1881 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1882 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1883 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1884 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1885};
1886
Peng Fan3dd26262018-08-10 14:07:54 +08001887#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1888static int mmc_select_hs400(struct mmc *mmc)
1889{
1890 int err;
1891
1892 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001893 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001894 if (err)
1895 return err;
1896
1897 /* configure the bus mode (host) */
1898 mmc_select_mode(mmc, MMC_HS_200);
1899 mmc_set_clock(mmc, mmc->tran_speed, false);
1900
1901 /* execute tuning if needed */
1902 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1903 if (err) {
1904 debug("tuning failed\n");
1905 return err;
1906 }
1907
1908 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001909 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001910
1911 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1912 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1913 if (err)
1914 return err;
1915
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001916 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001917 if (err)
1918 return err;
1919
1920 mmc_select_mode(mmc, MMC_HS_400);
1921 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1922 if (err)
1923 return err;
1924
1925 return 0;
1926}
1927#else
1928static int mmc_select_hs400(struct mmc *mmc)
1929{
1930 return -ENOTSUPP;
1931}
1932#endif
1933
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001934#define for_each_supported_width(caps, ddr, ecbv) \
1935 for (ecbv = ext_csd_bus_width;\
1936 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1937 ecbv++) \
1938 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1939
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001940static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001941{
1942 int err;
1943 const struct mode_width_tuning *mwt;
1944 const struct ext_csd_bus_width *ecbw;
1945
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001946#ifdef DEBUG
1947 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001948 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001949#endif
1950
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001951 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001952 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001953
1954 /* Only version 4 of MMC supports wider bus widths */
1955 if (mmc->version < MMC_VERSION_4)
1956 return 0;
1957
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001958 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001959 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001960 return -ENOTSUPP;
1961 }
1962
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001963#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
1964 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1965 /*
1966 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
1967 * before doing anything else, since a transition from either of
1968 * the HS200/HS400 mode directly to legacy mode is not supported.
1969 */
1970 if (mmc->selected_mode == MMC_HS_200 ||
1971 mmc->selected_mode == MMC_HS_400)
1972 mmc_set_card_speed(mmc, MMC_HS, true);
1973 else
1974#endif
1975 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001976
1977 for_each_mmc_mode_by_pref(card_caps, mwt) {
1978 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001979 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001980 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001981 pr_debug("trying mode %s width %d (at %d MHz)\n",
1982 mmc_mode_name(mwt->mode),
1983 bus_width(ecbw->cap),
1984 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001985 old_voltage = mmc->signal_voltage;
1986 err = mmc_set_lowest_voltage(mmc, mwt->mode,
1987 MMC_ALL_SIGNAL_VOLTAGE);
1988 if (err)
1989 continue;
1990
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001991 /* configure the bus width (card + host) */
1992 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1993 EXT_CSD_BUS_WIDTH,
1994 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
1995 if (err)
1996 goto error;
1997 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
1998
Peng Fan3dd26262018-08-10 14:07:54 +08001999 if (mwt->mode == MMC_HS_400) {
2000 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002001 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08002002 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002003 goto error;
2004 }
Peng Fan3dd26262018-08-10 14:07:54 +08002005 } else {
2006 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002007 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002008 if (err)
2009 goto error;
2010
2011 /*
2012 * configure the bus width AND the ddr mode
2013 * (card). The host side will be taken care
2014 * of in the next step
2015 */
2016 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2017 err = mmc_switch(mmc,
2018 EXT_CSD_CMD_SET_NORMAL,
2019 EXT_CSD_BUS_WIDTH,
2020 ecbw->ext_csd_bits);
2021 if (err)
2022 goto error;
2023 }
2024
2025 /* configure the bus mode (host) */
2026 mmc_select_mode(mmc, mwt->mode);
2027 mmc_set_clock(mmc, mmc->tran_speed,
2028 MMC_CLK_ENABLE);
2029#ifdef MMC_SUPPORTS_TUNING
2030
2031 /* execute tuning if needed */
2032 if (mwt->tuning) {
2033 err = mmc_execute_tuning(mmc,
2034 mwt->tuning);
2035 if (err) {
2036 pr_debug("tuning failed\n");
2037 goto error;
2038 }
2039 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002040#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002041 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002042
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002043 /* do a transfer to check the configuration */
2044 err = mmc_read_and_compare_ext_csd(mmc);
2045 if (!err)
2046 return 0;
2047error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002048 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002049 /* if an error occured, revert to a safer bus mode */
2050 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2051 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2052 mmc_select_mode(mmc, MMC_LEGACY);
2053 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002054 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002055 }
2056
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002057 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002058
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002059 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002060}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002061#endif
2062
2063#if CONFIG_IS_ENABLED(MMC_TINY)
2064DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2065#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002066
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002067static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002068{
2069 int err, i;
2070 u64 capacity;
2071 bool has_parts = false;
2072 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002073 static const u32 mmc_versions[] = {
2074 MMC_VERSION_4,
2075 MMC_VERSION_4_1,
2076 MMC_VERSION_4_2,
2077 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002078 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002079 MMC_VERSION_4_41,
2080 MMC_VERSION_4_5,
2081 MMC_VERSION_5_0,
2082 MMC_VERSION_5_1
2083 };
2084
Marek Vasut62d77ce2018-04-15 00:37:11 +02002085#if CONFIG_IS_ENABLED(MMC_TINY)
2086 u8 *ext_csd = ext_csd_bkup;
2087
2088 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2089 return 0;
2090
2091 if (!mmc->ext_csd)
2092 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2093
2094 err = mmc_send_ext_csd(mmc, ext_csd);
2095 if (err)
2096 goto error;
2097
2098 /* store the ext csd for future reference */
2099 if (!mmc->ext_csd)
2100 mmc->ext_csd = ext_csd;
2101#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002102 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002103
2104 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2105 return 0;
2106
2107 /* check ext_csd version and capacity */
2108 err = mmc_send_ext_csd(mmc, ext_csd);
2109 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002110 goto error;
2111
2112 /* store the ext csd for future reference */
2113 if (!mmc->ext_csd)
2114 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2115 if (!mmc->ext_csd)
2116 return -ENOMEM;
2117 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002118#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002119 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002120 return -EINVAL;
2121
2122 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2123
2124 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002125 /*
2126 * According to the JEDEC Standard, the value of
2127 * ext_csd's capacity is valid if the value is more
2128 * than 2GB
2129 */
2130 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2131 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2132 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2133 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2134 capacity *= MMC_MAX_BLOCK_LEN;
2135 if ((capacity >> 20) > 2 * 1024)
2136 mmc->capacity_user = capacity;
2137 }
2138
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +02002139 if (mmc->version >= MMC_VERSION_4_5)
2140 mmc->gen_cmd6_time = ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
2141
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002142 /* The partition data may be non-zero but it is only
2143 * effective if PARTITION_SETTING_COMPLETED is set in
2144 * EXT_CSD, so ignore any data if this bit is not set,
2145 * except for enabling the high-capacity group size
2146 * definition (see below).
2147 */
2148 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2149 EXT_CSD_PARTITION_SETTING_COMPLETED);
2150
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +02002151 mmc->part_switch_time = ext_csd[EXT_CSD_PART_SWITCH_TIME];
2152 /* Some eMMC set the value too low so set a minimum */
2153 if (mmc->part_switch_time < MMC_MIN_PART_SWITCH_TIME && mmc->part_switch_time)
2154 mmc->part_switch_time = MMC_MIN_PART_SWITCH_TIME;
2155
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002156 /* store the partition info of emmc */
2157 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2158 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2159 ext_csd[EXT_CSD_BOOT_MULT])
2160 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2161 if (part_completed &&
2162 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2163 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2164
2165 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2166
2167 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2168
2169 for (i = 0; i < 4; i++) {
2170 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2171 uint mult = (ext_csd[idx + 2] << 16) +
2172 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2173 if (mult)
2174 has_parts = true;
2175 if (!part_completed)
2176 continue;
2177 mmc->capacity_gp[i] = mult;
2178 mmc->capacity_gp[i] *=
2179 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2180 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2181 mmc->capacity_gp[i] <<= 19;
2182 }
2183
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002184#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002185 if (part_completed) {
2186 mmc->enh_user_size =
2187 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2188 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2189 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2190 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2191 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2192 mmc->enh_user_size <<= 19;
2193 mmc->enh_user_start =
2194 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2195 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2196 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2197 ext_csd[EXT_CSD_ENH_START_ADDR];
2198 if (mmc->high_capacity)
2199 mmc->enh_user_start <<= 9;
2200 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002201#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002202
2203 /*
2204 * Host needs to enable ERASE_GRP_DEF bit if device is
2205 * partitioned. This bit will be lost every time after a reset
2206 * or power off. This will affect erase size.
2207 */
2208 if (part_completed)
2209 has_parts = true;
2210 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2211 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2212 has_parts = true;
2213 if (has_parts) {
2214 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2215 EXT_CSD_ERASE_GROUP_DEF, 1);
2216
2217 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002218 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002219
2220 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2221 }
2222
2223 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002224#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002225 /* Read out group size from ext_csd */
2226 mmc->erase_grp_size =
2227 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002228#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002229 /*
2230 * if high capacity and partition setting completed
2231 * SEC_COUNT is valid even if it is smaller than 2 GiB
2232 * JEDEC Standard JESD84-B45, 6.2.4
2233 */
2234 if (mmc->high_capacity && part_completed) {
2235 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2236 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2237 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2238 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2239 capacity *= MMC_MAX_BLOCK_LEN;
2240 mmc->capacity_user = capacity;
2241 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002242 }
2243#if CONFIG_IS_ENABLED(MMC_WRITE)
2244 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002245 /* Calculate the group size from the csd value. */
2246 int erase_gsz, erase_gmul;
2247
2248 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2249 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2250 mmc->erase_grp_size = (erase_gsz + 1)
2251 * (erase_gmul + 1);
2252 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002253#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002254#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002255 mmc->hc_wp_grp_size = 1024
2256 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2257 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002258#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002259
2260 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2261
2262 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002263error:
2264 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002265#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002266 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002267#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002268 mmc->ext_csd = NULL;
2269 }
2270 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002271}
2272
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002273static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002274{
Stephen Warrenf866a462013-06-11 15:14:01 -06002275 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002276 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002277 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002278 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002279 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002280
Thomas Choud52ebf12010-12-24 13:12:21 +00002281#ifdef CONFIG_MMC_SPI_CRC_ON
2282 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2283 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2284 cmd.resp_type = MMC_RSP_R1;
2285 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002286 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002287 if (err)
2288 return err;
2289 }
2290#endif
2291
Andy Fleming272cc702008-10-30 16:41:01 -05002292 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002293 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2294 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002295 cmd.resp_type = MMC_RSP_R2;
2296 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002297
2298 err = mmc_send_cmd(mmc, &cmd, NULL);
2299
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002300#ifdef CONFIG_MMC_QUIRKS
2301 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2302 int retries = 4;
2303 /*
2304 * It has been seen that SEND_CID may fail on the first
2305 * attempt, let's try a few more time
2306 */
2307 do {
2308 err = mmc_send_cmd(mmc, &cmd, NULL);
2309 if (!err)
2310 break;
2311 } while (retries--);
2312 }
2313#endif
2314
Andy Fleming272cc702008-10-30 16:41:01 -05002315 if (err)
2316 return err;
2317
2318 memcpy(mmc->cid, cmd.response, 16);
2319
2320 /*
2321 * For MMC cards, set the Relative Address.
2322 * For SD cards, get the Relatvie Address.
2323 * This also puts the cards into Standby State
2324 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002325 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2326 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2327 cmd.cmdarg = mmc->rca << 16;
2328 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002329
Thomas Choud52ebf12010-12-24 13:12:21 +00002330 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002331
Thomas Choud52ebf12010-12-24 13:12:21 +00002332 if (err)
2333 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002334
Thomas Choud52ebf12010-12-24 13:12:21 +00002335 if (IS_SD(mmc))
2336 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2337 }
Andy Fleming272cc702008-10-30 16:41:01 -05002338
2339 /* Get the Card-Specific Data */
2340 cmd.cmdidx = MMC_CMD_SEND_CSD;
2341 cmd.resp_type = MMC_RSP_R2;
2342 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002343
2344 err = mmc_send_cmd(mmc, &cmd, NULL);
2345
2346 if (err)
2347 return err;
2348
Rabin Vincent998be3d2009-04-05 13:30:56 +05302349 mmc->csd[0] = cmd.response[0];
2350 mmc->csd[1] = cmd.response[1];
2351 mmc->csd[2] = cmd.response[2];
2352 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002353
2354 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302355 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002356
2357 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002358 case 0:
2359 mmc->version = MMC_VERSION_1_2;
2360 break;
2361 case 1:
2362 mmc->version = MMC_VERSION_1_4;
2363 break;
2364 case 2:
2365 mmc->version = MMC_VERSION_2_2;
2366 break;
2367 case 3:
2368 mmc->version = MMC_VERSION_3;
2369 break;
2370 case 4:
2371 mmc->version = MMC_VERSION_4;
2372 break;
2373 default:
2374 mmc->version = MMC_VERSION_1_2;
2375 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002376 }
2377 }
2378
2379 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302380 freq = fbase[(cmd.response[0] & 0x7)];
2381 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002382
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002383 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002384 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002385
Markus Niebelab711882013-12-16 13:40:46 +01002386 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302387 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002388#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002389
2390 if (IS_SD(mmc))
2391 mmc->write_bl_len = mmc->read_bl_len;
2392 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302393 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002394#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002395
2396 if (mmc->high_capacity) {
2397 csize = (mmc->csd[1] & 0x3f) << 16
2398 | (mmc->csd[2] & 0xffff0000) >> 16;
2399 cmult = 8;
2400 } else {
2401 csize = (mmc->csd[1] & 0x3ff) << 2
2402 | (mmc->csd[2] & 0xc0000000) >> 30;
2403 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2404 }
2405
Stephen Warrenf866a462013-06-11 15:14:01 -06002406 mmc->capacity_user = (csize + 1) << (cmult + 2);
2407 mmc->capacity_user *= mmc->read_bl_len;
2408 mmc->capacity_boot = 0;
2409 mmc->capacity_rpmb = 0;
2410 for (i = 0; i < 4; i++)
2411 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002412
Simon Glass8bfa1952013-04-03 08:54:30 +00002413 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2414 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002415
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002416#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002417 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2418 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002419#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002420
Markus Niebelab711882013-12-16 13:40:46 +01002421 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2422 cmd.cmdidx = MMC_CMD_SET_DSR;
2423 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2424 cmd.resp_type = MMC_RSP_NONE;
2425 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002426 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002427 }
2428
Andy Fleming272cc702008-10-30 16:41:01 -05002429 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002430 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2431 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002432 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002433 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002434 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002435
Thomas Choud52ebf12010-12-24 13:12:21 +00002436 if (err)
2437 return err;
2438 }
Andy Fleming272cc702008-10-30 16:41:01 -05002439
Lei Wene6f99a52011-06-22 17:03:31 +00002440 /*
2441 * For SD, its erase group is always one sector
2442 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002443#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002444 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002445#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002446 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002447
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002448 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002449 if (err)
2450 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302451
Simon Glassc40fdca2016-05-01 13:52:35 -06002452 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002453 if (err)
2454 return err;
2455
Marek Vasut62d77ce2018-04-15 00:37:11 +02002456#if CONFIG_IS_ENABLED(MMC_TINY)
2457 mmc_set_clock(mmc, mmc->legacy_speed, false);
2458 mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
2459 mmc_set_bus_width(mmc, 1);
2460#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002461 if (IS_SD(mmc)) {
2462 err = sd_get_capabilities(mmc);
2463 if (err)
2464 return err;
2465 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2466 } else {
2467 err = mmc_get_capabilities(mmc);
2468 if (err)
2469 return err;
2470 mmc_select_mode_and_width(mmc, mmc->card_caps);
2471 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002472#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002473 if (err)
2474 return err;
2475
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002476 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002477
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002478 /* Fix the block length for DDR mode */
2479 if (mmc->ddr_mode) {
2480 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002481#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002482 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002483#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002484 }
2485
Andy Fleming272cc702008-10-30 16:41:01 -05002486 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002487 bdesc = mmc_get_blk_desc(mmc);
2488 bdesc->lun = 0;
2489 bdesc->hwpart = 0;
2490 bdesc->type = 0;
2491 bdesc->blksz = mmc->read_bl_len;
2492 bdesc->log2blksz = LOG2(bdesc->blksz);
2493 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002494#if !defined(CONFIG_SPL_BUILD) || \
2495 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
2496 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002497 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002498 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2499 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002500 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002501 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2502 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2503 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002504 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002505 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002506#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002507 bdesc->vendor[0] = 0;
2508 bdesc->product[0] = 0;
2509 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002510#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002511
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002512#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2513 part_init(bdesc);
2514#endif
2515
Andy Fleming272cc702008-10-30 16:41:01 -05002516 return 0;
2517}
2518
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002519static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002520{
2521 struct mmc_cmd cmd;
2522 int err;
2523
2524 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2525 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002526 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002527 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002528
2529 err = mmc_send_cmd(mmc, &cmd, NULL);
2530
2531 if (err)
2532 return err;
2533
Rabin Vincent998be3d2009-04-05 13:30:56 +05302534 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002535 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002536 else
2537 mmc->version = SD_VERSION_2;
2538
2539 return 0;
2540}
2541
Simon Glassc4d660d2017-07-04 13:31:19 -06002542#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002543/* board-specific MMC power initializations. */
2544__weak void board_mmc_power_init(void)
2545{
2546}
Simon Glass05cbeb72017-04-22 19:10:56 -06002547#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002548
Peng Fan2051aef2016-10-11 15:08:43 +08002549static int mmc_power_init(struct mmc *mmc)
2550{
Simon Glassc4d660d2017-07-04 13:31:19 -06002551#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002552#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002553 int ret;
2554
2555 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002556 &mmc->vmmc_supply);
2557 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002558 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002559
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002560 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2561 &mmc->vqmmc_supply);
2562 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002563 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002564#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002565#else /* !CONFIG_DM_MMC */
2566 /*
2567 * Driver model should use a regulator, as above, rather than calling
2568 * out to board code.
2569 */
2570 board_mmc_power_init();
2571#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002572 return 0;
2573}
2574
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002575/*
2576 * put the host in the initial state:
2577 * - turn on Vdd (card power supply)
2578 * - configure the bus width and clock to minimal values
2579 */
2580static void mmc_set_initial_state(struct mmc *mmc)
2581{
2582 int err;
2583
2584 /* First try to set 3.3V. If it fails set to 1.8V */
2585 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2586 if (err != 0)
2587 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2588 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002589 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002590
2591 mmc_select_mode(mmc, MMC_LEGACY);
2592 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002593 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002594}
2595
2596static int mmc_power_on(struct mmc *mmc)
2597{
2598#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2599 if (mmc->vmmc_supply) {
2600 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2601
2602 if (ret) {
2603 puts("Error enabling VMMC supply\n");
2604 return ret;
2605 }
2606 }
2607#endif
2608 return 0;
2609}
2610
2611static int mmc_power_off(struct mmc *mmc)
2612{
Jaehoon Chung65117182018-01-26 19:25:29 +09002613 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002614#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2615 if (mmc->vmmc_supply) {
2616 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2617
2618 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002619 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002620 return ret;
2621 }
2622 }
2623#endif
2624 return 0;
2625}
2626
2627static int mmc_power_cycle(struct mmc *mmc)
2628{
2629 int ret;
2630
2631 ret = mmc_power_off(mmc);
2632 if (ret)
2633 return ret;
2634 /*
2635 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2636 * to be on the safer side.
2637 */
2638 udelay(2000);
2639 return mmc_power_on(mmc);
2640}
2641
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002642int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002643{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002644 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002645 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002646
Lei Wenbc897b12011-05-02 16:26:26 +00002647 if (mmc->has_init)
2648 return 0;
2649
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002650#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2651 mmc_adapter_card_type_ident();
2652#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002653 err = mmc_power_init(mmc);
2654 if (err)
2655 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002656
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002657#ifdef CONFIG_MMC_QUIRKS
2658 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
2659 MMC_QUIRK_RETRY_SEND_CID;
2660#endif
2661
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002662 err = mmc_power_cycle(mmc);
2663 if (err) {
2664 /*
2665 * if power cycling is not supported, we should not try
2666 * to use the UHS modes, because we wouldn't be able to
2667 * recover from an error during the UHS initialization.
2668 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002669 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002670 uhs_en = false;
2671 mmc->host_caps &= ~UHS_CAPS;
2672 err = mmc_power_on(mmc);
2673 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002674 if (err)
2675 return err;
2676
Simon Glasse7881d82017-07-29 11:35:31 -06002677#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002678 /* The device has already been probed ready for use */
2679#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002680 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002681 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002682 if (err)
2683 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002684#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002685 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002686
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002687retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002688 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002689
Andy Fleming272cc702008-10-30 16:41:01 -05002690 /* Reset the Card */
2691 err = mmc_go_idle(mmc);
2692
2693 if (err)
2694 return err;
2695
Lei Wenbc897b12011-05-02 16:26:26 +00002696 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002697 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002698
Andy Fleming272cc702008-10-30 16:41:01 -05002699 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002700 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002701
Andy Fleming272cc702008-10-30 16:41:01 -05002702 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002703 err = sd_send_op_cond(mmc, uhs_en);
2704 if (err && uhs_en) {
2705 uhs_en = false;
2706 mmc_power_cycle(mmc);
2707 goto retry;
2708 }
Andy Fleming272cc702008-10-30 16:41:01 -05002709
2710 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002711 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002712 err = mmc_send_op_cond(mmc);
2713
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002714 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002715#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002716 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002717#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002718 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002719 }
2720 }
2721
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002722 return err;
2723}
2724
2725int mmc_start_init(struct mmc *mmc)
2726{
2727 bool no_card;
2728 int err = 0;
2729
2730 /*
2731 * all hosts are capable of 1 bit bus-width and able to use the legacy
2732 * timings.
2733 */
2734 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
2735 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
2736
2737#if !defined(CONFIG_MMC_BROKEN_CD)
2738 /* we pretend there's no card when init is NULL */
2739 no_card = mmc_getcd(mmc) == 0;
2740#else
2741 no_card = 0;
2742#endif
2743#if !CONFIG_IS_ENABLED(DM_MMC)
2744 no_card = no_card || (mmc->cfg->ops->init == NULL);
2745#endif
2746 if (no_card) {
2747 mmc->has_init = 0;
2748#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2749 pr_err("MMC: no card present\n");
2750#endif
2751 return -ENOMEDIUM;
2752 }
2753
2754 err = mmc_get_op_cond(mmc);
2755
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002756 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002757 mmc->init_in_progress = 1;
2758
2759 return err;
2760}
2761
2762static int mmc_complete_init(struct mmc *mmc)
2763{
2764 int err = 0;
2765
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002766 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002767 if (mmc->op_cond_pending)
2768 err = mmc_complete_op_cond(mmc);
2769
2770 if (!err)
2771 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002772 if (err)
2773 mmc->has_init = 0;
2774 else
2775 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002776 return err;
2777}
2778
2779int mmc_init(struct mmc *mmc)
2780{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002781 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302782 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002783#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002784 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002785
Simon Glass33fb2112016-05-01 13:52:41 -06002786 upriv->mmc = mmc;
2787#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002788 if (mmc->has_init)
2789 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002790
2791 start = get_timer(0);
2792
Che-Liang Chioue9550442012-11-28 15:21:13 +00002793 if (!mmc->init_in_progress)
2794 err = mmc_start_init(mmc);
2795
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002796 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002797 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002798 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002799 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002800
Lei Wenbc897b12011-05-02 16:26:26 +00002801 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002802}
2803
Marek Vasutfceea992019-01-29 04:45:51 +01002804#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2805 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2806 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2807int mmc_deinit(struct mmc *mmc)
2808{
2809 u32 caps_filtered;
2810
2811 if (!mmc->has_init)
2812 return 0;
2813
2814 if (IS_SD(mmc)) {
2815 caps_filtered = mmc->card_caps &
2816 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2817 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2818 MMC_CAP(UHS_SDR104));
2819
2820 return sd_select_mode_and_width(mmc, caps_filtered);
2821 } else {
2822 caps_filtered = mmc->card_caps &
2823 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2824
2825 return mmc_select_mode_and_width(mmc, caps_filtered);
2826 }
2827}
2828#endif
2829
Markus Niebelab711882013-12-16 13:40:46 +01002830int mmc_set_dsr(struct mmc *mmc, u16 val)
2831{
2832 mmc->dsr = val;
2833 return 0;
2834}
2835
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002836/* CPU-specific MMC initializations */
2837__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002838{
2839 return -1;
2840}
2841
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002842/* board-specific MMC initializations. */
2843__weak int board_mmc_init(bd_t *bis)
2844{
2845 return -1;
2846}
Andy Fleming272cc702008-10-30 16:41:01 -05002847
Che-Liang Chioue9550442012-11-28 15:21:13 +00002848void mmc_set_preinit(struct mmc *mmc, int preinit)
2849{
2850 mmc->preinit = preinit;
2851}
2852
Faiz Abbas8a856db2018-02-12 19:35:24 +05302853#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002854static int mmc_probe(bd_t *bis)
2855{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002856 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002857 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002858 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002859
2860 ret = uclass_get(UCLASS_MMC, &uc);
2861 if (ret)
2862 return ret;
2863
Simon Glass4a1db6d2015-12-29 05:22:49 -07002864 /*
2865 * Try to add them in sequence order. Really with driver model we
2866 * should allow holes, but the current MMC list does not allow that.
2867 * So if we request 0, 1, 3 we will get 0, 1, 2.
2868 */
2869 for (i = 0; ; i++) {
2870 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2871 if (ret == -ENODEV)
2872 break;
2873 }
2874 uclass_foreach_dev(dev, uc) {
2875 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002876 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002877 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002878 }
2879
2880 return 0;
2881}
2882#else
2883static int mmc_probe(bd_t *bis)
2884{
2885 if (board_mmc_init(bis) < 0)
2886 cpu_mmc_init(bis);
2887
2888 return 0;
2889}
2890#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002891
Andy Fleming272cc702008-10-30 16:41:01 -05002892int mmc_initialize(bd_t *bis)
2893{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002894 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002895 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002896 if (initialized) /* Avoid initializing mmc multiple times */
2897 return 0;
2898 initialized = 1;
2899
Simon Glassc4d660d2017-07-04 13:31:19 -06002900#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002901#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002902 mmc_list_init();
2903#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002904#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002905 ret = mmc_probe(bis);
2906 if (ret)
2907 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002908
Ying Zhangbb0dc102013-08-16 15:16:11 +08002909#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002910 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002911#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002912
Simon Glassc40fdca2016-05-01 13:52:35 -06002913 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002914 return 0;
2915}
Tomas Melincd3d4882016-11-25 11:01:03 +02002916
2917#ifdef CONFIG_CMD_BKOPS_ENABLE
2918int mmc_set_bkops_enable(struct mmc *mmc)
2919{
2920 int err;
2921 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2922
2923 err = mmc_send_ext_csd(mmc, ext_csd);
2924 if (err) {
2925 puts("Could not get ext_csd register values\n");
2926 return err;
2927 }
2928
2929 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2930 puts("Background operations not supported on device\n");
2931 return -EMEDIUMTYPE;
2932 }
2933
2934 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2935 puts("Background operations already enabled\n");
2936 return 0;
2937 }
2938
2939 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2940 if (err) {
2941 puts("Failed to enable manual background operations\n");
2942 return err;
2943 }
2944
2945 puts("Enabled manual background operations\n");
2946
2947 return 0;
2948}
2949#endif