blob: a61e311ccaafe6231677cda5c24a0f9124505ae7 [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
32static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
33{
34 return -ENOSYS;
35}
36
Jeroen Hofstee750121c2014-07-12 21:24:08 +020037__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000038{
39 return -1;
40}
41
42int mmc_getwp(struct mmc *mmc)
43{
44 int wp;
45
46 wp = board_mmc_getwp(mmc);
47
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000048 if (wp < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +020049 if (mmc->cfg->ops->getwp)
50 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +000051 else
52 wp = 0;
53 }
Nikita Kiryanovd23d8d72012-12-03 02:19:46 +000054
55 return wp;
56}
57
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +020058__weak int board_mmc_getcd(struct mmc *mmc)
59{
Stefano Babic11fdade2010-02-05 15:04:43 +010060 return -1;
61}
Simon Glass8ca51e52016-06-12 23:30:22 -060062#endif
Stefano Babic11fdade2010-02-05 15:04:43 +010063
Marek Vasut8635ff92012-03-15 18:41:35 +000064#ifdef CONFIG_MMC_TRACE
Simon Glassc0c76eb2016-06-12 23:30:20 -060065void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
66{
67 printf("CMD_SEND:%d\n", cmd->cmdidx);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010068 printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
Simon Glassc0c76eb2016-06-12 23:30:20 -060069}
70
71void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
72{
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +000073 int i;
74 u8 *ptr;
75
Bin Meng7863ce52016-03-17 21:53:14 -070076 if (ret) {
77 printf("\t\tRET\t\t\t %d\n", ret);
78 } else {
79 switch (cmd->resp_type) {
80 case MMC_RSP_NONE:
81 printf("\t\tMMC_RSP_NONE\n");
82 break;
83 case MMC_RSP_R1:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010084 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070085 cmd->response[0]);
86 break;
87 case MMC_RSP_R1b:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010088 printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070089 cmd->response[0]);
90 break;
91 case MMC_RSP_R2:
Marek Vasut7d5ccb12019-03-23 18:54:45 +010092 printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070093 cmd->response[0]);
Marek Vasut7d5ccb12019-03-23 18:54:45 +010094 printf("\t\t \t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -070095 cmd->response[1]);
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[2]);
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[3]);
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000100 printf("\n");
Bin Meng7863ce52016-03-17 21:53:14 -0700101 printf("\t\t\t\t\tDUMPING DATA\n");
102 for (i = 0; i < 4; i++) {
103 int j;
104 printf("\t\t\t\t\t%03d - ", i*4);
105 ptr = (u8 *)&cmd->response[i];
106 ptr += 3;
107 for (j = 0; j < 4; j++)
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100108 printf("%02x ", *ptr--);
Bin Meng7863ce52016-03-17 21:53:14 -0700109 printf("\n");
110 }
111 break;
112 case MMC_RSP_R3:
Marek Vasut7d5ccb12019-03-23 18:54:45 +0100113 printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
Bin Meng7863ce52016-03-17 21:53:14 -0700114 cmd->response[0]);
115 break;
116 default:
117 printf("\t\tERROR MMC rsp not supported\n");
118 break;
Bin Meng53e8e402016-03-17 21:53:13 -0700119 }
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000120 }
Simon Glassc0c76eb2016-06-12 23:30:20 -0600121}
122
123void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
124{
125 int status;
126
127 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
128 printf("CURR STATE:%d\n", status);
129}
Raffaele Recalcati5db2fe32011-03-11 02:01:14 +0000130#endif
Simon Glassc0c76eb2016-06-12 23:30:20 -0600131
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200132#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
133const char *mmc_mode_name(enum bus_mode mode)
134{
135 static const char *const names[] = {
136 [MMC_LEGACY] = "MMC legacy",
137 [SD_LEGACY] = "SD Legacy",
138 [MMC_HS] = "MMC High Speed (26MHz)",
139 [SD_HS] = "SD High Speed (50MHz)",
140 [UHS_SDR12] = "UHS SDR12 (25MHz)",
141 [UHS_SDR25] = "UHS SDR25 (50MHz)",
142 [UHS_SDR50] = "UHS SDR50 (100MHz)",
143 [UHS_SDR104] = "UHS SDR104 (208MHz)",
144 [UHS_DDR50] = "UHS DDR50 (50MHz)",
145 [MMC_HS_52] = "MMC High Speed (52MHz)",
146 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
147 [MMC_HS_200] = "HS200 (200MHz)",
Peng Fan3dd26262018-08-10 14:07:54 +0800148 [MMC_HS_400] = "HS400 (200MHz)",
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200149 };
150
151 if (mode >= MMC_MODES_END)
152 return "Unknown mode";
153 else
154 return names[mode];
155}
156#endif
157
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200158static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
159{
160 static const int freqs[] = {
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900161 [MMC_LEGACY] = 25000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200162 [SD_LEGACY] = 25000000,
163 [MMC_HS] = 26000000,
164 [SD_HS] = 50000000,
Jaehoon Chung1b313aa2018-01-30 14:10:16 +0900165 [MMC_HS_52] = 52000000,
166 [MMC_DDR_52] = 52000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200167 [UHS_SDR12] = 25000000,
168 [UHS_SDR25] = 50000000,
169 [UHS_SDR50] = 100000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200170 [UHS_DDR50] = 50000000,
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100171 [UHS_SDR104] = 208000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200172 [MMC_HS_200] = 200000000,
Peng Fan3dd26262018-08-10 14:07:54 +0800173 [MMC_HS_400] = 200000000,
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200174 };
175
176 if (mode == MMC_LEGACY)
177 return mmc->legacy_speed;
178 else if (mode >= MMC_MODES_END)
179 return 0;
180 else
181 return freqs[mode];
182}
183
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200184static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
185{
186 mmc->selected_mode = mode;
Jean-Jacques Hiblot05038572017-09-21 16:29:55 +0200187 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200188 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900189 pr_debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
190 mmc->tran_speed / 1000000);
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +0200191 return 0;
192}
193
Simon Glasse7881d82017-07-29 11:35:31 -0600194#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassc0c76eb2016-06-12 23:30:20 -0600195int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
196{
197 int ret;
198
199 mmmc_trace_before_send(mmc, cmd);
200 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
201 mmmc_trace_after_send(mmc, cmd, ret);
202
Marek Vasut8635ff92012-03-15 18:41:35 +0000203 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500204}
Simon Glass8ca51e52016-06-12 23:30:22 -0600205#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500206
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200207int mmc_send_status(struct mmc *mmc, unsigned int *status)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000208{
209 struct mmc_cmd cmd;
Jan Kloetzked617c422012-02-05 22:29:12 +0000210 int err, retries = 5;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000211
212 cmd.cmdidx = MMC_CMD_SEND_STATUS;
213 cmd.resp_type = MMC_RSP_R1;
Marek Vasutaaf3d412011-08-10 09:24:48 +0200214 if (!mmc_host_is_spi(mmc))
215 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000216
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200217 while (retries--) {
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000218 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzked617c422012-02-05 22:29:12 +0000219 if (!err) {
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200220 mmc_trace_state(mmc, &cmd);
221 *status = cmd.response[0];
222 return 0;
223 }
224 }
225 mmc_trace_state(mmc, &cmd);
226 return -ECOMM;
227}
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +0200228
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200229int mmc_poll_for_busy(struct mmc *mmc, int timeout)
230{
231 unsigned int status;
232 int err;
233
Jean-Jacques Hiblotcd0b80e2019-07-02 10:53:53 +0200234 err = mmc_wait_dat0(mmc, 1, timeout);
235 if (err != -ENOSYS)
236 return err;
237
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200238 while (1) {
239 err = mmc_send_status(mmc, &status);
240 if (err)
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000241 return err;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000242
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200243 if ((status & MMC_STATUS_RDY_FOR_DATA) &&
244 (status & MMC_STATUS_CURR_STATE) !=
245 MMC_STATE_PRG)
246 break;
247
248 if (status & MMC_STATUS_MASK) {
249#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
250 pr_err("Status Error: 0x%08x\n", status);
251#endif
252 return -ECOMM;
253 }
254
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500255 if (timeout-- <= 0)
256 break;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000257
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500258 udelay(1000);
259 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000260
Jongman Heo5b0c9422012-06-03 21:32:13 +0000261 if (timeout <= 0) {
Paul Burton56196822013-09-04 16:12:25 +0100262#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100263 pr_err("Timeout waiting card ready\n");
Paul Burton56196822013-09-04 16:12:25 +0100264#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900265 return -ETIMEDOUT;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000266 }
267
268 return 0;
269}
270
Paul Burtonda61fa52013-09-09 15:30:26 +0100271int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Fleming272cc702008-10-30 16:41:01 -0500272{
273 struct mmc_cmd cmd;
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200274 int err;
Andy Fleming272cc702008-10-30 16:41:01 -0500275
Andrew Gabbasov786e8f82014-12-01 06:59:09 -0600276 if (mmc->ddr_mode)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900277 return 0;
278
Andy Fleming272cc702008-10-30 16:41:01 -0500279 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
280 cmd.resp_type = MMC_RSP_R1;
281 cmd.cmdarg = len;
Andy Fleming272cc702008-10-30 16:41:01 -0500282
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +0200283 err = mmc_send_cmd(mmc, &cmd, NULL);
284
285#ifdef CONFIG_MMC_QUIRKS
286 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
287 int retries = 4;
288 /*
289 * It has been seen that SET_BLOCKLEN may fail on the first
290 * attempt, let's try a few more time
291 */
292 do {
293 err = mmc_send_cmd(mmc, &cmd, NULL);
294 if (!err)
295 break;
296 } while (retries--);
297 }
298#endif
299
300 return err;
Andy Fleming272cc702008-10-30 16:41:01 -0500301}
302
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100303#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200304static const u8 tuning_blk_pattern_4bit[] = {
305 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
306 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
307 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
308 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
309 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
310 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
311 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
312 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
313};
314
315static const u8 tuning_blk_pattern_8bit[] = {
316 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
317 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
318 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
319 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
320 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
321 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
322 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
323 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
324 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
325 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
326 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
327 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
328 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
329 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
330 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
331 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
332};
333
334int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
335{
336 struct mmc_cmd cmd;
337 struct mmc_data data;
338 const u8 *tuning_block_pattern;
339 int size, err;
340
341 if (mmc->bus_width == 8) {
342 tuning_block_pattern = tuning_blk_pattern_8bit;
343 size = sizeof(tuning_blk_pattern_8bit);
344 } else if (mmc->bus_width == 4) {
345 tuning_block_pattern = tuning_blk_pattern_4bit;
346 size = sizeof(tuning_blk_pattern_4bit);
347 } else {
348 return -EINVAL;
349 }
350
351 ALLOC_CACHE_ALIGN_BUFFER(u8, data_buf, size);
352
353 cmd.cmdidx = opcode;
354 cmd.cmdarg = 0;
355 cmd.resp_type = MMC_RSP_R1;
356
357 data.dest = (void *)data_buf;
358 data.blocks = 1;
359 data.blocksize = size;
360 data.flags = MMC_DATA_READ;
361
362 err = mmc_send_cmd(mmc, &cmd, &data);
363 if (err)
364 return err;
365
366 if (memcmp(data_buf, tuning_block_pattern, size))
367 return -EIO;
368
369 return 0;
370}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100371#endif
Jean-Jacques Hiblot9815e3b2017-09-21 16:30:12 +0200372
Sascha Silbeff8fef52013-06-14 13:07:25 +0200373static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000374 lbaint_t blkcnt)
Andy Fleming272cc702008-10-30 16:41:01 -0500375{
376 struct mmc_cmd cmd;
377 struct mmc_data data;
378
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700379 if (blkcnt > 1)
380 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
381 else
382 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Fleming272cc702008-10-30 16:41:01 -0500383
384 if (mmc->high_capacity)
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700385 cmd.cmdarg = start;
Andy Fleming272cc702008-10-30 16:41:01 -0500386 else
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700387 cmd.cmdarg = start * mmc->read_bl_len;
Andy Fleming272cc702008-10-30 16:41:01 -0500388
389 cmd.resp_type = MMC_RSP_R1;
Andy Fleming272cc702008-10-30 16:41:01 -0500390
391 data.dest = dst;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700392 data.blocks = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500393 data.blocksize = mmc->read_bl_len;
394 data.flags = MMC_DATA_READ;
395
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700396 if (mmc_send_cmd(mmc, &cmd, &data))
397 return 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500398
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700399 if (blkcnt > 1) {
400 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
401 cmd.cmdarg = 0;
402 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700403 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton56196822013-09-04 16:12:25 +0100404#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100405 pr_err("mmc fail to send stop cmd\n");
Paul Burton56196822013-09-04 16:12:25 +0100406#endif
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700407 return 0;
408 }
Andy Fleming272cc702008-10-30 16:41:01 -0500409 }
410
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700411 return blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500412}
413
Simon Glassc4d660d2017-07-04 13:31:19 -0600414#if CONFIG_IS_ENABLED(BLK)
Simon Glass7dba0b92016-06-12 23:30:15 -0600415ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600416#else
Simon Glass7dba0b92016-06-12 23:30:15 -0600417ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
418 void *dst)
Simon Glass33fb2112016-05-01 13:52:41 -0600419#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500420{
Simon Glassc4d660d2017-07-04 13:31:19 -0600421#if CONFIG_IS_ENABLED(BLK)
Simon Glass33fb2112016-05-01 13:52:41 -0600422 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
423#endif
Simon Glassbcce53d2016-02-29 15:25:51 -0700424 int dev_num = block_dev->devnum;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700425 int err;
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700426 lbaint_t cur, blocks_todo = blkcnt;
Andy Fleming272cc702008-10-30 16:41:01 -0500427
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700428 if (blkcnt == 0)
429 return 0;
430
431 struct mmc *mmc = find_mmc_device(dev_num);
Andy Fleming272cc702008-10-30 16:41:01 -0500432 if (!mmc)
433 return 0;
434
Marek Vasutb5b838f2016-12-01 02:06:33 +0100435 if (CONFIG_IS_ENABLED(MMC_TINY))
436 err = mmc_switch_part(mmc, block_dev->hwpart);
437 else
438 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
439
Stephen Warren873cc1d2015-12-07 11:38:49 -0700440 if (err < 0)
441 return 0;
442
Simon Glassc40fdca2016-05-01 13:52:35 -0600443 if ((start + blkcnt) > block_dev->lba) {
Paul Burton56196822013-09-04 16:12:25 +0100444#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100445 pr_err("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
446 start + blkcnt, block_dev->lba);
Paul Burton56196822013-09-04 16:12:25 +0100447#endif
Lei Wend2bf29e2010-09-13 22:07:27 +0800448 return 0;
449 }
Andy Fleming272cc702008-10-30 16:41:01 -0500450
Simon Glass11692992015-06-23 15:38:50 -0600451 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900452 pr_debug("%s: Failed to set blocklen\n", __func__);
Andy Fleming272cc702008-10-30 16:41:01 -0500453 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600454 }
Andy Fleming272cc702008-10-30 16:41:01 -0500455
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700456 do {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200457 cur = (blocks_todo > mmc->cfg->b_max) ?
458 mmc->cfg->b_max : blocks_todo;
Simon Glass11692992015-06-23 15:38:50 -0600459 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900460 pr_debug("%s: Failed to read blocks\n", __func__);
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700461 return 0;
Simon Glass11692992015-06-23 15:38:50 -0600462 }
Alagu Sankar4a1a06b2010-10-25 07:23:56 -0700463 blocks_todo -= cur;
464 start += cur;
465 dst += cur * mmc->read_bl_len;
466 } while (blocks_todo > 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500467
468 return blkcnt;
469}
470
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000471static int mmc_go_idle(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -0500472{
473 struct mmc_cmd cmd;
474 int err;
475
476 udelay(1000);
477
478 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
479 cmd.cmdarg = 0;
480 cmd.resp_type = MMC_RSP_NONE;
Andy Fleming272cc702008-10-30 16:41:01 -0500481
482 err = mmc_send_cmd(mmc, &cmd, NULL);
483
484 if (err)
485 return err;
486
487 udelay(2000);
488
489 return 0;
490}
491
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100492#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200493static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
494{
495 struct mmc_cmd cmd;
496 int err = 0;
497
498 /*
499 * Send CMD11 only if the request is to switch the card to
500 * 1.8V signalling.
501 */
502 if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
503 return mmc_set_signal_voltage(mmc, signal_voltage);
504
505 cmd.cmdidx = SD_CMD_SWITCH_UHS18V;
506 cmd.cmdarg = 0;
507 cmd.resp_type = MMC_RSP_R1;
508
509 err = mmc_send_cmd(mmc, &cmd, NULL);
510 if (err)
511 return err;
512
513 if (!mmc_host_is_spi(mmc) && (cmd.response[0] & MMC_STATUS_ERROR))
514 return -EIO;
515
516 /*
517 * The card should drive cmd and dat[0:3] low immediately
518 * after the response of cmd11, but wait 100 us to be sure
519 */
520 err = mmc_wait_dat0(mmc, 0, 100);
521 if (err == -ENOSYS)
522 udelay(100);
523 else if (err)
524 return -ETIMEDOUT;
525
526 /*
527 * During a signal voltage level switch, the clock must be gated
528 * for 5 ms according to the SD spec
529 */
Jaehoon Chung65117182018-01-26 19:25:29 +0900530 mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200531
532 err = mmc_set_signal_voltage(mmc, signal_voltage);
533 if (err)
534 return err;
535
536 /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
537 mdelay(10);
Jaehoon Chung65117182018-01-26 19:25:29 +0900538 mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200539
540 /*
541 * Failure to switch is indicated by the card holding
542 * dat[0:3] low. Wait for at least 1 ms according to spec
543 */
544 err = mmc_wait_dat0(mmc, 1, 1000);
545 if (err == -ENOSYS)
546 udelay(1000);
547 else if (err)
548 return -ETIMEDOUT;
549
550 return 0;
551}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100552#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200553
554static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
Andy Fleming272cc702008-10-30 16:41:01 -0500555{
556 int timeout = 1000;
557 int err;
558 struct mmc_cmd cmd;
559
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500560 while (1) {
Andy Fleming272cc702008-10-30 16:41:01 -0500561 cmd.cmdidx = MMC_CMD_APP_CMD;
562 cmd.resp_type = MMC_RSP_R1;
563 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500564
565 err = mmc_send_cmd(mmc, &cmd, NULL);
566
567 if (err)
568 return err;
569
570 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
571 cmd.resp_type = MMC_RSP_R3;
Stefano Babic250de122010-01-20 18:20:39 +0100572
573 /*
574 * Most cards do not answer if some reserved bits
575 * in the ocr are set. However, Some controller
576 * can set bit 7 (reserved for low voltages), but
577 * how to manage low voltages SD card is not yet
578 * specified.
579 */
Thomas Choud52ebf12010-12-24 13:12:21 +0000580 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200581 (mmc->cfg->voltages & 0xff8000);
Andy Fleming272cc702008-10-30 16:41:01 -0500582
583 if (mmc->version == SD_VERSION_2)
584 cmd.cmdarg |= OCR_HCS;
585
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200586 if (uhs_en)
587 cmd.cmdarg |= OCR_S18R;
588
Andy Fleming272cc702008-10-30 16:41:01 -0500589 err = mmc_send_cmd(mmc, &cmd, NULL);
590
591 if (err)
592 return err;
593
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500594 if (cmd.response[0] & OCR_BUSY)
595 break;
Andy Fleming272cc702008-10-30 16:41:01 -0500596
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500597 if (timeout-- <= 0)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900598 return -EOPNOTSUPP;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500599
600 udelay(1000);
601 }
Andy Fleming272cc702008-10-30 16:41:01 -0500602
603 if (mmc->version != SD_VERSION_2)
604 mmc->version = SD_VERSION_1_0;
605
Thomas Choud52ebf12010-12-24 13:12:21 +0000606 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
607 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
608 cmd.resp_type = MMC_RSP_R3;
609 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000610
611 err = mmc_send_cmd(mmc, &cmd, NULL);
612
613 if (err)
614 return err;
615 }
616
Rabin Vincent998be3d2009-04-05 13:30:56 +0530617 mmc->ocr = cmd.response[0];
Andy Fleming272cc702008-10-30 16:41:01 -0500618
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100619#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200620 if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x41000000)
621 == 0x41000000) {
622 err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
623 if (err)
624 return err;
625 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100626#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +0200627
Andy Fleming272cc702008-10-30 16:41:01 -0500628 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
629 mmc->rca = 0;
630
631 return 0;
632}
633
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500634static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Fleming272cc702008-10-30 16:41:01 -0500635{
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500636 struct mmc_cmd cmd;
Andy Fleming272cc702008-10-30 16:41:01 -0500637 int err;
638
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500639 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
640 cmd.resp_type = MMC_RSP_R3;
641 cmd.cmdarg = 0;
Rob Herring5a203972015-03-23 17:56:59 -0500642 if (use_arg && !mmc_host_is_spi(mmc))
643 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou93bfd612014-03-11 19:34:20 +0200644 (mmc->cfg->voltages &
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500645 (mmc->ocr & OCR_VOLTAGE_MASK)) |
646 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000647
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500648 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chioue9550442012-11-28 15:21:13 +0000649 if (err)
650 return err;
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500651 mmc->ocr = cmd.response[0];
Che-Liang Chioue9550442012-11-28 15:21:13 +0000652 return 0;
653}
654
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200655static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000656{
Che-Liang Chioue9550442012-11-28 15:21:13 +0000657 int err, i;
658
Andy Fleming272cc702008-10-30 16:41:01 -0500659 /* Some cards seem to need this */
660 mmc_go_idle(mmc);
661
Raffaele Recalcati31cacba2011-03-11 02:01:13 +0000662 /* Asking to the card its capabilities */
Che-Liang Chioue9550442012-11-28 15:21:13 +0000663 for (i = 0; i < 2; i++) {
Andrew Gabbasov5289b532015-03-19 07:44:04 -0500664 err = mmc_send_op_cond_iter(mmc, i != 0);
Andy Fleming272cc702008-10-30 16:41:01 -0500665 if (err)
666 return err;
667
Che-Liang Chioue9550442012-11-28 15:21:13 +0000668 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500669 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500670 break;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000671 }
Andrew Gabbasovbd47c132015-03-19 07:44:07 -0500672 mmc->op_cond_pending = 1;
673 return 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000674}
Andy Fleming272cc702008-10-30 16:41:01 -0500675
Jeroen Hofstee750121c2014-07-12 21:24:08 +0200676static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chioue9550442012-11-28 15:21:13 +0000677{
678 struct mmc_cmd cmd;
679 int timeout = 1000;
Vipul Kumar36332b62018-05-03 12:20:54 +0530680 ulong start;
Che-Liang Chioue9550442012-11-28 15:21:13 +0000681 int err;
682
683 mmc->op_cond_pending = 0;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500684 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lud188b112016-08-02 15:33:18 +0800685 /* Some cards seem to need this */
686 mmc_go_idle(mmc);
687
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500688 start = get_timer(0);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500689 while (1) {
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500690 err = mmc_send_op_cond_iter(mmc, 1);
691 if (err)
692 return err;
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500693 if (mmc->ocr & OCR_BUSY)
694 break;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500695 if (get_timer(start) > timeout)
Jaehoon Chung915ffa52016-07-19 16:33:36 +0900696 return -EOPNOTSUPP;
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500697 udelay(100);
Andrew Gabbasov1677eef2015-03-19 07:44:06 -0500698 }
Andrew Gabbasovcc17c012015-03-19 07:44:05 -0500699 }
Andy Fleming272cc702008-10-30 16:41:01 -0500700
Thomas Choud52ebf12010-12-24 13:12:21 +0000701 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
702 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
703 cmd.resp_type = MMC_RSP_R3;
704 cmd.cmdarg = 0;
Thomas Choud52ebf12010-12-24 13:12:21 +0000705
706 err = mmc_send_cmd(mmc, &cmd, NULL);
707
708 if (err)
709 return err;
Andrew Gabbasova626c8d2015-03-19 07:44:03 -0500710
711 mmc->ocr = cmd.response[0];
Thomas Choud52ebf12010-12-24 13:12:21 +0000712 }
713
Andy Fleming272cc702008-10-30 16:41:01 -0500714 mmc->version = MMC_VERSION_UNKNOWN;
Andy Fleming272cc702008-10-30 16:41:01 -0500715
716 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrendef816a2014-01-30 16:11:12 -0700717 mmc->rca = 1;
Andy Fleming272cc702008-10-30 16:41:01 -0500718
719 return 0;
720}
721
722
Kim Phillipsfdbb8732012-10-29 13:34:43 +0000723static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Fleming272cc702008-10-30 16:41:01 -0500724{
725 struct mmc_cmd cmd;
726 struct mmc_data data;
727 int err;
728
729 /* Get the Card Status Register */
730 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
731 cmd.resp_type = MMC_RSP_R1;
732 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -0500733
Yoshihiro Shimodacdfd1ac2012-06-07 19:09:11 +0000734 data.dest = (char *)ext_csd;
Andy Fleming272cc702008-10-30 16:41:01 -0500735 data.blocks = 1;
Simon Glass8bfa1952013-04-03 08:54:30 +0000736 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -0500737 data.flags = MMC_DATA_READ;
738
739 err = mmc_send_cmd(mmc, &cmd, &data);
740
741 return err;
742}
743
Marek Vasut68925502019-02-06 11:34:27 +0100744static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
745 bool send_status)
Andy Fleming272cc702008-10-30 16:41:01 -0500746{
747 struct mmc_cmd cmd;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000748 int timeout = 1000;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100749 int retries = 3;
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000750 int ret;
Andy Fleming272cc702008-10-30 16:41:01 -0500751
752 cmd.cmdidx = MMC_CMD_SWITCH;
753 cmd.resp_type = MMC_RSP_R1b;
754 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000755 (index << 16) |
756 (value << 8);
Andy Fleming272cc702008-10-30 16:41:01 -0500757
Maxime Riparda9003dc2016-11-04 16:18:08 +0100758 while (retries > 0) {
759 ret = mmc_send_cmd(mmc, &cmd, NULL);
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000760
Marek Vasut68925502019-02-06 11:34:27 +0100761 if (ret) {
762 retries--;
763 continue;
Maxime Riparda9003dc2016-11-04 16:18:08 +0100764 }
765
Marek Vasut68925502019-02-06 11:34:27 +0100766 if (!send_status) {
767 mdelay(50);
768 return 0;
769 }
770
771 /* Waiting for the ready status */
Jean-Jacques Hiblot863d1002019-07-02 10:53:52 +0200772 return mmc_poll_for_busy(mmc, timeout);
Maxime Riparda9003dc2016-11-04 16:18:08 +0100773 }
Raffaele Recalcati5d4fc8d2011-03-11 02:01:12 +0000774
775 return ret;
776
Andy Fleming272cc702008-10-30 16:41:01 -0500777}
778
Marek Vasut68925502019-02-06 11:34:27 +0100779int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
780{
781 return __mmc_switch(mmc, set, index, value, true);
782}
783
Marek Vasut62d77ce2018-04-15 00:37:11 +0200784#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100785static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
786 bool hsdowngrade)
Andy Fleming272cc702008-10-30 16:41:01 -0500787{
Andy Fleming272cc702008-10-30 16:41:01 -0500788 int err;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200789 int speed_bits;
790
791 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
792
793 switch (mode) {
794 case MMC_HS:
795 case MMC_HS_52:
796 case MMC_DDR_52:
797 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200798 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100799#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200800 case MMC_HS_200:
801 speed_bits = EXT_CSD_TIMING_HS200;
802 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100803#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800804#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
805 case MMC_HS_400:
806 speed_bits = EXT_CSD_TIMING_HS400;
807 break;
808#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200809 case MMC_LEGACY:
810 speed_bits = EXT_CSD_TIMING_LEGACY;
811 break;
812 default:
813 return -EINVAL;
814 }
Marek Vasut68925502019-02-06 11:34:27 +0100815
816 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
817 speed_bits, !hsdowngrade);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200818 if (err)
819 return err;
820
Marek Vasutb9a2a0e2019-01-03 21:19:24 +0100821#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
822 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
823 /*
824 * In case the eMMC is in HS200/HS400 mode and we are downgrading
825 * to HS mode, the card clock are still running much faster than
826 * the supported HS mode clock, so we can not reliably read out
827 * Extended CSD. Reconfigure the controller to run at HS mode.
828 */
829 if (hsdowngrade) {
830 mmc_select_mode(mmc, MMC_HS);
831 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
832 }
833#endif
834
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200835 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
836 /* Now check to see that it worked */
837 err = mmc_send_ext_csd(mmc, test_csd);
838 if (err)
839 return err;
840
841 /* No high-speed support */
842 if (!test_csd[EXT_CSD_HS_TIMING])
843 return -ENOTSUPP;
844 }
845
846 return 0;
847}
848
849static int mmc_get_capabilities(struct mmc *mmc)
850{
851 u8 *ext_csd = mmc->ext_csd;
852 char cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500853
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +0100854 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -0500855
Thomas Choud52ebf12010-12-24 13:12:21 +0000856 if (mmc_host_is_spi(mmc))
857 return 0;
858
Andy Fleming272cc702008-10-30 16:41:01 -0500859 /* Only version 4 supports high-speed */
860 if (mmc->version < MMC_VERSION_4)
861 return 0;
862
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200863 if (!ext_csd) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +0100864 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200865 return -ENOTSUPP;
866 }
867
Andrew Gabbasovfc5b32f2014-12-25 10:22:25 -0600868 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
869
Peng Fan3dd26262018-08-10 14:07:54 +0800870 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +0200871 mmc->cardtype = cardtype;
Andy Fleming272cc702008-10-30 16:41:01 -0500872
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100873#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +0200874 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
875 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
876 mmc->card_caps |= MMC_MODE_HS200;
877 }
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +0100878#endif
Peng Fan3dd26262018-08-10 14:07:54 +0800879#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
880 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
881 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
882 mmc->card_caps |= MMC_MODE_HS400;
883 }
884#endif
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900885 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200886 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900887 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200888 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chungd22e3d42014-05-16 13:59:54 +0900889 }
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +0200890 if (cardtype & EXT_CSD_CARD_TYPE_26)
891 mmc->card_caps |= MMC_MODE_HS;
Andy Fleming272cc702008-10-30 16:41:01 -0500892
893 return 0;
894}
Marek Vasut62d77ce2018-04-15 00:37:11 +0200895#endif
Andy Fleming272cc702008-10-30 16:41:01 -0500896
Stephen Warrenf866a462013-06-11 15:14:01 -0600897static int mmc_set_capacity(struct mmc *mmc, int part_num)
898{
899 switch (part_num) {
900 case 0:
901 mmc->capacity = mmc->capacity_user;
902 break;
903 case 1:
904 case 2:
905 mmc->capacity = mmc->capacity_boot;
906 break;
907 case 3:
908 mmc->capacity = mmc->capacity_rpmb;
909 break;
910 case 4:
911 case 5:
912 case 6:
913 case 7:
914 mmc->capacity = mmc->capacity_gp[part_num - 4];
915 break;
916 default:
917 return -1;
918 }
919
Simon Glassc40fdca2016-05-01 13:52:35 -0600920 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrenf866a462013-06-11 15:14:01 -0600921
922 return 0;
923}
924
Marek Vasut72119aa2019-05-31 15:22:44 +0200925#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200926static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
927{
928 int forbidden = 0;
929 bool change = false;
930
931 if (part_num & PART_ACCESS_MASK)
Marek Vasut72119aa2019-05-31 15:22:44 +0200932 forbidden = MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200933
934 if (MMC_CAP(mmc->selected_mode) & forbidden) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900935 pr_debug("selected mode (%s) is forbidden for part %d\n",
936 mmc_mode_name(mmc->selected_mode), part_num);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200937 change = true;
938 } else if (mmc->selected_mode != mmc->best_mode) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +0900939 pr_debug("selected mode is not optimal\n");
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200940 change = true;
941 }
942
943 if (change)
944 return mmc_select_mode_and_width(mmc,
945 mmc->card_caps & ~forbidden);
946
947 return 0;
948}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +0100949#else
950static inline int mmc_boot_part_access_chk(struct mmc *mmc,
951 unsigned int part_num)
952{
953 return 0;
954}
955#endif
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200956
Simon Glass7dba0b92016-06-12 23:30:15 -0600957int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wenbc897b12011-05-02 16:26:26 +0000958{
Stephen Warrenf866a462013-06-11 15:14:01 -0600959 int ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000960
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +0200961 ret = mmc_boot_part_access_chk(mmc, part_num);
962 if (ret)
963 return ret;
964
Stephen Warrenf866a462013-06-11 15:14:01 -0600965 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
966 (mmc->part_config & ~PART_ACCESS_MASK)
967 | (part_num & PART_ACCESS_MASK));
Stephen Warrenf866a462013-06-11 15:14:01 -0600968
Peter Bigot6dc93e72014-09-02 18:31:23 -0500969 /*
970 * Set the capacity if the switch succeeded or was intended
971 * to return to representing the raw device.
972 */
Stephen Warren873cc1d2015-12-07 11:38:49 -0700973 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot6dc93e72014-09-02 18:31:23 -0500974 ret = mmc_set_capacity(mmc, part_num);
Simon Glassfdbb1392016-05-01 13:52:37 -0600975 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren873cc1d2015-12-07 11:38:49 -0700976 }
Peter Bigot6dc93e72014-09-02 18:31:23 -0500977
978 return ret;
Lei Wenbc897b12011-05-02 16:26:26 +0000979}
980
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +0100981#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100982int mmc_hwpart_config(struct mmc *mmc,
983 const struct mmc_hwpart_conf *conf,
984 enum mmc_hwpart_conf_mode mode)
985{
986 u8 part_attrs = 0;
987 u32 enh_size_mult;
988 u32 enh_start_addr;
989 u32 gp_size_mult[4];
990 u32 max_enh_size_mult;
991 u32 tot_enh_size_mult = 0;
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +0100992 u8 wr_rel_set;
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +0100993 int i, pidx, err;
994 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
995
996 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
997 return -EINVAL;
998
999 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001000 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001001 return -EMEDIUMTYPE;
1002 }
1003
1004 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001005 pr_err("Card does not support partitioning\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001006 return -EMEDIUMTYPE;
1007 }
1008
1009 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001010 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001011 return -EMEDIUMTYPE;
1012 }
1013
1014 /* check partition alignment and total enhanced size */
1015 if (conf->user.enh_size) {
1016 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1017 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001018 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001019 "size aligned\n");
1020 return -EINVAL;
1021 }
1022 part_attrs |= EXT_CSD_ENH_USR;
1023 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1024 if (mmc->high_capacity) {
1025 enh_start_addr = conf->user.enh_start;
1026 } else {
1027 enh_start_addr = (conf->user.enh_start << 9);
1028 }
1029 } else {
1030 enh_size_mult = 0;
1031 enh_start_addr = 0;
1032 }
1033 tot_enh_size_mult += enh_size_mult;
1034
1035 for (pidx = 0; pidx < 4; pidx++) {
1036 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001037 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001038 "aligned\n", pidx+1);
1039 return -EINVAL;
1040 }
1041 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1042 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1043 part_attrs |= EXT_CSD_ENH_GP(pidx);
1044 tot_enh_size_mult += gp_size_mult[pidx];
1045 }
1046 }
1047
1048 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001049 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001050 return -EMEDIUMTYPE;
1051 }
1052
1053 err = mmc_send_ext_csd(mmc, ext_csd);
1054 if (err)
1055 return err;
1056
1057 max_enh_size_mult =
1058 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1059 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1060 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1061 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001062 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001063 tot_enh_size_mult, max_enh_size_mult);
1064 return -EMEDIUMTYPE;
1065 }
1066
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001067 /* The default value of EXT_CSD_WR_REL_SET is device
1068 * dependent, the values can only be changed if the
1069 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1070 * changed only once and before partitioning is completed. */
1071 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1072 if (conf->user.wr_rel_change) {
1073 if (conf->user.wr_rel_set)
1074 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1075 else
1076 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1077 }
1078 for (pidx = 0; pidx < 4; pidx++) {
1079 if (conf->gp_part[pidx].wr_rel_change) {
1080 if (conf->gp_part[pidx].wr_rel_set)
1081 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1082 else
1083 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1084 }
1085 }
1086
1087 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1088 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1089 puts("Card does not support host controlled partition write "
1090 "reliability settings\n");
1091 return -EMEDIUMTYPE;
1092 }
1093
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001094 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1095 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001096 pr_err("Card already partitioned\n");
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001097 return -EPERM;
1098 }
1099
1100 if (mode == MMC_HWPART_CONF_CHECK)
1101 return 0;
1102
1103 /* Partitioning requires high-capacity size definitions */
1104 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1105 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1106 EXT_CSD_ERASE_GROUP_DEF, 1);
1107
1108 if (err)
1109 return err;
1110
1111 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1112
1113 /* update erase group size to be high-capacity */
1114 mmc->erase_grp_size =
1115 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
1116
1117 }
1118
1119 /* all OK, write the configuration */
1120 for (i = 0; i < 4; i++) {
1121 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1122 EXT_CSD_ENH_START_ADDR+i,
1123 (enh_start_addr >> (i*8)) & 0xFF);
1124 if (err)
1125 return err;
1126 }
1127 for (i = 0; i < 3; i++) {
1128 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1129 EXT_CSD_ENH_SIZE_MULT+i,
1130 (enh_size_mult >> (i*8)) & 0xFF);
1131 if (err)
1132 return err;
1133 }
1134 for (pidx = 0; pidx < 4; pidx++) {
1135 for (i = 0; i < 3; i++) {
1136 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1137 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1138 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1139 if (err)
1140 return err;
1141 }
1142 }
1143 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1144 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1145 if (err)
1146 return err;
1147
1148 if (mode == MMC_HWPART_CONF_SET)
1149 return 0;
1150
Diego Santa Cruz8dda5b0e2014-12-23 10:50:31 +01001151 /* The WR_REL_SET is a write-once register but shall be
1152 * written before setting PART_SETTING_COMPLETED. As it is
1153 * write-once we can only write it when completing the
1154 * partitioning. */
1155 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1156 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1157 EXT_CSD_WR_REL_SET, wr_rel_set);
1158 if (err)
1159 return err;
1160 }
1161
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001162 /* Setting PART_SETTING_COMPLETED confirms the partition
1163 * configuration but it only becomes effective after power
1164 * cycle, so we do not adjust the partition related settings
1165 * in the mmc struct. */
1166
1167 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1168 EXT_CSD_PARTITION_SETTING,
1169 EXT_CSD_PARTITION_SETTING_COMPLETED);
1170 if (err)
1171 return err;
1172
1173 return 0;
1174}
Jean-Jacques Hiblotcf177892017-11-30 17:44:02 +01001175#endif
Diego Santa Cruzac9da0e2014-12-23 10:50:29 +01001176
Simon Glasse7881d82017-07-29 11:35:31 -06001177#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Reding48972d92012-01-02 01:15:37 +00001178int mmc_getcd(struct mmc *mmc)
1179{
1180 int cd;
1181
1182 cd = board_mmc_getcd(mmc);
1183
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001184 if (cd < 0) {
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001185 if (mmc->cfg->ops->getcd)
1186 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardd4e1da42013-03-21 04:00:03 +00001187 else
1188 cd = 1;
1189 }
Thierry Reding48972d92012-01-02 01:15:37 +00001190
1191 return cd;
1192}
Simon Glass8ca51e52016-06-12 23:30:22 -06001193#endif
Thierry Reding48972d92012-01-02 01:15:37 +00001194
Marek Vasut62d77ce2018-04-15 00:37:11 +02001195#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillipsfdbb8732012-10-29 13:34:43 +00001196static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Fleming272cc702008-10-30 16:41:01 -05001197{
1198 struct mmc_cmd cmd;
1199 struct mmc_data data;
1200
1201 /* Switch the frequency */
1202 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1203 cmd.resp_type = MMC_RSP_R1;
1204 cmd.cmdarg = (mode << 31) | 0xffffff;
1205 cmd.cmdarg &= ~(0xf << (group * 4));
1206 cmd.cmdarg |= value << (group * 4);
Andy Fleming272cc702008-10-30 16:41:01 -05001207
1208 data.dest = (char *)resp;
1209 data.blocksize = 64;
1210 data.blocks = 1;
1211 data.flags = MMC_DATA_READ;
1212
1213 return mmc_send_cmd(mmc, &cmd, &data);
1214}
1215
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001216static int sd_get_capabilities(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001217{
1218 int err;
1219 struct mmc_cmd cmd;
Suniel Mahesh18e7c8f2017-10-05 11:32:00 +05301220 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1221 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Fleming272cc702008-10-30 16:41:01 -05001222 struct mmc_data data;
1223 int timeout;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001224#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001225 u32 sd3_bus_mode;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001226#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001227
Jean-Jacques Hiblot00e446f2017-11-30 17:43:56 +01001228 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05001229
Thomas Choud52ebf12010-12-24 13:12:21 +00001230 if (mmc_host_is_spi(mmc))
1231 return 0;
1232
Andy Fleming272cc702008-10-30 16:41:01 -05001233 /* Read the SCR to find out if this card supports higher speeds */
1234 cmd.cmdidx = MMC_CMD_APP_CMD;
1235 cmd.resp_type = MMC_RSP_R1;
1236 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05001237
1238 err = mmc_send_cmd(mmc, &cmd, NULL);
1239
1240 if (err)
1241 return err;
1242
1243 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1244 cmd.resp_type = MMC_RSP_R1;
1245 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05001246
1247 timeout = 3;
1248
1249retry_scr:
Anton staaff781dd32011-10-03 13:54:59 +00001250 data.dest = (char *)scr;
Andy Fleming272cc702008-10-30 16:41:01 -05001251 data.blocksize = 8;
1252 data.blocks = 1;
1253 data.flags = MMC_DATA_READ;
1254
1255 err = mmc_send_cmd(mmc, &cmd, &data);
1256
1257 if (err) {
1258 if (timeout--)
1259 goto retry_scr;
1260
1261 return err;
1262 }
1263
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001264 mmc->scr[0] = __be32_to_cpu(scr[0]);
1265 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Fleming272cc702008-10-30 16:41:01 -05001266
1267 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng53e8e402016-03-17 21:53:13 -07001268 case 0:
1269 mmc->version = SD_VERSION_1_0;
1270 break;
1271 case 1:
1272 mmc->version = SD_VERSION_1_10;
1273 break;
1274 case 2:
1275 mmc->version = SD_VERSION_2;
1276 if ((mmc->scr[0] >> 15) & 0x1)
1277 mmc->version = SD_VERSION_3;
1278 break;
1279 default:
1280 mmc->version = SD_VERSION_1_0;
1281 break;
Andy Fleming272cc702008-10-30 16:41:01 -05001282 }
1283
Alagu Sankarb44c7082010-05-12 15:08:24 +05301284 if (mmc->scr[0] & SD_DATA_4BIT)
1285 mmc->card_caps |= MMC_MODE_4BIT;
1286
Andy Fleming272cc702008-10-30 16:41:01 -05001287 /* Version 1.0 doesn't support switching */
1288 if (mmc->version == SD_VERSION_1_0)
1289 return 0;
1290
1291 timeout = 4;
1292 while (timeout--) {
1293 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaff781dd32011-10-03 13:54:59 +00001294 (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001295
1296 if (err)
1297 return err;
1298
1299 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy4e3d89b2009-05-07 00:43:30 +03001300 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Fleming272cc702008-10-30 16:41:01 -05001301 break;
1302 }
1303
Andy Fleming272cc702008-10-30 16:41:01 -05001304 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001305 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1306 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Fleming272cc702008-10-30 16:41:01 -05001307
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001308#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001309 /* Version before 3.0 don't support UHS modes */
1310 if (mmc->version < SD_VERSION_3)
1311 return 0;
1312
1313 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1314 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1315 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1316 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1317 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1318 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1319 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1320 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1321 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1322 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1323 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001324#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001325
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001326 return 0;
1327}
1328
1329static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1330{
1331 int err;
1332
1333 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001334 int speed;
Macpaul Lin2c3fbf42011-11-28 16:31:09 +00001335
Marek Vasutcf345762018-11-18 03:25:08 +01001336 /* SD version 1.00 and 1.01 does not support CMD 6 */
1337 if (mmc->version == SD_VERSION_1_0)
1338 return 0;
1339
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001340 switch (mode) {
1341 case SD_LEGACY:
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001342 speed = UHS_SDR12_BUS_SPEED;
1343 break;
1344 case SD_HS:
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001345 speed = HIGH_SPEED_BUS_SPEED;
1346 break;
1347#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1348 case UHS_SDR12:
1349 speed = UHS_SDR12_BUS_SPEED;
1350 break;
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001351 case UHS_SDR25:
1352 speed = UHS_SDR25_BUS_SPEED;
1353 break;
1354 case UHS_SDR50:
1355 speed = UHS_SDR50_BUS_SPEED;
1356 break;
1357 case UHS_DDR50:
1358 speed = UHS_DDR50_BUS_SPEED;
1359 break;
1360 case UHS_SDR104:
1361 speed = UHS_SDR104_BUS_SPEED;
1362 break;
Jean-Jacques Hiblotbaef2072018-01-04 15:23:30 +01001363#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001364 default:
1365 return -EINVAL;
1366 }
1367
1368 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Andy Fleming272cc702008-10-30 16:41:01 -05001369 if (err)
1370 return err;
1371
Jean-Jacques Hiblota0276f32018-02-09 12:09:27 +01001372 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001373 return -ENOTSUPP;
1374
1375 return 0;
1376}
1377
Marek Vasutec360e62018-04-15 00:36:45 +02001378static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001379{
1380 int err;
1381 struct mmc_cmd cmd;
1382
1383 if ((w != 4) && (w != 1))
1384 return -EINVAL;
1385
1386 cmd.cmdidx = MMC_CMD_APP_CMD;
1387 cmd.resp_type = MMC_RSP_R1;
1388 cmd.cmdarg = mmc->rca << 16;
1389
1390 err = mmc_send_cmd(mmc, &cmd, NULL);
1391 if (err)
1392 return err;
1393
1394 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1395 cmd.resp_type = MMC_RSP_R1;
1396 if (w == 4)
1397 cmd.cmdarg = 2;
1398 else if (w == 1)
1399 cmd.cmdarg = 0;
1400 err = mmc_send_cmd(mmc, &cmd, NULL);
1401 if (err)
1402 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05001403
1404 return 0;
1405}
Marek Vasut62d77ce2018-04-15 00:37:11 +02001406#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001407
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001408#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fan3697e592016-09-01 11:13:38 +08001409static int sd_read_ssr(struct mmc *mmc)
1410{
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001411 static const unsigned int sd_au_size[] = {
1412 0, SZ_16K / 512, SZ_32K / 512,
1413 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1414 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1415 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1416 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1417 SZ_64M / 512,
1418 };
Peng Fan3697e592016-09-01 11:13:38 +08001419 int err, i;
1420 struct mmc_cmd cmd;
1421 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1422 struct mmc_data data;
1423 int timeout = 3;
1424 unsigned int au, eo, et, es;
1425
1426 cmd.cmdidx = MMC_CMD_APP_CMD;
1427 cmd.resp_type = MMC_RSP_R1;
1428 cmd.cmdarg = mmc->rca << 16;
1429
1430 err = mmc_send_cmd(mmc, &cmd, NULL);
1431 if (err)
1432 return err;
1433
1434 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1435 cmd.resp_type = MMC_RSP_R1;
1436 cmd.cmdarg = 0;
1437
1438retry_ssr:
1439 data.dest = (char *)ssr;
1440 data.blocksize = 64;
1441 data.blocks = 1;
1442 data.flags = MMC_DATA_READ;
1443
1444 err = mmc_send_cmd(mmc, &cmd, &data);
1445 if (err) {
1446 if (timeout--)
1447 goto retry_ssr;
1448
1449 return err;
1450 }
1451
1452 for (i = 0; i < 16; i++)
1453 ssr[i] = be32_to_cpu(ssr[i]);
1454
1455 au = (ssr[2] >> 12) & 0xF;
1456 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1457 mmc->ssr.au = sd_au_size[au];
1458 es = (ssr[3] >> 24) & 0xFF;
1459 es |= (ssr[2] & 0xFF) << 8;
1460 et = (ssr[3] >> 18) & 0x3F;
1461 if (es && et) {
1462 eo = (ssr[3] >> 16) & 0x3;
1463 mmc->ssr.erase_timeout = (et * 1000) / es;
1464 mmc->ssr.erase_offset = eo * 1000;
1465 }
1466 } else {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001467 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fan3697e592016-09-01 11:13:38 +08001468 }
1469
1470 return 0;
1471}
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001472#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001473/* frequency bases */
1474/* divided by 10 to be nice to platforms without floating point */
Mike Frysinger5f837c22010-10-20 01:15:53 +00001475static const int fbase[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001476 10000,
1477 100000,
1478 1000000,
1479 10000000,
1480};
1481
1482/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1483 * to platforms without floating point.
1484 */
Simon Glass61fe0762016-05-14 14:02:57 -06001485static const u8 multipliers[] = {
Andy Fleming272cc702008-10-30 16:41:01 -05001486 0, /* reserved */
1487 10,
1488 12,
1489 13,
1490 15,
1491 20,
1492 25,
1493 30,
1494 35,
1495 40,
1496 45,
1497 50,
1498 55,
1499 60,
1500 70,
1501 80,
1502};
1503
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001504static inline int bus_width(uint cap)
1505{
1506 if (cap == MMC_MODE_8BIT)
1507 return 8;
1508 if (cap == MMC_MODE_4BIT)
1509 return 4;
1510 if (cap == MMC_MODE_1BIT)
1511 return 1;
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01001512 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001513 return 0;
1514}
1515
Simon Glasse7881d82017-07-29 11:35:31 -06001516#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001517#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001518static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1519{
1520 return -ENOTSUPP;
1521}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001522#endif
Kishon Vijay Abraham Iec841202017-09-21 16:30:05 +02001523
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001524static int mmc_set_ios(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05001525{
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001526 int ret = 0;
1527
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02001528 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001529 ret = mmc->cfg->ops->set_ios(mmc);
1530
1531 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05001532}
Simon Glass8ca51e52016-06-12 23:30:22 -06001533#endif
Andy Fleming272cc702008-10-30 16:41:01 -05001534
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001535int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Fleming272cc702008-10-30 16:41:01 -05001536{
Jaehoon Chungc0fafe62018-01-23 14:04:30 +09001537 if (!disable) {
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001538 if (clock > mmc->cfg->f_max)
1539 clock = mmc->cfg->f_max;
Andy Fleming272cc702008-10-30 16:41:01 -05001540
Jaehoon Chung9546eb92018-01-17 19:36:58 +09001541 if (clock < mmc->cfg->f_min)
1542 clock = mmc->cfg->f_min;
1543 }
Andy Fleming272cc702008-10-30 16:41:01 -05001544
1545 mmc->clock = clock;
Kishon Vijay Abraham I35f67822017-09-21 16:30:03 +02001546 mmc->clk_disable = disable;
Andy Fleming272cc702008-10-30 16:41:01 -05001547
Jaehoon Chungd2faadb2018-01-26 19:25:30 +09001548 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1549
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001550 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001551}
1552
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001553static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Fleming272cc702008-10-30 16:41:01 -05001554{
1555 mmc->bus_width = width;
1556
Kishon Vijay Abraham I2a4d2122017-09-21 16:29:59 +02001557 return mmc_set_ios(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05001558}
1559
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001560#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1561/*
1562 * helper function to display the capabilities in a human
1563 * friendly manner. The capabilities include bus width and
1564 * supported modes.
1565 */
1566void mmc_dump_capabilities(const char *text, uint caps)
1567{
1568 enum bus_mode mode;
1569
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001570 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001571 if (caps & MMC_MODE_8BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001572 pr_debug("8, ");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001573 if (caps & MMC_MODE_4BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001574 pr_debug("4, ");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001575 if (caps & MMC_MODE_1BIT)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001576 pr_debug("1, ");
1577 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001578 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1579 if (MMC_CAP(mode) & caps)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001580 pr_debug("%s, ", mmc_mode_name(mode));
1581 pr_debug("\b\b]\n");
Jean-Jacques Hiblot4c9d2aa2017-09-21 16:29:54 +02001582}
1583#endif
1584
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001585struct mode_width_tuning {
1586 enum bus_mode mode;
1587 uint widths;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001588#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001589 uint tuning;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001590#endif
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001591};
1592
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001593#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001594int mmc_voltage_to_mv(enum mmc_voltage voltage)
1595{
1596 switch (voltage) {
1597 case MMC_SIGNAL_VOLTAGE_000: return 0;
1598 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1599 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1600 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1601 }
1602 return -EINVAL;
1603}
1604
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001605static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1606{
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001607 int err;
1608
1609 if (mmc->signal_voltage == signal_voltage)
1610 return 0;
1611
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001612 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001613 err = mmc_set_ios(mmc);
1614 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001615 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001616
1617 return err;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001618}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001619#else
1620static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1621{
1622 return 0;
1623}
1624#endif
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02001625
Marek Vasut62d77ce2018-04-15 00:37:11 +02001626#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001627static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001628#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1629#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001630 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001631 .mode = UHS_SDR104,
1632 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1633 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1634 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001635#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001636 {
1637 .mode = UHS_SDR50,
1638 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1639 },
1640 {
1641 .mode = UHS_DDR50,
1642 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1643 },
1644 {
1645 .mode = UHS_SDR25,
1646 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1647 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001648#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001649 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001650 .mode = SD_HS,
1651 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1652 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001653#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001654 {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001655 .mode = UHS_SDR12,
1656 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1657 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001658#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001659 {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001660 .mode = SD_LEGACY,
1661 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1662 }
1663};
1664
1665#define for_each_sd_mode_by_pref(caps, mwt) \
1666 for (mwt = sd_modes_by_pref;\
1667 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1668 mwt++) \
1669 if (caps & MMC_CAP(mwt->mode))
1670
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001671static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001672{
1673 int err;
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001674 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1675 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001676#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001677 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001678#else
1679 bool uhs_en = false;
1680#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001681 uint caps;
1682
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001683#ifdef DEBUG
1684 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001685 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001686#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001687
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001688 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001689 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001690
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001691 if (!uhs_en)
1692 caps &= ~UHS_CAPS;
1693
1694 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001695 uint *w;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001696
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001697 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001698 if (*w & caps & mwt->widths) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001699 pr_debug("trying mode %s width %d (at %d MHz)\n",
1700 mmc_mode_name(mwt->mode),
1701 bus_width(*w),
1702 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001703
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001704 /* configure the bus width (card + host) */
1705 err = sd_select_bus_width(mmc, bus_width(*w));
1706 if (err)
1707 goto error;
1708 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001709
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001710 /* configure the bus mode (card) */
1711 err = sd_set_card_speed(mmc, mwt->mode);
1712 if (err)
1713 goto error;
1714
1715 /* configure the bus mode (host) */
1716 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung65117182018-01-26 19:25:29 +09001717 mmc_set_clock(mmc, mmc->tran_speed,
1718 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001719
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001720#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001721 /* execute tuning if needed */
1722 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1723 err = mmc_execute_tuning(mmc,
1724 mwt->tuning);
1725 if (err) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001726 pr_debug("tuning failed\n");
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001727 goto error;
1728 }
1729 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001730#endif
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02001731
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001732#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001733 err = sd_read_ssr(mmc);
Peng Fan0a4c2b02018-03-05 16:20:40 +08001734 if (err)
Jean-Jacques Hiblot5b2e72f2018-01-04 15:23:33 +01001735 pr_warn("unable to read ssr\n");
1736#endif
1737 if (!err)
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001738 return 0;
1739
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001740error:
1741 /* revert to a safer bus speed */
1742 mmc_select_mode(mmc, SD_LEGACY);
Jaehoon Chung65117182018-01-26 19:25:29 +09001743 mmc_set_clock(mmc, mmc->tran_speed,
1744 MMC_CLK_ENABLE);
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001745 }
1746 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001747 }
1748
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001749 pr_err("unable to select a mode\n");
Jean-Jacques Hiblotd0c221f2017-09-21 16:29:57 +02001750 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001751}
1752
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001753/*
1754 * read the compare the part of ext csd that is constant.
1755 * This can be used to check that the transfer is working
1756 * as expected.
1757 */
1758static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
1759{
1760 int err;
1761 const u8 *ext_csd = mmc->ext_csd;
1762 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1763
Jean-Jacques Hiblot1de06b92017-11-30 17:43:58 +01001764 if (mmc->version < MMC_VERSION_4)
1765 return 0;
1766
Jean-Jacques Hiblot7382e692017-09-21 16:29:52 +02001767 err = mmc_send_ext_csd(mmc, test_csd);
1768 if (err)
1769 return err;
1770
1771 /* Only compare read only fields */
1772 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1773 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1774 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1775 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1776 ext_csd[EXT_CSD_REV]
1777 == test_csd[EXT_CSD_REV] &&
1778 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1779 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1780 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1781 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1782 return 0;
1783
1784 return -EBADMSG;
1785}
1786
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001787#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001788static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1789 uint32_t allowed_mask)
1790{
1791 u32 card_mask = 0;
1792
1793 switch (mode) {
Peng Fan3dd26262018-08-10 14:07:54 +08001794 case MMC_HS_400:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001795 case MMC_HS_200:
Peng Fan3dd26262018-08-10 14:07:54 +08001796 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1797 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001798 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan3dd26262018-08-10 14:07:54 +08001799 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1800 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001801 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1802 break;
1803 case MMC_DDR_52:
1804 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1805 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1806 MMC_SIGNAL_VOLTAGE_180;
1807 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1808 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1809 break;
1810 default:
1811 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1812 break;
1813 }
1814
1815 while (card_mask & allowed_mask) {
1816 enum mmc_voltage best_match;
1817
1818 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1819 if (!mmc_set_signal_voltage(mmc, best_match))
1820 return 0;
1821
1822 allowed_mask &= ~best_match;
1823 }
1824
1825 return -ENOTSUPP;
1826}
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001827#else
1828static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1829 uint32_t allowed_mask)
1830{
1831 return 0;
1832}
1833#endif
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001834
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001835static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Fan3dd26262018-08-10 14:07:54 +08001836#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1837 {
1838 .mode = MMC_HS_400,
1839 .widths = MMC_MODE_8BIT,
1840 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1841 },
1842#endif
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001843#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001844 {
1845 .mode = MMC_HS_200,
1846 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02001847 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001848 },
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01001849#endif
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001850 {
1851 .mode = MMC_DDR_52,
1852 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1853 },
1854 {
1855 .mode = MMC_HS_52,
1856 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1857 },
1858 {
1859 .mode = MMC_HS,
1860 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1861 },
1862 {
1863 .mode = MMC_LEGACY,
1864 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1865 }
1866};
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001867
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001868#define for_each_mmc_mode_by_pref(caps, mwt) \
1869 for (mwt = mmc_modes_by_pref;\
1870 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1871 mwt++) \
1872 if (caps & MMC_CAP(mwt->mode))
1873
1874static const struct ext_csd_bus_width {
1875 uint cap;
1876 bool is_ddr;
1877 uint ext_csd_bits;
1878} ext_csd_bus_width[] = {
1879 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1880 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1881 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1882 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1883 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1884};
1885
Peng Fan3dd26262018-08-10 14:07:54 +08001886#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1887static int mmc_select_hs400(struct mmc *mmc)
1888{
1889 int err;
1890
1891 /* Set timing to HS200 for tuning */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001892 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001893 if (err)
1894 return err;
1895
1896 /* configure the bus mode (host) */
1897 mmc_select_mode(mmc, MMC_HS_200);
1898 mmc_set_clock(mmc, mmc->tran_speed, false);
1899
1900 /* execute tuning if needed */
1901 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1902 if (err) {
1903 debug("tuning failed\n");
1904 return err;
1905 }
1906
1907 /* Set back to HS */
BOUGH CHEN5cf12032019-03-26 06:24:17 +00001908 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan3dd26262018-08-10 14:07:54 +08001909
1910 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1911 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1912 if (err)
1913 return err;
1914
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001915 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan3dd26262018-08-10 14:07:54 +08001916 if (err)
1917 return err;
1918
1919 mmc_select_mode(mmc, MMC_HS_400);
1920 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1921 if (err)
1922 return err;
1923
1924 return 0;
1925}
1926#else
1927static int mmc_select_hs400(struct mmc *mmc)
1928{
1929 return -ENOTSUPP;
1930}
1931#endif
1932
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001933#define for_each_supported_width(caps, ddr, ecbv) \
1934 for (ecbv = ext_csd_bus_width;\
1935 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1936 ecbv++) \
1937 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1938
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001939static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001940{
1941 int err;
1942 const struct mode_width_tuning *mwt;
1943 const struct ext_csd_bus_width *ecbw;
1944
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001945#ifdef DEBUG
1946 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001947 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot52d241d2017-11-30 17:43:54 +01001948#endif
1949
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001950 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblot1da8eb52017-11-30 17:43:57 +01001951 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02001952
1953 /* Only version 4 of MMC supports wider bus widths */
1954 if (mmc->version < MMC_VERSION_4)
1955 return 0;
1956
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001957 if (!mmc->ext_csd) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001958 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02001959 return -ENOTSUPP;
1960 }
1961
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01001962#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
1963 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1964 /*
1965 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
1966 * before doing anything else, since a transition from either of
1967 * the HS200/HS400 mode directly to legacy mode is not supported.
1968 */
1969 if (mmc->selected_mode == MMC_HS_200 ||
1970 mmc->selected_mode == MMC_HS_400)
1971 mmc_set_card_speed(mmc, MMC_HS, true);
1972 else
1973#endif
1974 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02001975
1976 for_each_mmc_mode_by_pref(card_caps, mwt) {
1977 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001978 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001979 enum mmc_voltage old_voltage;
Masahiro Yamadad4d64882018-01-28 19:11:42 +09001980 pr_debug("trying mode %s width %d (at %d MHz)\n",
1981 mmc_mode_name(mwt->mode),
1982 bus_width(ecbw->cap),
1983 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02001984 old_voltage = mmc->signal_voltage;
1985 err = mmc_set_lowest_voltage(mmc, mwt->mode,
1986 MMC_ALL_SIGNAL_VOLTAGE);
1987 if (err)
1988 continue;
1989
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02001990 /* configure the bus width (card + host) */
1991 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1992 EXT_CSD_BUS_WIDTH,
1993 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
1994 if (err)
1995 goto error;
1996 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
1997
Peng Fan3dd26262018-08-10 14:07:54 +08001998 if (mwt->mode == MMC_HS_400) {
1999 err = mmc_select_hs400(mmc);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002000 if (err) {
Peng Fan3dd26262018-08-10 14:07:54 +08002001 printf("Select HS400 failed %d\n", err);
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002002 goto error;
2003 }
Peng Fan3dd26262018-08-10 14:07:54 +08002004 } else {
2005 /* configure the bus speed (card) */
Marek Vasutb9a2a0e2019-01-03 21:19:24 +01002006 err = mmc_set_card_speed(mmc, mwt->mode, false);
Peng Fan3dd26262018-08-10 14:07:54 +08002007 if (err)
2008 goto error;
2009
2010 /*
2011 * configure the bus width AND the ddr mode
2012 * (card). The host side will be taken care
2013 * of in the next step
2014 */
2015 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2016 err = mmc_switch(mmc,
2017 EXT_CSD_CMD_SET_NORMAL,
2018 EXT_CSD_BUS_WIDTH,
2019 ecbw->ext_csd_bits);
2020 if (err)
2021 goto error;
2022 }
2023
2024 /* configure the bus mode (host) */
2025 mmc_select_mode(mmc, mwt->mode);
2026 mmc_set_clock(mmc, mmc->tran_speed,
2027 MMC_CLK_ENABLE);
2028#ifdef MMC_SUPPORTS_TUNING
2029
2030 /* execute tuning if needed */
2031 if (mwt->tuning) {
2032 err = mmc_execute_tuning(mmc,
2033 mwt->tuning);
2034 if (err) {
2035 pr_debug("tuning failed\n");
2036 goto error;
2037 }
2038 }
Jean-Jacques Hiblotf99c2ef2017-11-30 17:44:01 +01002039#endif
Peng Fan3dd26262018-08-10 14:07:54 +08002040 }
Kishon Vijay Abraham I634d4842017-09-21 16:30:06 +02002041
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002042 /* do a transfer to check the configuration */
2043 err = mmc_read_and_compare_ext_csd(mmc);
2044 if (!err)
2045 return 0;
2046error:
Jean-Jacques Hiblotbc1e3272017-09-21 16:30:11 +02002047 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002048 /* if an error occured, revert to a safer bus mode */
2049 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2050 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2051 mmc_select_mode(mmc, MMC_LEGACY);
2052 mmc_set_bus_width(mmc, 1);
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002053 }
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002054 }
2055
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002056 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002057
Jean-Jacques Hiblot3862b852017-09-21 16:29:58 +02002058 return -ENOTSUPP;
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002059}
Marek Vasut62d77ce2018-04-15 00:37:11 +02002060#endif
2061
2062#if CONFIG_IS_ENABLED(MMC_TINY)
2063DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2064#endif
Jean-Jacques Hiblot8ac8a262017-09-21 16:29:49 +02002065
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002066static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002067{
2068 int err, i;
2069 u64 capacity;
2070 bool has_parts = false;
2071 bool part_completed;
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002072 static const u32 mmc_versions[] = {
2073 MMC_VERSION_4,
2074 MMC_VERSION_4_1,
2075 MMC_VERSION_4_2,
2076 MMC_VERSION_4_3,
Jean-Jacques Hiblotace1bed2018-02-09 12:09:28 +01002077 MMC_VERSION_4_4,
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002078 MMC_VERSION_4_41,
2079 MMC_VERSION_4_5,
2080 MMC_VERSION_5_0,
2081 MMC_VERSION_5_1
2082 };
2083
Marek Vasut62d77ce2018-04-15 00:37:11 +02002084#if CONFIG_IS_ENABLED(MMC_TINY)
2085 u8 *ext_csd = ext_csd_bkup;
2086
2087 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2088 return 0;
2089
2090 if (!mmc->ext_csd)
2091 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2092
2093 err = mmc_send_ext_csd(mmc, ext_csd);
2094 if (err)
2095 goto error;
2096
2097 /* store the ext csd for future reference */
2098 if (!mmc->ext_csd)
2099 mmc->ext_csd = ext_csd;
2100#else
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002101 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002102
2103 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2104 return 0;
2105
2106 /* check ext_csd version and capacity */
2107 err = mmc_send_ext_csd(mmc, ext_csd);
2108 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002109 goto error;
2110
2111 /* store the ext csd for future reference */
2112 if (!mmc->ext_csd)
2113 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2114 if (!mmc->ext_csd)
2115 return -ENOMEM;
2116 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002117#endif
Alexander Kochetkov76584e32018-02-20 14:35:55 +03002118 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblot58a6fb72018-01-04 15:23:31 +01002119 return -EINVAL;
2120
2121 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2122
2123 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002124 /*
2125 * According to the JEDEC Standard, the value of
2126 * ext_csd's capacity is valid if the value is more
2127 * than 2GB
2128 */
2129 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2130 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2131 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2132 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2133 capacity *= MMC_MAX_BLOCK_LEN;
2134 if ((capacity >> 20) > 2 * 1024)
2135 mmc->capacity_user = capacity;
2136 }
2137
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002138 /* The partition data may be non-zero but it is only
2139 * effective if PARTITION_SETTING_COMPLETED is set in
2140 * EXT_CSD, so ignore any data if this bit is not set,
2141 * except for enabling the high-capacity group size
2142 * definition (see below).
2143 */
2144 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2145 EXT_CSD_PARTITION_SETTING_COMPLETED);
2146
2147 /* store the partition info of emmc */
2148 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2149 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2150 ext_csd[EXT_CSD_BOOT_MULT])
2151 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2152 if (part_completed &&
2153 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2154 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2155
2156 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2157
2158 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2159
2160 for (i = 0; i < 4; i++) {
2161 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2162 uint mult = (ext_csd[idx + 2] << 16) +
2163 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2164 if (mult)
2165 has_parts = true;
2166 if (!part_completed)
2167 continue;
2168 mmc->capacity_gp[i] = mult;
2169 mmc->capacity_gp[i] *=
2170 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2171 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2172 mmc->capacity_gp[i] <<= 19;
2173 }
2174
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002175#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002176 if (part_completed) {
2177 mmc->enh_user_size =
2178 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2179 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2180 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2181 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2182 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2183 mmc->enh_user_size <<= 19;
2184 mmc->enh_user_start =
2185 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2186 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2187 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2188 ext_csd[EXT_CSD_ENH_START_ADDR];
2189 if (mmc->high_capacity)
2190 mmc->enh_user_start <<= 9;
2191 }
Jean-Jacques Hiblot173c06d2018-01-04 15:23:35 +01002192#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002193
2194 /*
2195 * Host needs to enable ERASE_GRP_DEF bit if device is
2196 * partitioned. This bit will be lost every time after a reset
2197 * or power off. This will affect erase size.
2198 */
2199 if (part_completed)
2200 has_parts = true;
2201 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2202 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2203 has_parts = true;
2204 if (has_parts) {
2205 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2206 EXT_CSD_ERASE_GROUP_DEF, 1);
2207
2208 if (err)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002209 goto error;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002210
2211 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2212 }
2213
2214 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002215#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002216 /* Read out group size from ext_csd */
2217 mmc->erase_grp_size =
2218 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002219#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002220 /*
2221 * if high capacity and partition setting completed
2222 * SEC_COUNT is valid even if it is smaller than 2 GiB
2223 * JEDEC Standard JESD84-B45, 6.2.4
2224 */
2225 if (mmc->high_capacity && part_completed) {
2226 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2227 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2228 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2229 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2230 capacity *= MMC_MAX_BLOCK_LEN;
2231 mmc->capacity_user = capacity;
2232 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002233 }
2234#if CONFIG_IS_ENABLED(MMC_WRITE)
2235 else {
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002236 /* Calculate the group size from the csd value. */
2237 int erase_gsz, erase_gmul;
2238
2239 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2240 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2241 mmc->erase_grp_size = (erase_gsz + 1)
2242 * (erase_gmul + 1);
2243 }
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002244#endif
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002245#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002246 mmc->hc_wp_grp_size = 1024
2247 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2248 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotb7a6e2c2018-01-04 15:23:36 +01002249#endif
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002250
2251 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2252
2253 return 0;
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002254error:
2255 if (mmc->ext_csd) {
Marek Vasut62d77ce2018-04-15 00:37:11 +02002256#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002257 free(mmc->ext_csd);
Marek Vasut62d77ce2018-04-15 00:37:11 +02002258#endif
Jean-Jacques Hiblotf7d5dff2017-11-30 17:43:59 +01002259 mmc->ext_csd = NULL;
2260 }
2261 return err;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002262}
2263
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002264static int mmc_startup(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002265{
Stephen Warrenf866a462013-06-11 15:14:01 -06002266 int err, i;
Andy Fleming272cc702008-10-30 16:41:01 -05002267 uint mult, freq;
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002268 u64 cmult, csize;
Andy Fleming272cc702008-10-30 16:41:01 -05002269 struct mmc_cmd cmd;
Simon Glassc40fdca2016-05-01 13:52:35 -06002270 struct blk_desc *bdesc;
Andy Fleming272cc702008-10-30 16:41:01 -05002271
Thomas Choud52ebf12010-12-24 13:12:21 +00002272#ifdef CONFIG_MMC_SPI_CRC_ON
2273 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2274 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2275 cmd.resp_type = MMC_RSP_R1;
2276 cmd.cmdarg = 1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002277 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Choud52ebf12010-12-24 13:12:21 +00002278 if (err)
2279 return err;
2280 }
2281#endif
2282
Andy Fleming272cc702008-10-30 16:41:01 -05002283 /* Put the Card in Identify Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002284 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2285 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Fleming272cc702008-10-30 16:41:01 -05002286 cmd.resp_type = MMC_RSP_R2;
2287 cmd.cmdarg = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002288
2289 err = mmc_send_cmd(mmc, &cmd, NULL);
2290
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002291#ifdef CONFIG_MMC_QUIRKS
2292 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2293 int retries = 4;
2294 /*
2295 * It has been seen that SEND_CID may fail on the first
2296 * attempt, let's try a few more time
2297 */
2298 do {
2299 err = mmc_send_cmd(mmc, &cmd, NULL);
2300 if (!err)
2301 break;
2302 } while (retries--);
2303 }
2304#endif
2305
Andy Fleming272cc702008-10-30 16:41:01 -05002306 if (err)
2307 return err;
2308
2309 memcpy(mmc->cid, cmd.response, 16);
2310
2311 /*
2312 * For MMC cards, set the Relative Address.
2313 * For SD cards, get the Relatvie Address.
2314 * This also puts the cards into Standby State
2315 */
Thomas Choud52ebf12010-12-24 13:12:21 +00002316 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2317 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2318 cmd.cmdarg = mmc->rca << 16;
2319 cmd.resp_type = MMC_RSP_R6;
Andy Fleming272cc702008-10-30 16:41:01 -05002320
Thomas Choud52ebf12010-12-24 13:12:21 +00002321 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002322
Thomas Choud52ebf12010-12-24 13:12:21 +00002323 if (err)
2324 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002325
Thomas Choud52ebf12010-12-24 13:12:21 +00002326 if (IS_SD(mmc))
2327 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2328 }
Andy Fleming272cc702008-10-30 16:41:01 -05002329
2330 /* Get the Card-Specific Data */
2331 cmd.cmdidx = MMC_CMD_SEND_CSD;
2332 cmd.resp_type = MMC_RSP_R2;
2333 cmd.cmdarg = mmc->rca << 16;
Andy Fleming272cc702008-10-30 16:41:01 -05002334
2335 err = mmc_send_cmd(mmc, &cmd, NULL);
2336
2337 if (err)
2338 return err;
2339
Rabin Vincent998be3d2009-04-05 13:30:56 +05302340 mmc->csd[0] = cmd.response[0];
2341 mmc->csd[1] = cmd.response[1];
2342 mmc->csd[2] = cmd.response[2];
2343 mmc->csd[3] = cmd.response[3];
Andy Fleming272cc702008-10-30 16:41:01 -05002344
2345 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302346 int version = (cmd.response[0] >> 26) & 0xf;
Andy Fleming272cc702008-10-30 16:41:01 -05002347
2348 switch (version) {
Bin Meng53e8e402016-03-17 21:53:13 -07002349 case 0:
2350 mmc->version = MMC_VERSION_1_2;
2351 break;
2352 case 1:
2353 mmc->version = MMC_VERSION_1_4;
2354 break;
2355 case 2:
2356 mmc->version = MMC_VERSION_2_2;
2357 break;
2358 case 3:
2359 mmc->version = MMC_VERSION_3;
2360 break;
2361 case 4:
2362 mmc->version = MMC_VERSION_4;
2363 break;
2364 default:
2365 mmc->version = MMC_VERSION_1_2;
2366 break;
Andy Fleming272cc702008-10-30 16:41:01 -05002367 }
2368 }
2369
2370 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincent0b453ff2009-04-05 13:30:55 +05302371 freq = fbase[(cmd.response[0] & 0x7)];
2372 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Fleming272cc702008-10-30 16:41:01 -05002373
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002374 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblot35f9e192017-09-21 16:29:53 +02002375 mmc_select_mode(mmc, MMC_LEGACY);
Andy Fleming272cc702008-10-30 16:41:01 -05002376
Markus Niebelab711882013-12-16 13:40:46 +01002377 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincent998be3d2009-04-05 13:30:56 +05302378 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002379#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Fleming272cc702008-10-30 16:41:01 -05002380
2381 if (IS_SD(mmc))
2382 mmc->write_bl_len = mmc->read_bl_len;
2383 else
Rabin Vincent998be3d2009-04-05 13:30:56 +05302384 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002385#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002386
2387 if (mmc->high_capacity) {
2388 csize = (mmc->csd[1] & 0x3f) << 16
2389 | (mmc->csd[2] & 0xffff0000) >> 16;
2390 cmult = 8;
2391 } else {
2392 csize = (mmc->csd[1] & 0x3ff) << 2
2393 | (mmc->csd[2] & 0xc0000000) >> 30;
2394 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2395 }
2396
Stephen Warrenf866a462013-06-11 15:14:01 -06002397 mmc->capacity_user = (csize + 1) << (cmult + 2);
2398 mmc->capacity_user *= mmc->read_bl_len;
2399 mmc->capacity_boot = 0;
2400 mmc->capacity_rpmb = 0;
2401 for (i = 0; i < 4; i++)
2402 mmc->capacity_gp[i] = 0;
Andy Fleming272cc702008-10-30 16:41:01 -05002403
Simon Glass8bfa1952013-04-03 08:54:30 +00002404 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2405 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Fleming272cc702008-10-30 16:41:01 -05002406
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002407#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glass8bfa1952013-04-03 08:54:30 +00002408 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2409 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002410#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002411
Markus Niebelab711882013-12-16 13:40:46 +01002412 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2413 cmd.cmdidx = MMC_CMD_SET_DSR;
2414 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2415 cmd.resp_type = MMC_RSP_NONE;
2416 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002417 pr_warn("MMC: SET_DSR failed\n");
Markus Niebelab711882013-12-16 13:40:46 +01002418 }
2419
Andy Fleming272cc702008-10-30 16:41:01 -05002420 /* Select the card, and put it into Transfer Mode */
Thomas Choud52ebf12010-12-24 13:12:21 +00002421 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2422 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargavfe8f7062011-10-05 03:13:23 +00002423 cmd.resp_type = MMC_RSP_R1;
Thomas Choud52ebf12010-12-24 13:12:21 +00002424 cmd.cmdarg = mmc->rca << 16;
Thomas Choud52ebf12010-12-24 13:12:21 +00002425 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Fleming272cc702008-10-30 16:41:01 -05002426
Thomas Choud52ebf12010-12-24 13:12:21 +00002427 if (err)
2428 return err;
2429 }
Andy Fleming272cc702008-10-30 16:41:01 -05002430
Lei Wene6f99a52011-06-22 17:03:31 +00002431 /*
2432 * For SD, its erase group is always one sector
2433 */
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002434#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wene6f99a52011-06-22 17:03:31 +00002435 mmc->erase_grp_size = 1;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002436#endif
Lei Wenbc897b12011-05-02 16:26:26 +00002437 mmc->part_config = MMCPART_NOAVAILABLE;
Lei Wenbc897b12011-05-02 16:26:26 +00002438
Jean-Jacques Hiblotdfda9d82017-09-21 16:29:51 +02002439 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblotc744b6f2017-09-21 16:29:50 +02002440 if (err)
2441 return err;
Sukumar Ghoraid23e2c02010-09-20 18:29:29 +05302442
Simon Glassc40fdca2016-05-01 13:52:35 -06002443 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrenf866a462013-06-11 15:14:01 -06002444 if (err)
2445 return err;
2446
Marek Vasut62d77ce2018-04-15 00:37:11 +02002447#if CONFIG_IS_ENABLED(MMC_TINY)
2448 mmc_set_clock(mmc, mmc->legacy_speed, false);
2449 mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
2450 mmc_set_bus_width(mmc, 1);
2451#else
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002452 if (IS_SD(mmc)) {
2453 err = sd_get_capabilities(mmc);
2454 if (err)
2455 return err;
2456 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2457 } else {
2458 err = mmc_get_capabilities(mmc);
2459 if (err)
2460 return err;
2461 mmc_select_mode_and_width(mmc, mmc->card_caps);
2462 }
Marek Vasut62d77ce2018-04-15 00:37:11 +02002463#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002464 if (err)
2465 return err;
2466
Jean-Jacques Hiblot01298da2017-09-21 16:30:09 +02002467 mmc->best_mode = mmc->selected_mode;
Jaehoon Chungad5fd922012-03-26 21:16:03 +00002468
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002469 /* Fix the block length for DDR mode */
2470 if (mmc->ddr_mode) {
2471 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002472#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002473 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblote6fa5a52018-01-04 15:23:34 +01002474#endif
Andrew Gabbasov5af8f452014-12-01 06:59:11 -06002475 }
2476
Andy Fleming272cc702008-10-30 16:41:01 -05002477 /* fill in device description */
Simon Glassc40fdca2016-05-01 13:52:35 -06002478 bdesc = mmc_get_blk_desc(mmc);
2479 bdesc->lun = 0;
2480 bdesc->hwpart = 0;
2481 bdesc->type = 0;
2482 bdesc->blksz = mmc->read_bl_len;
2483 bdesc->log2blksz = LOG2(bdesc->blksz);
2484 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsfc011f62015-12-04 23:27:40 +01002485#if !defined(CONFIG_SPL_BUILD) || \
2486 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
2487 !defined(CONFIG_USE_TINY_PRINTF))
Simon Glassc40fdca2016-05-01 13:52:35 -06002488 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Huttbabce5f2012-10-20 17:15:59 +00002489 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2490 (mmc->cid[3] >> 16) & 0xffff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002491 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002492 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2493 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2494 (mmc->cid[2] >> 24) & 0xff);
Simon Glassc40fdca2016-05-01 13:52:35 -06002495 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Huttbabce5f2012-10-20 17:15:59 +00002496 (mmc->cid[2] >> 16) & 0xf);
Paul Burton56196822013-09-04 16:12:25 +01002497#else
Simon Glassc40fdca2016-05-01 13:52:35 -06002498 bdesc->vendor[0] = 0;
2499 bdesc->product[0] = 0;
2500 bdesc->revision[0] = 0;
Paul Burton56196822013-09-04 16:12:25 +01002501#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002502
Andre Przywaraeef05fd2018-12-17 10:05:45 +00002503#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2504 part_init(bdesc);
2505#endif
2506
Andy Fleming272cc702008-10-30 16:41:01 -05002507 return 0;
2508}
2509
Kim Phillipsfdbb8732012-10-29 13:34:43 +00002510static int mmc_send_if_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002511{
2512 struct mmc_cmd cmd;
2513 int err;
2514
2515 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2516 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002517 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Fleming272cc702008-10-30 16:41:01 -05002518 cmd.resp_type = MMC_RSP_R7;
Andy Fleming272cc702008-10-30 16:41:01 -05002519
2520 err = mmc_send_cmd(mmc, &cmd, NULL);
2521
2522 if (err)
2523 return err;
2524
Rabin Vincent998be3d2009-04-05 13:30:56 +05302525 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002526 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002527 else
2528 mmc->version = SD_VERSION_2;
2529
2530 return 0;
2531}
2532
Simon Glassc4d660d2017-07-04 13:31:19 -06002533#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002534/* board-specific MMC power initializations. */
2535__weak void board_mmc_power_init(void)
2536{
2537}
Simon Glass05cbeb72017-04-22 19:10:56 -06002538#endif
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002539
Peng Fan2051aef2016-10-11 15:08:43 +08002540static int mmc_power_init(struct mmc *mmc)
2541{
Simon Glassc4d660d2017-07-04 13:31:19 -06002542#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002543#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan2051aef2016-10-11 15:08:43 +08002544 int ret;
2545
2546 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002547 &mmc->vmmc_supply);
2548 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002549 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002550
Jean-Jacques Hiblot06ec0452017-09-21 16:29:48 +02002551 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2552 &mmc->vqmmc_supply);
2553 if (ret)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002554 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Peng Fan2051aef2016-10-11 15:08:43 +08002555#endif
Simon Glass05cbeb72017-04-22 19:10:56 -06002556#else /* !CONFIG_DM_MMC */
2557 /*
2558 * Driver model should use a regulator, as above, rather than calling
2559 * out to board code.
2560 */
2561 board_mmc_power_init();
2562#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002563 return 0;
2564}
2565
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002566/*
2567 * put the host in the initial state:
2568 * - turn on Vdd (card power supply)
2569 * - configure the bus width and clock to minimal values
2570 */
2571static void mmc_set_initial_state(struct mmc *mmc)
2572{
2573 int err;
2574
2575 /* First try to set 3.3V. If it fails set to 1.8V */
2576 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2577 if (err != 0)
2578 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2579 if (err != 0)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002580 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002581
2582 mmc_select_mode(mmc, MMC_LEGACY);
2583 mmc_set_bus_width(mmc, 1);
Jaehoon Chung65117182018-01-26 19:25:29 +09002584 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002585}
2586
2587static int mmc_power_on(struct mmc *mmc)
2588{
2589#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2590 if (mmc->vmmc_supply) {
2591 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2592
2593 if (ret) {
2594 puts("Error enabling VMMC supply\n");
2595 return ret;
2596 }
2597 }
2598#endif
2599 return 0;
2600}
2601
2602static int mmc_power_off(struct mmc *mmc)
2603{
Jaehoon Chung65117182018-01-26 19:25:29 +09002604 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002605#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2606 if (mmc->vmmc_supply) {
2607 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2608
2609 if (ret) {
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002610 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002611 return ret;
2612 }
2613 }
2614#endif
2615 return 0;
2616}
2617
2618static int mmc_power_cycle(struct mmc *mmc)
2619{
2620 int ret;
2621
2622 ret = mmc_power_off(mmc);
2623 if (ret)
2624 return ret;
2625 /*
2626 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2627 * to be on the safer side.
2628 */
2629 udelay(2000);
2630 return mmc_power_on(mmc);
2631}
2632
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002633int mmc_get_op_cond(struct mmc *mmc)
Andy Fleming272cc702008-10-30 16:41:01 -05002634{
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002635 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Linafd59322011-11-14 23:35:39 +00002636 int err;
Andy Fleming272cc702008-10-30 16:41:01 -05002637
Lei Wenbc897b12011-05-02 16:26:26 +00002638 if (mmc->has_init)
2639 return 0;
2640
Yangbo Lu5a8dbdc2015-04-22 13:57:00 +08002641#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2642 mmc_adapter_card_type_ident();
2643#endif
Peng Fan2051aef2016-10-11 15:08:43 +08002644 err = mmc_power_init(mmc);
2645 if (err)
2646 return err;
Paul Kocialkowski95de9ab2014-11-08 20:55:45 +01002647
Kishon Vijay Abraham I83dc4222017-09-21 16:30:10 +02002648#ifdef CONFIG_MMC_QUIRKS
2649 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
2650 MMC_QUIRK_RETRY_SEND_CID;
2651#endif
2652
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002653 err = mmc_power_cycle(mmc);
2654 if (err) {
2655 /*
2656 * if power cycling is not supported, we should not try
2657 * to use the UHS modes, because we wouldn't be able to
2658 * recover from an error during the UHS initialization.
2659 */
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002660 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblot04a2ea22017-09-21 16:30:08 +02002661 uhs_en = false;
2662 mmc->host_caps &= ~UHS_CAPS;
2663 err = mmc_power_on(mmc);
2664 }
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002665 if (err)
2666 return err;
2667
Simon Glasse7881d82017-07-29 11:35:31 -06002668#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass8ca51e52016-06-12 23:30:22 -06002669 /* The device has already been probed ready for use */
2670#else
Pantelis Antoniouab769f22014-02-26 19:28:45 +02002671 /* made sure it's not NULL earlier */
Pantelis Antoniou93bfd612014-03-11 19:34:20 +02002672 err = mmc->cfg->ops->init(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002673 if (err)
2674 return err;
Simon Glass8ca51e52016-06-12 23:30:22 -06002675#endif
Andrew Gabbasov786e8f82014-12-01 06:59:09 -06002676 mmc->ddr_mode = 0;
Kishon Vijay Abraham Iaff5d3c2017-09-21 16:30:00 +02002677
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002678retry:
Kishon Vijay Abraham Ifb7c3be2017-09-21 16:30:02 +02002679 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot318a7a52017-09-21 16:30:01 +02002680
Andy Fleming272cc702008-10-30 16:41:01 -05002681 /* Reset the Card */
2682 err = mmc_go_idle(mmc);
2683
2684 if (err)
2685 return err;
2686
Lei Wenbc897b12011-05-02 16:26:26 +00002687 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glassc40fdca2016-05-01 13:52:35 -06002688 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wenbc897b12011-05-02 16:26:26 +00002689
Andy Fleming272cc702008-10-30 16:41:01 -05002690 /* Test for SD version 2 */
Macpaul Linafd59322011-11-14 23:35:39 +00002691 err = mmc_send_if_cond(mmc);
Andy Fleming272cc702008-10-30 16:41:01 -05002692
Andy Fleming272cc702008-10-30 16:41:01 -05002693 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotc10b85d2017-09-21 16:30:07 +02002694 err = sd_send_op_cond(mmc, uhs_en);
2695 if (err && uhs_en) {
2696 uhs_en = false;
2697 mmc_power_cycle(mmc);
2698 goto retry;
2699 }
Andy Fleming272cc702008-10-30 16:41:01 -05002700
2701 /* If the command timed out, we check for an MMC card */
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002702 if (err == -ETIMEDOUT) {
Andy Fleming272cc702008-10-30 16:41:01 -05002703 err = mmc_send_op_cond(mmc);
2704
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002705 if (err) {
Paul Burton56196822013-09-04 16:12:25 +01002706#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002707 pr_err("Card did not respond to voltage select!\n");
Paul Burton56196822013-09-04 16:12:25 +01002708#endif
Jaehoon Chung915ffa52016-07-19 16:33:36 +09002709 return -EOPNOTSUPP;
Andy Fleming272cc702008-10-30 16:41:01 -05002710 }
2711 }
2712
Jon Nettleton6c09eba2018-06-11 15:26:19 +03002713 return err;
2714}
2715
2716int mmc_start_init(struct mmc *mmc)
2717{
2718 bool no_card;
2719 int err = 0;
2720
2721 /*
2722 * all hosts are capable of 1 bit bus-width and able to use the legacy
2723 * timings.
2724 */
2725 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
2726 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
2727
2728#if !defined(CONFIG_MMC_BROKEN_CD)
2729 /* we pretend there's no card when init is NULL */
2730 no_card = mmc_getcd(mmc) == 0;
2731#else
2732 no_card = 0;
2733#endif
2734#if !CONFIG_IS_ENABLED(DM_MMC)
2735 no_card = no_card || (mmc->cfg->ops->init == NULL);
2736#endif
2737 if (no_card) {
2738 mmc->has_init = 0;
2739#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2740 pr_err("MMC: no card present\n");
2741#endif
2742 return -ENOMEDIUM;
2743 }
2744
2745 err = mmc_get_op_cond(mmc);
2746
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002747 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002748 mmc->init_in_progress = 1;
2749
2750 return err;
2751}
2752
2753static int mmc_complete_init(struct mmc *mmc)
2754{
2755 int err = 0;
2756
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002757 mmc->init_in_progress = 0;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002758 if (mmc->op_cond_pending)
2759 err = mmc_complete_op_cond(mmc);
2760
2761 if (!err)
2762 err = mmc_startup(mmc);
Lei Wenbc897b12011-05-02 16:26:26 +00002763 if (err)
2764 mmc->has_init = 0;
2765 else
2766 mmc->has_init = 1;
Che-Liang Chioue9550442012-11-28 15:21:13 +00002767 return err;
2768}
2769
2770int mmc_init(struct mmc *mmc)
2771{
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002772 int err = 0;
Vipul Kumar36332b62018-05-03 12:20:54 +05302773 __maybe_unused ulong start;
Simon Glassc4d660d2017-07-04 13:31:19 -06002774#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass33fb2112016-05-01 13:52:41 -06002775 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chioue9550442012-11-28 15:21:13 +00002776
Simon Glass33fb2112016-05-01 13:52:41 -06002777 upriv->mmc = mmc;
2778#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002779 if (mmc->has_init)
2780 return 0;
Mateusz Zalegad803fea2014-04-29 20:15:30 +02002781
2782 start = get_timer(0);
2783
Che-Liang Chioue9550442012-11-28 15:21:13 +00002784 if (!mmc->init_in_progress)
2785 err = mmc_start_init(mmc);
2786
Andrew Gabbasovbd47c132015-03-19 07:44:07 -05002787 if (!err)
Che-Liang Chioue9550442012-11-28 15:21:13 +00002788 err = mmc_complete_init(mmc);
Jagan Teki919b4852017-01-10 11:18:43 +01002789 if (err)
Masahiro Yamadad4d64882018-01-28 19:11:42 +09002790 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki919b4852017-01-10 11:18:43 +01002791
Lei Wenbc897b12011-05-02 16:26:26 +00002792 return err;
Andy Fleming272cc702008-10-30 16:41:01 -05002793}
2794
Marek Vasutfceea992019-01-29 04:45:51 +01002795#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2796 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2797 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2798int mmc_deinit(struct mmc *mmc)
2799{
2800 u32 caps_filtered;
2801
2802 if (!mmc->has_init)
2803 return 0;
2804
2805 if (IS_SD(mmc)) {
2806 caps_filtered = mmc->card_caps &
2807 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2808 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2809 MMC_CAP(UHS_SDR104));
2810
2811 return sd_select_mode_and_width(mmc, caps_filtered);
2812 } else {
2813 caps_filtered = mmc->card_caps &
2814 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2815
2816 return mmc_select_mode_and_width(mmc, caps_filtered);
2817 }
2818}
2819#endif
2820
Markus Niebelab711882013-12-16 13:40:46 +01002821int mmc_set_dsr(struct mmc *mmc, u16 val)
2822{
2823 mmc->dsr = val;
2824 return 0;
2825}
2826
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002827/* CPU-specific MMC initializations */
2828__weak int cpu_mmc_init(bd_t *bis)
Andy Fleming272cc702008-10-30 16:41:01 -05002829{
2830 return -1;
2831}
2832
Jeroen Hofsteecee9ab72014-07-10 22:46:28 +02002833/* board-specific MMC initializations. */
2834__weak int board_mmc_init(bd_t *bis)
2835{
2836 return -1;
2837}
Andy Fleming272cc702008-10-30 16:41:01 -05002838
Che-Liang Chioue9550442012-11-28 15:21:13 +00002839void mmc_set_preinit(struct mmc *mmc, int preinit)
2840{
2841 mmc->preinit = preinit;
2842}
2843
Faiz Abbas8a856db2018-02-12 19:35:24 +05302844#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002845static int mmc_probe(bd_t *bis)
2846{
Simon Glass4a1db6d2015-12-29 05:22:49 -07002847 int ret, i;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002848 struct uclass *uc;
Simon Glass4a1db6d2015-12-29 05:22:49 -07002849 struct udevice *dev;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002850
2851 ret = uclass_get(UCLASS_MMC, &uc);
2852 if (ret)
2853 return ret;
2854
Simon Glass4a1db6d2015-12-29 05:22:49 -07002855 /*
2856 * Try to add them in sequence order. Really with driver model we
2857 * should allow holes, but the current MMC list does not allow that.
2858 * So if we request 0, 1, 3 we will get 0, 1, 2.
2859 */
2860 for (i = 0; ; i++) {
2861 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
2862 if (ret == -ENODEV)
2863 break;
2864 }
2865 uclass_foreach_dev(dev, uc) {
2866 ret = device_probe(dev);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002867 if (ret)
Jean-Jacques Hiblotd8e3d422017-11-30 17:44:00 +01002868 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002869 }
2870
2871 return 0;
2872}
2873#else
2874static int mmc_probe(bd_t *bis)
2875{
2876 if (board_mmc_init(bis) < 0)
2877 cpu_mmc_init(bis);
2878
2879 return 0;
2880}
2881#endif
Che-Liang Chioue9550442012-11-28 15:21:13 +00002882
Andy Fleming272cc702008-10-30 16:41:01 -05002883int mmc_initialize(bd_t *bis)
2884{
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002885 static int initialized = 0;
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002886 int ret;
Daniel Kochmański1b26bab2015-05-29 16:55:43 +02002887 if (initialized) /* Avoid initializing mmc multiple times */
2888 return 0;
2889 initialized = 1;
2890
Simon Glassc4d660d2017-07-04 13:31:19 -06002891#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutb5b838f2016-12-01 02:06:33 +01002892#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glassc40fdca2016-05-01 13:52:35 -06002893 mmc_list_init();
2894#endif
Marek Vasutb5b838f2016-12-01 02:06:33 +01002895#endif
Sjoerd Simons8e3332e2015-08-30 16:55:45 -06002896 ret = mmc_probe(bis);
2897 if (ret)
2898 return ret;
Andy Fleming272cc702008-10-30 16:41:01 -05002899
Ying Zhangbb0dc102013-08-16 15:16:11 +08002900#ifndef CONFIG_SPL_BUILD
Andy Fleming272cc702008-10-30 16:41:01 -05002901 print_mmc_devices(',');
Ying Zhangbb0dc102013-08-16 15:16:11 +08002902#endif
Andy Fleming272cc702008-10-30 16:41:01 -05002903
Simon Glassc40fdca2016-05-01 13:52:35 -06002904 mmc_do_preinit();
Andy Fleming272cc702008-10-30 16:41:01 -05002905 return 0;
2906}
Tomas Melincd3d4882016-11-25 11:01:03 +02002907
2908#ifdef CONFIG_CMD_BKOPS_ENABLE
2909int mmc_set_bkops_enable(struct mmc *mmc)
2910{
2911 int err;
2912 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
2913
2914 err = mmc_send_ext_csd(mmc, ext_csd);
2915 if (err) {
2916 puts("Could not get ext_csd register values\n");
2917 return err;
2918 }
2919
2920 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
2921 puts("Background operations not supported on device\n");
2922 return -EMEDIUMTYPE;
2923 }
2924
2925 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
2926 puts("Background operations already enabled\n");
2927 return 0;
2928 }
2929
2930 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
2931 if (err) {
2932 puts("Failed to enable manual background operations\n");
2933 return err;
2934 }
2935
2936 puts("Enabled manual background operations\n");
2937
2938 return 0;
2939}
2940#endif