blob: fc3123c3c3d65eb8c7b6fca43879b7670af7cf61 [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);
Marek Vasutb5b838f2016-12-01 02:06:33 +010027
Simon Glasse7881d82017-07-29 11:35:31 -060028#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020029
Sam Protsenko6cf8a902019-08-14 22:52:51 +030030static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020031{
32 return -ENOSYS;
33}
34
Jeroen Hofstee750121c2014-07-12 21:24:08 +020035__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000036{
37 return -1;
38}
39
40int mmc_getwp(struct mmc *mmc)
41{
42 int wp;
43
44 wp = board_mmc_getwp(mmc);
45
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000046 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020047 if (mmc->cfg->ops->getwp)
48 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000049 else
50 wp = 0;
51 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000052
53 return wp;
54}
55
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020056__weak int board_mmc_getcd(struct mmc *mmc)
57{
Stefano Babic11fdade2010-02-05 15:04:43 +010058 return -1;
59}
Simon Glass8ca51e52016-06-12 23:30:22 -060060#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010061
Marek Vasut8635ff92012-03-15 18:41:35 +000062#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060063void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
64{
65 printf("CMD_SEND:%d\n", cmd->cmdidx);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010066 printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
Simon Glassc0c76eb2016-06-12 23:30:20 -060067}
68
69void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
70{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000071 int i;
72 u8 *ptr;
73
Bin Meng7863ce52016-03-17 21:53:14 -070074 if (ret) {
75 printf("\t\tRET\t\t\t %d\n", ret);
76 } else {
77 switch (cmd->resp_type) {
78 case MMC_RSP_NONE:
79 printf("\t\tMMC_RSP_NONE\n");
80 break;
81 case MMC_RSP_R1:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010082 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070083 cmd->response[0]);
84 break;
85 case MMC_RSP_R1b:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010086 printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070087 cmd->response[0]);
88 break;
89 case MMC_RSP_R2:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010090 printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070091 cmd->response[0]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010092 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070093 cmd->response[1]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010094 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070095 cmd->response[2]);
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[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000098 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -070099 printf("\t\t\t\t\tDUMPING DATA\n");
100 for (i = 0; i < 4; i++) {
101 int j;
102 printf("\t\t\t\t\t%03d - ", i*4);
103 ptr = (u8 *)&cmd->response[i];
104 ptr += 3;
105 for (j = 0; j < 4; j++)
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100106 printf("%02x ", *ptr--);
Bin Meng7863ce52016-03-17 21:53:14 -0700107 printf("\n");
108 }
109 break;
110 case MMC_RSP_R3:
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100111 printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700112 cmd->response[0]);
113 break;
114 default:
115 printf("\t\tERROR MMC rsp not supported\n");
116 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700117 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000118 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600119}
120
121void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
122{
123 int status;
124
125 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
126 printf("CURR STATE:%d\n", status);
127}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000128#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600129
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200130#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
131const char *mmc_mode_name(enum bus_mode mode)
132{
133 static const char *const names[] = {
134 [MMC_LEGACY] = "MMC legacy",
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200135 [MMC_HS] = "MMC High Speed (26MHz)",
136 [SD_HS] = "SD High Speed (50MHz)",
137 [UHS_SDR12] = "UHS SDR12 (25MHz)",
138 [UHS_SDR25] = "UHS SDR25 (50MHz)",
139 [UHS_SDR50] = "UHS SDR50 (100MHz)",
140 [UHS_SDR104] = "UHS SDR104 (208MHz)",
141 [UHS_DDR50] = "UHS DDR50 (50MHz)",
142 [MMC_HS_52] = "MMC High Speed (52MHz)",
143 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
144 [MMC_HS_200] = "HS200 (200MHz)",
Peng Fan3dd26262018-08-10 14:07:54 +0800145 [MMC_HS_400] = "HS400 (200MHz)",
Peng Fan44acd492019-07-10 14:43:07 +0800146 [MMC_HS_400_ES] = "HS400ES (200MHz)",
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200147 };
148
149 if (mode >= MMC_MODES_END)
150 return "Unknown mode";
151 else
152 return names[mode];
153}
154#endif
155
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200156static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
157{
158 static const int freqs[] = {
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900159 [MMC_LEGACY] = 25000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200160 [MMC_HS] = 26000000,
161 [SD_HS] = 50000000,
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900162 [MMC_HS_52] = 52000000,
163 [MMC_DDR_52] = 52000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200164 [UHS_SDR12] = 25000000,
165 [UHS_SDR25] = 50000000,
166 [UHS_SDR50] = 100000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200167 [UHS_DDR50] = 50000000,
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100168 [UHS_SDR104] = 208000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200169 [MMC_HS_200] = 200000000,
Peng Fan3dd26262018-08-10 14:07:54 +0800170 [MMC_HS_400] = 200000000,
Peng Fan44acd492019-07-10 14:43:07 +0800171 [MMC_HS_400_ES] = 200000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200172 };
173
174 if (mode == MMC_LEGACY)
175 return mmc->legacy_speed;
176 else if (mode >= MMC_MODES_END)
177 return 0;
178 else
179 return freqs[mode];
180}
181
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200182static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
183{
184 mmc->selected_mode = mode;
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200185 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200186 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900187 pr_debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
188 mmc->tran_speed / 1000000);
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200189 return 0;
190}
191
Simon Glasse7881d82017-07-29 11:35:31 -0600192#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassc0c76eb2016-06-12 23:30:20 -0600193int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
194{
195 int ret;
196
197 mmmc_trace_before_send(mmc, cmd);
198 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
199 mmmc_trace_after_send(mmc, cmd, ret);
200
Marek Vasut8635ff92012-03-15 18:41:35 +0000201 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500202}
Simon Glass8ca51e52016-06-12 23:30:22 -0600203#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500204
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200205int mmc_send_status(struct mmc *mmc, unsigned int *status)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000206{
207 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000208 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000209
210 cmd.cmdidx = MMC_CMD_SEND_STATUS;
211 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200212 if (!mmc_host_is_spi(mmc))
213 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000214
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200215 while (retries--) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000216 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000217 if (!err) {
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200218 mmc_trace_state(mmc, &cmd);
219 *status = cmd.response[0];
220 return 0;
221 }
222 }
223 mmc_trace_state(mmc, &cmd);
224 return -ECOMM;
225}
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200226
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300227int mmc_poll_for_busy(struct mmc *mmc, int timeout_ms)
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200228{
229 unsigned int status;
230 int err;
231
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300232 err = mmc_wait_dat0(mmc, 1, timeout_ms * 1000);
Jean-Jacques Hiblotcd0b80e2019-07-02 10:53:53 +0200233 if (err != -ENOSYS)
234 return err;
235
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200236 while (1) {
237 err = mmc_send_status(mmc, &status);
238 if (err)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000239 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000240
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200241 if ((status & MMC_STATUS_RDY_FOR_DATA) &&
242 (status & MMC_STATUS_CURR_STATE) !=
243 MMC_STATE_PRG)
244 break;
245
246 if (status & MMC_STATUS_MASK) {
247#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
248 pr_err("Status Error: 0x%08x\n", status);
249#endif
250 return -ECOMM;
251 }
252
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300253 if (timeout_ms-- <= 0)
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500254 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000255
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500256 udelay(1000);
257 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000258
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300259 if (timeout_ms <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100260#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100261 pr_err("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100262#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900263 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000264 }
265
266 return 0;
267}
268
Paul Burtonda61fa52013-09-09 15:30:26 +0100269int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500270{
271 struct mmc_cmd cmd;
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200272 int err;
Andy Fleming272cc702008-10-30 16:41:01 -0500273
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600274 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900275 return 0;
276
Andy Fleming272cc702008-10-30 16:41:01 -0500277 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
278 cmd.resp_type = MMC_RSP_R1;
279 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500280
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200281 err = mmc_send_cmd(mmc, &cmd, NULL);
282
283#ifdef CONFIG_MMC_QUIRKS
284 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
285 int retries = 4;
286 /*
287 * It has been seen that SET_BLOCKLEN may fail on the first
288 * attempt, let's try a few more time
289 */
290 do {
291 err = mmc_send_cmd(mmc, &cmd, NULL);
292 if (!err)
293 break;
294 } while (retries--);
295 }
296#endif
297
298 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500299}
300
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100301#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200302static const u8 tuning_blk_pattern_4bit[] = {
303 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
304 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
305 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
306 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
307 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
308 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
309 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
310 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
311};
312
313static const u8 tuning_blk_pattern_8bit[] = {
314 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
315 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
316 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
317 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
318 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
319 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
320 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
321 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
322 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
323 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
324 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
325 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
326 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
327 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
328 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
329 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
330};
331
332int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
333{
334 struct mmc_cmd cmd;
335 struct mmc_data data;
336 const u8 *tuning_block_pattern;
337 int size, err;
338
339 if (mmc->bus_width == 8) {
340 tuning_block_pattern = tuning_blk_pattern_8bit;
341 size = sizeof(tuning_blk_pattern_8bit);
342 } else if (mmc->bus_width == 4) {
343 tuning_block_pattern = tuning_blk_pattern_4bit;
344 size = sizeof(tuning_blk_pattern_4bit);
345 } else {
346 return -EINVAL;
347 }
348
349 ALLOC_CACHE_ALIGN_BUFFER(u8, data_buf, size);
350
351 cmd.cmdidx = opcode;
352 cmd.cmdarg = 0;
353 cmd.resp_type = MMC_RSP_R1;
354
355 data.dest = (void *)data_buf;
356 data.blocks = 1;
357 data.blocksize = size;
358 data.flags = MMC_DATA_READ;
359
360 err = mmc_send_cmd(mmc, &cmd, &data);
361 if (err)
362 return err;
363
364 if (memcmp(data_buf, tuning_block_pattern, size))
365 return -EIO;
366
367 return 0;
368}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100369#endif
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200370
Sascha Silbeff8fef52013-06-14 13:07:25 +0200371static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000372 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500373{
374 struct mmc_cmd cmd;
375 struct mmc_data data;
376
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700377 if (blkcnt > 1)
378 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
379 else
380 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500381
382 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700383 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500384 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700385 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500386
387 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500388
389 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700390 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500391 data.blocksize = mmc->read_bl_len;
392 data.flags = MMC_DATA_READ;
393
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700394 if (mmc_send_cmd(mmc, &cmd, &data))
395 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500396
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700397 if (blkcnt > 1) {
398 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
399 cmd.cmdarg = 0;
400 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700401 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100402#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100403 pr_err("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100404#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700405 return 0;
406 }
Andy Fleming272cc702008-10-30 16:41:01 -0500407 }
408
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700409 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500410}
411
Simon Glassc4d660d2017-07-04 13:31:19 -0600412#if CONFIG_IS_ENABLED(BLK)
Simon Glass7dba0b92016-06-12 23:30:15 -0600413ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600414#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600415ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
416 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600417#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500418{
Simon Glassc4d660d2017-07-04 13:31:19 -0600419#if CONFIG_IS_ENABLED(BLK)
Simon Glass33fb2112016-05-01 13:52:41 -0600420 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
421#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700422 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700423 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700424 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500425
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700426 if (blkcnt == 0)
427 return 0;
428
429 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500430 if (!mmc)
431 return 0;
432
Marek Vasutb5b838f2016-12-01 02:06:33 +0100433 if (CONFIG_IS_ENABLED(MMC_TINY))
434 err = mmc_switch_part(mmc, block_dev->hwpart);
435 else
436 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
437
Stephen Warren873cc1d2015-12-07 11:38:49 -0700438 if (err < 0)
439 return 0;
440
Simon Glassc40fdca2016-05-01 13:52:35 -0600441 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100442#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100443 pr_err("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
444 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100445#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800446 return 0;
447 }
Andy Fleming272cc702008-10-30 16:41:01 -0500448
Simon Glass11692992015-06-23 15:38:50 -0600449 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900450 pr_debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500451 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600452 }
Andy Fleming272cc702008-10-30 16:41:01 -0500453
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700454 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200455 cur = (blocks_todo > mmc->cfg->b_max) ?
456 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600457 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900458 pr_debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700459 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600460 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700461 blocks_todo -= cur;
462 start += cur;
463 dst += cur * mmc->read_bl_len;
464 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500465
466 return blkcnt;
467}
468
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000469static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500470{
471 struct mmc_cmd cmd;
472 int err;
473
474 udelay(1000);
475
476 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
477 cmd.cmdarg = 0;
478 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500479
480 err = mmc_send_cmd(mmc, &cmd, NULL);
481
482 if (err)
483 return err;
484
485 udelay(2000);
486
487 return 0;
488}
489
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100490#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200491static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
492{
493 struct mmc_cmd cmd;
494 int err = 0;
495
496 /*
497 * Send CMD11 only if the request is to switch the card to
498 * 1.8V signalling.
499 */
500 if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
501 return mmc_set_signal_voltage(mmc, signal_voltage);
502
503 cmd.cmdidx = SD_CMD_SWITCH_UHS18V;
504 cmd.cmdarg = 0;
505 cmd.resp_type = MMC_RSP_R1;
506
507 err = mmc_send_cmd(mmc, &cmd, NULL);
508 if (err)
509 return err;
510
511 if (!mmc_host_is_spi(mmc) && (cmd.response[0] & MMC_STATUS_ERROR))
512 return -EIO;
513
514 /*
515 * The card should drive cmd and dat[0:3] low immediately
516 * after the response of cmd11, but wait 100 us to be sure
517 */
518 err = mmc_wait_dat0(mmc, 0, 100);
519 if (err == -ENOSYS)
520 udelay(100);
521 else if (err)
522 return -ETIMEDOUT;
523
524 /*
525 * During a signal voltage level switch, the clock must be gated
526 * for 5 ms according to the SD spec
527 */
Jaehoon Chung65117182018-01-26 19:25:29 +0900528 mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200529
530 err = mmc_set_signal_voltage(mmc, signal_voltage);
531 if (err)
532 return err;
533
534 /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
535 mdelay(10);
Jaehoon Chung65117182018-01-26 19:25:29 +0900536 mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200537
538 /*
539 * Failure to switch is indicated by the card holding
540 * dat[0:3] low. Wait for at least 1 ms according to spec
541 */
542 err = mmc_wait_dat0(mmc, 1, 1000);
543 if (err == -ENOSYS)
544 udelay(1000);
545 else if (err)
546 return -ETIMEDOUT;
547
548 return 0;
549}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100550#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200551
552static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
Andy Fleming272cc702008-10-30 16:41:01 -0500553{
554 int timeout = 1000;
555 int err;
556 struct mmc_cmd cmd;
557
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500558 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500559 cmd.cmdidx = MMC_CMD_APP_CMD;
560 cmd.resp_type = MMC_RSP_R1;
561 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500562
563 err = mmc_send_cmd(mmc, &cmd, NULL);
564
565 if (err)
566 return err;
567
568 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
569 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100570
571 /*
572 * Most cards do not answer if some reserved bits
573 * in the ocr are set. However, Some controller
574 * can set bit 7 (reserved for low voltages), but
575 * how to manage low voltages SD card is not yet
576 * specified.
577 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000578 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200579 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500580
581 if (mmc->version == SD_VERSION_2)
582 cmd.cmdarg |= OCR_HCS;
583
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200584 if (uhs_en)
585 cmd.cmdarg |= OCR_S18R;
586
Andy Fleming272cc702008-10-30 16:41:01 -0500587 err = mmc_send_cmd(mmc, &cmd, NULL);
588
589 if (err)
590 return err;
591
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500592 if (cmd.response[0] & OCR_BUSY)
593 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500594
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500595 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900596 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500597
598 udelay(1000);
599 }
Andy Fleming272cc702008-10-30 16:41:01 -0500600
601 if (mmc->version != SD_VERSION_2)
602 mmc->version = SD_VERSION_1_0;
603
Thomas Choud52ebf12010-12-24 13:12:21 +0000604 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
605 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
606 cmd.resp_type = MMC_RSP_R3;
607 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000608
609 err = mmc_send_cmd(mmc, &cmd, NULL);
610
611 if (err)
612 return err;
613 }
614
Rabin Vincent998be3d2009-04-05 13:30:56 +0530615 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500616
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100617#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200618 if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x41000000)
619 == 0x41000000) {
620 err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
621 if (err)
622 return err;
623 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100624#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200625
Andy Fleming272cc702008-10-30 16:41:01 -0500626 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
627 mmc->rca = 0;
628
629 return 0;
630}
631
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500632static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500633{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500634 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500635 int err;
636
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500637 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
638 cmd.resp_type = MMC_RSP_R3;
639 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500640 if (use_arg && !mmc_host_is_spi(mmc))
641 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200642 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500643 (mmc->ocr & OCR_VOLTAGE_MASK)) |
644 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000645
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500646 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000647 if (err)
648 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500649 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000650 return 0;
651}
652
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200653static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000654{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000655 int err, i;
656
Andy Fleming272cc702008-10-30 16:41:01 -0500657 /* Some cards seem to need this */
658 mmc_go_idle(mmc);
659
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000660 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000661 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500662 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500663 if (err)
664 return err;
665
Che-Liang Chioue9550442012-11-28 15:21:13 +0000666 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500667 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500668 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000669 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500670 mmc->op_cond_pending = 1;
671 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000672}
Andy Fleming272cc702008-10-30 16:41:01 -0500673
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200674static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000675{
676 struct mmc_cmd cmd;
677 int timeout = 1000;
Vipul Kumar36332b62018-05-03 12:20:54 +0530678 ulong start;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000679 int err;
680
681 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500682 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lud188b112016-08-02 15:33:18 +0800683 /* Some cards seem to need this */
684 mmc_go_idle(mmc);
685
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500686 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500687 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500688 err = mmc_send_op_cond_iter(mmc, 1);
689 if (err)
690 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500691 if (mmc->ocr & OCR_BUSY)
692 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500693 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900694 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500695 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500696 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500697 }
Andy Fleming272cc702008-10-30 16:41:01 -0500698
Thomas Choud52ebf12010-12-24 13:12:21 +0000699 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
700 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
701 cmd.resp_type = MMC_RSP_R3;
702 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000703
704 err = mmc_send_cmd(mmc, &cmd, NULL);
705
706 if (err)
707 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500708
709 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000710 }
711
Andy Fleming272cc702008-10-30 16:41:01 -0500712 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500713
714 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700715 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500716
717 return 0;
718}
719
720
Heinrich Schuchardt1601ea22020-03-30 07:24:17 +0200721int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500722{
723 struct mmc_cmd cmd;
724 struct mmc_data data;
725 int err;
726
727 /* Get the Card Status Register */
728 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
729 cmd.resp_type = MMC_RSP_R1;
730 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500731
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000732 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500733 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000734 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500735 data.flags = MMC_DATA_READ;
736
737 err = mmc_send_cmd(mmc, &cmd, &data);
738
739 return err;
740}
741
Marek Vasut68925502019-02-06 11:34:27 +0100742static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
743 bool send_status)
Andy Fleming272cc702008-10-30 16:41:01 -0500744{
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200745 unsigned int status, start;
Andy Fleming272cc702008-10-30 16:41:01 -0500746 struct mmc_cmd cmd;
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300747 int timeout_ms = DEFAULT_CMD6_TIMEOUT_MS;
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200748 bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
749 (index == EXT_CSD_PART_CONF);
Maxime Riparda9003dc2016-11-04 16:18:08 +0100750 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000751 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500752
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200753 if (mmc->gen_cmd6_time)
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300754 timeout_ms = mmc->gen_cmd6_time * 10;
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +0200755
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200756 if (is_part_switch && mmc->part_switch_time)
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300757 timeout_ms = mmc->part_switch_time * 10;
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +0200758
Andy Fleming272cc702008-10-30 16:41:01 -0500759 cmd.cmdidx = MMC_CMD_SWITCH;
760 cmd.resp_type = MMC_RSP_R1b;
761 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000762 (index << 16) |
763 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500764
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200765 do {
Maxime Riparda9003dc2016-11-04 16:18:08 +0100766 ret = mmc_send_cmd(mmc, &cmd, NULL);
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200767 } while (ret && retries-- > 0);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000768
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200769 if (ret)
770 return ret;
771
772 start = get_timer(0);
773
774 /* poll dat0 for rdy/buys status */
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300775 ret = mmc_wait_dat0(mmc, 1, timeout_ms * 1000);
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200776 if (ret && ret != -ENOSYS)
777 return ret;
778
779 /*
780 * In cases when not allowed to poll by using CMD13 or because we aren't
781 * capable of polling by using mmc_wait_dat0, then rely on waiting the
782 * stated timeout to be sufficient.
783 */
784 if (ret == -ENOSYS && !send_status)
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300785 mdelay(timeout_ms);
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200786
787 /* Finally wait until the card is ready or indicates a failure
788 * to switch. It doesn't hurt to use CMD13 here even if send_status
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300789 * is false, because by now (after 'timeout_ms' ms) the bus should be
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200790 * reliable.
791 */
792 do {
793 ret = mmc_send_status(mmc, &status);
794
795 if (!ret && (status & MMC_STATUS_SWITCH_ERROR)) {
796 pr_debug("switch failed %d/%d/0x%x !\n", set, index,
797 value);
798 return -EIO;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100799 }
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200800 if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
Marek Vasut68925502019-02-06 11:34:27 +0100801 return 0;
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200802 udelay(100);
Sam Protsenko6cf8a902019-08-14 22:52:51 +0300803 } while (get_timer(start) < timeout_ms);
Marek Vasut68925502019-02-06 11:34:27 +0100804
Jean-Jacques Hiblotbb98b8c2019-07-02 10:53:56 +0200805 return -ETIMEDOUT;
Andy Fleming272cc702008-10-30 16:41:01 -0500806}
807
Marek Vasut68925502019-02-06 11:34:27 +0100808int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
809{
810 return __mmc_switch(mmc, set, index, value, true);
811}
812
Heinrich Schuchardt0469d842020-03-30 07:24:19 +0200813int mmc_boot_wp(struct mmc *mmc)
814{
815 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, 1);
816}
817
Marek Vasut62d77ce2018-04-15 00:37:11 +0200818#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100819static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
820 bool hsdowngrade)
Andy Fleming272cc702008-10-30 16:41:01 -0500821{
Andy Fleming272cc702008-10-30 16:41:01 -0500822 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200823 int speed_bits;
824
825 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
826
827 switch (mode) {
828 case MMC_HS:
829 case MMC_HS_52:
830 case MMC_DDR_52:
831 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200832 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100833#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200834 case MMC_HS_200:
835 speed_bits = EXT_CSD_TIMING_HS200;
836 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100837#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800838#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
839 case MMC_HS_400:
840 speed_bits = EXT_CSD_TIMING_HS400;
841 break;
842#endif
Peng Fan44acd492019-07-10 14:43:07 +0800843#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
844 case MMC_HS_400_ES:
845 speed_bits = EXT_CSD_TIMING_HS400;
846 break;
847#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200848 case MMC_LEGACY:
849 speed_bits = EXT_CSD_TIMING_LEGACY;
850 break;
851 default:
852 return -EINVAL;
853 }
Marek Vasut68925502019-02-06 11:34:27 +0100854
855 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
856 speed_bits, !hsdowngrade);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200857 if (err)
858 return err;
859
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100860#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
861 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
862 /*
863 * In case the eMMC is in HS200/HS400 mode and we are downgrading
864 * to HS mode, the card clock are still running much faster than
865 * the supported HS mode clock, so we can not reliably read out
866 * Extended CSD. Reconfigure the controller to run at HS mode.
867 */
868 if (hsdowngrade) {
869 mmc_select_mode(mmc, MMC_HS);
870 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
871 }
872#endif
873
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200874 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
875 /* Now check to see that it worked */
876 err = mmc_send_ext_csd(mmc, test_csd);
877 if (err)
878 return err;
879
880 /* No high-speed support */
881 if (!test_csd[EXT_CSD_HS_TIMING])
882 return -ENOTSUPP;
883 }
884
885 return 0;
886}
887
888static int mmc_get_capabilities(struct mmc *mmc)
889{
890 u8 *ext_csd = mmc->ext_csd;
891 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500892
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +0100893 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -0500894
Thomas Choud52ebf12010-12-24 13:12:21 +0000895 if (mmc_host_is_spi(mmc))
896 return 0;
897
Andy Fleming272cc702008-10-30 16:41:01 -0500898 /* Only version 4 supports high-speed */
899 if (mmc->version < MMC_VERSION_4)
900 return 0;
901
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200902 if (!ext_csd) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100903 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200904 return -ENOTSUPP;
905 }
906
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600907 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
908
Peng Fan3dd26262018-08-10 14:07:54 +0800909 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +0200910 mmc->cardtype = cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500911
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100912#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200913 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
914 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
915 mmc->card_caps |= MMC_MODE_HS200;
916 }
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100917#endif
Peng Fan44acd492019-07-10 14:43:07 +0800918#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) || \
919 CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
Peng Fan3dd26262018-08-10 14:07:54 +0800920 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
921 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
922 mmc->card_caps |= MMC_MODE_HS400;
923 }
924#endif
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900925 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200926 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900927 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200928 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900929 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200930 if (cardtype & EXT_CSD_CARD_TYPE_26)
931 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500932
Peng Fan44acd492019-07-10 14:43:07 +0800933#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
934 if (ext_csd[EXT_CSD_STROBE_SUPPORT] &&
935 (mmc->card_caps & MMC_MODE_HS400)) {
936 mmc->card_caps |= MMC_MODE_HS400_ES;
937 }
938#endif
939
Andy Fleming272cc702008-10-30 16:41:01 -0500940 return 0;
941}
Marek Vasut62d77ce2018-04-15 00:37:11 +0200942#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500943
Stephen Warrenf866a462013-06-11 15:14:01 -0600944static int mmc_set_capacity(struct mmc *mmc, int part_num)
945{
946 switch (part_num) {
947 case 0:
948 mmc->capacity = mmc->capacity_user;
949 break;
950 case 1:
951 case 2:
952 mmc->capacity = mmc->capacity_boot;
953 break;
954 case 3:
955 mmc->capacity = mmc->capacity_rpmb;
956 break;
957 case 4:
958 case 5:
959 case 6:
960 case 7:
961 mmc->capacity = mmc->capacity_gp[part_num - 4];
962 break;
963 default:
964 return -1;
965 }
966
Simon Glassc40fdca2016-05-01 13:52:35 -0600967 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600968
969 return 0;
970}
971
Simon Glass7dba0b92016-06-12 23:30:15 -0600972int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000973{
Stephen Warrenf866a462013-06-11 15:14:01 -0600974 int ret;
Jean-Jacques Hiblot05384772019-07-02 10:53:58 +0200975 int retry = 3;
Lei Wenbc897b12011-05-02 16:26:26 +0000976
Jean-Jacques Hiblot05384772019-07-02 10:53:58 +0200977 do {
978 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
979 EXT_CSD_PART_CONF,
980 (mmc->part_config & ~PART_ACCESS_MASK)
981 | (part_num & PART_ACCESS_MASK));
982 } while (ret && retry--);
Stephen Warrenf866a462013-06-11 15:14:01 -0600983
Peter Bigot6dc93e72014-09-02 18:31:23 -0500984 /*
985 * Set the capacity if the switch succeeded or was intended
986 * to return to representing the raw device.
987 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700988 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500989 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600990 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700991 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500992
993 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000994}
995
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100996#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100997int mmc_hwpart_config(struct mmc *mmc,
998 const struct mmc_hwpart_conf *conf,
999 enum mmc_hwpart_conf_mode mode)
1000{
1001 u8 part_attrs = 0;
1002 u32 enh_size_mult;
1003 u32 enh_start_addr;
1004 u32 gp_size_mult[4];
1005 u32 max_enh_size_mult;
1006 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001007 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001008 int i, pidx, err;
1009 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1010
1011 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
1012 return -EINVAL;
1013
1014 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001015 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001016 return -EMEDIUMTYPE;
1017 }
1018
1019 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001020 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001021 return -EMEDIUMTYPE;
1022 }
1023
1024 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001025 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001026 return -EMEDIUMTYPE;
1027 }
1028
1029 /* check partition alignment and total enhanced size */
1030 if (conf->user.enh_size) {
1031 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1032 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001033 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001034 "size aligned\n");
1035 return -EINVAL;
1036 }
1037 part_attrs |= EXT_CSD_ENH_USR;
1038 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1039 if (mmc->high_capacity) {
1040 enh_start_addr = conf->user.enh_start;
1041 } else {
1042 enh_start_addr = (conf->user.enh_start << 9);
1043 }
1044 } else {
1045 enh_size_mult = 0;
1046 enh_start_addr = 0;
1047 }
1048 tot_enh_size_mult += enh_size_mult;
1049
1050 for (pidx = 0; pidx < 4; pidx++) {
1051 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001052 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001053 "aligned\n", pidx+1);
1054 return -EINVAL;
1055 }
1056 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1057 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1058 part_attrs |= EXT_CSD_ENH_GP(pidx);
1059 tot_enh_size_mult += gp_size_mult[pidx];
1060 }
1061 }
1062
1063 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001064 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001065 return -EMEDIUMTYPE;
1066 }
1067
1068 err = mmc_send_ext_csd(mmc, ext_csd);
1069 if (err)
1070 return err;
1071
1072 max_enh_size_mult =
1073 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1074 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1075 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1076 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001077 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001078 tot_enh_size_mult, max_enh_size_mult);
1079 return -EMEDIUMTYPE;
1080 }
1081
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001082 /* The default value of EXT_CSD_WR_REL_SET is device
1083 * dependent, the values can only be changed if the
1084 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1085 * changed only once and before partitioning is completed. */
1086 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1087 if (conf->user.wr_rel_change) {
1088 if (conf->user.wr_rel_set)
1089 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1090 else
1091 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1092 }
1093 for (pidx = 0; pidx < 4; pidx++) {
1094 if (conf->gp_part[pidx].wr_rel_change) {
1095 if (conf->gp_part[pidx].wr_rel_set)
1096 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1097 else
1098 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1099 }
1100 }
1101
1102 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1103 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1104 puts("Card does not support host controlled partition write "
1105 "reliability settings\n");
1106 return -EMEDIUMTYPE;
1107 }
1108
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001109 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1110 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001111 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001112 return -EPERM;
1113 }
1114
1115 if (mode == MMC_HWPART_CONF_CHECK)
1116 return 0;
1117
1118 /* Partitioning requires high-capacity size definitions */
1119 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1120 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1121 EXT_CSD_ERASE_GROUP_DEF, 1);
1122
1123 if (err)
1124 return err;
1125
1126 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1127
Jaehoon Chung4af66592020-01-17 15:06:54 +09001128#if CONFIG_IS_ENABLED(MMC_WRITE)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001129 /* update erase group size to be high-capacity */
1130 mmc->erase_grp_size =
1131 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jaehoon Chung4af66592020-01-17 15:06:54 +09001132#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001133
1134 }
1135
1136 /* all OK, write the configuration */
1137 for (i = 0; i < 4; i++) {
1138 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1139 EXT_CSD_ENH_START_ADDR+i,
1140 (enh_start_addr >> (i*8)) & 0xFF);
1141 if (err)
1142 return err;
1143 }
1144 for (i = 0; i < 3; i++) {
1145 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1146 EXT_CSD_ENH_SIZE_MULT+i,
1147 (enh_size_mult >> (i*8)) & 0xFF);
1148 if (err)
1149 return err;
1150 }
1151 for (pidx = 0; pidx < 4; pidx++) {
1152 for (i = 0; i < 3; i++) {
1153 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1154 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1155 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1156 if (err)
1157 return err;
1158 }
1159 }
1160 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1161 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1162 if (err)
1163 return err;
1164
1165 if (mode == MMC_HWPART_CONF_SET)
1166 return 0;
1167
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001168 /* The WR_REL_SET is a write-once register but shall be
1169 * written before setting PART_SETTING_COMPLETED. As it is
1170 * write-once we can only write it when completing the
1171 * partitioning. */
1172 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1173 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1174 EXT_CSD_WR_REL_SET, wr_rel_set);
1175 if (err)
1176 return err;
1177 }
1178
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001179 /* Setting PART_SETTING_COMPLETED confirms the partition
1180 * configuration but it only becomes effective after power
1181 * cycle, so we do not adjust the partition related settings
1182 * in the mmc struct. */
1183
1184 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1185 EXT_CSD_PARTITION_SETTING,
1186 EXT_CSD_PARTITION_SETTING_COMPLETED);
1187 if (err)
1188 return err;
1189
1190 return 0;
1191}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001192#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001193
Simon Glasse7881d82017-07-29 11:35:31 -06001194#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001195int mmc_getcd(struct mmc *mmc)
1196{
1197 int cd;
1198
1199 cd = board_mmc_getcd(mmc);
1200
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001201 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001202 if (mmc->cfg->ops->getcd)
1203 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001204 else
1205 cd = 1;
1206 }
Thierry Reding48972d92012-01-02 01:15:37 +00001207
1208 return cd;
1209}
Simon Glass8ca51e52016-06-12 23:30:22 -06001210#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001211
Marek Vasut62d77ce2018-04-15 00:37:11 +02001212#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001213static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001214{
1215 struct mmc_cmd cmd;
1216 struct mmc_data data;
1217
1218 /* Switch the frequency */
1219 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1220 cmd.resp_type = MMC_RSP_R1;
1221 cmd.cmdarg = (mode << 31) | 0xffffff;
1222 cmd.cmdarg &= ~(0xf << (group * 4));
1223 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001224
1225 data.dest = (char *)resp;
1226 data.blocksize = 64;
1227 data.blocks = 1;
1228 data.flags = MMC_DATA_READ;
1229
1230 return mmc_send_cmd(mmc, &cmd, &data);
1231}
1232
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001233static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001234{
1235 int err;
1236 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301237 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1238 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001239 struct mmc_data data;
1240 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001241#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001242 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001243#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001244
Faiz Abbase8d5dde2020-02-26 13:44:32 +05301245 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001246
Thomas Choud52ebf12010-12-24 13:12:21 +00001247 if (mmc_host_is_spi(mmc))
1248 return 0;
1249
Andy Fleming272cc702008-10-30 16:41:01 -05001250 /* Read the SCR to find out if this card supports higher speeds */
1251 cmd.cmdidx = MMC_CMD_APP_CMD;
1252 cmd.resp_type = MMC_RSP_R1;
1253 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001254
1255 err = mmc_send_cmd(mmc, &cmd, NULL);
1256
1257 if (err)
1258 return err;
1259
1260 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1261 cmd.resp_type = MMC_RSP_R1;
1262 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001263
1264 timeout = 3;
1265
1266retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001267 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001268 data.blocksize = 8;
1269 data.blocks = 1;
1270 data.flags = MMC_DATA_READ;
1271
1272 err = mmc_send_cmd(mmc, &cmd, &data);
1273
1274 if (err) {
1275 if (timeout--)
1276 goto retry_scr;
1277
1278 return err;
1279 }
1280
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001281 mmc->scr[0] = __be32_to_cpu(scr[0]);
1282 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001283
1284 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001285 case 0:
1286 mmc->version = SD_VERSION_1_0;
1287 break;
1288 case 1:
1289 mmc->version = SD_VERSION_1_10;
1290 break;
1291 case 2:
1292 mmc->version = SD_VERSION_2;
1293 if ((mmc->scr[0] >> 15) & 0x1)
1294 mmc->version = SD_VERSION_3;
1295 break;
1296 default:
1297 mmc->version = SD_VERSION_1_0;
1298 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001299 }
1300
Alagu Sankarb44c7082010-05-12 15:08:24 +05301301 if (mmc->scr[0] & SD_DATA_4BIT)
1302 mmc->card_caps |= MMC_MODE_4BIT;
1303
Andy Fleming272cc702008-10-30 16:41:01 -05001304 /* Version 1.0 doesn't support switching */
1305 if (mmc->version == SD_VERSION_1_0)
1306 return 0;
1307
1308 timeout = 4;
1309 while (timeout--) {
1310 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001311 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001312
1313 if (err)
1314 return err;
1315
1316 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001317 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001318 break;
1319 }
1320
Andy Fleming272cc702008-10-30 16:41:01 -05001321 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001322 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1323 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001324
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001325#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001326 /* Version before 3.0 don't support UHS modes */
1327 if (mmc->version < SD_VERSION_3)
1328 return 0;
1329
1330 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1331 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1332 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1333 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1334 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1335 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1336 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1337 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1338 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1339 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1340 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001341#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001342
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001343 return 0;
1344}
1345
1346static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1347{
1348 int err;
1349
1350 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001351 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001352
Marek Vasutcf345762018-11-18 03:25:08 +01001353 /* SD version 1.00 and 1.01 does not support CMD 6 */
1354 if (mmc->version == SD_VERSION_1_0)
1355 return 0;
1356
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001357 switch (mode) {
Faiz Abbase8d5dde2020-02-26 13:44:32 +05301358 case MMC_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001359 speed = UHS_SDR12_BUS_SPEED;
1360 break;
1361 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001362 speed = HIGH_SPEED_BUS_SPEED;
1363 break;
1364#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1365 case UHS_SDR12:
1366 speed = UHS_SDR12_BUS_SPEED;
1367 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001368 case UHS_SDR25:
1369 speed = UHS_SDR25_BUS_SPEED;
1370 break;
1371 case UHS_SDR50:
1372 speed = UHS_SDR50_BUS_SPEED;
1373 break;
1374 case UHS_DDR50:
1375 speed = UHS_DDR50_BUS_SPEED;
1376 break;
1377 case UHS_SDR104:
1378 speed = UHS_SDR104_BUS_SPEED;
1379 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001380#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001381 default:
1382 return -EINVAL;
1383 }
1384
1385 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001386 if (err)
1387 return err;
1388
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001389 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001390 return -ENOTSUPP;
1391
1392 return 0;
1393}
1394
Marek Vasutec360e62018-04-15 00:36:45 +02001395static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001396{
1397 int err;
1398 struct mmc_cmd cmd;
1399
1400 if ((w != 4) && (w != 1))
1401 return -EINVAL;
1402
1403 cmd.cmdidx = MMC_CMD_APP_CMD;
1404 cmd.resp_type = MMC_RSP_R1;
1405 cmd.cmdarg = mmc->rca << 16;
1406
1407 err = mmc_send_cmd(mmc, &cmd, NULL);
1408 if (err)
1409 return err;
1410
1411 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1412 cmd.resp_type = MMC_RSP_R1;
1413 if (w == 4)
1414 cmd.cmdarg = 2;
1415 else if (w == 1)
1416 cmd.cmdarg = 0;
1417 err = mmc_send_cmd(mmc, &cmd, NULL);
1418 if (err)
1419 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001420
1421 return 0;
1422}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001423#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001424
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001425#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001426static int sd_read_ssr(struct mmc *mmc)
1427{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001428 static const unsigned int sd_au_size[] = {
1429 0, SZ_16K / 512, SZ_32K / 512,
1430 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1431 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1432 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1433 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1434 SZ_64M / 512,
1435 };
Peng Fan3697e592016-09-01 11:13:38 +08001436 int err, i;
1437 struct mmc_cmd cmd;
1438 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1439 struct mmc_data data;
1440 int timeout = 3;
1441 unsigned int au, eo, et, es;
1442
1443 cmd.cmdidx = MMC_CMD_APP_CMD;
1444 cmd.resp_type = MMC_RSP_R1;
1445 cmd.cmdarg = mmc->rca << 16;
1446
1447 err = mmc_send_cmd(mmc, &cmd, NULL);
Joel Johnsond4a5fa32020-01-11 09:08:14 -07001448#ifdef CONFIG_MMC_QUIRKS
1449 if (err && (mmc->quirks & MMC_QUIRK_RETRY_APP_CMD)) {
1450 int retries = 4;
1451 /*
1452 * It has been seen that APP_CMD may fail on the first
1453 * attempt, let's try a few more times
1454 */
1455 do {
1456 err = mmc_send_cmd(mmc, &cmd, NULL);
1457 if (!err)
1458 break;
1459 } while (retries--);
1460 }
1461#endif
Peng Fan3697e592016-09-01 11:13:38 +08001462 if (err)
1463 return err;
1464
1465 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1466 cmd.resp_type = MMC_RSP_R1;
1467 cmd.cmdarg = 0;
1468
1469retry_ssr:
1470 data.dest = (char *)ssr;
1471 data.blocksize = 64;
1472 data.blocks = 1;
1473 data.flags = MMC_DATA_READ;
1474
1475 err = mmc_send_cmd(mmc, &cmd, &data);
1476 if (err) {
1477 if (timeout--)
1478 goto retry_ssr;
1479
1480 return err;
1481 }
1482
1483 for (i = 0; i < 16; i++)
1484 ssr[i] = be32_to_cpu(ssr[i]);
1485
1486 au = (ssr[2] >> 12) & 0xF;
1487 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1488 mmc->ssr.au = sd_au_size[au];
1489 es = (ssr[3] >> 24) & 0xFF;
1490 es |= (ssr[2] & 0xFF) << 8;
1491 et = (ssr[3] >> 18) & 0x3F;
1492 if (es && et) {
1493 eo = (ssr[3] >> 16) & 0x3;
1494 mmc->ssr.erase_timeout = (et * 1000) / es;
1495 mmc->ssr.erase_offset = eo * 1000;
1496 }
1497 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001498 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001499 }
1500
1501 return 0;
1502}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001503#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001504/* frequency bases */
1505/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001506static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001507 10000,
1508 100000,
1509 1000000,
1510 10000000,
1511};
1512
1513/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1514 * to platforms without floating point.
1515 */
Simon Glass61fe0762016-05-14 14:02:57 -06001516static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001517 0, /* reserved */
1518 10,
1519 12,
1520 13,
1521 15,
1522 20,
1523 25,
1524 30,
1525 35,
1526 40,
1527 45,
1528 50,
1529 55,
1530 60,
1531 70,
1532 80,
1533};
1534
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001535static inline int bus_width(uint cap)
1536{
1537 if (cap == MMC_MODE_8BIT)
1538 return 8;
1539 if (cap == MMC_MODE_4BIT)
1540 return 4;
1541 if (cap == MMC_MODE_1BIT)
1542 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001543 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001544 return 0;
1545}
1546
Simon Glasse7881d82017-07-29 11:35:31 -06001547#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001548#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001549static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1550{
1551 return -ENOTSUPP;
1552}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001553#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001554
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001555static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001556{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001557 int ret = 0;
1558
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001559 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001560 ret = mmc->cfg->ops->set_ios(mmc);
1561
1562 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001563}
Yann Gautier3602a562019-09-19 17:56:12 +02001564
1565static int mmc_host_power_cycle(struct mmc *mmc)
1566{
1567 int ret = 0;
1568
1569 if (mmc->cfg->ops->host_power_cycle)
1570 ret = mmc->cfg->ops->host_power_cycle(mmc);
1571
1572 return ret;
1573}
Simon Glass8ca51e52016-06-12 23:30:22 -06001574#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001575
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001576int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001577{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001578 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001579 if (clock > mmc->cfg->f_max)
1580 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001581
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001582 if (clock < mmc->cfg->f_min)
1583 clock = mmc->cfg->f_min;
1584 }
Andy Fleming272cc702008-10-30 16:41:01 -05001585
1586 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001587 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001588
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001589 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1590
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001591 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001592}
1593
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001594static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001595{
1596 mmc->bus_width = width;
1597
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001598 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001599}
1600
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001601#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1602/*
1603 * helper function to display the capabilities in a human
1604 * friendly manner. The capabilities include bus width and
1605 * supported modes.
1606 */
1607void mmc_dump_capabilities(const char *text, uint caps)
1608{
1609 enum bus_mode mode;
1610
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001611 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001612 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001613 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001614 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001615 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001616 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001617 pr_debug("1, ");
1618 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001619 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1620 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001621 pr_debug("%s, ", mmc_mode_name(mode));
1622 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001623}
1624#endif
1625
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001626struct mode_width_tuning {
1627 enum bus_mode mode;
1628 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001629#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001630 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001631#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001632};
1633
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001634#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001635int mmc_voltage_to_mv(enum mmc_voltage voltage)
1636{
1637 switch (voltage) {
1638 case MMC_SIGNAL_VOLTAGE_000: return 0;
1639 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1640 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1641 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1642 }
1643 return -EINVAL;
1644}
1645
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001646static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1647{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001648 int err;
1649
1650 if (mmc->signal_voltage == signal_voltage)
1651 return 0;
1652
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001653 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001654 err = mmc_set_ios(mmc);
1655 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001656 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001657
1658 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001659}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001660#else
1661static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1662{
1663 return 0;
1664}
1665#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001666
Marek Vasut62d77ce2018-04-15 00:37:11 +02001667#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001668static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001669#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1670#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001671 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001672 .mode = UHS_SDR104,
1673 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1674 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1675 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001676#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001677 {
1678 .mode = UHS_SDR50,
1679 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1680 },
1681 {
1682 .mode = UHS_DDR50,
1683 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1684 },
1685 {
1686 .mode = UHS_SDR25,
1687 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1688 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001689#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001690 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001691 .mode = SD_HS,
1692 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1693 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001694#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001695 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001696 .mode = UHS_SDR12,
1697 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1698 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001699#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001700 {
Faiz Abbase8d5dde2020-02-26 13:44:32 +05301701 .mode = MMC_LEGACY,
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001702 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1703 }
1704};
1705
1706#define for_each_sd_mode_by_pref(caps, mwt) \
1707 for (mwt = sd_modes_by_pref;\
1708 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1709 mwt++) \
1710 if (caps & MMC_CAP(mwt->mode))
1711
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001712static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001713{
1714 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001715 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1716 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001717#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001718 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001719#else
1720 bool uhs_en = false;
1721#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001722 uint caps;
1723
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001724#ifdef DEBUG
1725 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001726 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001727#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001728
Anup Patelf49ff792019-07-08 04:10:43 +00001729 if (mmc_host_is_spi(mmc)) {
1730 mmc_set_bus_width(mmc, 1);
Faiz Abbase8d5dde2020-02-26 13:44:32 +05301731 mmc_select_mode(mmc, MMC_LEGACY);
Anup Patelf49ff792019-07-08 04:10:43 +00001732 mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
1733 return 0;
1734 }
1735
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001736 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001737 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001738
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001739 if (!uhs_en)
1740 caps &= ~UHS_CAPS;
1741
1742 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001743 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001744
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001745 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001746 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001747 pr_debug("trying mode %s width %d (at %d MHz)\n",
1748 mmc_mode_name(mwt->mode),
1749 bus_width(*w),
1750 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001751
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001752 /* configure the bus width (card + host) */
1753 err = sd_select_bus_width(mmc, bus_width(*w));
1754 if (err)
1755 goto error;
1756 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001757
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001758 /* configure the bus mode (card) */
1759 err = sd_set_card_speed(mmc, mwt->mode);
1760 if (err)
1761 goto error;
1762
1763 /* configure the bus mode (host) */
1764 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001765 mmc_set_clock(mmc, mmc->tran_speed,
1766 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001767
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001768#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001769 /* execute tuning if needed */
1770 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1771 err = mmc_execute_tuning(mmc,
1772 mwt->tuning);
1773 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001774 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001775 goto error;
1776 }
1777 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001778#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001779
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001780#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001781 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001782 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001783 pr_warn("unable to read ssr\n");
1784#endif
1785 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001786 return 0;
1787
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001788error:
1789 /* revert to a safer bus speed */
Faiz Abbase8d5dde2020-02-26 13:44:32 +05301790 mmc_select_mode(mmc, MMC_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001791 mmc_set_clock(mmc, mmc->tran_speed,
1792 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001793 }
1794 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001795 }
1796
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001797 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001798 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001799}
1800
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001801/*
1802 * read the compare the part of ext csd that is constant.
1803 * This can be used to check that the transfer is working
1804 * as expected.
1805 */
1806static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1807{
1808 int err;
1809 const u8 *ext_csd = mmc->ext_csd;
1810 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1811
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001812 if (mmc->version < MMC_VERSION_4)
1813 return 0;
1814
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001815 err = mmc_send_ext_csd(mmc, test_csd);
1816 if (err)
1817 return err;
1818
1819 /* Only compare read only fields */
1820 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1821 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1822 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1823 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1824 ext_csd[EXT_CSD_REV]
1825 == test_csd[EXT_CSD_REV] &&
1826 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1827 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1828 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1829 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1830 return 0;
1831
1832 return -EBADMSG;
1833}
1834
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001835#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001836static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1837 uint32_t allowed_mask)
1838{
1839 u32 card_mask = 0;
1840
1841 switch (mode) {
Peng Fan44acd492019-07-10 14:43:07 +08001842 case MMC_HS_400_ES:
Peng Fan3dd26262018-08-10 14:07:54 +08001843 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001844 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001845 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1846 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001847 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001848 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1849 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001850 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1851 break;
1852 case MMC_DDR_52:
1853 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1854 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1855 MMC_SIGNAL_VOLTAGE_180;
1856 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1857 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1858 break;
1859 default:
1860 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1861 break;
1862 }
1863
1864 while (card_mask & allowed_mask) {
1865 enum mmc_voltage best_match;
1866
1867 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1868 if (!mmc_set_signal_voltage(mmc, best_match))
1869 return 0;
1870
1871 allowed_mask &= ~best_match;
1872 }
1873
1874 return -ENOTSUPP;
1875}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001876#else
1877static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1878 uint32_t allowed_mask)
1879{
1880 return 0;
1881}
1882#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001883
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001884static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan44acd492019-07-10 14:43:07 +08001885#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
1886 {
1887 .mode = MMC_HS_400_ES,
1888 .widths = MMC_MODE_8BIT,
1889 },
1890#endif
Peng Fan3dd26262018-08-10 14:07:54 +08001891#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1892 {
1893 .mode = MMC_HS_400,
1894 .widths = MMC_MODE_8BIT,
1895 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1896 },
1897#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001898#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001899 {
1900 .mode = MMC_HS_200,
1901 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001902 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001903 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001904#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001905 {
1906 .mode = MMC_DDR_52,
1907 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1908 },
1909 {
1910 .mode = MMC_HS_52,
1911 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1912 },
1913 {
1914 .mode = MMC_HS,
1915 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1916 },
1917 {
1918 .mode = MMC_LEGACY,
1919 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1920 }
1921};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001922
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001923#define for_each_mmc_mode_by_pref(caps, mwt) \
1924 for (mwt = mmc_modes_by_pref;\
1925 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1926 mwt++) \
1927 if (caps & MMC_CAP(mwt->mode))
1928
1929static const struct ext_csd_bus_width {
1930 uint cap;
1931 bool is_ddr;
1932 uint ext_csd_bits;
1933} ext_csd_bus_width[] = {
1934 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1935 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1936 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1937 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1938 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1939};
1940
Peng Fan3dd26262018-08-10 14:07:54 +08001941#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1942static int mmc_select_hs400(struct mmc *mmc)
1943{
1944 int err;
1945
1946 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001947 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001948 if (err)
1949 return err;
1950
1951 /* configure the bus mode (host) */
1952 mmc_select_mode(mmc, MMC_HS_200);
1953 mmc_set_clock(mmc, mmc->tran_speed, false);
1954
1955 /* execute tuning if needed */
1956 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1957 if (err) {
1958 debug("tuning failed\n");
1959 return err;
1960 }
1961
1962 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001963 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001964
1965 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1966 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1967 if (err)
1968 return err;
1969
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001970 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001971 if (err)
1972 return err;
1973
1974 mmc_select_mode(mmc, MMC_HS_400);
1975 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1976 if (err)
1977 return err;
1978
1979 return 0;
1980}
1981#else
1982static int mmc_select_hs400(struct mmc *mmc)
1983{
1984 return -ENOTSUPP;
1985}
1986#endif
1987
Peng Fan44acd492019-07-10 14:43:07 +08001988#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
1989#if !CONFIG_IS_ENABLED(DM_MMC)
1990static int mmc_set_enhanced_strobe(struct mmc *mmc)
1991{
1992 return -ENOTSUPP;
1993}
1994#endif
1995static int mmc_select_hs400es(struct mmc *mmc)
1996{
1997 int err;
1998
1999 err = mmc_set_card_speed(mmc, MMC_HS, true);
2000 if (err)
2001 return err;
2002
2003 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
2004 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG |
2005 EXT_CSD_BUS_WIDTH_STROBE);
2006 if (err) {
2007 printf("switch to bus width for hs400 failed\n");
2008 return err;
2009 }
2010 /* TODO: driver strength */
2011 err = mmc_set_card_speed(mmc, MMC_HS_400_ES, false);
2012 if (err)
2013 return err;
2014
2015 mmc_select_mode(mmc, MMC_HS_400_ES);
2016 err = mmc_set_clock(mmc, mmc->tran_speed, false);
2017 if (err)
2018 return err;
2019
2020 return mmc_set_enhanced_strobe(mmc);
2021}
2022#else
2023static int mmc_select_hs400es(struct mmc *mmc)
2024{
2025 return -ENOTSUPP;
2026}
2027#endif
2028
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002029#define for_each_supported_width(caps, ddr, ecbv) \
2030 for (ecbv = ext_csd_bus_width;\
2031 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
2032 ecbv++) \
2033 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
2034
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002035static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002036{
2037 int err;
2038 const struct mode_width_tuning *mwt;
2039 const struct ext_csd_bus_width *ecbw;
2040
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01002041#ifdef DEBUG
2042 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01002043 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01002044#endif
2045
Anup Patelf49ff792019-07-08 04:10:43 +00002046 if (mmc_host_is_spi(mmc)) {
2047 mmc_set_bus_width(mmc, 1);
2048 mmc_select_mode(mmc, MMC_LEGACY);
2049 mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
2050 return 0;
2051 }
2052
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002053 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01002054 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002055
2056 /* Only version 4 of MMC supports wider bus widths */
2057 if (mmc->version < MMC_VERSION_4)
2058 return 0;
2059
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002060 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002061 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002062 return -ENOTSUPP;
2063 }
2064
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002065#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2066 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2067 /*
2068 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
2069 * before doing anything else, since a transition from either of
2070 * the HS200/HS400 mode directly to legacy mode is not supported.
2071 */
2072 if (mmc->selected_mode == MMC_HS_200 ||
2073 mmc->selected_mode == MMC_HS_400)
2074 mmc_set_card_speed(mmc, MMC_HS, true);
2075 else
2076#endif
2077 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002078
2079 for_each_mmc_mode_by_pref(card_caps, mwt) {
2080 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002081 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002082 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002083 pr_debug("trying mode %s width %d (at %d MHz)\n",
2084 mmc_mode_name(mwt->mode),
2085 bus_width(ecbw->cap),
2086 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002087 old_voltage = mmc->signal_voltage;
2088 err = mmc_set_lowest_voltage(mmc, mwt->mode,
2089 MMC_ALL_SIGNAL_VOLTAGE);
2090 if (err)
2091 continue;
2092
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002093 /* configure the bus width (card + host) */
2094 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2095 EXT_CSD_BUS_WIDTH,
2096 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
2097 if (err)
2098 goto error;
2099 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
2100
Peng Fan3dd26262018-08-10 14:07:54 +08002101 if (mwt->mode == MMC_HS_400) {
2102 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002103 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08002104 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002105 goto error;
2106 }
Peng Fan44acd492019-07-10 14:43:07 +08002107 } else if (mwt->mode == MMC_HS_400_ES) {
2108 err = mmc_select_hs400es(mmc);
2109 if (err) {
2110 printf("Select HS400ES failed %d\n",
2111 err);
2112 goto error;
2113 }
Peng Fan3dd26262018-08-10 14:07:54 +08002114 } else {
2115 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002116 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002117 if (err)
2118 goto error;
2119
2120 /*
2121 * configure the bus width AND the ddr mode
2122 * (card). The host side will be taken care
2123 * of in the next step
2124 */
2125 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2126 err = mmc_switch(mmc,
2127 EXT_CSD_CMD_SET_NORMAL,
2128 EXT_CSD_BUS_WIDTH,
2129 ecbw->ext_csd_bits);
2130 if (err)
2131 goto error;
2132 }
2133
2134 /* configure the bus mode (host) */
2135 mmc_select_mode(mmc, mwt->mode);
2136 mmc_set_clock(mmc, mmc->tran_speed,
2137 MMC_CLK_ENABLE);
2138#ifdef MMC_SUPPORTS_TUNING
2139
2140 /* execute tuning if needed */
2141 if (mwt->tuning) {
2142 err = mmc_execute_tuning(mmc,
2143 mwt->tuning);
2144 if (err) {
2145 pr_debug("tuning failed\n");
2146 goto error;
2147 }
2148 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002149#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002150 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002151
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002152 /* do a transfer to check the configuration */
2153 err = mmc_read_and_compare_ext_csd(mmc);
2154 if (!err)
2155 return 0;
2156error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002157 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002158 /* if an error occured, revert to a safer bus mode */
2159 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2160 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2161 mmc_select_mode(mmc, MMC_LEGACY);
2162 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002163 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002164 }
2165
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002166 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002167
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002168 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002169}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002170#endif
2171
2172#if CONFIG_IS_ENABLED(MMC_TINY)
2173DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2174#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002175
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002176static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002177{
2178 int err, i;
2179 u64 capacity;
2180 bool has_parts = false;
2181 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002182 static const u32 mmc_versions[] = {
2183 MMC_VERSION_4,
2184 MMC_VERSION_4_1,
2185 MMC_VERSION_4_2,
2186 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002187 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002188 MMC_VERSION_4_41,
2189 MMC_VERSION_4_5,
2190 MMC_VERSION_5_0,
2191 MMC_VERSION_5_1
2192 };
2193
Marek Vasut62d77ce2018-04-15 00:37:11 +02002194#if CONFIG_IS_ENABLED(MMC_TINY)
2195 u8 *ext_csd = ext_csd_bkup;
2196
2197 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2198 return 0;
2199
2200 if (!mmc->ext_csd)
2201 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2202
2203 err = mmc_send_ext_csd(mmc, ext_csd);
2204 if (err)
2205 goto error;
2206
2207 /* store the ext csd for future reference */
2208 if (!mmc->ext_csd)
2209 mmc->ext_csd = ext_csd;
2210#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002211 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002212
2213 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2214 return 0;
2215
2216 /* check ext_csd version and capacity */
2217 err = mmc_send_ext_csd(mmc, ext_csd);
2218 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002219 goto error;
2220
2221 /* store the ext csd for future reference */
2222 if (!mmc->ext_csd)
2223 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2224 if (!mmc->ext_csd)
2225 return -ENOMEM;
2226 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002227#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002228 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002229 return -EINVAL;
2230
2231 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2232
2233 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002234 /*
2235 * According to the JEDEC Standard, the value of
2236 * ext_csd's capacity is valid if the value is more
2237 * than 2GB
2238 */
2239 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2240 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2241 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2242 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2243 capacity *= MMC_MAX_BLOCK_LEN;
2244 if ((capacity >> 20) > 2 * 1024)
2245 mmc->capacity_user = capacity;
2246 }
2247
Jean-Jacques Hiblot39320c52019-07-02 10:53:54 +02002248 if (mmc->version >= MMC_VERSION_4_5)
2249 mmc->gen_cmd6_time = ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
2250
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002251 /* The partition data may be non-zero but it is only
2252 * effective if PARTITION_SETTING_COMPLETED is set in
2253 * EXT_CSD, so ignore any data if this bit is not set,
2254 * except for enabling the high-capacity group size
2255 * definition (see below).
2256 */
2257 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2258 EXT_CSD_PARTITION_SETTING_COMPLETED);
2259
Jean-Jacques Hiblot513e00b2019-07-02 10:53:55 +02002260 mmc->part_switch_time = ext_csd[EXT_CSD_PART_SWITCH_TIME];
2261 /* Some eMMC set the value too low so set a minimum */
2262 if (mmc->part_switch_time < MMC_MIN_PART_SWITCH_TIME && mmc->part_switch_time)
2263 mmc->part_switch_time = MMC_MIN_PART_SWITCH_TIME;
2264
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002265 /* store the partition info of emmc */
2266 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2267 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2268 ext_csd[EXT_CSD_BOOT_MULT])
2269 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2270 if (part_completed &&
2271 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2272 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2273
2274 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2275
2276 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2277
2278 for (i = 0; i < 4; i++) {
2279 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2280 uint mult = (ext_csd[idx + 2] << 16) +
2281 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2282 if (mult)
2283 has_parts = true;
2284 if (!part_completed)
2285 continue;
2286 mmc->capacity_gp[i] = mult;
2287 mmc->capacity_gp[i] *=
2288 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2289 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2290 mmc->capacity_gp[i] <<= 19;
2291 }
2292
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002293#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002294 if (part_completed) {
2295 mmc->enh_user_size =
2296 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2297 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2298 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2299 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2300 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2301 mmc->enh_user_size <<= 19;
2302 mmc->enh_user_start =
2303 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2304 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2305 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2306 ext_csd[EXT_CSD_ENH_START_ADDR];
2307 if (mmc->high_capacity)
2308 mmc->enh_user_start <<= 9;
2309 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002310#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002311
2312 /*
2313 * Host needs to enable ERASE_GRP_DEF bit if device is
2314 * partitioned. This bit will be lost every time after a reset
2315 * or power off. This will affect erase size.
2316 */
2317 if (part_completed)
2318 has_parts = true;
2319 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2320 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2321 has_parts = true;
2322 if (has_parts) {
2323 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2324 EXT_CSD_ERASE_GROUP_DEF, 1);
2325
2326 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002327 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002328
2329 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2330 }
2331
2332 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002333#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002334 /* Read out group size from ext_csd */
2335 mmc->erase_grp_size =
2336 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002337#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002338 /*
2339 * if high capacity and partition setting completed
2340 * SEC_COUNT is valid even if it is smaller than 2 GiB
2341 * JEDEC Standard JESD84-B45, 6.2.4
2342 */
2343 if (mmc->high_capacity && part_completed) {
2344 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2345 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2346 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2347 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2348 capacity *= MMC_MAX_BLOCK_LEN;
2349 mmc->capacity_user = capacity;
2350 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002351 }
2352#if CONFIG_IS_ENABLED(MMC_WRITE)
2353 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002354 /* Calculate the group size from the csd value. */
2355 int erase_gsz, erase_gmul;
2356
2357 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2358 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2359 mmc->erase_grp_size = (erase_gsz + 1)
2360 * (erase_gmul + 1);
2361 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002362#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002363#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002364 mmc->hc_wp_grp_size = 1024
2365 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2366 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002367#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002368
2369 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2370
2371 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002372error:
2373 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002374#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002375 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002376#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002377 mmc->ext_csd = NULL;
2378 }
2379 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002380}
2381
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002382static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002383{
Stephen Warrenf866a462013-06-11 15:14:01 -06002384 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002385 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002386 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002387 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002388 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002389
Thomas Choud52ebf12010-12-24 13:12:21 +00002390#ifdef CONFIG_MMC_SPI_CRC_ON
2391 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2392 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2393 cmd.resp_type = MMC_RSP_R1;
2394 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002395 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002396 if (err)
2397 return err;
2398 }
2399#endif
2400
Andy Fleming272cc702008-10-30 16:41:01 -05002401 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002402 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2403 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002404 cmd.resp_type = MMC_RSP_R2;
2405 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002406
2407 err = mmc_send_cmd(mmc, &cmd, NULL);
2408
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002409#ifdef CONFIG_MMC_QUIRKS
2410 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2411 int retries = 4;
2412 /*
2413 * It has been seen that SEND_CID may fail on the first
2414 * attempt, let's try a few more time
2415 */
2416 do {
2417 err = mmc_send_cmd(mmc, &cmd, NULL);
2418 if (!err)
2419 break;
2420 } while (retries--);
2421 }
2422#endif
2423
Andy Fleming272cc702008-10-30 16:41:01 -05002424 if (err)
2425 return err;
2426
2427 memcpy(mmc->cid, cmd.response, 16);
2428
2429 /*
2430 * For MMC cards, set the Relative Address.
2431 * For SD cards, get the Relatvie Address.
2432 * This also puts the cards into Standby State
2433 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002434 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2435 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2436 cmd.cmdarg = mmc->rca << 16;
2437 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002438
Thomas Choud52ebf12010-12-24 13:12:21 +00002439 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002440
Thomas Choud52ebf12010-12-24 13:12:21 +00002441 if (err)
2442 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002443
Thomas Choud52ebf12010-12-24 13:12:21 +00002444 if (IS_SD(mmc))
2445 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2446 }
Andy Fleming272cc702008-10-30 16:41:01 -05002447
2448 /* Get the Card-Specific Data */
2449 cmd.cmdidx = MMC_CMD_SEND_CSD;
2450 cmd.resp_type = MMC_RSP_R2;
2451 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002452
2453 err = mmc_send_cmd(mmc, &cmd, NULL);
2454
2455 if (err)
2456 return err;
2457
Rabin Vincent998be3d2009-04-05 13:30:56 +05302458 mmc->csd[0] = cmd.response[0];
2459 mmc->csd[1] = cmd.response[1];
2460 mmc->csd[2] = cmd.response[2];
2461 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002462
2463 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302464 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002465
2466 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002467 case 0:
2468 mmc->version = MMC_VERSION_1_2;
2469 break;
2470 case 1:
2471 mmc->version = MMC_VERSION_1_4;
2472 break;
2473 case 2:
2474 mmc->version = MMC_VERSION_2_2;
2475 break;
2476 case 3:
2477 mmc->version = MMC_VERSION_3;
2478 break;
2479 case 4:
2480 mmc->version = MMC_VERSION_4;
2481 break;
2482 default:
2483 mmc->version = MMC_VERSION_1_2;
2484 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002485 }
2486 }
2487
2488 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302489 freq = fbase[(cmd.response[0] & 0x7)];
2490 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002491
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002492 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002493 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002494
Markus Niebelab711882013-12-16 13:40:46 +01002495 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302496 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002497#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002498
2499 if (IS_SD(mmc))
2500 mmc->write_bl_len = mmc->read_bl_len;
2501 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302502 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002503#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002504
2505 if (mmc->high_capacity) {
2506 csize = (mmc->csd[1] & 0x3f) << 16
2507 | (mmc->csd[2] & 0xffff0000) >> 16;
2508 cmult = 8;
2509 } else {
2510 csize = (mmc->csd[1] & 0x3ff) << 2
2511 | (mmc->csd[2] & 0xc0000000) >> 30;
2512 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2513 }
2514
Stephen Warrenf866a462013-06-11 15:14:01 -06002515 mmc->capacity_user = (csize + 1) << (cmult + 2);
2516 mmc->capacity_user *= mmc->read_bl_len;
2517 mmc->capacity_boot = 0;
2518 mmc->capacity_rpmb = 0;
2519 for (i = 0; i < 4; i++)
2520 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002521
Simon Glass8bfa1952013-04-03 08:54:30 +00002522 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2523 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002524
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002525#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002526 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2527 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002528#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002529
Markus Niebelab711882013-12-16 13:40:46 +01002530 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2531 cmd.cmdidx = MMC_CMD_SET_DSR;
2532 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2533 cmd.resp_type = MMC_RSP_NONE;
2534 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002535 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002536 }
2537
Andy Fleming272cc702008-10-30 16:41:01 -05002538 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002539 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2540 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002541 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002542 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002543 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002544
Thomas Choud52ebf12010-12-24 13:12:21 +00002545 if (err)
2546 return err;
2547 }
Andy Fleming272cc702008-10-30 16:41:01 -05002548
Lei Wene6f99a52011-06-22 17:03:31 +00002549 /*
2550 * For SD, its erase group is always one sector
2551 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002552#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002553 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002554#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002555 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002556
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002557 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002558 if (err)
2559 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302560
Simon Glassc40fdca2016-05-01 13:52:35 -06002561 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002562 if (err)
2563 return err;
2564
Marek Vasut62d77ce2018-04-15 00:37:11 +02002565#if CONFIG_IS_ENABLED(MMC_TINY)
2566 mmc_set_clock(mmc, mmc->legacy_speed, false);
Faiz Abbase8d5dde2020-02-26 13:44:32 +05302567 mmc_select_mode(mmc, MMC_LEGACY);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002568 mmc_set_bus_width(mmc, 1);
2569#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002570 if (IS_SD(mmc)) {
2571 err = sd_get_capabilities(mmc);
2572 if (err)
2573 return err;
2574 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2575 } else {
2576 err = mmc_get_capabilities(mmc);
2577 if (err)
2578 return err;
Masahiro Yamada8adf50e2020-01-23 14:31:12 +09002579 err = mmc_select_mode_and_width(mmc, mmc->card_caps);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002580 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002581#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002582 if (err)
2583 return err;
2584
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002585 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002586
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002587 /* Fix the block length for DDR mode */
2588 if (mmc->ddr_mode) {
2589 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002590#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002591 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002592#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002593 }
2594
Andy Fleming272cc702008-10-30 16:41:01 -05002595 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002596 bdesc = mmc_get_blk_desc(mmc);
2597 bdesc->lun = 0;
2598 bdesc->hwpart = 0;
2599 bdesc->type = 0;
2600 bdesc->blksz = mmc->read_bl_len;
2601 bdesc->log2blksz = LOG2(bdesc->blksz);
2602 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002603#if !defined(CONFIG_SPL_BUILD) || \
2604 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
Simon Glass27084c02019-09-25 08:56:27 -06002605 !CONFIG_IS_ENABLED(USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002606 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002607 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2608 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002609 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002610 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2611 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2612 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002613 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002614 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002615#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002616 bdesc->vendor[0] = 0;
2617 bdesc->product[0] = 0;
2618 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002619#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002620
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002621#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2622 part_init(bdesc);
2623#endif
2624
Andy Fleming272cc702008-10-30 16:41:01 -05002625 return 0;
2626}
2627
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002628static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002629{
2630 struct mmc_cmd cmd;
2631 int err;
2632
2633 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2634 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002635 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002636 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002637
2638 err = mmc_send_cmd(mmc, &cmd, NULL);
2639
2640 if (err)
2641 return err;
2642
Rabin Vincent998be3d2009-04-05 13:30:56 +05302643 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002644 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002645 else
2646 mmc->version = SD_VERSION_2;
2647
2648 return 0;
2649}
2650
Simon Glassc4d660d2017-07-04 13:31:19 -06002651#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002652/* board-specific MMC power initializations. */
2653__weak void board_mmc_power_init(void)
2654{
2655}
Simon Glass05cbeb72017-04-22 19:10:56 -06002656#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002657
Peng Fan2051aef2016-10-11 15:08:43 +08002658static int mmc_power_init(struct mmc *mmc)
2659{
Simon Glassc4d660d2017-07-04 13:31:19 -06002660#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002661#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002662 int ret;
2663
2664 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002665 &mmc->vmmc_supply);
2666 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002667 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002668
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002669 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2670 &mmc->vqmmc_supply);
2671 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002672 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002673#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002674#else /* !CONFIG_DM_MMC */
2675 /*
2676 * Driver model should use a regulator, as above, rather than calling
2677 * out to board code.
2678 */
2679 board_mmc_power_init();
2680#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002681 return 0;
2682}
2683
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002684/*
2685 * put the host in the initial state:
2686 * - turn on Vdd (card power supply)
2687 * - configure the bus width and clock to minimal values
2688 */
2689static void mmc_set_initial_state(struct mmc *mmc)
2690{
2691 int err;
2692
2693 /* First try to set 3.3V. If it fails set to 1.8V */
2694 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2695 if (err != 0)
2696 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2697 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002698 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002699
2700 mmc_select_mode(mmc, MMC_LEGACY);
2701 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002702 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002703}
2704
2705static int mmc_power_on(struct mmc *mmc)
2706{
2707#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2708 if (mmc->vmmc_supply) {
2709 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2710
2711 if (ret) {
2712 puts("Error enabling VMMC supply\n");
2713 return ret;
2714 }
2715 }
2716#endif
2717 return 0;
2718}
2719
2720static int mmc_power_off(struct mmc *mmc)
2721{
Jaehoon Chung65117182018-01-26 19:25:29 +09002722 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002723#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2724 if (mmc->vmmc_supply) {
2725 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2726
2727 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002728 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002729 return ret;
2730 }
2731 }
2732#endif
2733 return 0;
2734}
2735
2736static int mmc_power_cycle(struct mmc *mmc)
2737{
2738 int ret;
2739
2740 ret = mmc_power_off(mmc);
2741 if (ret)
2742 return ret;
Yann Gautier3602a562019-09-19 17:56:12 +02002743
2744 ret = mmc_host_power_cycle(mmc);
2745 if (ret)
2746 return ret;
2747
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002748 /*
2749 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2750 * to be on the safer side.
2751 */
2752 udelay(2000);
2753 return mmc_power_on(mmc);
2754}
2755
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002756int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002757{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002758 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002759 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002760
Lei Wenbc897b12011-05-02 16:26:26 +00002761 if (mmc->has_init)
2762 return 0;
2763
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002764#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2765 mmc_adapter_card_type_ident();
2766#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002767 err = mmc_power_init(mmc);
2768 if (err)
2769 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002770
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002771#ifdef CONFIG_MMC_QUIRKS
2772 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
Joel Johnsond4a5fa32020-01-11 09:08:14 -07002773 MMC_QUIRK_RETRY_SEND_CID |
2774 MMC_QUIRK_RETRY_APP_CMD;
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002775#endif
2776
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002777 err = mmc_power_cycle(mmc);
2778 if (err) {
2779 /*
2780 * if power cycling is not supported, we should not try
2781 * to use the UHS modes, because we wouldn't be able to
2782 * recover from an error during the UHS initialization.
2783 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002784 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002785 uhs_en = false;
2786 mmc->host_caps &= ~UHS_CAPS;
2787 err = mmc_power_on(mmc);
2788 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002789 if (err)
2790 return err;
2791
Simon Glasse7881d82017-07-29 11:35:31 -06002792#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002793 /* The device has already been probed ready for use */
2794#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002795 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002796 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002797 if (err)
2798 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002799#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002800 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002801
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002802retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002803 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002804
Andy Fleming272cc702008-10-30 16:41:01 -05002805 /* Reset the Card */
2806 err = mmc_go_idle(mmc);
2807
2808 if (err)
2809 return err;
2810
Lei Wenbc897b12011-05-02 16:26:26 +00002811 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002812 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002813
Andy Fleming272cc702008-10-30 16:41:01 -05002814 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002815 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002816
Andy Fleming272cc702008-10-30 16:41:01 -05002817 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002818 err = sd_send_op_cond(mmc, uhs_en);
2819 if (err && uhs_en) {
2820 uhs_en = false;
2821 mmc_power_cycle(mmc);
2822 goto retry;
2823 }
Andy Fleming272cc702008-10-30 16:41:01 -05002824
2825 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002826 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002827 err = mmc_send_op_cond(mmc);
2828
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002829 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002830#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002831 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002832#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002833 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002834 }
2835 }
2836
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002837 return err;
2838}
2839
2840int mmc_start_init(struct mmc *mmc)
2841{
2842 bool no_card;
2843 int err = 0;
2844
2845 /*
2846 * all hosts are capable of 1 bit bus-width and able to use the legacy
2847 * timings.
2848 */
Faiz Abbase8d5dde2020-02-26 13:44:32 +05302849 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(MMC_LEGACY) |
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002850 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
Faiz Abbas32860bd2020-02-26 13:44:30 +05302851#if CONFIG_IS_ENABLED(DM_MMC)
2852 mmc_deferred_probe(mmc);
2853#endif
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002854#if !defined(CONFIG_MMC_BROKEN_CD)
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002855 no_card = mmc_getcd(mmc) == 0;
2856#else
2857 no_card = 0;
2858#endif
2859#if !CONFIG_IS_ENABLED(DM_MMC)
Baruch Siachfea39392019-07-22 15:52:12 +03002860 /* we pretend there's no card when init is NULL */
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002861 no_card = no_card || (mmc->cfg->ops->init == NULL);
2862#endif
2863 if (no_card) {
2864 mmc->has_init = 0;
2865#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2866 pr_err("MMC: no card present\n");
2867#endif
2868 return -ENOMEDIUM;
2869 }
2870
2871 err = mmc_get_op_cond(mmc);
2872
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002873 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002874 mmc->init_in_progress = 1;
2875
2876 return err;
2877}
2878
2879static int mmc_complete_init(struct mmc *mmc)
2880{
2881 int err = 0;
2882
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002883 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002884 if (mmc->op_cond_pending)
2885 err = mmc_complete_op_cond(mmc);
2886
2887 if (!err)
2888 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002889 if (err)
2890 mmc->has_init = 0;
2891 else
2892 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002893 return err;
2894}
2895
2896int mmc_init(struct mmc *mmc)
2897{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002898 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302899 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002900#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002901 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002902
Simon Glass33fb2112016-05-01 13:52:41 -06002903 upriv->mmc = mmc;
2904#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002905 if (mmc->has_init)
2906 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002907
2908 start = get_timer(0);
2909
Che-Liang Chioue9550442012-11-28 15:21:13 +00002910 if (!mmc->init_in_progress)
2911 err = mmc_start_init(mmc);
2912
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002913 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002914 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002915 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002916 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002917
Lei Wenbc897b12011-05-02 16:26:26 +00002918 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002919}
2920
Marek Vasutfceea992019-01-29 04:45:51 +01002921#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2922 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2923 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2924int mmc_deinit(struct mmc *mmc)
2925{
2926 u32 caps_filtered;
2927
2928 if (!mmc->has_init)
2929 return 0;
2930
2931 if (IS_SD(mmc)) {
2932 caps_filtered = mmc->card_caps &
2933 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2934 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2935 MMC_CAP(UHS_SDR104));
2936
2937 return sd_select_mode_and_width(mmc, caps_filtered);
2938 } else {
2939 caps_filtered = mmc->card_caps &
2940 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2941
2942 return mmc_select_mode_and_width(mmc, caps_filtered);
2943 }
2944}
2945#endif
2946
Markus Niebelab711882013-12-16 13:40:46 +01002947int mmc_set_dsr(struct mmc *mmc, u16 val)
2948{
2949 mmc->dsr = val;
2950 return 0;
2951}
2952
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002953/* CPU-specific MMC initializations */
2954__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002955{
2956 return -1;
2957}
2958
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002959/* board-specific MMC initializations. */
2960__weak int board_mmc_init(bd_t *bis)
2961{
2962 return -1;
2963}
Andy Fleming272cc702008-10-30 16:41:01 -05002964
Che-Liang Chioue9550442012-11-28 15:21:13 +00002965void mmc_set_preinit(struct mmc *mmc, int preinit)
2966{
2967 mmc->preinit = preinit;
2968}
2969
Faiz Abbas8a856db2018-02-12 19:35:24 +05302970#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002971static int mmc_probe(bd_t *bis)
2972{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002973 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002974 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002975 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002976
2977 ret = uclass_get(UCLASS_MMC, &uc);
2978 if (ret)
2979 return ret;
2980
Simon Glass4a1db6d2015-12-29 05:22:49 -07002981 /*
2982 * Try to add them in sequence order. Really with driver model we
2983 * should allow holes, but the current MMC list does not allow that.
2984 * So if we request 0, 1, 3 we will get 0, 1, 2.
2985 */
2986 for (i = 0; ; i++) {
2987 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2988 if (ret == -ENODEV)
2989 break;
2990 }
2991 uclass_foreach_dev(dev, uc) {
2992 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002993 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002994 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002995 }
2996
2997 return 0;
2998}
2999#else
3000static int mmc_probe(bd_t *bis)
3001{
3002 if (board_mmc_init(bis) < 0)
3003 cpu_mmc_init(bis);
3004
3005 return 0;
3006}
3007#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00003008
Andy Fleming272cc702008-10-30 16:41:01 -05003009int mmc_initialize(bd_t *bis)
3010{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02003011 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06003012 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02003013 if (initialized) /* Avoid initializing mmc multiple times */
3014 return 0;
3015 initialized = 1;
3016
Simon Glassc4d660d2017-07-04 13:31:19 -06003017#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01003018#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06003019 mmc_list_init();
3020#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01003021#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06003022 ret = mmc_probe(bis);
3023 if (ret)
3024 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05003025
Ying Zhangbb0dc102013-08-16 15:16:11 +08003026#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05003027 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08003028#endif
Andy Fleming272cc702008-10-30 16:41:01 -05003029
Simon Glassc40fdca2016-05-01 13:52:35 -06003030 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05003031 return 0;
3032}
Tomas Melincd3d4882016-11-25 11:01:03 +02003033
Lokesh Vutla80f02012019-09-09 14:40:36 +05303034#if CONFIG_IS_ENABLED(DM_MMC)
3035int mmc_init_device(int num)
3036{
3037 struct udevice *dev;
3038 struct mmc *m;
3039 int ret;
3040
3041 ret = uclass_get_device(UCLASS_MMC, num, &dev);
3042 if (ret)
3043 return ret;
3044
3045 m = mmc_get_mmc_dev(dev);
3046 if (!m)
3047 return 0;
3048#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
3049 mmc_set_preinit(m, 1);
3050#endif
3051 if (m->preinit)
3052 mmc_start_init(m);
3053
3054 return 0;
3055}
3056#endif
3057
Tomas Melincd3d4882016-11-25 11:01:03 +02003058#ifdef CONFIG_CMD_BKOPS_ENABLE
3059int mmc_set_bkops_enable(struct mmc *mmc)
3060{
3061 int err;
3062 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
3063
3064 err = mmc_send_ext_csd(mmc, ext_csd);
3065 if (err) {
3066 puts("Could not get ext_csd register values\n");
3067 return err;
3068 }
3069
3070 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
3071 puts("Background operations not supported on device\n");
3072 return -EMEDIUMTYPE;
3073 }
3074
3075 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
3076 puts("Background operations already enabled\n");
3077 return 0;
3078 }
3079
3080 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
3081 if (err) {
3082 puts("Failed to enable manual background operations\n");
3083 return err;
3084 }
3085
3086 puts("Enabled manual background operations\n");
3087
3088 return 0;
3089}
3090#endif