blob: 36cce79eafe38dbc2065347e5adeb4fcf4a8663e [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
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +020024static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +020025static int mmc_power_cycle(struct mmc *mmc);
Marek Vasut62d77ce2018-04-15 00:37:11 +020026#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +020027static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
Marek Vasutb5b838f2016-12-01 02:06:33 +010028#endif
29
Simon Glasse7881d82017-07-29 11:35:31 -060030#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020031
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +010032#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020033static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
34{
35 return -ENOSYS;
36}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +010037#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +020038
Jeroen Hofstee750121c2014-07-12 21:24:08 +020039__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000040{
41 return -1;
42}
43
44int mmc_getwp(struct mmc *mmc)
45{
46 int wp;
47
48 wp = board_mmc_getwp(mmc);
49
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000050 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020051 if (mmc->cfg->ops->getwp)
52 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000053 else
54 wp = 0;
55 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000056
57 return wp;
58}
59
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020060__weak int board_mmc_getcd(struct mmc *mmc)
61{
Stefano Babic11fdade2010-02-05 15:04:43 +010062 return -1;
63}
Simon Glass8ca51e52016-06-12 23:30:22 -060064#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010065
Marek Vasut8635ff92012-03-15 18:41:35 +000066#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060067void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
68{
69 printf("CMD_SEND:%d\n", cmd->cmdidx);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010070 printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
Simon Glassc0c76eb2016-06-12 23:30:20 -060071}
72
73void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
74{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000075 int i;
76 u8 *ptr;
77
Bin Meng7863ce52016-03-17 21:53:14 -070078 if (ret) {
79 printf("\t\tRET\t\t\t %d\n", ret);
80 } else {
81 switch (cmd->resp_type) {
82 case MMC_RSP_NONE:
83 printf("\t\tMMC_RSP_NONE\n");
84 break;
85 case MMC_RSP_R1:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010086 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070087 cmd->response[0]);
88 break;
89 case MMC_RSP_R1b:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010090 printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070091 cmd->response[0]);
92 break;
93 case MMC_RSP_R2:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010094 printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070095 cmd->response[0]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010096 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070097 cmd->response[1]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010098 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070099 cmd->response[2]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100100 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700101 cmd->response[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000102 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -0700103 printf("\t\t\t\t\tDUMPING DATA\n");
104 for (i = 0; i < 4; i++) {
105 int j;
106 printf("\t\t\t\t\t%03d - ", i*4);
107 ptr = (u8 *)&cmd->response[i];
108 ptr += 3;
109 for (j = 0; j < 4; j++)
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100110 printf("%02x ", *ptr--);
Bin Meng7863ce52016-03-17 21:53:14 -0700111 printf("\n");
112 }
113 break;
114 case MMC_RSP_R3:
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100115 printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700116 cmd->response[0]);
117 break;
118 default:
119 printf("\t\tERROR MMC rsp not supported\n");
120 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700121 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000122 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600123}
124
125void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
126{
127 int status;
128
129 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
130 printf("CURR STATE:%d\n", status);
131}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000132#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600133
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200134#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
135const char *mmc_mode_name(enum bus_mode mode)
136{
137 static const char *const names[] = {
138 [MMC_LEGACY] = "MMC legacy",
139 [SD_LEGACY] = "SD Legacy",
140 [MMC_HS] = "MMC High Speed (26MHz)",
141 [SD_HS] = "SD High Speed (50MHz)",
142 [UHS_SDR12] = "UHS SDR12 (25MHz)",
143 [UHS_SDR25] = "UHS SDR25 (50MHz)",
144 [UHS_SDR50] = "UHS SDR50 (100MHz)",
145 [UHS_SDR104] = "UHS SDR104 (208MHz)",
146 [UHS_DDR50] = "UHS DDR50 (50MHz)",
147 [MMC_HS_52] = "MMC High Speed (52MHz)",
148 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
149 [MMC_HS_200] = "HS200 (200MHz)",
Peng Fan3dd26262018-08-10 14:07:54 +0800150 [MMC_HS_400] = "HS400 (200MHz)",
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200151 };
152
153 if (mode >= MMC_MODES_END)
154 return "Unknown mode";
155 else
156 return names[mode];
157}
158#endif
159
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200160static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
161{
162 static const int freqs[] = {
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900163 [MMC_LEGACY] = 25000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200164 [SD_LEGACY] = 25000000,
165 [MMC_HS] = 26000000,
166 [SD_HS] = 50000000,
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900167 [MMC_HS_52] = 52000000,
168 [MMC_DDR_52] = 52000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200169 [UHS_SDR12] = 25000000,
170 [UHS_SDR25] = 50000000,
171 [UHS_SDR50] = 100000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200172 [UHS_DDR50] = 50000000,
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100173 [UHS_SDR104] = 208000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200174 [MMC_HS_200] = 200000000,
Peng Fan3dd26262018-08-10 14:07:54 +0800175 [MMC_HS_400] = 200000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200176 };
177
178 if (mode == MMC_LEGACY)
179 return mmc->legacy_speed;
180 else if (mode >= MMC_MODES_END)
181 return 0;
182 else
183 return freqs[mode];
184}
185
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200186static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
187{
188 mmc->selected_mode = mode;
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200189 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200190 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900191 pr_debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
192 mmc->tran_speed / 1000000);
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200193 return 0;
194}
195
Simon Glasse7881d82017-07-29 11:35:31 -0600196#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassc0c76eb2016-06-12 23:30:20 -0600197int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
198{
199 int ret;
200
201 mmmc_trace_before_send(mmc, cmd);
202 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
203 mmmc_trace_after_send(mmc, cmd, ret);
204
Marek Vasut8635ff92012-03-15 18:41:35 +0000205 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500206}
Simon Glass8ca51e52016-06-12 23:30:22 -0600207#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500208
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200209int mmc_send_status(struct mmc *mmc, unsigned int *status)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000210{
211 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000212 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000213
214 cmd.cmdidx = MMC_CMD_SEND_STATUS;
215 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200216 if (!mmc_host_is_spi(mmc))
217 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000218
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200219 while (retries--) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000220 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000221 if (!err) {
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200222 mmc_trace_state(mmc, &cmd);
223 *status = cmd.response[0];
224 return 0;
225 }
226 }
227 mmc_trace_state(mmc, &cmd);
228 return -ECOMM;
229}
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200230
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200231int mmc_poll_for_busy(struct mmc *mmc, int timeout)
232{
233 unsigned int status;
234 int err;
235
236 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
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500253 if (timeout-- <= 0)
254 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
Jongman Heo5b0c9422012-06-03 21:32:13 +0000259 if (timeout <= 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
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000721static int 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{
745 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000746 int timeout = 1000;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100747 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000748 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500749
750 cmd.cmdidx = MMC_CMD_SWITCH;
751 cmd.resp_type = MMC_RSP_R1b;
752 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000753 (index << 16) |
754 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500755
Maxime Riparda9003dc2016-11-04 16:18:08 +0100756 while (retries > 0) {
757 ret = mmc_send_cmd(mmc, &cmd, NULL);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000758
Marek Vasut68925502019-02-06 11:34:27 +0100759 if (ret) {
760 retries--;
761 continue;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100762 }
763
Marek Vasut68925502019-02-06 11:34:27 +0100764 if (!send_status) {
765 mdelay(50);
766 return 0;
767 }
768
769 /* Waiting for the ready status */
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200770 return mmc_poll_for_busy(mmc, timeout);
Maxime Riparda9003dc2016-11-04 16:18:08 +0100771 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000772
773 return ret;
774
Andy Fleming272cc702008-10-30 16:41:01 -0500775}
776
Marek Vasut68925502019-02-06 11:34:27 +0100777int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
778{
779 return __mmc_switch(mmc, set, index, value, true);
780}
781
Marek Vasut62d77ce2018-04-15 00:37:11 +0200782#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100783static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
784 bool hsdowngrade)
Andy Fleming272cc702008-10-30 16:41:01 -0500785{
Andy Fleming272cc702008-10-30 16:41:01 -0500786 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200787 int speed_bits;
788
789 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
790
791 switch (mode) {
792 case MMC_HS:
793 case MMC_HS_52:
794 case MMC_DDR_52:
795 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200796 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100797#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200798 case MMC_HS_200:
799 speed_bits = EXT_CSD_TIMING_HS200;
800 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100801#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800802#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
803 case MMC_HS_400:
804 speed_bits = EXT_CSD_TIMING_HS400;
805 break;
806#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200807 case MMC_LEGACY:
808 speed_bits = EXT_CSD_TIMING_LEGACY;
809 break;
810 default:
811 return -EINVAL;
812 }
Marek Vasut68925502019-02-06 11:34:27 +0100813
814 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
815 speed_bits, !hsdowngrade);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200816 if (err)
817 return err;
818
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100819#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
820 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
821 /*
822 * In case the eMMC is in HS200/HS400 mode and we are downgrading
823 * to HS mode, the card clock are still running much faster than
824 * the supported HS mode clock, so we can not reliably read out
825 * Extended CSD. Reconfigure the controller to run at HS mode.
826 */
827 if (hsdowngrade) {
828 mmc_select_mode(mmc, MMC_HS);
829 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
830 }
831#endif
832
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200833 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
834 /* Now check to see that it worked */
835 err = mmc_send_ext_csd(mmc, test_csd);
836 if (err)
837 return err;
838
839 /* No high-speed support */
840 if (!test_csd[EXT_CSD_HS_TIMING])
841 return -ENOTSUPP;
842 }
843
844 return 0;
845}
846
847static int mmc_get_capabilities(struct mmc *mmc)
848{
849 u8 *ext_csd = mmc->ext_csd;
850 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500851
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +0100852 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -0500853
Thomas Choud52ebf12010-12-24 13:12:21 +0000854 if (mmc_host_is_spi(mmc))
855 return 0;
856
Andy Fleming272cc702008-10-30 16:41:01 -0500857 /* Only version 4 supports high-speed */
858 if (mmc->version < MMC_VERSION_4)
859 return 0;
860
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200861 if (!ext_csd) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100862 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200863 return -ENOTSUPP;
864 }
865
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600866 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
867
Peng Fan3dd26262018-08-10 14:07:54 +0800868 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +0200869 mmc->cardtype = cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500870
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100871#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200872 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
873 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
874 mmc->card_caps |= MMC_MODE_HS200;
875 }
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100876#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800877#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
878 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
879 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
880 mmc->card_caps |= MMC_MODE_HS400;
881 }
882#endif
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900883 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200884 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900885 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200886 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900887 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200888 if (cardtype & EXT_CSD_CARD_TYPE_26)
889 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500890
891 return 0;
892}
Marek Vasut62d77ce2018-04-15 00:37:11 +0200893#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500894
Stephen Warrenf866a462013-06-11 15:14:01 -0600895static int mmc_set_capacity(struct mmc *mmc, int part_num)
896{
897 switch (part_num) {
898 case 0:
899 mmc->capacity = mmc->capacity_user;
900 break;
901 case 1:
902 case 2:
903 mmc->capacity = mmc->capacity_boot;
904 break;
905 case 3:
906 mmc->capacity = mmc->capacity_rpmb;
907 break;
908 case 4:
909 case 5:
910 case 6:
911 case 7:
912 mmc->capacity = mmc->capacity_gp[part_num - 4];
913 break;
914 default:
915 return -1;
916 }
917
Simon Glassc40fdca2016-05-01 13:52:35 -0600918 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600919
920 return 0;
921}
922
Marek Vasut72119aa2019-05-31 15:22:44 +0200923#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200924static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
925{
926 int forbidden = 0;
927 bool change = false;
928
929 if (part_num & PART_ACCESS_MASK)
Marek Vasut72119aa2019-05-31 15:22:44 +0200930 forbidden = MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200931
932 if (MMC_CAP(mmc->selected_mode) & forbidden) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900933 pr_debug("selected mode (%s) is forbidden for part %d\n",
934 mmc_mode_name(mmc->selected_mode), part_num);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200935 change = true;
936 } else if (mmc->selected_mode != mmc->best_mode) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900937 pr_debug("selected mode is not optimal\n");
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200938 change = true;
939 }
940
941 if (change)
942 return mmc_select_mode_and_width(mmc,
943 mmc->card_caps & ~forbidden);
944
945 return 0;
946}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100947#else
948static inline int mmc_boot_part_access_chk(struct mmc *mmc,
949 unsigned int part_num)
950{
951 return 0;
952}
953#endif
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200954
Simon Glass7dba0b92016-06-12 23:30:15 -0600955int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000956{
Stephen Warrenf866a462013-06-11 15:14:01 -0600957 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000958
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200959 ret = mmc_boot_part_access_chk(mmc, part_num);
960 if (ret)
961 return ret;
962
Stephen Warrenf866a462013-06-11 15:14:01 -0600963 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
964 (mmc->part_config & ~PART_ACCESS_MASK)
965 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600966
Peter Bigot6dc93e72014-09-02 18:31:23 -0500967 /*
968 * Set the capacity if the switch succeeded or was intended
969 * to return to representing the raw device.
970 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700971 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500972 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600973 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700974 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500975
976 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000977}
978
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100979#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100980int mmc_hwpart_config(struct mmc *mmc,
981 const struct mmc_hwpart_conf *conf,
982 enum mmc_hwpart_conf_mode mode)
983{
984 u8 part_attrs = 0;
985 u32 enh_size_mult;
986 u32 enh_start_addr;
987 u32 gp_size_mult[4];
988 u32 max_enh_size_mult;
989 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100990 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100991 int i, pidx, err;
992 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
993
994 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
995 return -EINVAL;
996
997 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100998 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100999 return -EMEDIUMTYPE;
1000 }
1001
1002 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001003 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001004 return -EMEDIUMTYPE;
1005 }
1006
1007 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001008 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001009 return -EMEDIUMTYPE;
1010 }
1011
1012 /* check partition alignment and total enhanced size */
1013 if (conf->user.enh_size) {
1014 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1015 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001016 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001017 "size aligned\n");
1018 return -EINVAL;
1019 }
1020 part_attrs |= EXT_CSD_ENH_USR;
1021 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1022 if (mmc->high_capacity) {
1023 enh_start_addr = conf->user.enh_start;
1024 } else {
1025 enh_start_addr = (conf->user.enh_start << 9);
1026 }
1027 } else {
1028 enh_size_mult = 0;
1029 enh_start_addr = 0;
1030 }
1031 tot_enh_size_mult += enh_size_mult;
1032
1033 for (pidx = 0; pidx < 4; pidx++) {
1034 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001035 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001036 "aligned\n", pidx+1);
1037 return -EINVAL;
1038 }
1039 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1040 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1041 part_attrs |= EXT_CSD_ENH_GP(pidx);
1042 tot_enh_size_mult += gp_size_mult[pidx];
1043 }
1044 }
1045
1046 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001047 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001048 return -EMEDIUMTYPE;
1049 }
1050
1051 err = mmc_send_ext_csd(mmc, ext_csd);
1052 if (err)
1053 return err;
1054
1055 max_enh_size_mult =
1056 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1057 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1058 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1059 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001060 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001061 tot_enh_size_mult, max_enh_size_mult);
1062 return -EMEDIUMTYPE;
1063 }
1064
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001065 /* The default value of EXT_CSD_WR_REL_SET is device
1066 * dependent, the values can only be changed if the
1067 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1068 * changed only once and before partitioning is completed. */
1069 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1070 if (conf->user.wr_rel_change) {
1071 if (conf->user.wr_rel_set)
1072 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1073 else
1074 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1075 }
1076 for (pidx = 0; pidx < 4; pidx++) {
1077 if (conf->gp_part[pidx].wr_rel_change) {
1078 if (conf->gp_part[pidx].wr_rel_set)
1079 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1080 else
1081 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1082 }
1083 }
1084
1085 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1086 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1087 puts("Card does not support host controlled partition write "
1088 "reliability settings\n");
1089 return -EMEDIUMTYPE;
1090 }
1091
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001092 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1093 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001094 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001095 return -EPERM;
1096 }
1097
1098 if (mode == MMC_HWPART_CONF_CHECK)
1099 return 0;
1100
1101 /* Partitioning requires high-capacity size definitions */
1102 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1103 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1104 EXT_CSD_ERASE_GROUP_DEF, 1);
1105
1106 if (err)
1107 return err;
1108
1109 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1110
1111 /* update erase group size to be high-capacity */
1112 mmc->erase_grp_size =
1113 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1114
1115 }
1116
1117 /* all OK, write the configuration */
1118 for (i = 0; i < 4; i++) {
1119 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1120 EXT_CSD_ENH_START_ADDR+i,
1121 (enh_start_addr >> (i*8)) & 0xFF);
1122 if (err)
1123 return err;
1124 }
1125 for (i = 0; i < 3; i++) {
1126 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1127 EXT_CSD_ENH_SIZE_MULT+i,
1128 (enh_size_mult >> (i*8)) & 0xFF);
1129 if (err)
1130 return err;
1131 }
1132 for (pidx = 0; pidx < 4; pidx++) {
1133 for (i = 0; i < 3; i++) {
1134 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1135 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1136 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1137 if (err)
1138 return err;
1139 }
1140 }
1141 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1142 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1143 if (err)
1144 return err;
1145
1146 if (mode == MMC_HWPART_CONF_SET)
1147 return 0;
1148
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001149 /* The WR_REL_SET is a write-once register but shall be
1150 * written before setting PART_SETTING_COMPLETED. As it is
1151 * write-once we can only write it when completing the
1152 * partitioning. */
1153 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1154 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1155 EXT_CSD_WR_REL_SET, wr_rel_set);
1156 if (err)
1157 return err;
1158 }
1159
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001160 /* Setting PART_SETTING_COMPLETED confirms the partition
1161 * configuration but it only becomes effective after power
1162 * cycle, so we do not adjust the partition related settings
1163 * in the mmc struct. */
1164
1165 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1166 EXT_CSD_PARTITION_SETTING,
1167 EXT_CSD_PARTITION_SETTING_COMPLETED);
1168 if (err)
1169 return err;
1170
1171 return 0;
1172}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001173#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001174
Simon Glasse7881d82017-07-29 11:35:31 -06001175#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001176int mmc_getcd(struct mmc *mmc)
1177{
1178 int cd;
1179
1180 cd = board_mmc_getcd(mmc);
1181
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001182 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001183 if (mmc->cfg->ops->getcd)
1184 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001185 else
1186 cd = 1;
1187 }
Thierry Reding48972d92012-01-02 01:15:37 +00001188
1189 return cd;
1190}
Simon Glass8ca51e52016-06-12 23:30:22 -06001191#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001192
Marek Vasut62d77ce2018-04-15 00:37:11 +02001193#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001194static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001195{
1196 struct mmc_cmd cmd;
1197 struct mmc_data data;
1198
1199 /* Switch the frequency */
1200 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1201 cmd.resp_type = MMC_RSP_R1;
1202 cmd.cmdarg = (mode << 31) | 0xffffff;
1203 cmd.cmdarg &= ~(0xf << (group * 4));
1204 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001205
1206 data.dest = (char *)resp;
1207 data.blocksize = 64;
1208 data.blocks = 1;
1209 data.flags = MMC_DATA_READ;
1210
1211 return mmc_send_cmd(mmc, &cmd, &data);
1212}
1213
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001214static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001215{
1216 int err;
1217 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301218 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1219 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001220 struct mmc_data data;
1221 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001222#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001223 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001224#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001225
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +01001226 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001227
Thomas Choud52ebf12010-12-24 13:12:21 +00001228 if (mmc_host_is_spi(mmc))
1229 return 0;
1230
Andy Fleming272cc702008-10-30 16:41:01 -05001231 /* Read the SCR to find out if this card supports higher speeds */
1232 cmd.cmdidx = MMC_CMD_APP_CMD;
1233 cmd.resp_type = MMC_RSP_R1;
1234 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001235
1236 err = mmc_send_cmd(mmc, &cmd, NULL);
1237
1238 if (err)
1239 return err;
1240
1241 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1242 cmd.resp_type = MMC_RSP_R1;
1243 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001244
1245 timeout = 3;
1246
1247retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001248 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001249 data.blocksize = 8;
1250 data.blocks = 1;
1251 data.flags = MMC_DATA_READ;
1252
1253 err = mmc_send_cmd(mmc, &cmd, &data);
1254
1255 if (err) {
1256 if (timeout--)
1257 goto retry_scr;
1258
1259 return err;
1260 }
1261
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001262 mmc->scr[0] = __be32_to_cpu(scr[0]);
1263 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001264
1265 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001266 case 0:
1267 mmc->version = SD_VERSION_1_0;
1268 break;
1269 case 1:
1270 mmc->version = SD_VERSION_1_10;
1271 break;
1272 case 2:
1273 mmc->version = SD_VERSION_2;
1274 if ((mmc->scr[0] >> 15) & 0x1)
1275 mmc->version = SD_VERSION_3;
1276 break;
1277 default:
1278 mmc->version = SD_VERSION_1_0;
1279 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001280 }
1281
Alagu Sankarb44c7082010-05-12 15:08:24 +05301282 if (mmc->scr[0] & SD_DATA_4BIT)
1283 mmc->card_caps |= MMC_MODE_4BIT;
1284
Andy Fleming272cc702008-10-30 16:41:01 -05001285 /* Version 1.0 doesn't support switching */
1286 if (mmc->version == SD_VERSION_1_0)
1287 return 0;
1288
1289 timeout = 4;
1290 while (timeout--) {
1291 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001292 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001293
1294 if (err)
1295 return err;
1296
1297 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001298 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001299 break;
1300 }
1301
Andy Fleming272cc702008-10-30 16:41:01 -05001302 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001303 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1304 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001305
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001306#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001307 /* Version before 3.0 don't support UHS modes */
1308 if (mmc->version < SD_VERSION_3)
1309 return 0;
1310
1311 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1312 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1313 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1314 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1315 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1316 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1317 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1318 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1319 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1320 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1321 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001322#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001323
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001324 return 0;
1325}
1326
1327static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1328{
1329 int err;
1330
1331 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001332 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001333
Marek Vasutcf345762018-11-18 03:25:08 +01001334 /* SD version 1.00 and 1.01 does not support CMD 6 */
1335 if (mmc->version == SD_VERSION_1_0)
1336 return 0;
1337
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001338 switch (mode) {
1339 case SD_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001340 speed = UHS_SDR12_BUS_SPEED;
1341 break;
1342 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001343 speed = HIGH_SPEED_BUS_SPEED;
1344 break;
1345#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1346 case UHS_SDR12:
1347 speed = UHS_SDR12_BUS_SPEED;
1348 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001349 case UHS_SDR25:
1350 speed = UHS_SDR25_BUS_SPEED;
1351 break;
1352 case UHS_SDR50:
1353 speed = UHS_SDR50_BUS_SPEED;
1354 break;
1355 case UHS_DDR50:
1356 speed = UHS_DDR50_BUS_SPEED;
1357 break;
1358 case UHS_SDR104:
1359 speed = UHS_SDR104_BUS_SPEED;
1360 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001361#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001362 default:
1363 return -EINVAL;
1364 }
1365
1366 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001367 if (err)
1368 return err;
1369
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001370 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001371 return -ENOTSUPP;
1372
1373 return 0;
1374}
1375
Marek Vasutec360e62018-04-15 00:36:45 +02001376static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001377{
1378 int err;
1379 struct mmc_cmd cmd;
1380
1381 if ((w != 4) && (w != 1))
1382 return -EINVAL;
1383
1384 cmd.cmdidx = MMC_CMD_APP_CMD;
1385 cmd.resp_type = MMC_RSP_R1;
1386 cmd.cmdarg = mmc->rca << 16;
1387
1388 err = mmc_send_cmd(mmc, &cmd, NULL);
1389 if (err)
1390 return err;
1391
1392 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1393 cmd.resp_type = MMC_RSP_R1;
1394 if (w == 4)
1395 cmd.cmdarg = 2;
1396 else if (w == 1)
1397 cmd.cmdarg = 0;
1398 err = mmc_send_cmd(mmc, &cmd, NULL);
1399 if (err)
1400 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001401
1402 return 0;
1403}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001404#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001405
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001406#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001407static int sd_read_ssr(struct mmc *mmc)
1408{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001409 static const unsigned int sd_au_size[] = {
1410 0, SZ_16K / 512, SZ_32K / 512,
1411 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1412 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1413 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1414 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1415 SZ_64M / 512,
1416 };
Peng Fan3697e592016-09-01 11:13:38 +08001417 int err, i;
1418 struct mmc_cmd cmd;
1419 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1420 struct mmc_data data;
1421 int timeout = 3;
1422 unsigned int au, eo, et, es;
1423
1424 cmd.cmdidx = MMC_CMD_APP_CMD;
1425 cmd.resp_type = MMC_RSP_R1;
1426 cmd.cmdarg = mmc->rca << 16;
1427
1428 err = mmc_send_cmd(mmc, &cmd, NULL);
1429 if (err)
1430 return err;
1431
1432 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1433 cmd.resp_type = MMC_RSP_R1;
1434 cmd.cmdarg = 0;
1435
1436retry_ssr:
1437 data.dest = (char *)ssr;
1438 data.blocksize = 64;
1439 data.blocks = 1;
1440 data.flags = MMC_DATA_READ;
1441
1442 err = mmc_send_cmd(mmc, &cmd, &data);
1443 if (err) {
1444 if (timeout--)
1445 goto retry_ssr;
1446
1447 return err;
1448 }
1449
1450 for (i = 0; i < 16; i++)
1451 ssr[i] = be32_to_cpu(ssr[i]);
1452
1453 au = (ssr[2] >> 12) & 0xF;
1454 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1455 mmc->ssr.au = sd_au_size[au];
1456 es = (ssr[3] >> 24) & 0xFF;
1457 es |= (ssr[2] & 0xFF) << 8;
1458 et = (ssr[3] >> 18) & 0x3F;
1459 if (es && et) {
1460 eo = (ssr[3] >> 16) & 0x3;
1461 mmc->ssr.erase_timeout = (et * 1000) / es;
1462 mmc->ssr.erase_offset = eo * 1000;
1463 }
1464 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001465 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001466 }
1467
1468 return 0;
1469}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001470#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001471/* frequency bases */
1472/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001473static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001474 10000,
1475 100000,
1476 1000000,
1477 10000000,
1478};
1479
1480/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1481 * to platforms without floating point.
1482 */
Simon Glass61fe0762016-05-14 14:02:57 -06001483static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001484 0, /* reserved */
1485 10,
1486 12,
1487 13,
1488 15,
1489 20,
1490 25,
1491 30,
1492 35,
1493 40,
1494 45,
1495 50,
1496 55,
1497 60,
1498 70,
1499 80,
1500};
1501
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001502static inline int bus_width(uint cap)
1503{
1504 if (cap == MMC_MODE_8BIT)
1505 return 8;
1506 if (cap == MMC_MODE_4BIT)
1507 return 4;
1508 if (cap == MMC_MODE_1BIT)
1509 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001510 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001511 return 0;
1512}
1513
Simon Glasse7881d82017-07-29 11:35:31 -06001514#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001515#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001516static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1517{
1518 return -ENOTSUPP;
1519}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001520#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001521
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001522static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001523{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001524 int ret = 0;
1525
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001526 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001527 ret = mmc->cfg->ops->set_ios(mmc);
1528
1529 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001530}
Simon Glass8ca51e52016-06-12 23:30:22 -06001531#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001532
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001533int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001534{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001535 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001536 if (clock > mmc->cfg->f_max)
1537 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001538
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001539 if (clock < mmc->cfg->f_min)
1540 clock = mmc->cfg->f_min;
1541 }
Andy Fleming272cc702008-10-30 16:41:01 -05001542
1543 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001544 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001545
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001546 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1547
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001548 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001549}
1550
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001551static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001552{
1553 mmc->bus_width = width;
1554
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001555 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001556}
1557
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001558#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1559/*
1560 * helper function to display the capabilities in a human
1561 * friendly manner. The capabilities include bus width and
1562 * supported modes.
1563 */
1564void mmc_dump_capabilities(const char *text, uint caps)
1565{
1566 enum bus_mode mode;
1567
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001568 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001569 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001570 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001571 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001572 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001573 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001574 pr_debug("1, ");
1575 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001576 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1577 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001578 pr_debug("%s, ", mmc_mode_name(mode));
1579 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001580}
1581#endif
1582
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001583struct mode_width_tuning {
1584 enum bus_mode mode;
1585 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001586#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001587 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001588#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001589};
1590
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001591#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001592int mmc_voltage_to_mv(enum mmc_voltage voltage)
1593{
1594 switch (voltage) {
1595 case MMC_SIGNAL_VOLTAGE_000: return 0;
1596 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1597 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1598 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1599 }
1600 return -EINVAL;
1601}
1602
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001603static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1604{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001605 int err;
1606
1607 if (mmc->signal_voltage == signal_voltage)
1608 return 0;
1609
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001610 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001611 err = mmc_set_ios(mmc);
1612 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001613 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001614
1615 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001616}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001617#else
1618static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1619{
1620 return 0;
1621}
1622#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001623
Marek Vasut62d77ce2018-04-15 00:37:11 +02001624#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001625static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001626#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1627#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001628 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001629 .mode = UHS_SDR104,
1630 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1631 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1632 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001633#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001634 {
1635 .mode = UHS_SDR50,
1636 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1637 },
1638 {
1639 .mode = UHS_DDR50,
1640 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1641 },
1642 {
1643 .mode = UHS_SDR25,
1644 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1645 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001646#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001647 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001648 .mode = SD_HS,
1649 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1650 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001651#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001652 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001653 .mode = UHS_SDR12,
1654 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1655 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001656#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001657 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001658 .mode = SD_LEGACY,
1659 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1660 }
1661};
1662
1663#define for_each_sd_mode_by_pref(caps, mwt) \
1664 for (mwt = sd_modes_by_pref;\
1665 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1666 mwt++) \
1667 if (caps & MMC_CAP(mwt->mode))
1668
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001669static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001670{
1671 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001672 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1673 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001674#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001675 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001676#else
1677 bool uhs_en = false;
1678#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001679 uint caps;
1680
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001681#ifdef DEBUG
1682 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001683 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001684#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001685
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001686 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001687 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001688
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001689 if (!uhs_en)
1690 caps &= ~UHS_CAPS;
1691
1692 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001693 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001694
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001695 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001696 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001697 pr_debug("trying mode %s width %d (at %d MHz)\n",
1698 mmc_mode_name(mwt->mode),
1699 bus_width(*w),
1700 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001701
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001702 /* configure the bus width (card + host) */
1703 err = sd_select_bus_width(mmc, bus_width(*w));
1704 if (err)
1705 goto error;
1706 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001707
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001708 /* configure the bus mode (card) */
1709 err = sd_set_card_speed(mmc, mwt->mode);
1710 if (err)
1711 goto error;
1712
1713 /* configure the bus mode (host) */
1714 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001715 mmc_set_clock(mmc, mmc->tran_speed,
1716 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001717
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001718#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001719 /* execute tuning if needed */
1720 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1721 err = mmc_execute_tuning(mmc,
1722 mwt->tuning);
1723 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001724 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001725 goto error;
1726 }
1727 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001728#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001729
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001730#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001731 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001732 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001733 pr_warn("unable to read ssr\n");
1734#endif
1735 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001736 return 0;
1737
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001738error:
1739 /* revert to a safer bus speed */
1740 mmc_select_mode(mmc, SD_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001741 mmc_set_clock(mmc, mmc->tran_speed,
1742 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001743 }
1744 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001745 }
1746
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001747 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001748 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001749}
1750
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001751/*
1752 * read the compare the part of ext csd that is constant.
1753 * This can be used to check that the transfer is working
1754 * as expected.
1755 */
1756static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1757{
1758 int err;
1759 const u8 *ext_csd = mmc->ext_csd;
1760 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1761
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001762 if (mmc->version < MMC_VERSION_4)
1763 return 0;
1764
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001765 err = mmc_send_ext_csd(mmc, test_csd);
1766 if (err)
1767 return err;
1768
1769 /* Only compare read only fields */
1770 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1771 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1772 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1773 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1774 ext_csd[EXT_CSD_REV]
1775 == test_csd[EXT_CSD_REV] &&
1776 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1777 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1778 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1779 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1780 return 0;
1781
1782 return -EBADMSG;
1783}
1784
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001785#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001786static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1787 uint32_t allowed_mask)
1788{
1789 u32 card_mask = 0;
1790
1791 switch (mode) {
Peng Fan3dd26262018-08-10 14:07:54 +08001792 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001793 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001794 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1795 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001796 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001797 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1798 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001799 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1800 break;
1801 case MMC_DDR_52:
1802 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1803 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1804 MMC_SIGNAL_VOLTAGE_180;
1805 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1806 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1807 break;
1808 default:
1809 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1810 break;
1811 }
1812
1813 while (card_mask & allowed_mask) {
1814 enum mmc_voltage best_match;
1815
1816 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1817 if (!mmc_set_signal_voltage(mmc, best_match))
1818 return 0;
1819
1820 allowed_mask &= ~best_match;
1821 }
1822
1823 return -ENOTSUPP;
1824}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001825#else
1826static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1827 uint32_t allowed_mask)
1828{
1829 return 0;
1830}
1831#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001832
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001833static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan3dd26262018-08-10 14:07:54 +08001834#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1835 {
1836 .mode = MMC_HS_400,
1837 .widths = MMC_MODE_8BIT,
1838 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1839 },
1840#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001841#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001842 {
1843 .mode = MMC_HS_200,
1844 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001845 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001846 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001847#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001848 {
1849 .mode = MMC_DDR_52,
1850 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1851 },
1852 {
1853 .mode = MMC_HS_52,
1854 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1855 },
1856 {
1857 .mode = MMC_HS,
1858 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1859 },
1860 {
1861 .mode = MMC_LEGACY,
1862 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1863 }
1864};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001865
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001866#define for_each_mmc_mode_by_pref(caps, mwt) \
1867 for (mwt = mmc_modes_by_pref;\
1868 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1869 mwt++) \
1870 if (caps & MMC_CAP(mwt->mode))
1871
1872static const struct ext_csd_bus_width {
1873 uint cap;
1874 bool is_ddr;
1875 uint ext_csd_bits;
1876} ext_csd_bus_width[] = {
1877 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1878 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1879 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1880 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1881 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1882};
1883
Peng Fan3dd26262018-08-10 14:07:54 +08001884#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1885static int mmc_select_hs400(struct mmc *mmc)
1886{
1887 int err;
1888
1889 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001890 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001891 if (err)
1892 return err;
1893
1894 /* configure the bus mode (host) */
1895 mmc_select_mode(mmc, MMC_HS_200);
1896 mmc_set_clock(mmc, mmc->tran_speed, false);
1897
1898 /* execute tuning if needed */
1899 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1900 if (err) {
1901 debug("tuning failed\n");
1902 return err;
1903 }
1904
1905 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001906 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001907
1908 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1909 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1910 if (err)
1911 return err;
1912
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001913 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001914 if (err)
1915 return err;
1916
1917 mmc_select_mode(mmc, MMC_HS_400);
1918 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1919 if (err)
1920 return err;
1921
1922 return 0;
1923}
1924#else
1925static int mmc_select_hs400(struct mmc *mmc)
1926{
1927 return -ENOTSUPP;
1928}
1929#endif
1930
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001931#define for_each_supported_width(caps, ddr, ecbv) \
1932 for (ecbv = ext_csd_bus_width;\
1933 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1934 ecbv++) \
1935 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1936
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001937static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001938{
1939 int err;
1940 const struct mode_width_tuning *mwt;
1941 const struct ext_csd_bus_width *ecbw;
1942
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001943#ifdef DEBUG
1944 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001945 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001946#endif
1947
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001948 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001949 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001950
1951 /* Only version 4 of MMC supports wider bus widths */
1952 if (mmc->version < MMC_VERSION_4)
1953 return 0;
1954
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001955 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001956 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001957 return -ENOTSUPP;
1958 }
1959
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001960#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
1961 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1962 /*
1963 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
1964 * before doing anything else, since a transition from either of
1965 * the HS200/HS400 mode directly to legacy mode is not supported.
1966 */
1967 if (mmc->selected_mode == MMC_HS_200 ||
1968 mmc->selected_mode == MMC_HS_400)
1969 mmc_set_card_speed(mmc, MMC_HS, true);
1970 else
1971#endif
1972 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001973
1974 for_each_mmc_mode_by_pref(card_caps, mwt) {
1975 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001976 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001977 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001978 pr_debug("trying mode %s width %d (at %d MHz)\n",
1979 mmc_mode_name(mwt->mode),
1980 bus_width(ecbw->cap),
1981 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001982 old_voltage = mmc->signal_voltage;
1983 err = mmc_set_lowest_voltage(mmc, mwt->mode,
1984 MMC_ALL_SIGNAL_VOLTAGE);
1985 if (err)
1986 continue;
1987
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001988 /* configure the bus width (card + host) */
1989 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1990 EXT_CSD_BUS_WIDTH,
1991 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
1992 if (err)
1993 goto error;
1994 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
1995
Peng Fan3dd26262018-08-10 14:07:54 +08001996 if (mwt->mode == MMC_HS_400) {
1997 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001998 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08001999 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002000 goto error;
2001 }
Peng Fan3dd26262018-08-10 14:07:54 +08002002 } else {
2003 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002004 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002005 if (err)
2006 goto error;
2007
2008 /*
2009 * configure the bus width AND the ddr mode
2010 * (card). The host side will be taken care
2011 * of in the next step
2012 */
2013 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2014 err = mmc_switch(mmc,
2015 EXT_CSD_CMD_SET_NORMAL,
2016 EXT_CSD_BUS_WIDTH,
2017 ecbw->ext_csd_bits);
2018 if (err)
2019 goto error;
2020 }
2021
2022 /* configure the bus mode (host) */
2023 mmc_select_mode(mmc, mwt->mode);
2024 mmc_set_clock(mmc, mmc->tran_speed,
2025 MMC_CLK_ENABLE);
2026#ifdef MMC_SUPPORTS_TUNING
2027
2028 /* execute tuning if needed */
2029 if (mwt->tuning) {
2030 err = mmc_execute_tuning(mmc,
2031 mwt->tuning);
2032 if (err) {
2033 pr_debug("tuning failed\n");
2034 goto error;
2035 }
2036 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002037#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002038 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002039
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002040 /* do a transfer to check the configuration */
2041 err = mmc_read_and_compare_ext_csd(mmc);
2042 if (!err)
2043 return 0;
2044error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002045 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002046 /* if an error occured, revert to a safer bus mode */
2047 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2048 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2049 mmc_select_mode(mmc, MMC_LEGACY);
2050 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002051 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002052 }
2053
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002054 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002055
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002056 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002057}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002058#endif
2059
2060#if CONFIG_IS_ENABLED(MMC_TINY)
2061DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2062#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002063
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002064static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002065{
2066 int err, i;
2067 u64 capacity;
2068 bool has_parts = false;
2069 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002070 static const u32 mmc_versions[] = {
2071 MMC_VERSION_4,
2072 MMC_VERSION_4_1,
2073 MMC_VERSION_4_2,
2074 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002075 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002076 MMC_VERSION_4_41,
2077 MMC_VERSION_4_5,
2078 MMC_VERSION_5_0,
2079 MMC_VERSION_5_1
2080 };
2081
Marek Vasut62d77ce2018-04-15 00:37:11 +02002082#if CONFIG_IS_ENABLED(MMC_TINY)
2083 u8 *ext_csd = ext_csd_bkup;
2084
2085 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2086 return 0;
2087
2088 if (!mmc->ext_csd)
2089 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2090
2091 err = mmc_send_ext_csd(mmc, ext_csd);
2092 if (err)
2093 goto error;
2094
2095 /* store the ext csd for future reference */
2096 if (!mmc->ext_csd)
2097 mmc->ext_csd = ext_csd;
2098#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002099 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002100
2101 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2102 return 0;
2103
2104 /* check ext_csd version and capacity */
2105 err = mmc_send_ext_csd(mmc, ext_csd);
2106 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002107 goto error;
2108
2109 /* store the ext csd for future reference */
2110 if (!mmc->ext_csd)
2111 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2112 if (!mmc->ext_csd)
2113 return -ENOMEM;
2114 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002115#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002116 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002117 return -EINVAL;
2118
2119 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2120
2121 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002122 /*
2123 * According to the JEDEC Standard, the value of
2124 * ext_csd's capacity is valid if the value is more
2125 * than 2GB
2126 */
2127 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2128 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2129 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2130 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2131 capacity *= MMC_MAX_BLOCK_LEN;
2132 if ((capacity >> 20) > 2 * 1024)
2133 mmc->capacity_user = capacity;
2134 }
2135
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002136 /* The partition data may be non-zero but it is only
2137 * effective if PARTITION_SETTING_COMPLETED is set in
2138 * EXT_CSD, so ignore any data if this bit is not set,
2139 * except for enabling the high-capacity group size
2140 * definition (see below).
2141 */
2142 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2143 EXT_CSD_PARTITION_SETTING_COMPLETED);
2144
2145 /* store the partition info of emmc */
2146 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2147 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2148 ext_csd[EXT_CSD_BOOT_MULT])
2149 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2150 if (part_completed &&
2151 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2152 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2153
2154 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2155
2156 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2157
2158 for (i = 0; i < 4; i++) {
2159 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2160 uint mult = (ext_csd[idx + 2] << 16) +
2161 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2162 if (mult)
2163 has_parts = true;
2164 if (!part_completed)
2165 continue;
2166 mmc->capacity_gp[i] = mult;
2167 mmc->capacity_gp[i] *=
2168 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2169 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2170 mmc->capacity_gp[i] <<= 19;
2171 }
2172
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002173#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002174 if (part_completed) {
2175 mmc->enh_user_size =
2176 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2177 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2178 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2179 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2180 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2181 mmc->enh_user_size <<= 19;
2182 mmc->enh_user_start =
2183 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2184 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2185 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2186 ext_csd[EXT_CSD_ENH_START_ADDR];
2187 if (mmc->high_capacity)
2188 mmc->enh_user_start <<= 9;
2189 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002190#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002191
2192 /*
2193 * Host needs to enable ERASE_GRP_DEF bit if device is
2194 * partitioned. This bit will be lost every time after a reset
2195 * or power off. This will affect erase size.
2196 */
2197 if (part_completed)
2198 has_parts = true;
2199 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2200 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2201 has_parts = true;
2202 if (has_parts) {
2203 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2204 EXT_CSD_ERASE_GROUP_DEF, 1);
2205
2206 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002207 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002208
2209 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2210 }
2211
2212 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002213#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002214 /* Read out group size from ext_csd */
2215 mmc->erase_grp_size =
2216 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002217#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002218 /*
2219 * if high capacity and partition setting completed
2220 * SEC_COUNT is valid even if it is smaller than 2 GiB
2221 * JEDEC Standard JESD84-B45, 6.2.4
2222 */
2223 if (mmc->high_capacity && part_completed) {
2224 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2225 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2226 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2227 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2228 capacity *= MMC_MAX_BLOCK_LEN;
2229 mmc->capacity_user = capacity;
2230 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002231 }
2232#if CONFIG_IS_ENABLED(MMC_WRITE)
2233 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002234 /* Calculate the group size from the csd value. */
2235 int erase_gsz, erase_gmul;
2236
2237 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2238 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2239 mmc->erase_grp_size = (erase_gsz + 1)
2240 * (erase_gmul + 1);
2241 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002242#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002243#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002244 mmc->hc_wp_grp_size = 1024
2245 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2246 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002247#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002248
2249 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2250
2251 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002252error:
2253 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002254#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002255 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002256#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002257 mmc->ext_csd = NULL;
2258 }
2259 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002260}
2261
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002262static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002263{
Stephen Warrenf866a462013-06-11 15:14:01 -06002264 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002265 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002266 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002267 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002268 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002269
Thomas Choud52ebf12010-12-24 13:12:21 +00002270#ifdef CONFIG_MMC_SPI_CRC_ON
2271 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2272 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2273 cmd.resp_type = MMC_RSP_R1;
2274 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002275 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002276 if (err)
2277 return err;
2278 }
2279#endif
2280
Andy Fleming272cc702008-10-30 16:41:01 -05002281 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002282 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2283 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002284 cmd.resp_type = MMC_RSP_R2;
2285 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002286
2287 err = mmc_send_cmd(mmc, &cmd, NULL);
2288
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002289#ifdef CONFIG_MMC_QUIRKS
2290 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2291 int retries = 4;
2292 /*
2293 * It has been seen that SEND_CID may fail on the first
2294 * attempt, let's try a few more time
2295 */
2296 do {
2297 err = mmc_send_cmd(mmc, &cmd, NULL);
2298 if (!err)
2299 break;
2300 } while (retries--);
2301 }
2302#endif
2303
Andy Fleming272cc702008-10-30 16:41:01 -05002304 if (err)
2305 return err;
2306
2307 memcpy(mmc->cid, cmd.response, 16);
2308
2309 /*
2310 * For MMC cards, set the Relative Address.
2311 * For SD cards, get the Relatvie Address.
2312 * This also puts the cards into Standby State
2313 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002314 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2315 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2316 cmd.cmdarg = mmc->rca << 16;
2317 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002318
Thomas Choud52ebf12010-12-24 13:12:21 +00002319 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002320
Thomas Choud52ebf12010-12-24 13:12:21 +00002321 if (err)
2322 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002323
Thomas Choud52ebf12010-12-24 13:12:21 +00002324 if (IS_SD(mmc))
2325 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2326 }
Andy Fleming272cc702008-10-30 16:41:01 -05002327
2328 /* Get the Card-Specific Data */
2329 cmd.cmdidx = MMC_CMD_SEND_CSD;
2330 cmd.resp_type = MMC_RSP_R2;
2331 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002332
2333 err = mmc_send_cmd(mmc, &cmd, NULL);
2334
2335 if (err)
2336 return err;
2337
Rabin Vincent998be3d2009-04-05 13:30:56 +05302338 mmc->csd[0] = cmd.response[0];
2339 mmc->csd[1] = cmd.response[1];
2340 mmc->csd[2] = cmd.response[2];
2341 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002342
2343 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302344 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002345
2346 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002347 case 0:
2348 mmc->version = MMC_VERSION_1_2;
2349 break;
2350 case 1:
2351 mmc->version = MMC_VERSION_1_4;
2352 break;
2353 case 2:
2354 mmc->version = MMC_VERSION_2_2;
2355 break;
2356 case 3:
2357 mmc->version = MMC_VERSION_3;
2358 break;
2359 case 4:
2360 mmc->version = MMC_VERSION_4;
2361 break;
2362 default:
2363 mmc->version = MMC_VERSION_1_2;
2364 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002365 }
2366 }
2367
2368 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302369 freq = fbase[(cmd.response[0] & 0x7)];
2370 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002371
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002372 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002373 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002374
Markus Niebelab711882013-12-16 13:40:46 +01002375 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302376 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002377#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002378
2379 if (IS_SD(mmc))
2380 mmc->write_bl_len = mmc->read_bl_len;
2381 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302382 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002383#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002384
2385 if (mmc->high_capacity) {
2386 csize = (mmc->csd[1] & 0x3f) << 16
2387 | (mmc->csd[2] & 0xffff0000) >> 16;
2388 cmult = 8;
2389 } else {
2390 csize = (mmc->csd[1] & 0x3ff) << 2
2391 | (mmc->csd[2] & 0xc0000000) >> 30;
2392 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2393 }
2394
Stephen Warrenf866a462013-06-11 15:14:01 -06002395 mmc->capacity_user = (csize + 1) << (cmult + 2);
2396 mmc->capacity_user *= mmc->read_bl_len;
2397 mmc->capacity_boot = 0;
2398 mmc->capacity_rpmb = 0;
2399 for (i = 0; i < 4; i++)
2400 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002401
Simon Glass8bfa1952013-04-03 08:54:30 +00002402 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2403 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002404
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002405#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002406 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2407 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002408#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002409
Markus Niebelab711882013-12-16 13:40:46 +01002410 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2411 cmd.cmdidx = MMC_CMD_SET_DSR;
2412 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2413 cmd.resp_type = MMC_RSP_NONE;
2414 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002415 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002416 }
2417
Andy Fleming272cc702008-10-30 16:41:01 -05002418 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002419 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2420 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002421 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002422 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002423 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002424
Thomas Choud52ebf12010-12-24 13:12:21 +00002425 if (err)
2426 return err;
2427 }
Andy Fleming272cc702008-10-30 16:41:01 -05002428
Lei Wene6f99a52011-06-22 17:03:31 +00002429 /*
2430 * For SD, its erase group is always one sector
2431 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002432#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002433 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002434#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002435 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002436
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002437 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002438 if (err)
2439 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302440
Simon Glassc40fdca2016-05-01 13:52:35 -06002441 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002442 if (err)
2443 return err;
2444
Marek Vasut62d77ce2018-04-15 00:37:11 +02002445#if CONFIG_IS_ENABLED(MMC_TINY)
2446 mmc_set_clock(mmc, mmc->legacy_speed, false);
2447 mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
2448 mmc_set_bus_width(mmc, 1);
2449#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002450 if (IS_SD(mmc)) {
2451 err = sd_get_capabilities(mmc);
2452 if (err)
2453 return err;
2454 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2455 } else {
2456 err = mmc_get_capabilities(mmc);
2457 if (err)
2458 return err;
2459 mmc_select_mode_and_width(mmc, mmc->card_caps);
2460 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002461#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002462 if (err)
2463 return err;
2464
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002465 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002466
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002467 /* Fix the block length for DDR mode */
2468 if (mmc->ddr_mode) {
2469 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002470#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002471 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002472#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002473 }
2474
Andy Fleming272cc702008-10-30 16:41:01 -05002475 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002476 bdesc = mmc_get_blk_desc(mmc);
2477 bdesc->lun = 0;
2478 bdesc->hwpart = 0;
2479 bdesc->type = 0;
2480 bdesc->blksz = mmc->read_bl_len;
2481 bdesc->log2blksz = LOG2(bdesc->blksz);
2482 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002483#if !defined(CONFIG_SPL_BUILD) || \
2484 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
2485 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002486 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002487 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2488 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002489 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002490 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2491 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2492 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002493 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002494 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002495#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002496 bdesc->vendor[0] = 0;
2497 bdesc->product[0] = 0;
2498 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002499#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002500
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002501#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2502 part_init(bdesc);
2503#endif
2504
Andy Fleming272cc702008-10-30 16:41:01 -05002505 return 0;
2506}
2507
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002508static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002509{
2510 struct mmc_cmd cmd;
2511 int err;
2512
2513 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2514 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002515 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002516 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002517
2518 err = mmc_send_cmd(mmc, &cmd, NULL);
2519
2520 if (err)
2521 return err;
2522
Rabin Vincent998be3d2009-04-05 13:30:56 +05302523 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002524 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002525 else
2526 mmc->version = SD_VERSION_2;
2527
2528 return 0;
2529}
2530
Simon Glassc4d660d2017-07-04 13:31:19 -06002531#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002532/* board-specific MMC power initializations. */
2533__weak void board_mmc_power_init(void)
2534{
2535}
Simon Glass05cbeb72017-04-22 19:10:56 -06002536#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002537
Peng Fan2051aef2016-10-11 15:08:43 +08002538static int mmc_power_init(struct mmc *mmc)
2539{
Simon Glassc4d660d2017-07-04 13:31:19 -06002540#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002541#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002542 int ret;
2543
2544 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002545 &mmc->vmmc_supply);
2546 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002547 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002548
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002549 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2550 &mmc->vqmmc_supply);
2551 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002552 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002553#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002554#else /* !CONFIG_DM_MMC */
2555 /*
2556 * Driver model should use a regulator, as above, rather than calling
2557 * out to board code.
2558 */
2559 board_mmc_power_init();
2560#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002561 return 0;
2562}
2563
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002564/*
2565 * put the host in the initial state:
2566 * - turn on Vdd (card power supply)
2567 * - configure the bus width and clock to minimal values
2568 */
2569static void mmc_set_initial_state(struct mmc *mmc)
2570{
2571 int err;
2572
2573 /* First try to set 3.3V. If it fails set to 1.8V */
2574 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2575 if (err != 0)
2576 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2577 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002578 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002579
2580 mmc_select_mode(mmc, MMC_LEGACY);
2581 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002582 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002583}
2584
2585static int mmc_power_on(struct mmc *mmc)
2586{
2587#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2588 if (mmc->vmmc_supply) {
2589 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2590
2591 if (ret) {
2592 puts("Error enabling VMMC supply\n");
2593 return ret;
2594 }
2595 }
2596#endif
2597 return 0;
2598}
2599
2600static int mmc_power_off(struct mmc *mmc)
2601{
Jaehoon Chung65117182018-01-26 19:25:29 +09002602 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002603#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2604 if (mmc->vmmc_supply) {
2605 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2606
2607 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002608 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002609 return ret;
2610 }
2611 }
2612#endif
2613 return 0;
2614}
2615
2616static int mmc_power_cycle(struct mmc *mmc)
2617{
2618 int ret;
2619
2620 ret = mmc_power_off(mmc);
2621 if (ret)
2622 return ret;
2623 /*
2624 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2625 * to be on the safer side.
2626 */
2627 udelay(2000);
2628 return mmc_power_on(mmc);
2629}
2630
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002631int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002632{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002633 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002634 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002635
Lei Wenbc897b12011-05-02 16:26:26 +00002636 if (mmc->has_init)
2637 return 0;
2638
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002639#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2640 mmc_adapter_card_type_ident();
2641#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002642 err = mmc_power_init(mmc);
2643 if (err)
2644 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002645
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002646#ifdef CONFIG_MMC_QUIRKS
2647 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
2648 MMC_QUIRK_RETRY_SEND_CID;
2649#endif
2650
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002651 err = mmc_power_cycle(mmc);
2652 if (err) {
2653 /*
2654 * if power cycling is not supported, we should not try
2655 * to use the UHS modes, because we wouldn't be able to
2656 * recover from an error during the UHS initialization.
2657 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002658 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002659 uhs_en = false;
2660 mmc->host_caps &= ~UHS_CAPS;
2661 err = mmc_power_on(mmc);
2662 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002663 if (err)
2664 return err;
2665
Simon Glasse7881d82017-07-29 11:35:31 -06002666#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002667 /* The device has already been probed ready for use */
2668#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002669 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002670 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002671 if (err)
2672 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002673#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002674 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002675
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002676retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002677 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002678
Andy Fleming272cc702008-10-30 16:41:01 -05002679 /* Reset the Card */
2680 err = mmc_go_idle(mmc);
2681
2682 if (err)
2683 return err;
2684
Lei Wenbc897b12011-05-02 16:26:26 +00002685 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002686 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002687
Andy Fleming272cc702008-10-30 16:41:01 -05002688 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002689 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002690
Andy Fleming272cc702008-10-30 16:41:01 -05002691 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002692 err = sd_send_op_cond(mmc, uhs_en);
2693 if (err && uhs_en) {
2694 uhs_en = false;
2695 mmc_power_cycle(mmc);
2696 goto retry;
2697 }
Andy Fleming272cc702008-10-30 16:41:01 -05002698
2699 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002700 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002701 err = mmc_send_op_cond(mmc);
2702
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002703 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002704#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002705 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002706#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002707 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002708 }
2709 }
2710
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002711 return err;
2712}
2713
2714int mmc_start_init(struct mmc *mmc)
2715{
2716 bool no_card;
2717 int err = 0;
2718
2719 /*
2720 * all hosts are capable of 1 bit bus-width and able to use the legacy
2721 * timings.
2722 */
2723 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
2724 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
2725
2726#if !defined(CONFIG_MMC_BROKEN_CD)
2727 /* we pretend there's no card when init is NULL */
2728 no_card = mmc_getcd(mmc) == 0;
2729#else
2730 no_card = 0;
2731#endif
2732#if !CONFIG_IS_ENABLED(DM_MMC)
2733 no_card = no_card || (mmc->cfg->ops->init == NULL);
2734#endif
2735 if (no_card) {
2736 mmc->has_init = 0;
2737#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2738 pr_err("MMC: no card present\n");
2739#endif
2740 return -ENOMEDIUM;
2741 }
2742
2743 err = mmc_get_op_cond(mmc);
2744
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002745 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002746 mmc->init_in_progress = 1;
2747
2748 return err;
2749}
2750
2751static int mmc_complete_init(struct mmc *mmc)
2752{
2753 int err = 0;
2754
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002755 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002756 if (mmc->op_cond_pending)
2757 err = mmc_complete_op_cond(mmc);
2758
2759 if (!err)
2760 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002761 if (err)
2762 mmc->has_init = 0;
2763 else
2764 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002765 return err;
2766}
2767
2768int mmc_init(struct mmc *mmc)
2769{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002770 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302771 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002772#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002773 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002774
Simon Glass33fb2112016-05-01 13:52:41 -06002775 upriv->mmc = mmc;
2776#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002777 if (mmc->has_init)
2778 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002779
2780 start = get_timer(0);
2781
Che-Liang Chioue9550442012-11-28 15:21:13 +00002782 if (!mmc->init_in_progress)
2783 err = mmc_start_init(mmc);
2784
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002785 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002786 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002787 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002788 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002789
Lei Wenbc897b12011-05-02 16:26:26 +00002790 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002791}
2792
Marek Vasutfceea992019-01-29 04:45:51 +01002793#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2794 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2795 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2796int mmc_deinit(struct mmc *mmc)
2797{
2798 u32 caps_filtered;
2799
2800 if (!mmc->has_init)
2801 return 0;
2802
2803 if (IS_SD(mmc)) {
2804 caps_filtered = mmc->card_caps &
2805 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2806 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2807 MMC_CAP(UHS_SDR104));
2808
2809 return sd_select_mode_and_width(mmc, caps_filtered);
2810 } else {
2811 caps_filtered = mmc->card_caps &
2812 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2813
2814 return mmc_select_mode_and_width(mmc, caps_filtered);
2815 }
2816}
2817#endif
2818
Markus Niebelab711882013-12-16 13:40:46 +01002819int mmc_set_dsr(struct mmc *mmc, u16 val)
2820{
2821 mmc->dsr = val;
2822 return 0;
2823}
2824
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002825/* CPU-specific MMC initializations */
2826__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002827{
2828 return -1;
2829}
2830
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002831/* board-specific MMC initializations. */
2832__weak int board_mmc_init(bd_t *bis)
2833{
2834 return -1;
2835}
Andy Fleming272cc702008-10-30 16:41:01 -05002836
Che-Liang Chioue9550442012-11-28 15:21:13 +00002837void mmc_set_preinit(struct mmc *mmc, int preinit)
2838{
2839 mmc->preinit = preinit;
2840}
2841
Faiz Abbas8a856db2018-02-12 19:35:24 +05302842#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002843static int mmc_probe(bd_t *bis)
2844{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002845 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002846 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002847 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002848
2849 ret = uclass_get(UCLASS_MMC, &uc);
2850 if (ret)
2851 return ret;
2852
Simon Glass4a1db6d2015-12-29 05:22:49 -07002853 /*
2854 * Try to add them in sequence order. Really with driver model we
2855 * should allow holes, but the current MMC list does not allow that.
2856 * So if we request 0, 1, 3 we will get 0, 1, 2.
2857 */
2858 for (i = 0; ; i++) {
2859 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2860 if (ret == -ENODEV)
2861 break;
2862 }
2863 uclass_foreach_dev(dev, uc) {
2864 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002865 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002866 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002867 }
2868
2869 return 0;
2870}
2871#else
2872static int mmc_probe(bd_t *bis)
2873{
2874 if (board_mmc_init(bis) < 0)
2875 cpu_mmc_init(bis);
2876
2877 return 0;
2878}
2879#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002880
Andy Fleming272cc702008-10-30 16:41:01 -05002881int mmc_initialize(bd_t *bis)
2882{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002883 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002884 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002885 if (initialized) /* Avoid initializing mmc multiple times */
2886 return 0;
2887 initialized = 1;
2888
Simon Glassc4d660d2017-07-04 13:31:19 -06002889#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002890#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002891 mmc_list_init();
2892#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002893#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002894 ret = mmc_probe(bis);
2895 if (ret)
2896 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002897
Ying Zhangbb0dc102013-08-16 15:16:11 +08002898#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002899 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002900#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002901
Simon Glassc40fdca2016-05-01 13:52:35 -06002902 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002903 return 0;
2904}
Tomas Melincd3d4882016-11-25 11:01:03 +02002905
2906#ifdef CONFIG_CMD_BKOPS_ENABLE
2907int mmc_set_bkops_enable(struct mmc *mmc)
2908{
2909 int err;
2910 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2911
2912 err = mmc_send_ext_csd(mmc, ext_csd);
2913 if (err) {
2914 puts("Could not get ext_csd register values\n");
2915 return err;
2916 }
2917
2918 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2919 puts("Background operations not supported on device\n");
2920 return -EMEDIUMTYPE;
2921 }
2922
2923 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2924 puts("Background operations already enabled\n");
2925 return 0;
2926 }
2927
2928 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2929 if (err) {
2930 puts("Failed to enable manual background operations\n");
2931 return err;
2932 }
2933
2934 puts("Enabled manual background operations\n");
2935
2936 return 0;
2937}
2938#endif