blob: 523c0559676d8263a269a98f3e63246d2f725413 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Flemingad347bb2008-10-30 16:41:01 -05002/*
3 * Copyright 2008, Freescale Semiconductor, Inc
4 * Andy Fleming
5 *
6 * Based vaguely on the Linux code
Andy Flemingad347bb2008-10-30 16:41:01 -05007 */
8
9#include <config.h>
10#include <common.h>
11#include <command.h>
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -060012#include <dm.h>
13#include <dm/device-internal.h>
Stephen Warrenbf0c7852014-05-23 12:47:06 -060014#include <errno.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050015#include <mmc.h>
16#include <part.h>
Peng Fan15305962016-10-11 15:08:43 +080017#include <power/regulator.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050018#include <malloc.h>
Simon Glass2dd337a2015-09-02 17:24:58 -060019#include <memalign.h>
Andy Flemingad347bb2008-10-30 16:41:01 -050020#include <linux/list.h>
Rabin Vincent69d4e2c2009-04-05 13:30:54 +053021#include <div64.h>
Paul Burton8d30cc92013-09-09 15:30:26 +010022#include "mmc_private.h"
Andy Flemingad347bb2008-10-30 16:41:01 -050023
Jean-Jacques Hiblot201559c2019-07-02 10:53:54 +020024#define DEFAULT_CMD6_TIMEOUT_MS 500
25
Kishon Vijay Abraham I4afb12b2017-09-21 16:30:00 +020026static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
Marek Vasutf537e392016-12-01 02:06:33 +010027
Simon Glasseba48f92017-07-29 11:35:31 -060028#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +020029
Sam Protsenkodb174c62019-08-14 22:52:51 +030030static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +020031{
32 return -ENOSYS;
33}
34
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +020035__weak int board_mmc_getwp(struct mmc *mmc)
Nikita Kiryanov020f2612012-12-03 02:19:46 +000036{
37 return -1;
38}
39
40int mmc_getwp(struct mmc *mmc)
41{
42 int wp;
43
44 wp = board_mmc_getwp(mmc);
45
Peter Korsgaardf7b15102013-03-21 04:00:03 +000046 if (wp < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +020047 if (mmc->cfg->ops->getwp)
48 wp = mmc->cfg->ops->getwp(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +000049 else
50 wp = 0;
51 }
Nikita Kiryanov020f2612012-12-03 02:19:46 +000052
53 return wp;
54}
55
Jeroen Hofstee47726302014-07-10 22:46:28 +020056__weak int board_mmc_getcd(struct mmc *mmc)
57{
Stefano Babic6e00edf2010-02-05 15:04:43 +010058 return -1;
59}
Simon Glass394dfc02016-06-12 23:30:22 -060060#endif
Stefano Babic6e00edf2010-02-05 15:04:43 +010061
Simon Glassb23d96e2016-06-12 23:30:20 -060062#ifdef CONFIG_MMC_TRACE
63void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
Andy Flemingad347bb2008-10-30 16:41:01 -050064{
Simon Glassb23d96e2016-06-12 23:30:20 -060065 printf("CMD_SEND:%d\n", cmd->cmdidx);
Marek Vasut6eeee302019-03-23 18:54:45 +010066 printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
Simon Glassb23d96e2016-06-12 23:30:20 -060067}
Marek Vasutdccb6082012-03-15 18:41:35 +000068
Simon Glassb23d96e2016-06-12 23:30:20 -060069void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
70{
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000071 int i;
72 u8 *ptr;
73
Bin Meng8d1ad1e2016-03-17 21:53:14 -070074 if (ret) {
75 printf("\t\tRET\t\t\t %d\n", ret);
76 } else {
77 switch (cmd->resp_type) {
78 case MMC_RSP_NONE:
79 printf("\t\tMMC_RSP_NONE\n");
80 break;
81 case MMC_RSP_R1:
Marek Vasut6eeee302019-03-23 18:54:45 +010082 printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -070083 cmd->response[0]);
84 break;
85 case MMC_RSP_R1b:
Marek Vasut6eeee302019-03-23 18:54:45 +010086 printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -070087 cmd->response[0]);
88 break;
89 case MMC_RSP_R2:
Marek Vasut6eeee302019-03-23 18:54:45 +010090 printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -070091 cmd->response[0]);
Marek Vasut6eeee302019-03-23 18:54:45 +010092 printf("\t\t \t\t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -070093 cmd->response[1]);
Marek Vasut6eeee302019-03-23 18:54:45 +010094 printf("\t\t \t\t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -070095 cmd->response[2]);
Marek Vasut6eeee302019-03-23 18:54:45 +010096 printf("\t\t \t\t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -070097 cmd->response[3]);
Raffaele Recalcati894b1e22011-03-11 02:01:14 +000098 printf("\n");
Bin Meng8d1ad1e2016-03-17 21:53:14 -070099 printf("\t\t\t\t\tDUMPING DATA\n");
100 for (i = 0; i < 4; i++) {
101 int j;
102 printf("\t\t\t\t\t%03d - ", i*4);
103 ptr = (u8 *)&cmd->response[i];
104 ptr += 3;
105 for (j = 0; j < 4; j++)
Marek Vasut6eeee302019-03-23 18:54:45 +0100106 printf("%02x ", *ptr--);
Bin Meng8d1ad1e2016-03-17 21:53:14 -0700107 printf("\n");
108 }
109 break;
110 case MMC_RSP_R3:
Marek Vasut6eeee302019-03-23 18:54:45 +0100111 printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
Bin Meng8d1ad1e2016-03-17 21:53:14 -0700112 cmd->response[0]);
113 break;
114 default:
115 printf("\t\tERROR MMC rsp not supported\n");
116 break;
Bin Meng4a4ef872016-03-17 21:53:13 -0700117 }
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000118 }
Simon Glassb23d96e2016-06-12 23:30:20 -0600119}
120
121void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
122{
123 int status;
124
125 status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
126 printf("CURR STATE:%d\n", status);
127}
Raffaele Recalcati894b1e22011-03-11 02:01:14 +0000128#endif
Simon Glassb23d96e2016-06-12 23:30:20 -0600129
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +0200130#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
131const char *mmc_mode_name(enum bus_mode mode)
132{
133 static const char *const names[] = {
134 [MMC_LEGACY] = "MMC legacy",
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +0200135 [MMC_HS] = "MMC High Speed (26MHz)",
136 [SD_HS] = "SD High Speed (50MHz)",
137 [UHS_SDR12] = "UHS SDR12 (25MHz)",
138 [UHS_SDR25] = "UHS SDR25 (50MHz)",
139 [UHS_SDR50] = "UHS SDR50 (100MHz)",
140 [UHS_SDR104] = "UHS SDR104 (208MHz)",
141 [UHS_DDR50] = "UHS DDR50 (50MHz)",
142 [MMC_HS_52] = "MMC High Speed (52MHz)",
143 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
144 [MMC_HS_200] = "HS200 (200MHz)",
Peng Fan46801252018-08-10 14:07:54 +0800145 [MMC_HS_400] = "HS400 (200MHz)",
Peng Faneede83b2019-07-10 14:43:07 +0800146 [MMC_HS_400_ES] = "HS400ES (200MHz)",
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +0200147 };
148
149 if (mode >= MMC_MODES_END)
150 return "Unknown mode";
151 else
152 return names[mode];
153}
154#endif
155
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200156static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
157{
158 static const int freqs[] = {
Jaehoon Chung7c5c7302018-01-30 14:10:16 +0900159 [MMC_LEGACY] = 25000000,
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200160 [MMC_HS] = 26000000,
161 [SD_HS] = 50000000,
Jaehoon Chung7c5c7302018-01-30 14:10:16 +0900162 [MMC_HS_52] = 52000000,
163 [MMC_DDR_52] = 52000000,
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200164 [UHS_SDR12] = 25000000,
165 [UHS_SDR25] = 50000000,
166 [UHS_SDR50] = 100000000,
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200167 [UHS_DDR50] = 50000000,
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100168 [UHS_SDR104] = 208000000,
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200169 [MMC_HS_200] = 200000000,
Peng Fan46801252018-08-10 14:07:54 +0800170 [MMC_HS_400] = 200000000,
Peng Faneede83b2019-07-10 14:43:07 +0800171 [MMC_HS_400_ES] = 200000000,
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200172 };
173
174 if (mode == MMC_LEGACY)
175 return mmc->legacy_speed;
176 else if (mode >= MMC_MODES_END)
177 return 0;
178 else
179 return freqs[mode];
180}
181
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +0200182static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
183{
184 mmc->selected_mode = mode;
Jean-Jacques Hiblot78422312017-09-21 16:29:55 +0200185 mmc->tran_speed = mmc_mode2freq(mmc, mode);
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200186 mmc->ddr_mode = mmc_is_mode_ddr(mode);
Masahiro Yamadaf97b1482018-01-28 19:11:42 +0900187 pr_debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
188 mmc->tran_speed / 1000000);
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +0200189 return 0;
190}
191
Simon Glasseba48f92017-07-29 11:35:31 -0600192#if !CONFIG_IS_ENABLED(DM_MMC)
Simon Glassb23d96e2016-06-12 23:30:20 -0600193int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
194{
195 int ret;
196
197 mmmc_trace_before_send(mmc, cmd);
198 ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
199 mmmc_trace_after_send(mmc, cmd, ret);
200
Marek Vasutdccb6082012-03-15 18:41:35 +0000201 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500202}
Simon Glass394dfc02016-06-12 23:30:22 -0600203#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500204
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200205int mmc_send_status(struct mmc *mmc, unsigned int *status)
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000206{
207 struct mmc_cmd cmd;
Jan Kloetzke31789322012-02-05 22:29:12 +0000208 int err, retries = 5;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000209
210 cmd.cmdidx = MMC_CMD_SEND_STATUS;
211 cmd.resp_type = MMC_RSP_R1;
Marek Vasutc4427392011-08-10 09:24:48 +0200212 if (!mmc_host_is_spi(mmc))
213 cmd.cmdarg = mmc->rca << 16;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000214
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200215 while (retries--) {
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000216 err = mmc_send_cmd(mmc, &cmd, NULL);
Jan Kloetzke31789322012-02-05 22:29:12 +0000217 if (!err) {
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200218 mmc_trace_state(mmc, &cmd);
219 *status = cmd.response[0];
220 return 0;
221 }
222 }
223 mmc_trace_state(mmc, &cmd);
224 return -ECOMM;
225}
226
Sam Protsenkodb174c62019-08-14 22:52:51 +0300227int mmc_poll_for_busy(struct mmc *mmc, int timeout_ms)
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200228{
229 unsigned int status;
230 int err;
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +0200231
Sam Protsenkodb174c62019-08-14 22:52:51 +0300232 err = mmc_wait_dat0(mmc, 1, timeout_ms * 1000);
Jean-Jacques Hiblot4f04a322019-07-02 10:53:53 +0200233 if (err != -ENOSYS)
234 return err;
235
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200236 while (1) {
237 err = mmc_send_status(mmc, &status);
238 if (err)
239 return err;
240
241 if ((status & MMC_STATUS_RDY_FOR_DATA) &&
242 (status & MMC_STATUS_CURR_STATE) !=
243 MMC_STATE_PRG)
244 break;
245
246 if (status & MMC_STATUS_MASK) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100247#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200248 pr_err("Status Error: 0x%08x\n", status);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100249#endif
Jean-Jacques Hiblot443edbe2019-07-02 10:53:52 +0200250 return -ECOMM;
251 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000252
Sam Protsenkodb174c62019-08-14 22:52:51 +0300253 if (timeout_ms-- <= 0)
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500254 break;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000255
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500256 udelay(1000);
257 }
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000258
Sam Protsenkodb174c62019-08-14 22:52:51 +0300259 if (timeout_ms <= 0) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100260#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +0100261 pr_err("Timeout waiting card ready\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100262#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +0900263 return -ETIMEDOUT;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000264 }
265
266 return 0;
267}
268
Paul Burton8d30cc92013-09-09 15:30:26 +0100269int mmc_set_blocklen(struct mmc *mmc, int len)
Andy Flemingad347bb2008-10-30 16:41:01 -0500270{
271 struct mmc_cmd cmd;
Kishon Vijay Abraham I07baaa62017-09-21 16:30:10 +0200272 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500273
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -0600274 if (mmc->ddr_mode)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900275 return 0;
276
Andy Flemingad347bb2008-10-30 16:41:01 -0500277 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
278 cmd.resp_type = MMC_RSP_R1;
279 cmd.cmdarg = len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500280
Kishon Vijay Abraham I07baaa62017-09-21 16:30:10 +0200281 err = mmc_send_cmd(mmc, &cmd, NULL);
282
283#ifdef CONFIG_MMC_QUIRKS
284 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
285 int retries = 4;
286 /*
287 * It has been seen that SET_BLOCKLEN may fail on the first
288 * attempt, let's try a few more time
289 */
290 do {
291 err = mmc_send_cmd(mmc, &cmd, NULL);
292 if (!err)
293 break;
294 } while (retries--);
295 }
296#endif
297
298 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -0500299}
300
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100301#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot71264bb2017-09-21 16:30:12 +0200302static const u8 tuning_blk_pattern_4bit[] = {
303 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
304 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
305 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
306 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
307 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
308 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
309 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
310 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
311};
312
313static const u8 tuning_blk_pattern_8bit[] = {
314 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
315 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
316 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
317 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
318 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
319 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
320 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
321 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
322 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
323 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
324 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
325 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
326 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
327 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
328 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
329 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
330};
331
332int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
333{
334 struct mmc_cmd cmd;
335 struct mmc_data data;
336 const u8 *tuning_block_pattern;
337 int size, err;
338
339 if (mmc->bus_width == 8) {
340 tuning_block_pattern = tuning_blk_pattern_8bit;
341 size = sizeof(tuning_blk_pattern_8bit);
342 } else if (mmc->bus_width == 4) {
343 tuning_block_pattern = tuning_blk_pattern_4bit;
344 size = sizeof(tuning_blk_pattern_4bit);
345 } else {
346 return -EINVAL;
347 }
348
349 ALLOC_CACHE_ALIGN_BUFFER(u8, data_buf, size);
350
351 cmd.cmdidx = opcode;
352 cmd.cmdarg = 0;
353 cmd.resp_type = MMC_RSP_R1;
354
355 data.dest = (void *)data_buf;
356 data.blocks = 1;
357 data.blocksize = size;
358 data.flags = MMC_DATA_READ;
359
360 err = mmc_send_cmd(mmc, &cmd, &data);
361 if (err)
362 return err;
363
364 if (memcmp(data_buf, tuning_block_pattern, size))
365 return -EIO;
366
367 return 0;
368}
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100369#endif
Jean-Jacques Hiblot71264bb2017-09-21 16:30:12 +0200370
Sascha Silbe4bdf6fd2013-06-14 13:07:25 +0200371static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
Kim Phillips87ea3892012-10-29 13:34:43 +0000372 lbaint_t blkcnt)
Andy Flemingad347bb2008-10-30 16:41:01 -0500373{
374 struct mmc_cmd cmd;
375 struct mmc_data data;
376
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700377 if (blkcnt > 1)
378 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
379 else
380 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
Andy Flemingad347bb2008-10-30 16:41:01 -0500381
382 if (mmc->high_capacity)
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700383 cmd.cmdarg = start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500384 else
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700385 cmd.cmdarg = start * mmc->read_bl_len;
Andy Flemingad347bb2008-10-30 16:41:01 -0500386
387 cmd.resp_type = MMC_RSP_R1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500388
389 data.dest = dst;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700390 data.blocks = blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500391 data.blocksize = mmc->read_bl_len;
392 data.flags = MMC_DATA_READ;
393
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700394 if (mmc_send_cmd(mmc, &cmd, &data))
395 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500396
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700397 if (blkcnt > 1) {
398 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
399 cmd.cmdarg = 0;
400 cmd.resp_type = MMC_RSP_R1b;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700401 if (mmc_send_cmd(mmc, &cmd, NULL)) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100402#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +0100403 pr_err("mmc fail to send stop cmd\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100404#endif
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700405 return 0;
406 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500407 }
408
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700409 return blkcnt;
Andy Flemingad347bb2008-10-30 16:41:01 -0500410}
411
Marek Vasut31976d92020-04-04 12:45:05 +0200412#if !CONFIG_IS_ENABLED(DM_MMC)
413static int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt)
414{
415 if (mmc->cfg->ops->get_b_max)
416 return mmc->cfg->ops->get_b_max(mmc, dst, blkcnt);
417 else
418 return mmc->cfg->b_max;
419}
420#endif
421
Simon Glass5f4bd8c2017-07-04 13:31:19 -0600422#if CONFIG_IS_ENABLED(BLK)
Simon Glass62e293a2016-06-12 23:30:15 -0600423ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600424#else
Simon Glass62e293a2016-06-12 23:30:15 -0600425ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
426 void *dst)
Simon Glass59bc6f22016-05-01 13:52:41 -0600427#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500428{
Simon Glass5f4bd8c2017-07-04 13:31:19 -0600429#if CONFIG_IS_ENABLED(BLK)
Simon Glass59bc6f22016-05-01 13:52:41 -0600430 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
431#endif
Simon Glass2f26fff2016-02-29 15:25:51 -0700432 int dev_num = block_dev->devnum;
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700433 int err;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700434 lbaint_t cur, blocks_todo = blkcnt;
Marek Vasut31976d92020-04-04 12:45:05 +0200435 uint b_max;
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700436
437 if (blkcnt == 0)
438 return 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500439
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700440 struct mmc *mmc = find_mmc_device(dev_num);
Andy Flemingad347bb2008-10-30 16:41:01 -0500441 if (!mmc)
442 return 0;
443
Marek Vasutf537e392016-12-01 02:06:33 +0100444 if (CONFIG_IS_ENABLED(MMC_TINY))
445 err = mmc_switch_part(mmc, block_dev->hwpart);
446 else
447 err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
448
Stephen Warren1e0f92a2015-12-07 11:38:49 -0700449 if (err < 0)
450 return 0;
451
Simon Glasse5db1152016-05-01 13:52:35 -0600452 if ((start + blkcnt) > block_dev->lba) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100453#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +0100454 pr_err("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
455 start + blkcnt, block_dev->lba);
Paul Burton6a7c5ba2013-09-04 16:12:25 +0100456#endif
Lei Wene1cc9c82010-09-13 22:07:27 +0800457 return 0;
458 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500459
Simon Glassa4343c42015-06-23 15:38:50 -0600460 if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +0900461 pr_debug("%s: Failed to set blocklen\n", __func__);
Andy Flemingad347bb2008-10-30 16:41:01 -0500462 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600463 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500464
Marek Vasut31976d92020-04-04 12:45:05 +0200465 b_max = mmc_get_b_max(mmc, dst, blkcnt);
466
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700467 do {
Marek Vasut31976d92020-04-04 12:45:05 +0200468 cur = (blocks_todo > b_max) ? b_max : blocks_todo;
Simon Glassa4343c42015-06-23 15:38:50 -0600469 if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +0900470 pr_debug("%s: Failed to read blocks\n", __func__);
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700471 return 0;
Simon Glassa4343c42015-06-23 15:38:50 -0600472 }
Alagu Sankarc25d1b92010-10-25 07:23:56 -0700473 blocks_todo -= cur;
474 start += cur;
475 dst += cur * mmc->read_bl_len;
476 } while (blocks_todo > 0);
Andy Flemingad347bb2008-10-30 16:41:01 -0500477
478 return blkcnt;
479}
480
Kim Phillips87ea3892012-10-29 13:34:43 +0000481static int mmc_go_idle(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -0500482{
483 struct mmc_cmd cmd;
484 int err;
485
486 udelay(1000);
487
488 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
489 cmd.cmdarg = 0;
490 cmd.resp_type = MMC_RSP_NONE;
Andy Flemingad347bb2008-10-30 16:41:01 -0500491
492 err = mmc_send_cmd(mmc, &cmd, NULL);
493
494 if (err)
495 return err;
496
497 udelay(2000);
498
499 return 0;
500}
501
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100502#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200503static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
504{
505 struct mmc_cmd cmd;
506 int err = 0;
507
508 /*
509 * Send CMD11 only if the request is to switch the card to
510 * 1.8V signalling.
511 */
512 if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
513 return mmc_set_signal_voltage(mmc, signal_voltage);
514
515 cmd.cmdidx = SD_CMD_SWITCH_UHS18V;
516 cmd.cmdarg = 0;
517 cmd.resp_type = MMC_RSP_R1;
518
519 err = mmc_send_cmd(mmc, &cmd, NULL);
520 if (err)
521 return err;
522
523 if (!mmc_host_is_spi(mmc) && (cmd.response[0] & MMC_STATUS_ERROR))
524 return -EIO;
525
526 /*
527 * The card should drive cmd and dat[0:3] low immediately
528 * after the response of cmd11, but wait 100 us to be sure
529 */
530 err = mmc_wait_dat0(mmc, 0, 100);
531 if (err == -ENOSYS)
532 udelay(100);
533 else if (err)
534 return -ETIMEDOUT;
535
536 /*
537 * During a signal voltage level switch, the clock must be gated
538 * for 5 ms according to the SD spec
539 */
Jaehoon Chung239cb2f2018-01-26 19:25:29 +0900540 mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200541
542 err = mmc_set_signal_voltage(mmc, signal_voltage);
543 if (err)
544 return err;
545
546 /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
547 mdelay(10);
Jaehoon Chung239cb2f2018-01-26 19:25:29 +0900548 mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200549
550 /*
551 * Failure to switch is indicated by the card holding
552 * dat[0:3] low. Wait for at least 1 ms according to spec
553 */
554 err = mmc_wait_dat0(mmc, 1, 1000);
555 if (err == -ENOSYS)
556 udelay(1000);
557 else if (err)
558 return -ETIMEDOUT;
559
560 return 0;
561}
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100562#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200563
564static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
Andy Flemingad347bb2008-10-30 16:41:01 -0500565{
566 int timeout = 1000;
567 int err;
568 struct mmc_cmd cmd;
569
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500570 while (1) {
Andy Flemingad347bb2008-10-30 16:41:01 -0500571 cmd.cmdidx = MMC_CMD_APP_CMD;
572 cmd.resp_type = MMC_RSP_R1;
573 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500574
575 err = mmc_send_cmd(mmc, &cmd, NULL);
576
577 if (err)
578 return err;
579
580 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
581 cmd.resp_type = MMC_RSP_R3;
Stefano Babicf8e9a212010-01-20 18:20:39 +0100582
583 /*
584 * Most cards do not answer if some reserved bits
585 * in the ocr are set. However, Some controller
586 * can set bit 7 (reserved for low voltages), but
587 * how to manage low voltages SD card is not yet
588 * specified.
589 */
Thomas Chou1254c3d2010-12-24 13:12:21 +0000590 cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200591 (mmc->cfg->voltages & 0xff8000);
Andy Flemingad347bb2008-10-30 16:41:01 -0500592
593 if (mmc->version == SD_VERSION_2)
594 cmd.cmdarg |= OCR_HCS;
595
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200596 if (uhs_en)
597 cmd.cmdarg |= OCR_S18R;
598
Andy Flemingad347bb2008-10-30 16:41:01 -0500599 err = mmc_send_cmd(mmc, &cmd, NULL);
600
601 if (err)
602 return err;
603
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500604 if (cmd.response[0] & OCR_BUSY)
605 break;
Andy Flemingad347bb2008-10-30 16:41:01 -0500606
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500607 if (timeout-- <= 0)
Jaehoon Chung7825d202016-07-19 16:33:36 +0900608 return -EOPNOTSUPP;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500609
610 udelay(1000);
611 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500612
613 if (mmc->version != SD_VERSION_2)
614 mmc->version = SD_VERSION_1_0;
615
Thomas Chou1254c3d2010-12-24 13:12:21 +0000616 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
617 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
618 cmd.resp_type = MMC_RSP_R3;
619 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000620
621 err = mmc_send_cmd(mmc, &cmd, NULL);
622
623 if (err)
624 return err;
625 }
626
Rabin Vincentb6eed942009-04-05 13:30:56 +0530627 mmc->ocr = cmd.response[0];
Andy Flemingad347bb2008-10-30 16:41:01 -0500628
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100629#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200630 if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x41000000)
631 == 0x41000000) {
632 err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
633 if (err)
634 return err;
635 }
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +0100636#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +0200637
Andy Flemingad347bb2008-10-30 16:41:01 -0500638 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
639 mmc->rca = 0;
640
641 return 0;
642}
643
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500644static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
Andy Flemingad347bb2008-10-30 16:41:01 -0500645{
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500646 struct mmc_cmd cmd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500647 int err;
648
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500649 cmd.cmdidx = MMC_CMD_SEND_OP_COND;
650 cmd.resp_type = MMC_RSP_R3;
651 cmd.cmdarg = 0;
Rob Herring5fd3edd2015-03-23 17:56:59 -0500652 if (use_arg && !mmc_host_is_spi(mmc))
653 cmd.cmdarg = OCR_HCS |
Pantelis Antoniou2c850462014-03-11 19:34:20 +0200654 (mmc->cfg->voltages &
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500655 (mmc->ocr & OCR_VOLTAGE_MASK)) |
656 (mmc->ocr & OCR_ACCESS_MODE);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000657
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500658 err = mmc_send_cmd(mmc, &cmd, NULL);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000659 if (err)
660 return err;
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500661 mmc->ocr = cmd.response[0];
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000662 return 0;
663}
664
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200665static int mmc_send_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000666{
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000667 int err, i;
668
Andy Flemingad347bb2008-10-30 16:41:01 -0500669 /* Some cards seem to need this */
670 mmc_go_idle(mmc);
671
Raffaele Recalcati1df837e2011-03-11 02:01:13 +0000672 /* Asking to the card its capabilities */
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000673 for (i = 0; i < 2; i++) {
Andrew Gabbasovfafa6a02015-03-19 07:44:04 -0500674 err = mmc_send_op_cond_iter(mmc, i != 0);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000675 if (err)
676 return err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200677
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000678 /* exit if not busy (flag seems to be inverted) */
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500679 if (mmc->ocr & OCR_BUSY)
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500680 break;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000681 }
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -0500682 mmc->op_cond_pending = 1;
683 return 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000684}
Wolfgang Denk80f70212011-05-19 22:21:41 +0200685
Jeroen Hofsteeaedeeaa2014-07-12 21:24:08 +0200686static int mmc_complete_op_cond(struct mmc *mmc)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000687{
688 struct mmc_cmd cmd;
689 int timeout = 1000;
Vipul Kumardbad7b42018-05-03 12:20:54 +0530690 ulong start;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000691 int err;
Wolfgang Denk80f70212011-05-19 22:21:41 +0200692
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +0000693 mmc->op_cond_pending = 0;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500694 if (!(mmc->ocr & OCR_BUSY)) {
Yangbo Lu9c720612016-08-02 15:33:18 +0800695 /* Some cards seem to need this */
696 mmc_go_idle(mmc);
697
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500698 start = get_timer(0);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500699 while (1) {
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500700 err = mmc_send_op_cond_iter(mmc, 1);
701 if (err)
702 return err;
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500703 if (mmc->ocr & OCR_BUSY)
704 break;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500705 if (get_timer(start) > timeout)
Jaehoon Chung7825d202016-07-19 16:33:36 +0900706 return -EOPNOTSUPP;
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500707 udelay(100);
Andrew Gabbasov034857c2015-03-19 07:44:06 -0500708 }
Andrew Gabbasov5a513ca2015-03-19 07:44:05 -0500709 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500710
Thomas Chou1254c3d2010-12-24 13:12:21 +0000711 if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
712 cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
713 cmd.resp_type = MMC_RSP_R3;
714 cmd.cmdarg = 0;
Thomas Chou1254c3d2010-12-24 13:12:21 +0000715
716 err = mmc_send_cmd(mmc, &cmd, NULL);
717
718 if (err)
719 return err;
Andrew Gabbasovec600d12015-03-19 07:44:03 -0500720
721 mmc->ocr = cmd.response[0];
Thomas Chou1254c3d2010-12-24 13:12:21 +0000722 }
723
Andy Flemingad347bb2008-10-30 16:41:01 -0500724 mmc->version = MMC_VERSION_UNKNOWN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500725
726 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
Stephen Warrenf6545f12014-01-30 16:11:12 -0700727 mmc->rca = 1;
Andy Flemingad347bb2008-10-30 16:41:01 -0500728
729 return 0;
730}
731
732
Heinrich Schuchardtbf230e12020-03-30 07:24:17 +0200733int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
Andy Flemingad347bb2008-10-30 16:41:01 -0500734{
735 struct mmc_cmd cmd;
736 struct mmc_data data;
737 int err;
738
739 /* Get the Card Status Register */
740 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
741 cmd.resp_type = MMC_RSP_R1;
742 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -0500743
Yoshihiro Shimodaf6bec732012-06-07 19:09:11 +0000744 data.dest = (char *)ext_csd;
Andy Flemingad347bb2008-10-30 16:41:01 -0500745 data.blocks = 1;
Simon Glassa09c2b72013-04-03 08:54:30 +0000746 data.blocksize = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -0500747 data.flags = MMC_DATA_READ;
748
749 err = mmc_send_cmd(mmc, &cmd, &data);
750
751 return err;
752}
753
Marek Vasut8a966472019-02-06 11:34:27 +0100754static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
755 bool send_status)
Andy Flemingad347bb2008-10-30 16:41:01 -0500756{
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200757 unsigned int status, start;
Andy Flemingad347bb2008-10-30 16:41:01 -0500758 struct mmc_cmd cmd;
Sam Protsenkodb174c62019-08-14 22:52:51 +0300759 int timeout_ms = DEFAULT_CMD6_TIMEOUT_MS;
Jean-Jacques Hiblot7f5b1692019-07-02 10:53:55 +0200760 bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
761 (index == EXT_CSD_PART_CONF);
Maxime Riparde7462aa2016-11-04 16:18:08 +0100762 int retries = 3;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000763 int ret;
Andy Flemingad347bb2008-10-30 16:41:01 -0500764
Jean-Jacques Hiblot201559c2019-07-02 10:53:54 +0200765 if (mmc->gen_cmd6_time)
Sam Protsenkodb174c62019-08-14 22:52:51 +0300766 timeout_ms = mmc->gen_cmd6_time * 10;
Jean-Jacques Hiblot201559c2019-07-02 10:53:54 +0200767
Jean-Jacques Hiblot7f5b1692019-07-02 10:53:55 +0200768 if (is_part_switch && mmc->part_switch_time)
Sam Protsenkodb174c62019-08-14 22:52:51 +0300769 timeout_ms = mmc->part_switch_time * 10;
Jean-Jacques Hiblot7f5b1692019-07-02 10:53:55 +0200770
Andy Flemingad347bb2008-10-30 16:41:01 -0500771 cmd.cmdidx = MMC_CMD_SWITCH;
772 cmd.resp_type = MMC_RSP_R1b;
773 cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000774 (index << 16) |
775 (value << 8);
Andy Flemingad347bb2008-10-30 16:41:01 -0500776
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200777 do {
Maxime Riparde7462aa2016-11-04 16:18:08 +0100778 ret = mmc_send_cmd(mmc, &cmd, NULL);
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200779 } while (ret && retries-- > 0);
Maxime Riparde7462aa2016-11-04 16:18:08 +0100780
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200781 if (ret)
782 return ret;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000783
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200784 start = get_timer(0);
Marek Vasut8a966472019-02-06 11:34:27 +0100785
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200786 /* poll dat0 for rdy/buys status */
Sam Protsenkodb174c62019-08-14 22:52:51 +0300787 ret = mmc_wait_dat0(mmc, 1, timeout_ms * 1000);
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200788 if (ret && ret != -ENOSYS)
789 return ret;
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000790
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200791 /*
792 * In cases when not allowed to poll by using CMD13 or because we aren't
793 * capable of polling by using mmc_wait_dat0, then rely on waiting the
794 * stated timeout to be sufficient.
795 */
796 if (ret == -ENOSYS && !send_status)
Sam Protsenkodb174c62019-08-14 22:52:51 +0300797 mdelay(timeout_ms);
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200798
799 /* Finally wait until the card is ready or indicates a failure
800 * to switch. It doesn't hurt to use CMD13 here even if send_status
Sam Protsenkodb174c62019-08-14 22:52:51 +0300801 * is false, because by now (after 'timeout_ms' ms) the bus should be
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200802 * reliable.
803 */
804 do {
805 ret = mmc_send_status(mmc, &status);
806
807 if (!ret && (status & MMC_STATUS_SWITCH_ERROR)) {
808 pr_debug("switch failed %d/%d/0x%x !\n", set, index,
809 value);
810 return -EIO;
811 }
812 if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
813 return 0;
814 udelay(100);
Sam Protsenkodb174c62019-08-14 22:52:51 +0300815 } while (get_timer(start) < timeout_ms);
Raffaele Recalcati01a0dc62011-03-11 02:01:12 +0000816
Jean-Jacques Hiblot5a7cf402019-07-02 10:53:56 +0200817 return -ETIMEDOUT;
Andy Flemingad347bb2008-10-30 16:41:01 -0500818}
819
Marek Vasut8a966472019-02-06 11:34:27 +0100820int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
821{
822 return __mmc_switch(mmc, set, index, value, true);
823}
824
Heinrich Schuchardt75e5a642020-03-30 07:24:19 +0200825int mmc_boot_wp(struct mmc *mmc)
826{
827 return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, 1);
828}
829
Marek Vasuta318a7a2018-04-15 00:37:11 +0200830#if !CONFIG_IS_ENABLED(MMC_TINY)
Marek Vasut111572f2019-01-03 21:19:24 +0100831static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
832 bool hsdowngrade)
Andy Flemingad347bb2008-10-30 16:41:01 -0500833{
Andy Flemingad347bb2008-10-30 16:41:01 -0500834 int err;
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200835 int speed_bits;
836
837 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
838
839 switch (mode) {
840 case MMC_HS:
841 case MMC_HS_52:
842 case MMC_DDR_52:
843 speed_bits = EXT_CSD_TIMING_HS;
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +0200844 break;
Jean-Jacques Hiblot74c98b22018-01-04 15:23:30 +0100845#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +0200846 case MMC_HS_200:
847 speed_bits = EXT_CSD_TIMING_HS200;
848 break;
Jean-Jacques Hiblot74c98b22018-01-04 15:23:30 +0100849#endif
Peng Fan46801252018-08-10 14:07:54 +0800850#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
851 case MMC_HS_400:
852 speed_bits = EXT_CSD_TIMING_HS400;
853 break;
854#endif
Peng Faneede83b2019-07-10 14:43:07 +0800855#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
856 case MMC_HS_400_ES:
857 speed_bits = EXT_CSD_TIMING_HS400;
858 break;
859#endif
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200860 case MMC_LEGACY:
861 speed_bits = EXT_CSD_TIMING_LEGACY;
862 break;
863 default:
864 return -EINVAL;
865 }
Marek Vasut8a966472019-02-06 11:34:27 +0100866
867 err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
868 speed_bits, !hsdowngrade);
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200869 if (err)
870 return err;
871
Marek Vasut111572f2019-01-03 21:19:24 +0100872#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
873 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
874 /*
875 * In case the eMMC is in HS200/HS400 mode and we are downgrading
876 * to HS mode, the card clock are still running much faster than
877 * the supported HS mode clock, so we can not reliably read out
878 * Extended CSD. Reconfigure the controller to run at HS mode.
879 */
880 if (hsdowngrade) {
881 mmc_select_mode(mmc, MMC_HS);
882 mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
883 }
884#endif
885
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200886 if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
887 /* Now check to see that it worked */
888 err = mmc_send_ext_csd(mmc, test_csd);
889 if (err)
890 return err;
891
892 /* No high-speed support */
893 if (!test_csd[EXT_CSD_HS_TIMING])
894 return -ENOTSUPP;
895 }
896
897 return 0;
898}
899
900static int mmc_get_capabilities(struct mmc *mmc)
901{
902 u8 *ext_csd = mmc->ext_csd;
903 char cardtype;
Andy Flemingad347bb2008-10-30 16:41:01 -0500904
Jean-Jacques Hiblot3f2ffc22017-11-30 17:43:56 +0100905 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Flemingad347bb2008-10-30 16:41:01 -0500906
Thomas Chou1254c3d2010-12-24 13:12:21 +0000907 if (mmc_host_is_spi(mmc))
908 return 0;
909
Andy Flemingad347bb2008-10-30 16:41:01 -0500910 /* Only version 4 supports high-speed */
911 if (mmc->version < MMC_VERSION_4)
912 return 0;
913
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200914 if (!ext_csd) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +0100915 pr_err("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200916 return -ENOTSUPP;
917 }
Andy Flemingad347bb2008-10-30 16:41:01 -0500918
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200919 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
Andy Flemingad347bb2008-10-30 16:41:01 -0500920
Peng Fan46801252018-08-10 14:07:54 +0800921 cardtype = ext_csd[EXT_CSD_CARD_TYPE];
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +0200922 mmc->cardtype = cardtype;
Andy Flemingad347bb2008-10-30 16:41:01 -0500923
Jean-Jacques Hiblot74c98b22018-01-04 15:23:30 +0100924#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +0200925 if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
926 EXT_CSD_CARD_TYPE_HS200_1_8V)) {
927 mmc->card_caps |= MMC_MODE_HS200;
928 }
Jean-Jacques Hiblot74c98b22018-01-04 15:23:30 +0100929#endif
Peng Faneede83b2019-07-10 14:43:07 +0800930#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) || \
931 CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
Peng Fan46801252018-08-10 14:07:54 +0800932 if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
933 EXT_CSD_CARD_TYPE_HS400_1_8V)) {
934 mmc->card_caps |= MMC_MODE_HS400;
935 }
936#endif
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900937 if (cardtype & EXT_CSD_CARD_TYPE_52) {
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200938 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900939 mmc->card_caps |= MMC_MODE_DDR_52MHz;
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200940 mmc->card_caps |= MMC_MODE_HS_52MHz;
Jaehoon Chung38ce30b2014-05-16 13:59:54 +0900941 }
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +0200942 if (cardtype & EXT_CSD_CARD_TYPE_26)
943 mmc->card_caps |= MMC_MODE_HS;
Andy Flemingad347bb2008-10-30 16:41:01 -0500944
Peng Faneede83b2019-07-10 14:43:07 +0800945#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
946 if (ext_csd[EXT_CSD_STROBE_SUPPORT] &&
947 (mmc->card_caps & MMC_MODE_HS400)) {
948 mmc->card_caps |= MMC_MODE_HS400_ES;
949 }
950#endif
951
Andy Flemingad347bb2008-10-30 16:41:01 -0500952 return 0;
953}
Marek Vasuta318a7a2018-04-15 00:37:11 +0200954#endif
Andy Flemingad347bb2008-10-30 16:41:01 -0500955
Stephen Warrene315ae82013-06-11 15:14:01 -0600956static int mmc_set_capacity(struct mmc *mmc, int part_num)
957{
958 switch (part_num) {
959 case 0:
960 mmc->capacity = mmc->capacity_user;
961 break;
962 case 1:
963 case 2:
964 mmc->capacity = mmc->capacity_boot;
965 break;
966 case 3:
967 mmc->capacity = mmc->capacity_rpmb;
968 break;
969 case 4:
970 case 5:
971 case 6:
972 case 7:
973 mmc->capacity = mmc->capacity_gp[part_num - 4];
974 break;
975 default:
976 return -1;
977 }
978
Simon Glasse5db1152016-05-01 13:52:35 -0600979 mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Stephen Warrene315ae82013-06-11 15:14:01 -0600980
981 return 0;
982}
983
Simon Glass62e293a2016-06-12 23:30:15 -0600984int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
Lei Wen31b99802011-05-02 16:26:26 +0000985{
Stephen Warrene315ae82013-06-11 15:14:01 -0600986 int ret;
Jean-Jacques Hiblotfaf5c952019-07-02 10:53:58 +0200987 int retry = 3;
Lei Wen31b99802011-05-02 16:26:26 +0000988
Jean-Jacques Hiblotfaf5c952019-07-02 10:53:58 +0200989 do {
990 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
991 EXT_CSD_PART_CONF,
992 (mmc->part_config & ~PART_ACCESS_MASK)
993 | (part_num & PART_ACCESS_MASK));
994 } while (ret && retry--);
Peter Bigot45fde892014-09-02 18:31:23 -0500995
996 /*
997 * Set the capacity if the switch succeeded or was intended
998 * to return to representing the raw device.
999 */
Stephen Warren1e0f92a2015-12-07 11:38:49 -07001000 if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
Peter Bigot45fde892014-09-02 18:31:23 -05001001 ret = mmc_set_capacity(mmc, part_num);
Simon Glass984db5d2016-05-01 13:52:37 -06001002 mmc_get_blk_desc(mmc)->hwpart = part_num;
Stephen Warren1e0f92a2015-12-07 11:38:49 -07001003 }
Stephen Warrene315ae82013-06-11 15:14:01 -06001004
Peter Bigot45fde892014-09-02 18:31:23 -05001005 return ret;
Lei Wen31b99802011-05-02 16:26:26 +00001006}
1007
Jean-Jacques Hiblot1d7769a2017-11-30 17:44:02 +01001008#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001009int mmc_hwpart_config(struct mmc *mmc,
1010 const struct mmc_hwpart_conf *conf,
1011 enum mmc_hwpart_conf_mode mode)
1012{
1013 u8 part_attrs = 0;
1014 u32 enh_size_mult;
1015 u32 enh_start_addr;
1016 u32 gp_size_mult[4];
1017 u32 max_enh_size_mult;
1018 u32 tot_enh_size_mult = 0;
Diego Santa Cruz80200272014-12-23 10:50:31 +01001019 u8 wr_rel_set;
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001020 int i, pidx, err;
1021 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1022
1023 if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
1024 return -EINVAL;
1025
1026 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001027 pr_err("eMMC >= 4.4 required for enhanced user data area\n");
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001028 return -EMEDIUMTYPE;
1029 }
1030
1031 if (!(mmc->part_support & PART_SUPPORT)) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001032 pr_err("Card does not support partitioning\n");
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001033 return -EMEDIUMTYPE;
1034 }
1035
1036 if (!mmc->hc_wp_grp_size) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001037 pr_err("Card does not define HC WP group size\n");
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001038 return -EMEDIUMTYPE;
1039 }
1040
1041 /* check partition alignment and total enhanced size */
1042 if (conf->user.enh_size) {
1043 if (conf->user.enh_size % mmc->hc_wp_grp_size ||
1044 conf->user.enh_start % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001045 pr_err("User data enhanced area not HC WP group "
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001046 "size aligned\n");
1047 return -EINVAL;
1048 }
1049 part_attrs |= EXT_CSD_ENH_USR;
1050 enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
1051 if (mmc->high_capacity) {
1052 enh_start_addr = conf->user.enh_start;
1053 } else {
1054 enh_start_addr = (conf->user.enh_start << 9);
1055 }
1056 } else {
1057 enh_size_mult = 0;
1058 enh_start_addr = 0;
1059 }
1060 tot_enh_size_mult += enh_size_mult;
1061
1062 for (pidx = 0; pidx < 4; pidx++) {
1063 if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001064 pr_err("GP%i partition not HC WP group size "
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001065 "aligned\n", pidx+1);
1066 return -EINVAL;
1067 }
1068 gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
1069 if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
1070 part_attrs |= EXT_CSD_ENH_GP(pidx);
1071 tot_enh_size_mult += gp_size_mult[pidx];
1072 }
1073 }
1074
1075 if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001076 pr_err("Card does not support enhanced attribute\n");
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001077 return -EMEDIUMTYPE;
1078 }
1079
1080 err = mmc_send_ext_csd(mmc, ext_csd);
1081 if (err)
1082 return err;
1083
1084 max_enh_size_mult =
1085 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
1086 (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
1087 ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
1088 if (tot_enh_size_mult > max_enh_size_mult) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001089 pr_err("Total enhanced size exceeds maximum (%u > %u)\n",
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001090 tot_enh_size_mult, max_enh_size_mult);
1091 return -EMEDIUMTYPE;
1092 }
1093
Diego Santa Cruz80200272014-12-23 10:50:31 +01001094 /* The default value of EXT_CSD_WR_REL_SET is device
1095 * dependent, the values can only be changed if the
1096 * EXT_CSD_HS_CTRL_REL bit is set. The values can be
1097 * changed only once and before partitioning is completed. */
1098 wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1099 if (conf->user.wr_rel_change) {
1100 if (conf->user.wr_rel_set)
1101 wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
1102 else
1103 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
1104 }
1105 for (pidx = 0; pidx < 4; pidx++) {
1106 if (conf->gp_part[pidx].wr_rel_change) {
1107 if (conf->gp_part[pidx].wr_rel_set)
1108 wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
1109 else
1110 wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
1111 }
1112 }
1113
1114 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
1115 !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
1116 puts("Card does not support host controlled partition write "
1117 "reliability settings\n");
1118 return -EMEDIUMTYPE;
1119 }
1120
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001121 if (ext_csd[EXT_CSD_PARTITION_SETTING] &
1122 EXT_CSD_PARTITION_SETTING_COMPLETED) {
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001123 pr_err("Card already partitioned\n");
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001124 return -EPERM;
1125 }
1126
1127 if (mode == MMC_HWPART_CONF_CHECK)
1128 return 0;
1129
1130 /* Partitioning requires high-capacity size definitions */
1131 if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
1132 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1133 EXT_CSD_ERASE_GROUP_DEF, 1);
1134
1135 if (err)
1136 return err;
1137
1138 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
1139
Jaehoon Chung58b9eb82020-01-17 15:06:54 +09001140#if CONFIG_IS_ENABLED(MMC_WRITE)
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001141 /* update erase group size to be high-capacity */
1142 mmc->erase_grp_size =
1143 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jaehoon Chung58b9eb82020-01-17 15:06:54 +09001144#endif
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001145
1146 }
1147
1148 /* all OK, write the configuration */
1149 for (i = 0; i < 4; i++) {
1150 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1151 EXT_CSD_ENH_START_ADDR+i,
1152 (enh_start_addr >> (i*8)) & 0xFF);
1153 if (err)
1154 return err;
1155 }
1156 for (i = 0; i < 3; i++) {
1157 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1158 EXT_CSD_ENH_SIZE_MULT+i,
1159 (enh_size_mult >> (i*8)) & 0xFF);
1160 if (err)
1161 return err;
1162 }
1163 for (pidx = 0; pidx < 4; pidx++) {
1164 for (i = 0; i < 3; i++) {
1165 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1166 EXT_CSD_GP_SIZE_MULT+pidx*3+i,
1167 (gp_size_mult[pidx] >> (i*8)) & 0xFF);
1168 if (err)
1169 return err;
1170 }
1171 }
1172 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1173 EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
1174 if (err)
1175 return err;
1176
1177 if (mode == MMC_HWPART_CONF_SET)
1178 return 0;
1179
Diego Santa Cruz80200272014-12-23 10:50:31 +01001180 /* The WR_REL_SET is a write-once register but shall be
1181 * written before setting PART_SETTING_COMPLETED. As it is
1182 * write-once we can only write it when completing the
1183 * partitioning. */
1184 if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
1185 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1186 EXT_CSD_WR_REL_SET, wr_rel_set);
1187 if (err)
1188 return err;
1189 }
1190
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001191 /* Setting PART_SETTING_COMPLETED confirms the partition
1192 * configuration but it only becomes effective after power
1193 * cycle, so we do not adjust the partition related settings
1194 * in the mmc struct. */
1195
1196 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1197 EXT_CSD_PARTITION_SETTING,
1198 EXT_CSD_PARTITION_SETTING_COMPLETED);
1199 if (err)
1200 return err;
1201
1202 return 0;
1203}
Jean-Jacques Hiblot1d7769a2017-11-30 17:44:02 +01001204#endif
Diego Santa Cruz69eb71a02014-12-23 10:50:29 +01001205
Simon Glasseba48f92017-07-29 11:35:31 -06001206#if !CONFIG_IS_ENABLED(DM_MMC)
Thierry Redingb9c8b772012-01-02 01:15:37 +00001207int mmc_getcd(struct mmc *mmc)
1208{
1209 int cd;
1210
1211 cd = board_mmc_getcd(mmc);
1212
Peter Korsgaardf7b15102013-03-21 04:00:03 +00001213 if (cd < 0) {
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001214 if (mmc->cfg->ops->getcd)
1215 cd = mmc->cfg->ops->getcd(mmc);
Peter Korsgaardf7b15102013-03-21 04:00:03 +00001216 else
1217 cd = 1;
1218 }
Thierry Redingb9c8b772012-01-02 01:15:37 +00001219
1220 return cd;
1221}
Simon Glass394dfc02016-06-12 23:30:22 -06001222#endif
Thierry Redingb9c8b772012-01-02 01:15:37 +00001223
Marek Vasuta318a7a2018-04-15 00:37:11 +02001224#if !CONFIG_IS_ENABLED(MMC_TINY)
Kim Phillips87ea3892012-10-29 13:34:43 +00001225static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
Andy Flemingad347bb2008-10-30 16:41:01 -05001226{
1227 struct mmc_cmd cmd;
1228 struct mmc_data data;
1229
1230 /* Switch the frequency */
1231 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
1232 cmd.resp_type = MMC_RSP_R1;
1233 cmd.cmdarg = (mode << 31) | 0xffffff;
1234 cmd.cmdarg &= ~(0xf << (group * 4));
1235 cmd.cmdarg |= value << (group * 4);
Andy Flemingad347bb2008-10-30 16:41:01 -05001236
1237 data.dest = (char *)resp;
1238 data.blocksize = 64;
1239 data.blocks = 1;
1240 data.flags = MMC_DATA_READ;
1241
1242 return mmc_send_cmd(mmc, &cmd, &data);
1243}
1244
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001245static int sd_get_capabilities(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001246{
1247 int err;
1248 struct mmc_cmd cmd;
Suniel Mahesh2f423da2017-10-05 11:32:00 +05301249 ALLOC_CACHE_ALIGN_BUFFER(__be32, scr, 2);
1250 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
Andy Flemingad347bb2008-10-30 16:41:01 -05001251 struct mmc_data data;
1252 int timeout;
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001253#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001254 u32 sd3_bus_mode;
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001255#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001256
Faiz Abbas01db77e2020-02-26 13:44:32 +05301257 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
Andy Flemingad347bb2008-10-30 16:41:01 -05001258
Thomas Chou1254c3d2010-12-24 13:12:21 +00001259 if (mmc_host_is_spi(mmc))
1260 return 0;
1261
Andy Flemingad347bb2008-10-30 16:41:01 -05001262 /* Read the SCR to find out if this card supports higher speeds */
1263 cmd.cmdidx = MMC_CMD_APP_CMD;
1264 cmd.resp_type = MMC_RSP_R1;
1265 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05001266
1267 err = mmc_send_cmd(mmc, &cmd, NULL);
1268
1269 if (err)
1270 return err;
1271
1272 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
1273 cmd.resp_type = MMC_RSP_R1;
1274 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05001275
1276 timeout = 3;
1277
1278retry_scr:
Anton staaf9b00f0d2011-10-03 13:54:59 +00001279 data.dest = (char *)scr;
Andy Flemingad347bb2008-10-30 16:41:01 -05001280 data.blocksize = 8;
1281 data.blocks = 1;
1282 data.flags = MMC_DATA_READ;
1283
1284 err = mmc_send_cmd(mmc, &cmd, &data);
1285
1286 if (err) {
1287 if (timeout--)
1288 goto retry_scr;
1289
1290 return err;
1291 }
1292
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +03001293 mmc->scr[0] = __be32_to_cpu(scr[0]);
1294 mmc->scr[1] = __be32_to_cpu(scr[1]);
Andy Flemingad347bb2008-10-30 16:41:01 -05001295
1296 switch ((mmc->scr[0] >> 24) & 0xf) {
Bin Meng4a4ef872016-03-17 21:53:13 -07001297 case 0:
1298 mmc->version = SD_VERSION_1_0;
1299 break;
1300 case 1:
1301 mmc->version = SD_VERSION_1_10;
1302 break;
1303 case 2:
1304 mmc->version = SD_VERSION_2;
1305 if ((mmc->scr[0] >> 15) & 0x1)
1306 mmc->version = SD_VERSION_3;
1307 break;
1308 default:
1309 mmc->version = SD_VERSION_1_0;
1310 break;
Andy Flemingad347bb2008-10-30 16:41:01 -05001311 }
1312
Alagu Sankar24bb5ab2010-05-12 15:08:24 +05301313 if (mmc->scr[0] & SD_DATA_4BIT)
1314 mmc->card_caps |= MMC_MODE_4BIT;
1315
Andy Flemingad347bb2008-10-30 16:41:01 -05001316 /* Version 1.0 doesn't support switching */
1317 if (mmc->version == SD_VERSION_1_0)
1318 return 0;
1319
1320 timeout = 4;
1321 while (timeout--) {
1322 err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
Anton staaf9b00f0d2011-10-03 13:54:59 +00001323 (u8 *)switch_status);
Andy Flemingad347bb2008-10-30 16:41:01 -05001324
1325 if (err)
1326 return err;
1327
1328 /* The high-speed function is busy. Try again */
Yauhen Kharuzhy6e8edf42009-05-07 00:43:30 +03001329 if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
Andy Flemingad347bb2008-10-30 16:41:01 -05001330 break;
1331 }
1332
Andy Flemingad347bb2008-10-30 16:41:01 -05001333 /* If high-speed isn't supported, we return */
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001334 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1335 mmc->card_caps |= MMC_CAP(SD_HS);
Andy Flemingad347bb2008-10-30 16:41:01 -05001336
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001337#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001338 /* Version before 3.0 don't support UHS modes */
1339 if (mmc->version < SD_VERSION_3)
1340 return 0;
1341
1342 sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
1343 if (sd3_bus_mode & SD_MODE_UHS_SDR104)
1344 mmc->card_caps |= MMC_CAP(UHS_SDR104);
1345 if (sd3_bus_mode & SD_MODE_UHS_SDR50)
1346 mmc->card_caps |= MMC_CAP(UHS_SDR50);
1347 if (sd3_bus_mode & SD_MODE_UHS_SDR25)
1348 mmc->card_caps |= MMC_CAP(UHS_SDR25);
1349 if (sd3_bus_mode & SD_MODE_UHS_SDR12)
1350 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1351 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1352 mmc->card_caps |= MMC_CAP(UHS_DDR50);
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001353#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001354
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001355 return 0;
1356}
1357
1358static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
1359{
1360 int err;
1361
1362 ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001363 int speed;
Macpaul Lin24e92ec2011-11-28 16:31:09 +00001364
Marek Vasut4105e972018-11-18 03:25:08 +01001365 /* SD version 1.00 and 1.01 does not support CMD 6 */
1366 if (mmc->version == SD_VERSION_1_0)
1367 return 0;
1368
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001369 switch (mode) {
Faiz Abbas01db77e2020-02-26 13:44:32 +05301370 case MMC_LEGACY:
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001371 speed = UHS_SDR12_BUS_SPEED;
1372 break;
1373 case SD_HS:
Jean-Jacques Hiblot74c98b22018-01-04 15:23:30 +01001374 speed = HIGH_SPEED_BUS_SPEED;
1375 break;
1376#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1377 case UHS_SDR12:
1378 speed = UHS_SDR12_BUS_SPEED;
1379 break;
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001380 case UHS_SDR25:
1381 speed = UHS_SDR25_BUS_SPEED;
1382 break;
1383 case UHS_SDR50:
1384 speed = UHS_SDR50_BUS_SPEED;
1385 break;
1386 case UHS_DDR50:
1387 speed = UHS_DDR50_BUS_SPEED;
1388 break;
1389 case UHS_SDR104:
1390 speed = UHS_SDR104_BUS_SPEED;
1391 break;
Jean-Jacques Hiblot74c98b22018-01-04 15:23:30 +01001392#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001393 default:
1394 return -EINVAL;
1395 }
1396
1397 err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, speed, (u8 *)switch_status);
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001398 if (err)
1399 return err;
1400
Jean-Jacques Hiblote7f664e2018-02-09 12:09:27 +01001401 if (((__be32_to_cpu(switch_status[4]) >> 24) & 0xF) != speed)
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001402 return -ENOTSUPP;
1403
1404 return 0;
1405}
Andy Flemingad347bb2008-10-30 16:41:01 -05001406
Marek Vasut8ff55fb2018-04-15 00:36:45 +02001407static int sd_select_bus_width(struct mmc *mmc, int w)
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001408{
1409 int err;
1410 struct mmc_cmd cmd;
1411
1412 if ((w != 4) && (w != 1))
1413 return -EINVAL;
1414
1415 cmd.cmdidx = MMC_CMD_APP_CMD;
1416 cmd.resp_type = MMC_RSP_R1;
1417 cmd.cmdarg = mmc->rca << 16;
1418
1419 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05001420 if (err)
1421 return err;
1422
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001423 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
1424 cmd.resp_type = MMC_RSP_R1;
1425 if (w == 4)
1426 cmd.cmdarg = 2;
1427 else if (w == 1)
1428 cmd.cmdarg = 0;
1429 err = mmc_send_cmd(mmc, &cmd, NULL);
1430 if (err)
1431 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05001432
1433 return 0;
1434}
Marek Vasuta318a7a2018-04-15 00:37:11 +02001435#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001436
Jean-Jacques Hiblotcb534f02018-01-04 15:23:33 +01001437#if CONFIG_IS_ENABLED(MMC_WRITE)
Peng Fanb3fcf1e2016-09-01 11:13:38 +08001438static int sd_read_ssr(struct mmc *mmc)
1439{
Jean-Jacques Hiblotcb534f02018-01-04 15:23:33 +01001440 static const unsigned int sd_au_size[] = {
1441 0, SZ_16K / 512, SZ_32K / 512,
1442 SZ_64K / 512, SZ_128K / 512, SZ_256K / 512,
1443 SZ_512K / 512, SZ_1M / 512, SZ_2M / 512,
1444 SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
1445 SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512,
1446 SZ_64M / 512,
1447 };
Peng Fanb3fcf1e2016-09-01 11:13:38 +08001448 int err, i;
1449 struct mmc_cmd cmd;
1450 ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16);
1451 struct mmc_data data;
1452 int timeout = 3;
1453 unsigned int au, eo, et, es;
1454
1455 cmd.cmdidx = MMC_CMD_APP_CMD;
1456 cmd.resp_type = MMC_RSP_R1;
1457 cmd.cmdarg = mmc->rca << 16;
1458
1459 err = mmc_send_cmd(mmc, &cmd, NULL);
Joel Johnson5ea041b2020-01-11 09:08:14 -07001460#ifdef CONFIG_MMC_QUIRKS
1461 if (err && (mmc->quirks & MMC_QUIRK_RETRY_APP_CMD)) {
1462 int retries = 4;
1463 /*
1464 * It has been seen that APP_CMD may fail on the first
1465 * attempt, let's try a few more times
1466 */
1467 do {
1468 err = mmc_send_cmd(mmc, &cmd, NULL);
1469 if (!err)
1470 break;
1471 } while (retries--);
1472 }
1473#endif
Peng Fanb3fcf1e2016-09-01 11:13:38 +08001474 if (err)
1475 return err;
1476
1477 cmd.cmdidx = SD_CMD_APP_SD_STATUS;
1478 cmd.resp_type = MMC_RSP_R1;
1479 cmd.cmdarg = 0;
1480
1481retry_ssr:
1482 data.dest = (char *)ssr;
1483 data.blocksize = 64;
1484 data.blocks = 1;
1485 data.flags = MMC_DATA_READ;
1486
1487 err = mmc_send_cmd(mmc, &cmd, &data);
1488 if (err) {
1489 if (timeout--)
1490 goto retry_ssr;
1491
1492 return err;
1493 }
1494
1495 for (i = 0; i < 16; i++)
1496 ssr[i] = be32_to_cpu(ssr[i]);
1497
1498 au = (ssr[2] >> 12) & 0xF;
1499 if ((au <= 9) || (mmc->version == SD_VERSION_3)) {
1500 mmc->ssr.au = sd_au_size[au];
1501 es = (ssr[3] >> 24) & 0xFF;
1502 es |= (ssr[2] & 0xFF) << 8;
1503 et = (ssr[3] >> 18) & 0x3F;
1504 if (es && et) {
1505 eo = (ssr[3] >> 16) & 0x3;
1506 mmc->ssr.erase_timeout = (et * 1000) / es;
1507 mmc->ssr.erase_offset = eo * 1000;
1508 }
1509 } else {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001510 pr_debug("Invalid Allocation Unit Size.\n");
Peng Fanb3fcf1e2016-09-01 11:13:38 +08001511 }
1512
1513 return 0;
1514}
Jean-Jacques Hiblotcb534f02018-01-04 15:23:33 +01001515#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001516/* frequency bases */
1517/* divided by 10 to be nice to platforms without floating point */
Mike Frysingerb588caf2010-10-20 01:15:53 +00001518static const int fbase[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -05001519 10000,
1520 100000,
1521 1000000,
1522 10000000,
1523};
1524
1525/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
1526 * to platforms without floating point.
1527 */
Simon Glass03317cc2016-05-14 14:02:57 -06001528static const u8 multipliers[] = {
Andy Flemingad347bb2008-10-30 16:41:01 -05001529 0, /* reserved */
1530 10,
1531 12,
1532 13,
1533 15,
1534 20,
1535 25,
1536 30,
1537 35,
1538 40,
1539 45,
1540 50,
1541 55,
1542 60,
1543 70,
1544 80,
1545};
1546
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001547static inline int bus_width(uint cap)
1548{
1549 if (cap == MMC_MODE_8BIT)
1550 return 8;
1551 if (cap == MMC_MODE_4BIT)
1552 return 4;
1553 if (cap == MMC_MODE_1BIT)
1554 return 1;
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01001555 pr_warn("invalid bus witdh capability 0x%x\n", cap);
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001556 return 0;
1557}
1558
Simon Glasseba48f92017-07-29 11:35:31 -06001559#if !CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001560#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham Iae7174f2017-09-21 16:30:05 +02001561static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1562{
1563 return -ENOTSUPP;
1564}
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001565#endif
Kishon Vijay Abraham Iae7174f2017-09-21 16:30:05 +02001566
Kishon Vijay Abraham Ie178c112017-09-21 16:29:59 +02001567static int mmc_set_ios(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05001568{
Kishon Vijay Abraham Ie178c112017-09-21 16:29:59 +02001569 int ret = 0;
1570
Pantelis Antoniou2c850462014-03-11 19:34:20 +02001571 if (mmc->cfg->ops->set_ios)
Kishon Vijay Abraham Ie178c112017-09-21 16:29:59 +02001572 ret = mmc->cfg->ops->set_ios(mmc);
1573
1574 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -05001575}
Yann Gautier6f558332019-09-19 17:56:12 +02001576
1577static int mmc_host_power_cycle(struct mmc *mmc)
1578{
1579 int ret = 0;
1580
1581 if (mmc->cfg->ops->host_power_cycle)
1582 ret = mmc->cfg->ops->host_power_cycle(mmc);
1583
1584 return ret;
1585}
Simon Glass394dfc02016-06-12 23:30:22 -06001586#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05001587
Kishon Vijay Abraham Id6246bf2017-09-21 16:30:03 +02001588int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
Andy Flemingad347bb2008-10-30 16:41:01 -05001589{
Jaehoon Chungab4d4052018-01-23 14:04:30 +09001590 if (!disable) {
Jaehoon Chung8a933292018-01-17 19:36:58 +09001591 if (clock > mmc->cfg->f_max)
1592 clock = mmc->cfg->f_max;
Andy Flemingad347bb2008-10-30 16:41:01 -05001593
Jaehoon Chung8a933292018-01-17 19:36:58 +09001594 if (clock < mmc->cfg->f_min)
1595 clock = mmc->cfg->f_min;
1596 }
Andy Flemingad347bb2008-10-30 16:41:01 -05001597
1598 mmc->clock = clock;
Kishon Vijay Abraham Id6246bf2017-09-21 16:30:03 +02001599 mmc->clk_disable = disable;
Andy Flemingad347bb2008-10-30 16:41:01 -05001600
Jaehoon Chungc8477d62018-01-26 19:25:30 +09001601 debug("clock is %s (%dHz)\n", disable ? "disabled" : "enabled", clock);
1602
Kishon Vijay Abraham Ie178c112017-09-21 16:29:59 +02001603 return mmc_set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001604}
1605
Kishon Vijay Abraham Ie178c112017-09-21 16:29:59 +02001606static int mmc_set_bus_width(struct mmc *mmc, uint width)
Andy Flemingad347bb2008-10-30 16:41:01 -05001607{
1608 mmc->bus_width = width;
1609
Kishon Vijay Abraham Ie178c112017-09-21 16:29:59 +02001610 return mmc_set_ios(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05001611}
1612
Jean-Jacques Hiblot00de5042017-09-21 16:29:54 +02001613#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
1614/*
1615 * helper function to display the capabilities in a human
1616 * friendly manner. The capabilities include bus width and
1617 * supported modes.
1618 */
1619void mmc_dump_capabilities(const char *text, uint caps)
1620{
1621 enum bus_mode mode;
1622
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001623 pr_debug("%s: widths [", text);
Jean-Jacques Hiblot00de5042017-09-21 16:29:54 +02001624 if (caps & MMC_MODE_8BIT)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001625 pr_debug("8, ");
Jean-Jacques Hiblot00de5042017-09-21 16:29:54 +02001626 if (caps & MMC_MODE_4BIT)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001627 pr_debug("4, ");
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001628 if (caps & MMC_MODE_1BIT)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001629 pr_debug("1, ");
1630 pr_debug("\b\b] modes [");
Jean-Jacques Hiblot00de5042017-09-21 16:29:54 +02001631 for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
1632 if (MMC_CAP(mode) & caps)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001633 pr_debug("%s, ", mmc_mode_name(mode));
1634 pr_debug("\b\b]\n");
Jean-Jacques Hiblot00de5042017-09-21 16:29:54 +02001635}
1636#endif
1637
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001638struct mode_width_tuning {
1639 enum bus_mode mode;
1640 uint widths;
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001641#ifdef MMC_SUPPORTS_TUNING
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +02001642 uint tuning;
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001643#endif
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001644};
1645
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001646#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001647int mmc_voltage_to_mv(enum mmc_voltage voltage)
1648{
1649 switch (voltage) {
1650 case MMC_SIGNAL_VOLTAGE_000: return 0;
1651 case MMC_SIGNAL_VOLTAGE_330: return 3300;
1652 case MMC_SIGNAL_VOLTAGE_180: return 1800;
1653 case MMC_SIGNAL_VOLTAGE_120: return 1200;
1654 }
1655 return -EINVAL;
1656}
1657
Kishon Vijay Abraham I4afb12b2017-09-21 16:30:00 +02001658static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1659{
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001660 int err;
1661
1662 if (mmc->signal_voltage == signal_voltage)
1663 return 0;
1664
Kishon Vijay Abraham I4afb12b2017-09-21 16:30:00 +02001665 mmc->signal_voltage = signal_voltage;
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001666 err = mmc_set_ios(mmc);
1667 if (err)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001668 pr_debug("unable to set voltage (err %d)\n", err);
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001669
1670 return err;
Kishon Vijay Abraham I4afb12b2017-09-21 16:30:00 +02001671}
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001672#else
1673static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
1674{
1675 return 0;
1676}
1677#endif
Kishon Vijay Abraham I4afb12b2017-09-21 16:30:00 +02001678
Marek Vasuta318a7a2018-04-15 00:37:11 +02001679#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001680static const struct mode_width_tuning sd_modes_by_pref[] = {
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001681#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1682#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001683 {
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001684 .mode = UHS_SDR104,
1685 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1686 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1687 },
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001688#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001689 {
1690 .mode = UHS_SDR50,
1691 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1692 },
1693 {
1694 .mode = UHS_DDR50,
1695 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1696 },
1697 {
1698 .mode = UHS_SDR25,
1699 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1700 },
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001701#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001702 {
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001703 .mode = SD_HS,
1704 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1705 },
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001706#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001707 {
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001708 .mode = UHS_SDR12,
1709 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1710 },
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001711#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001712 {
Faiz Abbas01db77e2020-02-26 13:44:32 +05301713 .mode = MMC_LEGACY,
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001714 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1715 }
1716};
1717
1718#define for_each_sd_mode_by_pref(caps, mwt) \
1719 for (mwt = sd_modes_by_pref;\
1720 mwt < sd_modes_by_pref + ARRAY_SIZE(sd_modes_by_pref);\
1721 mwt++) \
1722 if (caps & MMC_CAP(mwt->mode))
1723
Jean-Jacques Hiblot3d30972b2017-09-21 16:30:09 +02001724static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001725{
1726 int err;
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001727 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1728 const struct mode_width_tuning *mwt;
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001729#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001730 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001731#else
1732 bool uhs_en = false;
1733#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001734 uint caps;
1735
Jean-Jacques Hiblot93c31d12017-11-30 17:43:54 +01001736#ifdef DEBUG
1737 mmc_dump_capabilities("sd card", card_caps);
Jean-Jacques Hiblotd7e5e032017-11-30 17:43:57 +01001738 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot93c31d12017-11-30 17:43:54 +01001739#endif
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001740
Anup Pateld9c92c72019-07-08 04:10:43 +00001741 if (mmc_host_is_spi(mmc)) {
1742 mmc_set_bus_width(mmc, 1);
Faiz Abbas01db77e2020-02-26 13:44:32 +05301743 mmc_select_mode(mmc, MMC_LEGACY);
Anup Pateld9c92c72019-07-08 04:10:43 +00001744 mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
1745 return 0;
1746 }
1747
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001748 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblotd7e5e032017-11-30 17:43:57 +01001749 caps = card_caps & mmc->host_caps;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001750
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001751 if (!uhs_en)
1752 caps &= ~UHS_CAPS;
1753
1754 for_each_sd_mode_by_pref(caps, mwt) {
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001755 uint *w;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001756
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001757 for (w = widths; w < widths + ARRAY_SIZE(widths); w++) {
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001758 if (*w & caps & mwt->widths) {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001759 pr_debug("trying mode %s width %d (at %d MHz)\n",
1760 mmc_mode_name(mwt->mode),
1761 bus_width(*w),
1762 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001763
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001764 /* configure the bus width (card + host) */
1765 err = sd_select_bus_width(mmc, bus_width(*w));
1766 if (err)
1767 goto error;
1768 mmc_set_bus_width(mmc, bus_width(*w));
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001769
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001770 /* configure the bus mode (card) */
1771 err = sd_set_card_speed(mmc, mwt->mode);
1772 if (err)
1773 goto error;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001774
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001775 /* configure the bus mode (host) */
1776 mmc_select_mode(mmc, mwt->mode);
Jaehoon Chung239cb2f2018-01-26 19:25:29 +09001777 mmc_set_clock(mmc, mmc->tran_speed,
1778 MMC_CLK_ENABLE);
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001779
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001780#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001781 /* execute tuning if needed */
1782 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1783 err = mmc_execute_tuning(mmc,
1784 mwt->tuning);
1785 if (err) {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001786 pr_debug("tuning failed\n");
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001787 goto error;
1788 }
1789 }
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001790#endif
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02001791
Jean-Jacques Hiblotcb534f02018-01-04 15:23:33 +01001792#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001793 err = sd_read_ssr(mmc);
Peng Fan2d2fe8e2018-03-05 16:20:40 +08001794 if (err)
Jean-Jacques Hiblotcb534f02018-01-04 15:23:33 +01001795 pr_warn("unable to read ssr\n");
1796#endif
1797 if (!err)
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001798 return 0;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001799
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001800error:
1801 /* revert to a safer bus speed */
Faiz Abbas01db77e2020-02-26 13:44:32 +05301802 mmc_select_mode(mmc, MMC_LEGACY);
Jaehoon Chung239cb2f2018-01-26 19:25:29 +09001803 mmc_set_clock(mmc, mmc->tran_speed,
1804 MMC_CLK_ENABLE);
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001805 }
1806 }
1807 }
1808
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09001809 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot5b1a4d92017-09-21 16:29:57 +02001810 return -ENOTSUPP;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001811}
1812
Jean-Jacques Hiblot933d1262017-09-21 16:29:52 +02001813/*
1814 * read the compare the part of ext csd that is constant.
1815 * This can be used to check that the transfer is working
1816 * as expected.
1817 */
1818static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02001819{
Jean-Jacques Hiblot933d1262017-09-21 16:29:52 +02001820 int err;
Jean-Jacques Hibloted9506b2017-09-21 16:29:51 +02001821 const u8 *ext_csd = mmc->ext_csd;
Jean-Jacques Hiblot933d1262017-09-21 16:29:52 +02001822 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1823
Jean-Jacques Hiblot7ab1b622017-11-30 17:43:58 +01001824 if (mmc->version < MMC_VERSION_4)
1825 return 0;
1826
Jean-Jacques Hiblot933d1262017-09-21 16:29:52 +02001827 err = mmc_send_ext_csd(mmc, test_csd);
1828 if (err)
1829 return err;
1830
1831 /* Only compare read only fields */
1832 if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
1833 == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
1834 ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
1835 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
1836 ext_csd[EXT_CSD_REV]
1837 == test_csd[EXT_CSD_REV] &&
1838 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
1839 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
1840 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
1841 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
1842 return 0;
1843
1844 return -EBADMSG;
1845}
1846
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001847#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001848static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1849 uint32_t allowed_mask)
1850{
1851 u32 card_mask = 0;
1852
1853 switch (mode) {
Peng Faneede83b2019-07-10 14:43:07 +08001854 case MMC_HS_400_ES:
Peng Fan46801252018-08-10 14:07:54 +08001855 case MMC_HS_400:
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001856 case MMC_HS_200:
Peng Fan46801252018-08-10 14:07:54 +08001857 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
1858 EXT_CSD_CARD_TYPE_HS400_1_8V))
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001859 card_mask |= MMC_SIGNAL_VOLTAGE_180;
Peng Fan46801252018-08-10 14:07:54 +08001860 if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
1861 EXT_CSD_CARD_TYPE_HS400_1_2V))
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001862 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1863 break;
1864 case MMC_DDR_52:
1865 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
1866 card_mask |= MMC_SIGNAL_VOLTAGE_330 |
1867 MMC_SIGNAL_VOLTAGE_180;
1868 if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
1869 card_mask |= MMC_SIGNAL_VOLTAGE_120;
1870 break;
1871 default:
1872 card_mask |= MMC_SIGNAL_VOLTAGE_330;
1873 break;
1874 }
1875
1876 while (card_mask & allowed_mask) {
1877 enum mmc_voltage best_match;
1878
1879 best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
1880 if (!mmc_set_signal_voltage(mmc, best_match))
1881 return 0;
1882
1883 allowed_mask &= ~best_match;
1884 }
1885
1886 return -ENOTSUPP;
1887}
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001888#else
1889static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1890 uint32_t allowed_mask)
1891{
1892 return 0;
1893}
1894#endif
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02001895
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02001896static const struct mode_width_tuning mmc_modes_by_pref[] = {
Peng Faneede83b2019-07-10 14:43:07 +08001897#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
1898 {
1899 .mode = MMC_HS_400_ES,
1900 .widths = MMC_MODE_8BIT,
1901 },
1902#endif
Peng Fan46801252018-08-10 14:07:54 +08001903#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1904 {
1905 .mode = MMC_HS_400,
1906 .widths = MMC_MODE_8BIT,
1907 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1908 },
1909#endif
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001910#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02001911 {
1912 .mode = MMC_HS_200,
1913 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +02001914 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02001915 },
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01001916#endif
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02001917 {
1918 .mode = MMC_DDR_52,
1919 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1920 },
1921 {
1922 .mode = MMC_HS_52,
1923 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1924 },
1925 {
1926 .mode = MMC_HS,
1927 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1928 },
1929 {
1930 .mode = MMC_LEGACY,
1931 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
1932 }
1933};
1934
1935#define for_each_mmc_mode_by_pref(caps, mwt) \
1936 for (mwt = mmc_modes_by_pref;\
1937 mwt < mmc_modes_by_pref + ARRAY_SIZE(mmc_modes_by_pref);\
1938 mwt++) \
1939 if (caps & MMC_CAP(mwt->mode))
1940
1941static const struct ext_csd_bus_width {
1942 uint cap;
1943 bool is_ddr;
1944 uint ext_csd_bits;
1945} ext_csd_bus_width[] = {
1946 {MMC_MODE_8BIT, true, EXT_CSD_DDR_BUS_WIDTH_8},
1947 {MMC_MODE_4BIT, true, EXT_CSD_DDR_BUS_WIDTH_4},
1948 {MMC_MODE_8BIT, false, EXT_CSD_BUS_WIDTH_8},
1949 {MMC_MODE_4BIT, false, EXT_CSD_BUS_WIDTH_4},
1950 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1951};
1952
Peng Fan46801252018-08-10 14:07:54 +08001953#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
1954static int mmc_select_hs400(struct mmc *mmc)
1955{
1956 int err;
1957
1958 /* Set timing to HS200 for tuning */
Marek Vasut111572f2019-01-03 21:19:24 +01001959 err = mmc_set_card_speed(mmc, MMC_HS_200, false);
Peng Fan46801252018-08-10 14:07:54 +08001960 if (err)
1961 return err;
1962
1963 /* configure the bus mode (host) */
1964 mmc_select_mode(mmc, MMC_HS_200);
1965 mmc_set_clock(mmc, mmc->tran_speed, false);
1966
1967 /* execute tuning if needed */
1968 err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
1969 if (err) {
1970 debug("tuning failed\n");
1971 return err;
1972 }
1973
1974 /* Set back to HS */
BOUGH CHEN8702bbc2019-03-26 06:24:17 +00001975 mmc_set_card_speed(mmc, MMC_HS, true);
Peng Fan46801252018-08-10 14:07:54 +08001976
1977 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1978 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
1979 if (err)
1980 return err;
1981
Marek Vasut111572f2019-01-03 21:19:24 +01001982 err = mmc_set_card_speed(mmc, MMC_HS_400, false);
Peng Fan46801252018-08-10 14:07:54 +08001983 if (err)
1984 return err;
1985
1986 mmc_select_mode(mmc, MMC_HS_400);
1987 err = mmc_set_clock(mmc, mmc->tran_speed, false);
1988 if (err)
1989 return err;
1990
1991 return 0;
1992}
1993#else
1994static int mmc_select_hs400(struct mmc *mmc)
1995{
1996 return -ENOTSUPP;
1997}
1998#endif
1999
Peng Faneede83b2019-07-10 14:43:07 +08002000#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
2001#if !CONFIG_IS_ENABLED(DM_MMC)
2002static int mmc_set_enhanced_strobe(struct mmc *mmc)
2003{
2004 return -ENOTSUPP;
2005}
2006#endif
2007static int mmc_select_hs400es(struct mmc *mmc)
2008{
2009 int err;
2010
2011 err = mmc_set_card_speed(mmc, MMC_HS, true);
2012 if (err)
2013 return err;
2014
2015 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
2016 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG |
2017 EXT_CSD_BUS_WIDTH_STROBE);
2018 if (err) {
2019 printf("switch to bus width for hs400 failed\n");
2020 return err;
2021 }
2022 /* TODO: driver strength */
2023 err = mmc_set_card_speed(mmc, MMC_HS_400_ES, false);
2024 if (err)
2025 return err;
2026
2027 mmc_select_mode(mmc, MMC_HS_400_ES);
2028 err = mmc_set_clock(mmc, mmc->tran_speed, false);
2029 if (err)
2030 return err;
2031
2032 return mmc_set_enhanced_strobe(mmc);
2033}
2034#else
2035static int mmc_select_hs400es(struct mmc *mmc)
2036{
2037 return -ENOTSUPP;
2038}
2039#endif
2040
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002041#define for_each_supported_width(caps, ddr, ecbv) \
2042 for (ecbv = ext_csd_bus_width;\
2043 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
2044 ecbv++) \
2045 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
2046
Jean-Jacques Hiblot3d30972b2017-09-21 16:30:09 +02002047static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
Jean-Jacques Hiblot933d1262017-09-21 16:29:52 +02002048{
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002049 int err;
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002050 const struct mode_width_tuning *mwt;
2051 const struct ext_csd_bus_width *ecbw;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002052
Jean-Jacques Hiblot93c31d12017-11-30 17:43:54 +01002053#ifdef DEBUG
2054 mmc_dump_capabilities("mmc", card_caps);
Jean-Jacques Hiblotd7e5e032017-11-30 17:43:57 +01002055 mmc_dump_capabilities("host", mmc->host_caps);
Jean-Jacques Hiblot93c31d12017-11-30 17:43:54 +01002056#endif
2057
Anup Pateld9c92c72019-07-08 04:10:43 +00002058 if (mmc_host_is_spi(mmc)) {
2059 mmc_set_bus_width(mmc, 1);
2060 mmc_select_mode(mmc, MMC_LEGACY);
2061 mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
2062 return 0;
2063 }
2064
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002065 /* Restrict card's capabilities by what the host can do */
Jean-Jacques Hiblotd7e5e032017-11-30 17:43:57 +01002066 card_caps &= mmc->host_caps;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002067
2068 /* Only version 4 of MMC supports wider bus widths */
2069 if (mmc->version < MMC_VERSION_4)
2070 return 0;
2071
Jean-Jacques Hibloted9506b2017-09-21 16:29:51 +02002072 if (!mmc->ext_csd) {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002073 pr_debug("No ext_csd found!\n"); /* this should enver happen */
Jean-Jacques Hibloted9506b2017-09-21 16:29:51 +02002074 return -ENOTSUPP;
2075 }
2076
Marek Vasut111572f2019-01-03 21:19:24 +01002077#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2078 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2079 /*
2080 * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
2081 * before doing anything else, since a transition from either of
2082 * the HS200/HS400 mode directly to legacy mode is not supported.
2083 */
2084 if (mmc->selected_mode == MMC_HS_200 ||
2085 mmc->selected_mode == MMC_HS_400)
2086 mmc_set_card_speed(mmc, MMC_HS, true);
2087 else
2088#endif
2089 mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
Jean-Jacques Hiblot3d30972b2017-09-21 16:30:09 +02002090
2091 for_each_mmc_mode_by_pref(card_caps, mwt) {
2092 for_each_supported_width(card_caps & mwt->widths,
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002093 mmc_is_mode_ddr(mwt->mode), ecbw) {
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02002094 enum mmc_voltage old_voltage;
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002095 pr_debug("trying mode %s width %d (at %d MHz)\n",
2096 mmc_mode_name(mwt->mode),
2097 bus_width(ecbw->cap),
2098 mmc_mode2freq(mmc, mwt->mode) / 1000000);
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02002099 old_voltage = mmc->signal_voltage;
2100 err = mmc_set_lowest_voltage(mmc, mwt->mode,
2101 MMC_ALL_SIGNAL_VOLTAGE);
2102 if (err)
2103 continue;
2104
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002105 /* configure the bus width (card + host) */
2106 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2107 EXT_CSD_BUS_WIDTH,
2108 ecbw->ext_csd_bits & ~EXT_CSD_DDR_FLAG);
2109 if (err)
2110 goto error;
2111 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002112
Peng Fan46801252018-08-10 14:07:54 +08002113 if (mwt->mode == MMC_HS_400) {
2114 err = mmc_select_hs400(mmc);
2115 if (err) {
2116 printf("Select HS400 failed %d\n", err);
2117 goto error;
2118 }
Peng Faneede83b2019-07-10 14:43:07 +08002119 } else if (mwt->mode == MMC_HS_400_ES) {
2120 err = mmc_select_hs400es(mmc);
2121 if (err) {
2122 printf("Select HS400ES failed %d\n",
2123 err);
2124 goto error;
2125 }
Peng Fan46801252018-08-10 14:07:54 +08002126 } else {
2127 /* configure the bus speed (card) */
Marek Vasut111572f2019-01-03 21:19:24 +01002128 err = mmc_set_card_speed(mmc, mwt->mode, false);
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002129 if (err)
2130 goto error;
Peng Fan46801252018-08-10 14:07:54 +08002131
2132 /*
2133 * configure the bus width AND the ddr mode
2134 * (card). The host side will be taken care
2135 * of in the next step
2136 */
2137 if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
2138 err = mmc_switch(mmc,
2139 EXT_CSD_CMD_SET_NORMAL,
2140 EXT_CSD_BUS_WIDTH,
2141 ecbw->ext_csd_bits);
2142 if (err)
2143 goto error;
2144 }
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002145
Peng Fan46801252018-08-10 14:07:54 +08002146 /* configure the bus mode (host) */
2147 mmc_select_mode(mmc, mwt->mode);
2148 mmc_set_clock(mmc, mmc->tran_speed,
2149 MMC_CLK_ENABLE);
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01002150#ifdef MMC_SUPPORTS_TUNING
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002151
Peng Fan46801252018-08-10 14:07:54 +08002152 /* execute tuning if needed */
2153 if (mwt->tuning) {
2154 err = mmc_execute_tuning(mmc,
2155 mwt->tuning);
2156 if (err) {
2157 pr_debug("tuning failed\n");
2158 goto error;
2159 }
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +02002160 }
Jean-Jacques Hiblot6051e782017-11-30 17:44:01 +01002161#endif
Peng Fan46801252018-08-10 14:07:54 +08002162 }
Kishon Vijay Abraham I210369f2017-09-21 16:30:06 +02002163
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002164 /* do a transfer to check the configuration */
2165 err = mmc_read_and_compare_ext_csd(mmc);
2166 if (!err)
2167 return 0;
2168error:
Jean-Jacques Hiblotb6937d62017-09-21 16:30:11 +02002169 mmc_set_signal_voltage(mmc, old_voltage);
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002170 /* if an error occured, revert to a safer bus mode */
2171 mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2172 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
2173 mmc_select_mode(mmc, MMC_LEGACY);
2174 mmc_set_bus_width(mmc, 1);
2175 }
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002176 }
2177
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01002178 pr_err("unable to select a mode\n");
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002179
Jean-Jacques Hiblotec346832017-09-21 16:29:58 +02002180 return -ENOTSUPP;
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002181}
Marek Vasuta318a7a2018-04-15 00:37:11 +02002182#endif
2183
2184#if CONFIG_IS_ENABLED(MMC_TINY)
2185DEFINE_CACHE_ALIGN_BUFFER(u8, ext_csd_bkup, MMC_MAX_BLOCK_LEN);
2186#endif
Jean-Jacques Hiblot31e7cf32017-09-21 16:29:49 +02002187
Jean-Jacques Hibloted9506b2017-09-21 16:29:51 +02002188static int mmc_startup_v4(struct mmc *mmc)
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002189{
2190 int err, i;
2191 u64 capacity;
2192 bool has_parts = false;
2193 bool part_completed;
Jean-Jacques Hiblotfa6c5772018-01-04 15:23:31 +01002194 static const u32 mmc_versions[] = {
2195 MMC_VERSION_4,
2196 MMC_VERSION_4_1,
2197 MMC_VERSION_4_2,
2198 MMC_VERSION_4_3,
Jean-Jacques Hiblotc64862b2018-02-09 12:09:28 +01002199 MMC_VERSION_4_4,
Jean-Jacques Hiblotfa6c5772018-01-04 15:23:31 +01002200 MMC_VERSION_4_41,
2201 MMC_VERSION_4_5,
2202 MMC_VERSION_5_0,
2203 MMC_VERSION_5_1
2204 };
2205
Marek Vasuta318a7a2018-04-15 00:37:11 +02002206#if CONFIG_IS_ENABLED(MMC_TINY)
2207 u8 *ext_csd = ext_csd_bkup;
2208
2209 if (IS_SD(mmc) || mmc->version < MMC_VERSION_4)
2210 return 0;
2211
2212 if (!mmc->ext_csd)
2213 memset(ext_csd_bkup, 0, sizeof(ext_csd_bkup));
2214
2215 err = mmc_send_ext_csd(mmc, ext_csd);
2216 if (err)
2217 goto error;
2218
2219 /* store the ext csd for future reference */
2220 if (!mmc->ext_csd)
2221 mmc->ext_csd = ext_csd;
2222#else
Jean-Jacques Hiblot06976eb2017-11-30 17:43:59 +01002223 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002224
2225 if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
2226 return 0;
2227
2228 /* check ext_csd version and capacity */
2229 err = mmc_send_ext_csd(mmc, ext_csd);
2230 if (err)
Jean-Jacques Hiblot06976eb2017-11-30 17:43:59 +01002231 goto error;
2232
2233 /* store the ext csd for future reference */
2234 if (!mmc->ext_csd)
2235 mmc->ext_csd = malloc(MMC_MAX_BLOCK_LEN);
2236 if (!mmc->ext_csd)
2237 return -ENOMEM;
2238 memcpy(mmc->ext_csd, ext_csd, MMC_MAX_BLOCK_LEN);
Marek Vasuta318a7a2018-04-15 00:37:11 +02002239#endif
Alexander Kochetkovf1133c92018-02-20 14:35:55 +03002240 if (ext_csd[EXT_CSD_REV] >= ARRAY_SIZE(mmc_versions))
Jean-Jacques Hiblotfa6c5772018-01-04 15:23:31 +01002241 return -EINVAL;
2242
2243 mmc->version = mmc_versions[ext_csd[EXT_CSD_REV]];
2244
2245 if (mmc->version >= MMC_VERSION_4_2) {
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002246 /*
2247 * According to the JEDEC Standard, the value of
2248 * ext_csd's capacity is valid if the value is more
2249 * than 2GB
2250 */
2251 capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
2252 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8
2253 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16
2254 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
2255 capacity *= MMC_MAX_BLOCK_LEN;
2256 if ((capacity >> 20) > 2 * 1024)
2257 mmc->capacity_user = capacity;
2258 }
2259
Jean-Jacques Hiblot201559c2019-07-02 10:53:54 +02002260 if (mmc->version >= MMC_VERSION_4_5)
2261 mmc->gen_cmd6_time = ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
2262
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002263 /* The partition data may be non-zero but it is only
2264 * effective if PARTITION_SETTING_COMPLETED is set in
2265 * EXT_CSD, so ignore any data if this bit is not set,
2266 * except for enabling the high-capacity group size
2267 * definition (see below).
2268 */
2269 part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
2270 EXT_CSD_PARTITION_SETTING_COMPLETED);
2271
Jean-Jacques Hiblot7f5b1692019-07-02 10:53:55 +02002272 mmc->part_switch_time = ext_csd[EXT_CSD_PART_SWITCH_TIME];
2273 /* Some eMMC set the value too low so set a minimum */
2274 if (mmc->part_switch_time < MMC_MIN_PART_SWITCH_TIME && mmc->part_switch_time)
2275 mmc->part_switch_time = MMC_MIN_PART_SWITCH_TIME;
2276
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002277 /* store the partition info of emmc */
2278 mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
2279 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
2280 ext_csd[EXT_CSD_BOOT_MULT])
2281 mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
2282 if (part_completed &&
2283 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
2284 mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
2285
2286 mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
2287
2288 mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
2289
2290 for (i = 0; i < 4; i++) {
2291 int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
2292 uint mult = (ext_csd[idx + 2] << 16) +
2293 (ext_csd[idx + 1] << 8) + ext_csd[idx];
2294 if (mult)
2295 has_parts = true;
2296 if (!part_completed)
2297 continue;
2298 mmc->capacity_gp[i] = mult;
2299 mmc->capacity_gp[i] *=
2300 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2301 mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2302 mmc->capacity_gp[i] <<= 19;
2303 }
2304
Jean-Jacques Hiblotc94c5472018-01-04 15:23:35 +01002305#ifndef CONFIG_SPL_BUILD
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002306 if (part_completed) {
2307 mmc->enh_user_size =
2308 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) +
2309 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
2310 ext_csd[EXT_CSD_ENH_SIZE_MULT];
2311 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
2312 mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
2313 mmc->enh_user_size <<= 19;
2314 mmc->enh_user_start =
2315 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) +
2316 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
2317 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
2318 ext_csd[EXT_CSD_ENH_START_ADDR];
2319 if (mmc->high_capacity)
2320 mmc->enh_user_start <<= 9;
2321 }
Jean-Jacques Hiblotc94c5472018-01-04 15:23:35 +01002322#endif
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002323
2324 /*
2325 * Host needs to enable ERASE_GRP_DEF bit if device is
2326 * partitioned. This bit will be lost every time after a reset
2327 * or power off. This will affect erase size.
2328 */
2329 if (part_completed)
2330 has_parts = true;
2331 if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
2332 (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
2333 has_parts = true;
2334 if (has_parts) {
2335 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
2336 EXT_CSD_ERASE_GROUP_DEF, 1);
2337
2338 if (err)
Jean-Jacques Hiblot06976eb2017-11-30 17:43:59 +01002339 goto error;
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002340
2341 ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
2342 }
2343
2344 if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002345#if CONFIG_IS_ENABLED(MMC_WRITE)
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002346 /* Read out group size from ext_csd */
2347 mmc->erase_grp_size =
2348 ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002349#endif
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002350 /*
2351 * if high capacity and partition setting completed
2352 * SEC_COUNT is valid even if it is smaller than 2 GiB
2353 * JEDEC Standard JESD84-B45, 6.2.4
2354 */
2355 if (mmc->high_capacity && part_completed) {
2356 capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
2357 (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
2358 (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
2359 (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
2360 capacity *= MMC_MAX_BLOCK_LEN;
2361 mmc->capacity_user = capacity;
2362 }
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002363 }
2364#if CONFIG_IS_ENABLED(MMC_WRITE)
2365 else {
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002366 /* Calculate the group size from the csd value. */
2367 int erase_gsz, erase_gmul;
2368
2369 erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
2370 erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
2371 mmc->erase_grp_size = (erase_gsz + 1)
2372 * (erase_gmul + 1);
2373 }
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002374#endif
Jean-Jacques Hiblotba54ab82018-01-04 15:23:36 +01002375#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002376 mmc->hc_wp_grp_size = 1024
2377 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
2378 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
Jean-Jacques Hiblotba54ab82018-01-04 15:23:36 +01002379#endif
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002380
2381 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2382
2383 return 0;
Jean-Jacques Hiblot06976eb2017-11-30 17:43:59 +01002384error:
2385 if (mmc->ext_csd) {
Marek Vasuta318a7a2018-04-15 00:37:11 +02002386#if !CONFIG_IS_ENABLED(MMC_TINY)
Jean-Jacques Hiblot06976eb2017-11-30 17:43:59 +01002387 free(mmc->ext_csd);
Marek Vasuta318a7a2018-04-15 00:37:11 +02002388#endif
Jean-Jacques Hiblot06976eb2017-11-30 17:43:59 +01002389 mmc->ext_csd = NULL;
2390 }
2391 return err;
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002392}
2393
Kim Phillips87ea3892012-10-29 13:34:43 +00002394static int mmc_startup(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05002395{
Stephen Warrene315ae82013-06-11 15:14:01 -06002396 int err, i;
Andy Flemingad347bb2008-10-30 16:41:01 -05002397 uint mult, freq;
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002398 u64 cmult, csize;
Andy Flemingad347bb2008-10-30 16:41:01 -05002399 struct mmc_cmd cmd;
Simon Glasse5db1152016-05-01 13:52:35 -06002400 struct blk_desc *bdesc;
Andy Flemingad347bb2008-10-30 16:41:01 -05002401
Thomas Chou1254c3d2010-12-24 13:12:21 +00002402#ifdef CONFIG_MMC_SPI_CRC_ON
2403 if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
2404 cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
2405 cmd.resp_type = MMC_RSP_R1;
2406 cmd.cmdarg = 1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00002407 err = mmc_send_cmd(mmc, &cmd, NULL);
Thomas Chou1254c3d2010-12-24 13:12:21 +00002408 if (err)
2409 return err;
2410 }
2411#endif
2412
Andy Flemingad347bb2008-10-30 16:41:01 -05002413 /* Put the Card in Identify Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00002414 cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
2415 MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
Andy Flemingad347bb2008-10-30 16:41:01 -05002416 cmd.resp_type = MMC_RSP_R2;
2417 cmd.cmdarg = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05002418
2419 err = mmc_send_cmd(mmc, &cmd, NULL);
2420
Kishon Vijay Abraham I07baaa62017-09-21 16:30:10 +02002421#ifdef CONFIG_MMC_QUIRKS
2422 if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
2423 int retries = 4;
2424 /*
2425 * It has been seen that SEND_CID may fail on the first
2426 * attempt, let's try a few more time
2427 */
2428 do {
2429 err = mmc_send_cmd(mmc, &cmd, NULL);
2430 if (!err)
2431 break;
2432 } while (retries--);
2433 }
2434#endif
2435
Andy Flemingad347bb2008-10-30 16:41:01 -05002436 if (err)
2437 return err;
2438
2439 memcpy(mmc->cid, cmd.response, 16);
2440
2441 /*
2442 * For MMC cards, set the Relative Address.
2443 * For SD cards, get the Relatvie Address.
2444 * This also puts the cards into Standby State
2445 */
Thomas Chou1254c3d2010-12-24 13:12:21 +00002446 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2447 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
2448 cmd.cmdarg = mmc->rca << 16;
2449 cmd.resp_type = MMC_RSP_R6;
Andy Flemingad347bb2008-10-30 16:41:01 -05002450
Thomas Chou1254c3d2010-12-24 13:12:21 +00002451 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05002452
Thomas Chou1254c3d2010-12-24 13:12:21 +00002453 if (err)
2454 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05002455
Thomas Chou1254c3d2010-12-24 13:12:21 +00002456 if (IS_SD(mmc))
2457 mmc->rca = (cmd.response[0] >> 16) & 0xffff;
2458 }
Andy Flemingad347bb2008-10-30 16:41:01 -05002459
2460 /* Get the Card-Specific Data */
2461 cmd.cmdidx = MMC_CMD_SEND_CSD;
2462 cmd.resp_type = MMC_RSP_R2;
2463 cmd.cmdarg = mmc->rca << 16;
Andy Flemingad347bb2008-10-30 16:41:01 -05002464
2465 err = mmc_send_cmd(mmc, &cmd, NULL);
2466
2467 if (err)
2468 return err;
2469
Rabin Vincentb6eed942009-04-05 13:30:56 +05302470 mmc->csd[0] = cmd.response[0];
2471 mmc->csd[1] = cmd.response[1];
2472 mmc->csd[2] = cmd.response[2];
2473 mmc->csd[3] = cmd.response[3];
Andy Flemingad347bb2008-10-30 16:41:01 -05002474
2475 if (mmc->version == MMC_VERSION_UNKNOWN) {
Rabin Vincentbdf7a682009-04-05 13:30:55 +05302476 int version = (cmd.response[0] >> 26) & 0xf;
Andy Flemingad347bb2008-10-30 16:41:01 -05002477
2478 switch (version) {
Bin Meng4a4ef872016-03-17 21:53:13 -07002479 case 0:
2480 mmc->version = MMC_VERSION_1_2;
2481 break;
2482 case 1:
2483 mmc->version = MMC_VERSION_1_4;
2484 break;
2485 case 2:
2486 mmc->version = MMC_VERSION_2_2;
2487 break;
2488 case 3:
2489 mmc->version = MMC_VERSION_3;
2490 break;
2491 case 4:
2492 mmc->version = MMC_VERSION_4;
2493 break;
2494 default:
2495 mmc->version = MMC_VERSION_1_2;
2496 break;
Andy Flemingad347bb2008-10-30 16:41:01 -05002497 }
2498 }
2499
2500 /* divide frequency by 10, since the mults are 10x bigger */
Rabin Vincentbdf7a682009-04-05 13:30:55 +05302501 freq = fbase[(cmd.response[0] & 0x7)];
2502 mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
Andy Flemingad347bb2008-10-30 16:41:01 -05002503
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +02002504 mmc->legacy_speed = freq * mult;
Jean-Jacques Hiblota94fb412017-09-21 16:29:53 +02002505 mmc_select_mode(mmc, MMC_LEGACY);
Andy Flemingad347bb2008-10-30 16:41:01 -05002506
Markus Niebel03951412013-12-16 13:40:46 +01002507 mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
Rabin Vincentb6eed942009-04-05 13:30:56 +05302508 mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002509#if CONFIG_IS_ENABLED(MMC_WRITE)
Andy Flemingad347bb2008-10-30 16:41:01 -05002510
2511 if (IS_SD(mmc))
2512 mmc->write_bl_len = mmc->read_bl_len;
2513 else
Rabin Vincentb6eed942009-04-05 13:30:56 +05302514 mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002515#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05002516
2517 if (mmc->high_capacity) {
2518 csize = (mmc->csd[1] & 0x3f) << 16
2519 | (mmc->csd[2] & 0xffff0000) >> 16;
2520 cmult = 8;
2521 } else {
2522 csize = (mmc->csd[1] & 0x3ff) << 2
2523 | (mmc->csd[2] & 0xc0000000) >> 30;
2524 cmult = (mmc->csd[2] & 0x00038000) >> 15;
2525 }
2526
Stephen Warrene315ae82013-06-11 15:14:01 -06002527 mmc->capacity_user = (csize + 1) << (cmult + 2);
2528 mmc->capacity_user *= mmc->read_bl_len;
2529 mmc->capacity_boot = 0;
2530 mmc->capacity_rpmb = 0;
2531 for (i = 0; i < 4; i++)
2532 mmc->capacity_gp[i] = 0;
Andy Flemingad347bb2008-10-30 16:41:01 -05002533
Simon Glassa09c2b72013-04-03 08:54:30 +00002534 if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
2535 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Andy Flemingad347bb2008-10-30 16:41:01 -05002536
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002537#if CONFIG_IS_ENABLED(MMC_WRITE)
Simon Glassa09c2b72013-04-03 08:54:30 +00002538 if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
2539 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002540#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05002541
Markus Niebel03951412013-12-16 13:40:46 +01002542 if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
2543 cmd.cmdidx = MMC_CMD_SET_DSR;
2544 cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
2545 cmd.resp_type = MMC_RSP_NONE;
2546 if (mmc_send_cmd(mmc, &cmd, NULL))
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01002547 pr_warn("MMC: SET_DSR failed\n");
Markus Niebel03951412013-12-16 13:40:46 +01002548 }
2549
Andy Flemingad347bb2008-10-30 16:41:01 -05002550 /* Select the card, and put it into Transfer Mode */
Thomas Chou1254c3d2010-12-24 13:12:21 +00002551 if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
2552 cmd.cmdidx = MMC_CMD_SELECT_CARD;
Ajay Bhargav4a32fba2011-10-05 03:13:23 +00002553 cmd.resp_type = MMC_RSP_R1;
Thomas Chou1254c3d2010-12-24 13:12:21 +00002554 cmd.cmdarg = mmc->rca << 16;
Thomas Chou1254c3d2010-12-24 13:12:21 +00002555 err = mmc_send_cmd(mmc, &cmd, NULL);
Andy Flemingad347bb2008-10-30 16:41:01 -05002556
Thomas Chou1254c3d2010-12-24 13:12:21 +00002557 if (err)
2558 return err;
2559 }
Andy Flemingad347bb2008-10-30 16:41:01 -05002560
Lei Wenea526762011-06-22 17:03:31 +00002561 /*
2562 * For SD, its erase group is always one sector
2563 */
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002564#if CONFIG_IS_ENABLED(MMC_WRITE)
Lei Wenea526762011-06-22 17:03:31 +00002565 mmc->erase_grp_size = 1;
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002566#endif
Lei Wen31b99802011-05-02 16:26:26 +00002567 mmc->part_config = MMCPART_NOAVAILABLE;
Diego Santa Cruza7a75992014-12-23 10:50:27 +01002568
Jean-Jacques Hibloted9506b2017-09-21 16:29:51 +02002569 err = mmc_startup_v4(mmc);
Jean-Jacques Hiblote84459c2017-09-21 16:29:50 +02002570 if (err)
2571 return err;
Sukumar Ghorai232293c2010-09-20 18:29:29 +05302572
Simon Glasse5db1152016-05-01 13:52:35 -06002573 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
Stephen Warrene315ae82013-06-11 15:14:01 -06002574 if (err)
2575 return err;
2576
Marek Vasuta318a7a2018-04-15 00:37:11 +02002577#if CONFIG_IS_ENABLED(MMC_TINY)
2578 mmc_set_clock(mmc, mmc->legacy_speed, false);
Faiz Abbas01db77e2020-02-26 13:44:32 +05302579 mmc_select_mode(mmc, MMC_LEGACY);
Marek Vasuta318a7a2018-04-15 00:37:11 +02002580 mmc_set_bus_width(mmc, 1);
2581#else
Jean-Jacques Hiblot3d30972b2017-09-21 16:30:09 +02002582 if (IS_SD(mmc)) {
2583 err = sd_get_capabilities(mmc);
2584 if (err)
2585 return err;
2586 err = sd_select_mode_and_width(mmc, mmc->card_caps);
2587 } else {
2588 err = mmc_get_capabilities(mmc);
2589 if (err)
2590 return err;
Masahiro Yamadabf1f25c2020-01-23 14:31:12 +09002591 err = mmc_select_mode_and_width(mmc, mmc->card_caps);
Jean-Jacques Hiblot3d30972b2017-09-21 16:30:09 +02002592 }
Marek Vasuta318a7a2018-04-15 00:37:11 +02002593#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05002594 if (err)
2595 return err;
2596
Jean-Jacques Hiblot3d30972b2017-09-21 16:30:09 +02002597 mmc->best_mode = mmc->selected_mode;
Jaehoon Chunge1d4c7b2012-03-26 21:16:03 +00002598
Andrew Gabbasov532663b2014-12-01 06:59:11 -06002599 /* Fix the block length for DDR mode */
2600 if (mmc->ddr_mode) {
2601 mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002602#if CONFIG_IS_ENABLED(MMC_WRITE)
Andrew Gabbasov532663b2014-12-01 06:59:11 -06002603 mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
Jean-Jacques Hiblot27edffe2018-01-04 15:23:34 +01002604#endif
Andrew Gabbasov532663b2014-12-01 06:59:11 -06002605 }
2606
Andy Flemingad347bb2008-10-30 16:41:01 -05002607 /* fill in device description */
Simon Glasse5db1152016-05-01 13:52:35 -06002608 bdesc = mmc_get_blk_desc(mmc);
2609 bdesc->lun = 0;
2610 bdesc->hwpart = 0;
2611 bdesc->type = 0;
2612 bdesc->blksz = mmc->read_bl_len;
2613 bdesc->log2blksz = LOG2(bdesc->blksz);
2614 bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
Sjoerd Simonsd67754f2015-12-04 23:27:40 +01002615#if !defined(CONFIG_SPL_BUILD) || \
2616 (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
Simon Glass7611ac62019-09-25 08:56:27 -06002617 !CONFIG_IS_ENABLED(USE_TINY_PRINTF))
Simon Glasse5db1152016-05-01 13:52:35 -06002618 sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
Taylor Hutt7367ec22012-10-20 17:15:59 +00002619 mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
2620 (mmc->cid[3] >> 16) & 0xffff);
Simon Glasse5db1152016-05-01 13:52:35 -06002621 sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
Taylor Hutt7367ec22012-10-20 17:15:59 +00002622 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
2623 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
2624 (mmc->cid[2] >> 24) & 0xff);
Simon Glasse5db1152016-05-01 13:52:35 -06002625 sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
Taylor Hutt7367ec22012-10-20 17:15:59 +00002626 (mmc->cid[2] >> 16) & 0xf);
Paul Burton6a7c5ba2013-09-04 16:12:25 +01002627#else
Simon Glasse5db1152016-05-01 13:52:35 -06002628 bdesc->vendor[0] = 0;
2629 bdesc->product[0] = 0;
2630 bdesc->revision[0] = 0;
Paul Burton6a7c5ba2013-09-04 16:12:25 +01002631#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05002632
Andre Przywara17798042018-12-17 10:05:45 +00002633#if !defined(CONFIG_DM_MMC) && (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT))
2634 part_init(bdesc);
2635#endif
2636
Andy Flemingad347bb2008-10-30 16:41:01 -05002637 return 0;
2638}
2639
Kim Phillips87ea3892012-10-29 13:34:43 +00002640static int mmc_send_if_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05002641{
2642 struct mmc_cmd cmd;
2643 int err;
2644
2645 cmd.cmdidx = SD_CMD_SEND_IF_COND;
2646 /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02002647 cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
Andy Flemingad347bb2008-10-30 16:41:01 -05002648 cmd.resp_type = MMC_RSP_R7;
Andy Flemingad347bb2008-10-30 16:41:01 -05002649
2650 err = mmc_send_cmd(mmc, &cmd, NULL);
2651
2652 if (err)
2653 return err;
2654
Rabin Vincentb6eed942009-04-05 13:30:56 +05302655 if ((cmd.response[0] & 0xff) != 0xaa)
Jaehoon Chung7825d202016-07-19 16:33:36 +09002656 return -EOPNOTSUPP;
Andy Flemingad347bb2008-10-30 16:41:01 -05002657 else
2658 mmc->version = SD_VERSION_2;
2659
2660 return 0;
2661}
2662
Simon Glass5f4bd8c2017-07-04 13:31:19 -06002663#if !CONFIG_IS_ENABLED(DM_MMC)
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01002664/* board-specific MMC power initializations. */
2665__weak void board_mmc_power_init(void)
2666{
2667}
Simon Glass833b80d2017-04-22 19:10:56 -06002668#endif
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01002669
Peng Fan15305962016-10-11 15:08:43 +08002670static int mmc_power_init(struct mmc *mmc)
2671{
Simon Glass5f4bd8c2017-07-04 13:31:19 -06002672#if CONFIG_IS_ENABLED(DM_MMC)
Jean-Jacques Hiblota49ffa12017-09-21 16:29:48 +02002673#if CONFIG_IS_ENABLED(DM_REGULATOR)
Peng Fan15305962016-10-11 15:08:43 +08002674 int ret;
2675
2676 ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
Jean-Jacques Hiblota49ffa12017-09-21 16:29:48 +02002677 &mmc->vmmc_supply);
2678 if (ret)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002679 pr_debug("%s: No vmmc supply\n", mmc->dev->name);
Jean-Jacques Hiblota49ffa12017-09-21 16:29:48 +02002680
2681 ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
2682 &mmc->vqmmc_supply);
2683 if (ret)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002684 pr_debug("%s: No vqmmc supply\n", mmc->dev->name);
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002685#endif
2686#else /* !CONFIG_DM_MMC */
2687 /*
2688 * Driver model should use a regulator, as above, rather than calling
2689 * out to board code.
2690 */
2691 board_mmc_power_init();
2692#endif
2693 return 0;
2694}
2695
2696/*
2697 * put the host in the initial state:
2698 * - turn on Vdd (card power supply)
2699 * - configure the bus width and clock to minimal values
2700 */
2701static void mmc_set_initial_state(struct mmc *mmc)
2702{
2703 int err;
2704
2705 /* First try to set 3.3V. If it fails set to 1.8V */
2706 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
2707 if (err != 0)
2708 err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
2709 if (err != 0)
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01002710 pr_warn("mmc: failed to set signal voltage\n");
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002711
2712 mmc_select_mode(mmc, MMC_LEGACY);
2713 mmc_set_bus_width(mmc, 1);
Jaehoon Chung239cb2f2018-01-26 19:25:29 +09002714 mmc_set_clock(mmc, 0, MMC_CLK_ENABLE);
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002715}
Peng Fan15305962016-10-11 15:08:43 +08002716
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002717static int mmc_power_on(struct mmc *mmc)
2718{
2719#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
Jean-Jacques Hiblota49ffa12017-09-21 16:29:48 +02002720 if (mmc->vmmc_supply) {
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002721 int ret = regulator_set_enable(mmc->vmmc_supply, true);
2722
Jean-Jacques Hiblota49ffa12017-09-21 16:29:48 +02002723 if (ret) {
2724 puts("Error enabling VMMC supply\n");
2725 return ret;
2726 }
Peng Fan15305962016-10-11 15:08:43 +08002727 }
2728#endif
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002729 return 0;
2730}
2731
2732static int mmc_power_off(struct mmc *mmc)
2733{
Jaehoon Chung239cb2f2018-01-26 19:25:29 +09002734 mmc_set_clock(mmc, 0, MMC_CLK_DISABLE);
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002735#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
2736 if (mmc->vmmc_supply) {
2737 int ret = regulator_set_enable(mmc->vmmc_supply, false);
2738
2739 if (ret) {
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002740 pr_debug("Error disabling VMMC supply\n");
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002741 return ret;
2742 }
2743 }
Simon Glass833b80d2017-04-22 19:10:56 -06002744#endif
Peng Fan15305962016-10-11 15:08:43 +08002745 return 0;
2746}
2747
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002748static int mmc_power_cycle(struct mmc *mmc)
2749{
2750 int ret;
2751
2752 ret = mmc_power_off(mmc);
2753 if (ret)
2754 return ret;
Yann Gautier6f558332019-09-19 17:56:12 +02002755
2756 ret = mmc_host_power_cycle(mmc);
2757 if (ret)
2758 return ret;
2759
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002760 /*
2761 * SD spec recommends at least 1ms of delay. Let's wait for 2ms
2762 * to be on the safer side.
2763 */
2764 udelay(2000);
2765 return mmc_power_on(mmc);
2766}
2767
Jon Nettleton2663fe42018-06-11 15:26:19 +03002768int mmc_get_op_cond(struct mmc *mmc)
Andy Flemingad347bb2008-10-30 16:41:01 -05002769{
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02002770 bool uhs_en = supports_uhs(mmc->cfg->host_caps);
Macpaul Lin028bde12011-11-14 23:35:39 +00002771 int err;
Andy Flemingad347bb2008-10-30 16:41:01 -05002772
Lei Wen31b99802011-05-02 16:26:26 +00002773 if (mmc->has_init)
2774 return 0;
2775
Yangbo Lub124f8a2015-04-22 13:57:00 +08002776#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
2777 mmc_adapter_card_type_ident();
2778#endif
Peng Fan15305962016-10-11 15:08:43 +08002779 err = mmc_power_init(mmc);
2780 if (err)
2781 return err;
Paul Kocialkowski2439fe92014-11-08 20:55:45 +01002782
Kishon Vijay Abraham I07baaa62017-09-21 16:30:10 +02002783#ifdef CONFIG_MMC_QUIRKS
2784 mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
Joel Johnson5ea041b2020-01-11 09:08:14 -07002785 MMC_QUIRK_RETRY_SEND_CID |
2786 MMC_QUIRK_RETRY_APP_CMD;
Kishon Vijay Abraham I07baaa62017-09-21 16:30:10 +02002787#endif
2788
Jean-Jacques Hiblotdc030fb2017-09-21 16:30:08 +02002789 err = mmc_power_cycle(mmc);
2790 if (err) {
2791 /*
2792 * if power cycling is not supported, we should not try
2793 * to use the UHS modes, because we wouldn't be able to
2794 * recover from an error during the UHS initialization.
2795 */
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002796 pr_debug("Unable to do a full power cycle. Disabling the UHS modes for safety\n");
Jean-Jacques Hiblotdc030fb2017-09-21 16:30:08 +02002797 uhs_en = false;
2798 mmc->host_caps &= ~UHS_CAPS;
2799 err = mmc_power_on(mmc);
2800 }
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002801 if (err)
2802 return err;
2803
Simon Glasseba48f92017-07-29 11:35:31 -06002804#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass394dfc02016-06-12 23:30:22 -06002805 /* The device has already been probed ready for use */
2806#else
Pantelis Antoniouc9e75912014-02-26 19:28:45 +02002807 /* made sure it's not NULL earlier */
Pantelis Antoniou2c850462014-03-11 19:34:20 +02002808 err = mmc->cfg->ops->init(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05002809 if (err)
2810 return err;
Simon Glass394dfc02016-06-12 23:30:22 -06002811#endif
Andrew Gabbasov9fc2a412014-12-01 06:59:09 -06002812 mmc->ddr_mode = 0;
Kishon Vijay Abraham I4afb12b2017-09-21 16:30:00 +02002813
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02002814retry:
Kishon Vijay Abraham I80b87e12017-09-21 16:30:02 +02002815 mmc_set_initial_state(mmc);
Jean-Jacques Hiblot5f23d872017-09-21 16:30:01 +02002816
Andy Flemingad347bb2008-10-30 16:41:01 -05002817 /* Reset the Card */
2818 err = mmc_go_idle(mmc);
2819
2820 if (err)
2821 return err;
2822
Lei Wen31b99802011-05-02 16:26:26 +00002823 /* The internal partition reset to user partition(0) at every CMD0*/
Simon Glasse5db1152016-05-01 13:52:35 -06002824 mmc_get_blk_desc(mmc)->hwpart = 0;
Lei Wen31b99802011-05-02 16:26:26 +00002825
Andy Flemingad347bb2008-10-30 16:41:01 -05002826 /* Test for SD version 2 */
Macpaul Lin028bde12011-11-14 23:35:39 +00002827 err = mmc_send_if_cond(mmc);
Andy Flemingad347bb2008-10-30 16:41:01 -05002828
Andy Flemingad347bb2008-10-30 16:41:01 -05002829 /* Now try to get the SD card's operating condition */
Jean-Jacques Hiblotf4d5b3e2017-09-21 16:30:07 +02002830 err = sd_send_op_cond(mmc, uhs_en);
2831 if (err && uhs_en) {
2832 uhs_en = false;
2833 mmc_power_cycle(mmc);
2834 goto retry;
2835 }
Andy Flemingad347bb2008-10-30 16:41:01 -05002836
2837 /* If the command timed out, we check for an MMC card */
Jaehoon Chung7825d202016-07-19 16:33:36 +09002838 if (err == -ETIMEDOUT) {
Andy Flemingad347bb2008-10-30 16:41:01 -05002839 err = mmc_send_op_cond(mmc);
2840
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05002841 if (err) {
Paul Burton6a7c5ba2013-09-04 16:12:25 +01002842#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01002843 pr_err("Card did not respond to voltage select!\n");
Paul Burton6a7c5ba2013-09-04 16:12:25 +01002844#endif
Jaehoon Chung7825d202016-07-19 16:33:36 +09002845 return -EOPNOTSUPP;
Andy Flemingad347bb2008-10-30 16:41:01 -05002846 }
2847 }
2848
Jon Nettleton2663fe42018-06-11 15:26:19 +03002849 return err;
2850}
2851
2852int mmc_start_init(struct mmc *mmc)
2853{
2854 bool no_card;
2855 int err = 0;
2856
2857 /*
2858 * all hosts are capable of 1 bit bus-width and able to use the legacy
2859 * timings.
2860 */
Faiz Abbas01db77e2020-02-26 13:44:32 +05302861 mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(MMC_LEGACY) |
Jon Nettleton2663fe42018-06-11 15:26:19 +03002862 MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
Faiz Abbasf6fd4ec2020-02-26 13:44:30 +05302863#if CONFIG_IS_ENABLED(DM_MMC)
2864 mmc_deferred_probe(mmc);
2865#endif
Jon Nettleton2663fe42018-06-11 15:26:19 +03002866#if !defined(CONFIG_MMC_BROKEN_CD)
Jon Nettleton2663fe42018-06-11 15:26:19 +03002867 no_card = mmc_getcd(mmc) == 0;
2868#else
2869 no_card = 0;
2870#endif
2871#if !CONFIG_IS_ENABLED(DM_MMC)
Baruch Siach0448ce62019-07-22 15:52:12 +03002872 /* we pretend there's no card when init is NULL */
Jon Nettleton2663fe42018-06-11 15:26:19 +03002873 no_card = no_card || (mmc->cfg->ops->init == NULL);
2874#endif
2875 if (no_card) {
2876 mmc->has_init = 0;
2877#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
2878 pr_err("MMC: no card present\n");
2879#endif
2880 return -ENOMEDIUM;
2881 }
2882
2883 err = mmc_get_op_cond(mmc);
2884
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05002885 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002886 mmc->init_in_progress = 1;
2887
2888 return err;
2889}
2890
2891static int mmc_complete_init(struct mmc *mmc)
2892{
2893 int err = 0;
2894
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05002895 mmc->init_in_progress = 0;
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002896 if (mmc->op_cond_pending)
2897 err = mmc_complete_op_cond(mmc);
2898
2899 if (!err)
2900 err = mmc_startup(mmc);
Lei Wen31b99802011-05-02 16:26:26 +00002901 if (err)
2902 mmc->has_init = 0;
2903 else
2904 mmc->has_init = 1;
2905 return err;
Andy Flemingad347bb2008-10-30 16:41:01 -05002906}
2907
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002908int mmc_init(struct mmc *mmc)
2909{
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05002910 int err = 0;
Vipul Kumardbad7b42018-05-03 12:20:54 +05302911 __maybe_unused ulong start;
Simon Glass5f4bd8c2017-07-04 13:31:19 -06002912#if CONFIG_IS_ENABLED(DM_MMC)
Simon Glass59bc6f22016-05-01 13:52:41 -06002913 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002914
Simon Glass59bc6f22016-05-01 13:52:41 -06002915 upriv->mmc = mmc;
2916#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002917 if (mmc->has_init)
2918 return 0;
Mateusz Zalegada351782014-04-29 20:15:30 +02002919
2920 start = get_timer(0);
2921
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002922 if (!mmc->init_in_progress)
2923 err = mmc_start_init(mmc);
2924
Andrew Gabbasov3a669bc2015-03-19 07:44:07 -05002925 if (!err)
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002926 err = mmc_complete_init(mmc);
Jagan Teki9bee2b52017-01-10 11:18:43 +01002927 if (err)
Masahiro Yamadaf97b1482018-01-28 19:11:42 +09002928 pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
Jagan Teki9bee2b52017-01-10 11:18:43 +01002929
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002930 return err;
2931}
2932
Marek Vasuta4773fc2019-01-29 04:45:51 +01002933#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
2934 CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
2935 CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
2936int mmc_deinit(struct mmc *mmc)
2937{
2938 u32 caps_filtered;
2939
2940 if (!mmc->has_init)
2941 return 0;
2942
2943 if (IS_SD(mmc)) {
2944 caps_filtered = mmc->card_caps &
2945 ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
2946 MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
2947 MMC_CAP(UHS_SDR104));
2948
2949 return sd_select_mode_and_width(mmc, caps_filtered);
2950 } else {
2951 caps_filtered = mmc->card_caps &
2952 ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
2953
2954 return mmc_select_mode_and_width(mmc, caps_filtered);
2955 }
2956}
2957#endif
2958
Markus Niebel03951412013-12-16 13:40:46 +01002959int mmc_set_dsr(struct mmc *mmc, u16 val)
2960{
2961 mmc->dsr = val;
2962 return 0;
2963}
2964
Jeroen Hofstee47726302014-07-10 22:46:28 +02002965/* CPU-specific MMC initializations */
2966__weak int cpu_mmc_init(bd_t *bis)
Andy Flemingad347bb2008-10-30 16:41:01 -05002967{
2968 return -1;
2969}
2970
Jeroen Hofstee47726302014-07-10 22:46:28 +02002971/* board-specific MMC initializations. */
2972__weak int board_mmc_init(bd_t *bis)
2973{
2974 return -1;
2975}
Andy Flemingad347bb2008-10-30 16:41:01 -05002976
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00002977void mmc_set_preinit(struct mmc *mmc, int preinit)
2978{
2979 mmc->preinit = preinit;
2980}
2981
Faiz Abbasb3857fd2018-02-12 19:35:24 +05302982#if CONFIG_IS_ENABLED(DM_MMC)
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06002983static int mmc_probe(bd_t *bis)
2984{
Simon Glass547cb342015-12-29 05:22:49 -07002985 int ret, i;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06002986 struct uclass *uc;
Simon Glass547cb342015-12-29 05:22:49 -07002987 struct udevice *dev;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06002988
2989 ret = uclass_get(UCLASS_MMC, &uc);
2990 if (ret)
2991 return ret;
2992
Simon Glass547cb342015-12-29 05:22:49 -07002993 /*
2994 * Try to add them in sequence order. Really with driver model we
2995 * should allow holes, but the current MMC list does not allow that.
2996 * So if we request 0, 1, 3 we will get 0, 1, 2.
2997 */
2998 for (i = 0; ; i++) {
2999 ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
3000 if (ret == -ENODEV)
3001 break;
3002 }
3003 uclass_foreach_dev(dev, uc) {
3004 ret = device_probe(dev);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06003005 if (ret)
Jean-Jacques Hiblot678b6082017-11-30 17:44:00 +01003006 pr_err("%s - probe failed: %d\n", dev->name, ret);
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06003007 }
3008
3009 return 0;
3010}
3011#else
3012static int mmc_probe(bd_t *bis)
3013{
3014 if (board_mmc_init(bis) < 0)
3015 cpu_mmc_init(bis);
3016
3017 return 0;
3018}
3019#endif
Che-Liang Chiou4a2c7d72012-11-28 15:21:13 +00003020
Andy Flemingad347bb2008-10-30 16:41:01 -05003021int mmc_initialize(bd_t *bis)
3022{
Daniel Kochmański13df57b2015-05-29 16:55:43 +02003023 static int initialized = 0;
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06003024 int ret;
Daniel Kochmański13df57b2015-05-29 16:55:43 +02003025 if (initialized) /* Avoid initializing mmc multiple times */
3026 return 0;
3027 initialized = 1;
3028
Simon Glass5f4bd8c2017-07-04 13:31:19 -06003029#if !CONFIG_IS_ENABLED(BLK)
Marek Vasutf537e392016-12-01 02:06:33 +01003030#if !CONFIG_IS_ENABLED(MMC_TINY)
Simon Glasse5db1152016-05-01 13:52:35 -06003031 mmc_list_init();
3032#endif
Marek Vasutf537e392016-12-01 02:06:33 +01003033#endif
Sjoerd Simonsdf8aa522015-08-30 16:55:45 -06003034 ret = mmc_probe(bis);
3035 if (ret)
3036 return ret;
Andy Flemingad347bb2008-10-30 16:41:01 -05003037
Ying Zhang9ff70262013-08-16 15:16:11 +08003038#ifndef CONFIG_SPL_BUILD
Andy Flemingad347bb2008-10-30 16:41:01 -05003039 print_mmc_devices(',');
Ying Zhang9ff70262013-08-16 15:16:11 +08003040#endif
Andy Flemingad347bb2008-10-30 16:41:01 -05003041
Simon Glasse5db1152016-05-01 13:52:35 -06003042 mmc_do_preinit();
Andy Flemingad347bb2008-10-30 16:41:01 -05003043 return 0;
3044}
Tomas Melinc17dae52016-11-25 11:01:03 +02003045
Lokesh Vutlac59b41c2019-09-09 14:40:36 +05303046#if CONFIG_IS_ENABLED(DM_MMC)
3047int mmc_init_device(int num)
3048{
3049 struct udevice *dev;
3050 struct mmc *m;
3051 int ret;
3052
3053 ret = uclass_get_device(UCLASS_MMC, num, &dev);
3054 if (ret)
3055 return ret;
3056
3057 m = mmc_get_mmc_dev(dev);
3058 if (!m)
3059 return 0;
3060#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
3061 mmc_set_preinit(m, 1);
3062#endif
3063 if (m->preinit)
3064 mmc_start_init(m);
3065
3066 return 0;
3067}
3068#endif
3069
Tomas Melinc17dae52016-11-25 11:01:03 +02003070#ifdef CONFIG_CMD_BKOPS_ENABLE
3071int mmc_set_bkops_enable(struct mmc *mmc)
3072{
3073 int err;
3074 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
3075
3076 err = mmc_send_ext_csd(mmc, ext_csd);
3077 if (err) {
3078 puts("Could not get ext_csd register values\n");
3079 return err;
3080 }
3081
3082 if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
3083 puts("Background operations not supported on device\n");
3084 return -EMEDIUMTYPE;
3085 }
3086
3087 if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) {
3088 puts("Background operations already enabled\n");
3089 return 0;
3090 }
3091
3092 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1);
3093 if (err) {
3094 puts("Failed to enable manual background operations\n");
3095 return err;
3096 }
3097
3098 puts("Enabled manual background operations\n");
3099
3100 return 0;
3101}
3102#endif