blob: 2aaa29245f19689e2dfeb6a0b4af1e8ba7aa21e5 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Patrick Georgiafd4c872020-05-05 23:43:18 +02002/*
Martin Roth0443ac22019-08-30 21:29:41 -06003 * MultiMediaCard (MMC) and eMMC specific support code
4 * This code is controller independent
Lee Leahyeef40eb2017-03-23 10:54:57 -07005 */
6
Lee Leahy48dbc662017-05-08 16:56:03 -07007#include <commonlib/storage.h>
Lee Leahy927f06a2017-06-19 10:53:18 -07008#include <delay.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -07009#include "mmc.h"
10#include "sd_mmc.h"
11#include "storage.h"
12#include <string.h>
Lee Leahy927f06a2017-06-19 10:53:18 -070013#include <timer.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070014
15/* We pass in the cmd since otherwise the init seems to fail */
16static int mmc_send_op_cond_iter(struct storage_media *media,
17 struct mmc_command *cmd, int use_arg)
18{
19 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
20
21 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
22 cmd->resp_type = CARD_RSP_R3;
23
24 /* Set the controller's operating conditions */
25 if (use_arg) {
26 uint32_t mask = media->op_cond_response &
27 (OCR_VOLTAGE_MASK | OCR_ACCESS_MODE);
28 cmd->cmdarg = ctrlr->voltages & mask;
29
30 /* Always request high capacity if supported by the
31 * controller
32 */
33 if (ctrlr->caps & DRVR_CAP_HC)
34 cmd->cmdarg |= OCR_HCS;
35 }
36 cmd->flags = 0;
37 int err = ctrlr->send_cmd(ctrlr, cmd, NULL);
38 if (err)
39 return err;
40
41 media->op_cond_response = cmd->response[0];
42 return 0;
43}
44
45int mmc_send_op_cond(struct storage_media *media)
46{
47 struct mmc_command cmd;
48 int max_iters = 2;
49
50 /* Ask the card for its operating conditions */
51 cmd.cmdarg = 0;
52 for (int i = 0; i < max_iters; i++) {
53 int err = mmc_send_op_cond_iter(media, &cmd, i != 0);
54 if (err)
55 return err;
56
57 // OCR_BUSY is active low, this bit set means
58 // "initialization complete".
59 if (media->op_cond_response & OCR_BUSY)
60 return 0;
61 }
62 return CARD_IN_PROGRESS;
63}
64
65int mmc_complete_op_cond(struct storage_media *media)
66{
67 struct mmc_command cmd;
68 struct stopwatch sw;
69
70 stopwatch_init_msecs_expire(&sw, MMC_INIT_TIMEOUT_US_MS);
71 while (1) {
72 // CMD1 queries whether initialization is done.
73 int err = mmc_send_op_cond_iter(media, &cmd, 1);
74 if (err)
75 return err;
76
77 // OCR_BUSY means "initialization complete".
78 if (media->op_cond_response & OCR_BUSY)
79 break;
80
81 // Check if init timeout has expired.
82 if (stopwatch_expired(&sw))
83 return CARD_UNUSABLE_ERR;
84
85 udelay(100);
86 }
87
88 media->version = MMC_VERSION_UNKNOWN;
89 media->ocr = cmd.response[0];
90
91 media->high_capacity = ((media->ocr & OCR_HCS) == OCR_HCS);
92 media->rca = 0;
93 return 0;
94}
95
96int mmc_send_ext_csd(struct sd_mmc_ctrlr *ctrlr, unsigned char *ext_csd)
97{
98 struct mmc_command cmd;
99 struct mmc_data data;
100 int rv;
101
102 /* Get the Card Status Register */
103 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
104 cmd.resp_type = CARD_RSP_R1;
105 cmd.cmdarg = 0;
106 cmd.flags = 0;
107
108 data.dest = (char *)ext_csd;
109 data.blocks = 1;
110 data.blocksize = 512;
111 data.flags = DATA_FLAG_READ;
112
113 rv = ctrlr->send_cmd(ctrlr, &cmd, &data);
114
Julius Wernercd49cce2019-03-05 16:53:33 -0800115 if (!rv && CONFIG(SD_MMC_TRACE)) {
Lee Leahyeef40eb2017-03-23 10:54:57 -0700116 int i, size;
117
118 size = data.blocks * data.blocksize;
119 sd_mmc_trace("\t%p ext_csd:", ctrlr);
120 for (i = 0; i < size; i++) {
121 if (!(i % 32))
122 sd_mmc_trace("\n");
123 sd_mmc_trace(" %2.2x", ext_csd[i]);
124 }
125 sd_mmc_trace("\n");
126 }
127 return rv;
128}
129
130static int mmc_switch(struct storage_media *media, uint8_t index, uint8_t value)
131{
132 struct mmc_command cmd;
133 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
134
135 cmd.cmdidx = MMC_CMD_SWITCH;
136 cmd.resp_type = CARD_RSP_R1b;
137 cmd.cmdarg = ((MMC_SWITCH_MODE_WRITE_BYTE << 24) |
138 (index << 16) | (value << 8));
139 cmd.flags = 0;
140
141 int ret = ctrlr->send_cmd(ctrlr, &cmd, NULL);
142
143 /* Waiting for the ready status */
144 sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
145 return ret;
146
147}
148
149static void mmc_recalculate_clock(struct storage_media *media)
150{
151 uint32_t clock;
152
153 clock = CLOCK_26MHZ;
154 if (media->caps & DRVR_CAP_HS) {
155 if ((media->caps & DRVR_CAP_HS200) ||
156 (media->caps & DRVR_CAP_HS400))
157 clock = CLOCK_200MHZ;
158 else if (media->caps & DRVR_CAP_HS52)
159 clock = CLOCK_52MHZ;
160 }
161 SET_CLOCK(media->ctrlr, clock);
162}
163
164static int mmc_select_hs(struct storage_media *media)
165{
166 int ret;
167
168 /* Switch the MMC device into high speed mode */
169 ret = mmc_switch(media, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS);
170 if (ret) {
171 sd_mmc_error("Timing switch to high speed failed\n");
172 return ret;
173 }
174 sdhc_debug("SDHCI switched MMC to high speed\n");
175
176 /* Increase the controller clock speed */
177 SET_TIMING(media->ctrlr, BUS_TIMING_MMC_HS);
Bora Guvendik3280b762019-12-16 16:51:38 -0800178 media->caps &= ~(DRVR_CAP_HS200 | DRVR_CAP_HS400);
Lee Leahyeef40eb2017-03-23 10:54:57 -0700179 media->caps |= DRVR_CAP_HS52 | DRVR_CAP_HS;
180 mmc_recalculate_clock(media);
181 ret = sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
182 return ret;
183}
184
Elyes HAOUAS0b133972018-08-15 11:17:39 +0200185static int mmc_send_tuning_seq(struct sd_mmc_ctrlr *ctrlr, char *buffer)
Lee Leahyeef40eb2017-03-23 10:54:57 -0700186{
187 struct mmc_command cmd;
188 struct mmc_data data;
189
190 /* Request the device send the tuning sequence to the host */
191 cmd.cmdidx = MMC_CMD_AUTO_TUNING_SEQUENCE;
192 cmd.resp_type = CARD_RSP_R1;
193 cmd.cmdarg = 0;
194 cmd.flags = CMD_FLAG_IGNORE_INHIBIT;
195
196 data.dest = buffer;
197 data.blocks = 1;
198 data.blocksize = (ctrlr->bus_width == 8) ? 128 : 64;
199 data.flags = DATA_FLAG_READ;
200 return ctrlr->send_cmd(ctrlr, &cmd, &data);
201}
202
203static int mmc_bus_tuning(struct storage_media *media)
204{
205 ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 128);
206 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
207 int index;
208 int successful;
209
210 /* Request the device send the tuning sequence up to 40 times */
211 ctrlr->tuning_start(ctrlr, 0);
212 for (index = 0; index < 40; index++) {
Elyes HAOUAS0b133972018-08-15 11:17:39 +0200213 mmc_send_tuning_seq(ctrlr, buffer);
Lee Leahyeef40eb2017-03-23 10:54:57 -0700214 if (ctrlr->is_tuning_complete(ctrlr, &successful)) {
215 if (successful)
216 return 0;
217 break;
218 }
219 }
220 sd_mmc_error("Bus tuning failed!\n");
221 return -1;
222}
223
224static int mmc_select_hs400(struct storage_media *media)
225{
226 uint8_t bus_width;
227 uint32_t caps;
228 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
229 int ret;
230 uint32_t timing;
231
232 /* Switch the MMC device into high speed mode */
233 ret = mmc_select_hs(media);
234 if (ret)
235 return ret;
236
237 /* Switch MMC device to 8-bit DDR with strobe */
238 bus_width = EXT_CSD_DDR_BUS_WIDTH_8;
239 caps = DRVR_CAP_HS400 | DRVR_CAP_HS52 | DRVR_CAP_HS;
240 timing = BUS_TIMING_MMC_HS400;
241 if ((ctrlr->caps & DRVR_CAP_ENHANCED_STROBE)
242 && (media->caps & DRVR_CAP_ENHANCED_STROBE)) {
243 bus_width |= EXT_CSD_BUS_WIDTH_STROBE;
244 caps |= DRVR_CAP_ENHANCED_STROBE;
245 timing = BUS_TIMING_MMC_HS400ES;
246 }
247 ret = mmc_switch(media, EXT_CSD_BUS_WIDTH, bus_width);
248 if (ret) {
249 sd_mmc_error("Switching bus width for HS400 failed\n");
250 return ret;
251 }
252 sdhc_debug("SDHCI switched MMC to 8-bit DDR\n");
253
254 /* Set controller to 8-bit mode */
255 SET_BUS_WIDTH(ctrlr, 8);
256 media->caps |= EXT_CSD_BUS_WIDTH_8;
257
258 /* Switch MMC device to HS400 */
259 ret = mmc_switch(media, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400);
260 if (ret) {
261 sd_mmc_error("Switch to HS400 timing failed\n");
262 return ret;
263 }
264
265 /* Set controller to 200 MHz and use receive strobe */
266 SET_TIMING(ctrlr, timing);
267 media->caps |= caps;
268 mmc_recalculate_clock(media);
269 ret = sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
270 return ret;
271}
272
273static int mmc_select_hs200(struct storage_media *media)
274{
275 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
276 int ret;
277
278 /* Switch the MMC device to 8-bit SDR */
279 ret = mmc_switch(media, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
280 if (ret) {
281 sd_mmc_error("Switching bus width for HS200 failed\n");
282 return ret;
283 }
284
285 /* Set controller to 8-bit mode */
286 SET_BUS_WIDTH(ctrlr, 8);
287 media->caps |= EXT_CSD_BUS_WIDTH_8;
288
289 /* Switch to HS200 */
290 ret = mmc_switch(media, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200);
291
292 if (ret) {
293 sd_mmc_error("Switch to HS200 failed\n");
294 return ret;
295 }
296 sdhc_debug("SDHCI switched MMC to 8-bit SDR\n");
297
298 /* Set controller to 200 MHz */
299 SET_TIMING(ctrlr, BUS_TIMING_MMC_HS200);
300 media->caps |= DRVR_CAP_HS200 | DRVR_CAP_HS52 | DRVR_CAP_HS;
301 mmc_recalculate_clock(media);
302
303 /* Tune the receive sampling point for the bus */
304 if ((!ret) && (ctrlr->caps & DRVR_CAP_HS200_TUNING))
305 ret = mmc_bus_tuning(media);
306 return ret;
307}
308
309int mmc_change_freq(struct storage_media *media)
310{
311 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
312 int err;
313 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, 512);
314
315 media->caps = 0;
316
317 /* Only version 4 supports high-speed */
318 if (media->version < MMC_VERSION_4)
319 return 0;
320
321 err = mmc_send_ext_csd(ctrlr, ext_csd);
322 if (err)
323 return err;
324
Barnali Sarkare9628402017-12-27 13:51:18 +0530325 /* Determine if the device supports enhanced strobe */
326 media->caps |= ext_csd[EXT_CSD_STROBE_SUPPORT]
327 ? DRVR_CAP_ENHANCED_STROBE : 0;
328
Lee Leahyeef40eb2017-03-23 10:54:57 -0700329 if ((ctrlr->caps & DRVR_CAP_HS400) &&
330 (ext_csd[EXT_CSD_CARD_TYPE] & MMC_HS400))
331 err = mmc_select_hs400(media);
332 else if ((ctrlr->caps & DRVR_CAP_HS200) &&
333 (ext_csd[EXT_CSD_CARD_TYPE] & MMC_HS_200MHZ))
334 err = mmc_select_hs200(media);
335 else
336 err = mmc_select_hs(media);
337
338 return err;
339}
340
341int mmc_set_bus_width(struct storage_media *media)
342{
343 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
344 int err;
345 int width;
346
347 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, EXT_CSD_SIZE);
348 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, test_csd, EXT_CSD_SIZE);
349
350 /* Set the bus width */
351 err = 0;
352 for (width = EXT_CSD_BUS_WIDTH_8; width >= 0; width--) {
353 /* If HS200 is switched, Bus Width has been 8-bit */
354 if ((media->caps & DRVR_CAP_HS200) ||
355 (media->caps & DRVR_CAP_HS400))
356 break;
357
358 /* Set the card to use 4 bit*/
359 err = mmc_switch(media, EXT_CSD_BUS_WIDTH, width);
360 if (err)
361 continue;
362
363 if (!width) {
364 SET_BUS_WIDTH(ctrlr, 1);
365 break;
366 }
367 SET_BUS_WIDTH(ctrlr, 4 * width);
368
369 err = mmc_send_ext_csd(ctrlr, test_csd);
370 if (!err &&
371 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] ==
372 test_csd[EXT_CSD_PARTITIONING_SUPPORT]) &&
373 (ext_csd[EXT_CSD_ERASE_GROUP_DEF] ==
374 test_csd[EXT_CSD_ERASE_GROUP_DEF]) &&
375 (ext_csd[EXT_CSD_REV] ==
376 test_csd[EXT_CSD_REV]) &&
377 (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] ==
378 test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
379 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
380 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
381 media->caps |= width;
382 break;
383 }
384 }
385 return err;
386}
387
388int mmc_update_capacity(struct storage_media *media)
389{
390 uint64_t capacity;
391 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
392 int err;
393 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, EXT_CSD_SIZE);
394 uint32_t erase_size;
395 uint32_t hc_erase_size;
396 uint64_t hc_wp_size;
397 int index;
398
399 if (media->version < MMC_VERSION_4)
400 return 0;
401
402 /* check ext_csd version and capacity */
403 err = mmc_send_ext_csd(ctrlr, ext_csd);
404 if (err)
405 return err;
406
407 if (ext_csd[EXT_CSD_REV] < 2)
408 return 0;
409
Lee Leahyeef40eb2017-03-23 10:54:57 -0700410 /* Determine the eMMC device information */
411 media->partition_config = ext_csd[EXT_CSD_PART_CONF]
412 & EXT_CSD_PART_ACCESS_MASK;
413
414 /* Determine the user partition size
415 *
416 * According to the JEDEC Standard, the value of
417 * ext_csd's capacity is valid if the value is
418 * more than 2GB
419 */
Lee Leahyf968a4c2017-06-27 09:28:35 -0700420 capacity = (uint32_t)(ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
Lee Leahyeef40eb2017-03-23 10:54:57 -0700421 ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
422 ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
423 ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
424 capacity *= 512;
425 if ((capacity >> 20) > 2 * 1024)
426 media->capacity[MMC_PARTITION_USER] = capacity;
427
Elyes HAOUASb8473d02020-01-08 15:39:34 +0100428 /* Determine the boot partition sizes */
Lee Leahyeef40eb2017-03-23 10:54:57 -0700429 hc_erase_size = ext_csd[224] * 512 * KiB;
430 capacity = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * 128 * KiB;
431 media->capacity[MMC_PARTITION_BOOT_1] = capacity;
432 media->capacity[MMC_PARTITION_BOOT_2] = capacity;
433
434 /* Determine the RPMB size */
435 hc_wp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE] * hc_erase_size;
436 capacity = 128 * KiB * ext_csd[EXT_CSD_RPMB_SIZE_MULT];
437 media->capacity[MMC_PARTITION_RPMB] = capacity;
438
439 /* Determine the general partition sizes */
440 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP0 + 2] << 16)
441 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP0 + 1] << 8)
442 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP0];
443 capacity *= hc_wp_size;
444 media->capacity[MMC_PARTITION_GP1] = capacity;
445
446 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP1 + 2] << 16)
447 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP1 + 1] << 8)
448 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP1];
449 capacity *= hc_wp_size;
450 media->capacity[MMC_PARTITION_GP2] = capacity;
451
452 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP2 + 2] << 16)
453 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP2 + 1] << 8)
454 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP2];
455 capacity *= hc_wp_size;
456 media->capacity[MMC_PARTITION_GP3] = capacity;
457
458 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP3 + 2] << 16)
459 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP3 + 1] << 8)
460 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP3];
461 capacity *= hc_wp_size;
462 media->capacity[MMC_PARTITION_GP4] = capacity;
463
464 /* Determine the erase size */
465 erase_size = (sd_mmc_extract_uint32_bits(media->csd,
466 81, 5) + 1) *
467 (sd_mmc_extract_uint32_bits(media->csd, 86, 5)
468 + 1);
469 for (index = MMC_PARTITION_BOOT_1; index <= MMC_PARTITION_GP4;
470 index++) {
471 if (media->capacity[index] != 0) {
472 /* Enable the partitions */
473 err = mmc_switch(media, EXT_CSD_ERASE_GROUP_DEF,
474 EXT_CSD_PARTITION_ENABLE);
475 if (err) {
476 sdhc_error("Failed to enable partition access\n");
477 return err;
478 }
479
480 /* Use HC erase group size */
481 erase_size = hc_erase_size / media->write_bl_len;
482 break;
483 }
484 }
485 media->erase_blocks = erase_size;
486 media->trim_mult = ext_csd[EXT_CSD_TRIM_MULT];
487
488 return 0;
489}
490
491int mmc_set_partition(struct storage_media *media,
492 unsigned int partition_number)
493{
494 uint8_t partition_config;
495
496 /* Validate the partition number */
497 if ((partition_number > MMC_PARTITION_GP4)
498 || (!media->capacity[partition_number]))
499 return -1;
500
501 /* Update the partition register */
502 partition_config = media->partition_config;
503 partition_config &= ~EXT_CSD_PART_ACCESS_MASK;
504 partition_config |= partition_number;
505
506 /* Select the new partition */
507 int ret = mmc_switch(media, EXT_CSD_PART_CONF, partition_config);
508 if (!ret)
509 media->partition_config = partition_config;
510
511 return ret;
512}
513
514const char *mmc_partition_name(struct storage_media *media,
515 unsigned int partition_number)
516{
Elyes HAOUAS6c9737b2018-07-08 12:30:02 +0200517 static const char *const partition_name[8] = {
Lee Leahyeef40eb2017-03-23 10:54:57 -0700518 "User", /* 0 */
519 "Boot 1", /* 1 */
520 "Boot 2", /* 2 */
521 "RPMB", /* 3 */
522 "GP 1", /* 4 */
523 "GP 2", /* 5 */
524 "GP 3", /* 6 */
525 "GP 4" /* 7 */
526 };
527
528 if (partition_number >= ARRAY_SIZE(partition_name))
529 return "";
530 return partition_name[partition_number];
531}