soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / commonlib / storage / mmc.c
blob135105db9641edeceed17b5a5c3d267a3f4fc858
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * MultiMediaCard (MMC) and eMMC specific support code
4 * This code is controller independent
5 */
7 #include <cbmem.h>
8 #include <commonlib/storage.h>
9 #include <delay.h>
10 #include "mmc.h"
11 #include "sd_mmc.h"
12 #include "storage.h"
13 #include <string.h>
14 #include <timer.h>
16 /* We pass in the cmd since otherwise the init seems to fail */
17 static int mmc_send_op_cond_iter(struct storage_media *media,
18 struct mmc_command *cmd, int use_arg)
20 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
22 cmd->cmdidx = MMC_CMD_SEND_OP_COND;
23 cmd->resp_type = CARD_RSP_R3;
25 /* Set the controller's operating conditions */
26 if (use_arg) {
27 uint32_t mask = media->op_cond_response &
28 (OCR_VOLTAGE_MASK | OCR_ACCESS_MODE);
29 cmd->cmdarg = ctrlr->voltages & mask;
31 /* Always request high capacity if supported by the
32 * controller
34 if (ctrlr->caps & DRVR_CAP_HC)
35 cmd->cmdarg |= OCR_HCS;
37 cmd->flags = 0;
38 int err = ctrlr->send_cmd(ctrlr, cmd, NULL);
39 if (err)
40 return err;
42 media->op_cond_response = cmd->response[0];
43 return 0;
46 int mmc_send_op_cond(struct storage_media *media)
48 struct mmc_command cmd;
49 int max_iters = 2;
51 /* Ask the card for its operating conditions */
52 cmd.cmdarg = 0;
53 for (int i = 0; i < max_iters; i++) {
54 int err = mmc_send_op_cond_iter(media, &cmd, i != 0);
55 if (err)
56 return err;
58 // OCR_BUSY is active low, this bit set means
59 // "initialization complete".
60 if (media->op_cond_response & OCR_BUSY)
61 return 0;
63 return CARD_IN_PROGRESS;
66 int mmc_complete_op_cond(struct storage_media *media)
68 struct mmc_command cmd;
69 struct stopwatch sw;
71 stopwatch_init_msecs_expire(&sw, MMC_INIT_TIMEOUT_US_MS);
72 while (1) {
73 // CMD1 queries whether initialization is done.
74 int err = mmc_send_op_cond_iter(media, &cmd, 1);
75 if (err)
76 return err;
78 // OCR_BUSY means "initialization complete".
79 if (media->op_cond_response & OCR_BUSY)
80 break;
82 // Check if init timeout has expired.
83 if (stopwatch_expired(&sw))
84 return CARD_UNUSABLE_ERR;
86 udelay(100);
89 media->version = MMC_VERSION_UNKNOWN;
90 media->ocr = cmd.response[0];
92 media->high_capacity = ((media->ocr & OCR_HCS) == OCR_HCS);
93 media->rca = 0;
94 return 0;
97 int mmc_send_ext_csd(struct sd_mmc_ctrlr *ctrlr, unsigned char *ext_csd)
99 struct mmc_command cmd;
100 struct mmc_data data;
101 int rv;
103 /* Get the Card Status Register */
104 cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
105 cmd.resp_type = CARD_RSP_R1;
106 cmd.cmdarg = 0;
107 cmd.flags = 0;
109 data.dest = (char *)ext_csd;
110 data.blocks = 1;
111 data.blocksize = 512;
112 data.flags = DATA_FLAG_READ;
114 rv = ctrlr->send_cmd(ctrlr, &cmd, &data);
116 if (!rv && CONFIG(SD_MMC_TRACE)) {
117 int i, size;
119 size = data.blocks * data.blocksize;
120 sd_mmc_trace("\t%p ext_csd:", ctrlr);
121 for (i = 0; i < size; i++) {
122 if (!(i % 32))
123 sd_mmc_trace("\n");
124 sd_mmc_trace(" %2.2x", ext_csd[i]);
126 sd_mmc_trace("\n");
128 return rv;
131 static int mmc_switch(struct storage_media *media, uint8_t index, uint8_t value)
133 struct mmc_command cmd;
134 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
136 cmd.cmdidx = MMC_CMD_SWITCH;
137 cmd.resp_type = CARD_RSP_R1b;
138 cmd.cmdarg = ((MMC_SWITCH_MODE_WRITE_BYTE << 24) |
139 (index << 16) | (value << 8));
140 cmd.flags = 0;
142 int ret = ctrlr->send_cmd(ctrlr, &cmd, NULL);
144 /* Waiting for the ready status */
145 sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
146 return ret;
150 static void mmc_recalculate_clock(struct storage_media *media)
152 uint32_t clock;
154 clock = CLOCK_26MHZ;
155 if (media->caps & DRVR_CAP_HS) {
156 if ((media->caps & DRVR_CAP_HS200) ||
157 (media->caps & DRVR_CAP_HS400))
158 clock = CLOCK_200MHZ;
159 else if (media->caps & DRVR_CAP_HS52)
160 clock = CLOCK_52MHZ;
162 SET_CLOCK(media->ctrlr, clock);
165 static int mmc_select_hs(struct storage_media *media)
167 int ret;
169 /* Switch the MMC device into high speed mode */
170 ret = mmc_switch(media, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS);
171 if (ret) {
172 sd_mmc_error("Timing switch to high speed failed\n");
173 return ret;
175 sdhc_debug("SDHCI switched MMC to high speed\n");
177 /* Increase the controller clock speed */
178 SET_TIMING(media->ctrlr, BUS_TIMING_MMC_HS);
179 media->caps &= ~(DRVR_CAP_HS200 | DRVR_CAP_HS400);
180 media->caps |= DRVR_CAP_HS52 | DRVR_CAP_HS;
181 mmc_recalculate_clock(media);
182 ret = sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
183 return ret;
186 static int mmc_send_tuning_seq(struct sd_mmc_ctrlr *ctrlr, char *buffer)
188 struct mmc_command cmd;
189 struct mmc_data data;
191 /* Request the device send the tuning sequence to the host */
192 cmd.cmdidx = MMC_CMD_AUTO_TUNING_SEQUENCE;
193 cmd.resp_type = CARD_RSP_R1;
194 cmd.cmdarg = 0;
195 cmd.flags = CMD_FLAG_IGNORE_INHIBIT;
197 data.dest = buffer;
198 data.blocks = 1;
199 data.blocksize = (ctrlr->bus_width == 8) ? 128 : 64;
200 data.flags = DATA_FLAG_READ;
201 return ctrlr->send_cmd(ctrlr, &cmd, &data);
204 static int mmc_bus_tuning(struct storage_media *media)
206 ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 128);
207 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
208 int index;
209 int successful;
211 /* Request the device send the tuning sequence up to 40 times */
212 ctrlr->tuning_start(ctrlr, 0);
213 for (index = 0; index < 40; index++) {
214 mmc_send_tuning_seq(ctrlr, buffer);
215 if (ctrlr->is_tuning_complete(ctrlr, &successful)) {
216 if (successful)
217 return 0;
218 break;
221 sd_mmc_error("Bus tuning failed!\n");
222 return -1;
225 static int mmc_select_hs400(struct storage_media *media)
227 uint8_t bus_width;
228 uint32_t caps;
229 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
230 int ret;
231 uint32_t timing;
233 /* Switch the MMC device into high speed mode */
234 ret = mmc_select_hs(media);
235 if (ret)
236 return ret;
238 /* Switch MMC device to 8-bit DDR with strobe */
239 bus_width = EXT_CSD_DDR_BUS_WIDTH_8;
240 caps = DRVR_CAP_HS400 | DRVR_CAP_HS52 | DRVR_CAP_HS;
241 timing = BUS_TIMING_MMC_HS400;
242 if ((ctrlr->caps & DRVR_CAP_ENHANCED_STROBE)
243 && (media->caps & DRVR_CAP_ENHANCED_STROBE)) {
244 bus_width |= EXT_CSD_BUS_WIDTH_STROBE;
245 caps |= DRVR_CAP_ENHANCED_STROBE;
246 timing = BUS_TIMING_MMC_HS400ES;
248 ret = mmc_switch(media, EXT_CSD_BUS_WIDTH, bus_width);
249 if (ret) {
250 sd_mmc_error("Switching bus width for HS400 failed\n");
251 return ret;
253 sdhc_debug("SDHCI switched MMC to 8-bit DDR\n");
255 /* Set controller to 8-bit mode */
256 SET_BUS_WIDTH(ctrlr, 8);
257 media->caps |= EXT_CSD_BUS_WIDTH_8;
259 /* Switch MMC device to HS400 */
260 ret = mmc_switch(media, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400);
261 if (ret) {
262 sd_mmc_error("Switch to HS400 timing failed\n");
263 return ret;
266 /* Set controller to 200 MHz and use receive strobe */
267 SET_TIMING(ctrlr, timing);
268 media->caps |= caps;
269 mmc_recalculate_clock(media);
270 ret = sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
271 return ret;
274 static int mmc_select_hs200(struct storage_media *media)
276 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
277 int ret;
279 /* Switch the MMC device to 8-bit SDR */
280 ret = mmc_switch(media, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
281 if (ret) {
282 sd_mmc_error("Switching bus width for HS200 failed\n");
283 return ret;
286 /* Set controller to 8-bit mode */
287 SET_BUS_WIDTH(ctrlr, 8);
288 media->caps |= EXT_CSD_BUS_WIDTH_8;
290 /* Switch to HS200 */
291 ret = mmc_switch(media, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200);
293 if (ret) {
294 sd_mmc_error("Switch to HS200 failed\n");
295 return ret;
297 sdhc_debug("SDHCI switched MMC to 8-bit SDR\n");
299 /* Set controller to 200 MHz */
300 SET_TIMING(ctrlr, BUS_TIMING_MMC_HS200);
301 media->caps |= DRVR_CAP_HS200 | DRVR_CAP_HS52 | DRVR_CAP_HS;
302 mmc_recalculate_clock(media);
304 /* Tune the receive sampling point for the bus */
305 if ((!ret) && (ctrlr->caps & DRVR_CAP_HS200_TUNING))
306 ret = mmc_bus_tuning(media);
307 return ret;
310 int mmc_change_freq(struct storage_media *media)
312 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
313 int err;
314 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, 512);
316 media->caps = 0;
318 /* Only version 4 supports high-speed */
319 if (media->version < MMC_VERSION_4)
320 return 0;
322 err = mmc_send_ext_csd(ctrlr, ext_csd);
323 if (err)
324 return err;
326 /* Determine if the device supports enhanced strobe */
327 media->caps |= ext_csd[EXT_CSD_STROBE_SUPPORT]
328 ? DRVR_CAP_ENHANCED_STROBE : 0;
330 if ((ctrlr->caps & DRVR_CAP_HS400) &&
331 (ext_csd[EXT_CSD_CARD_TYPE] & MMC_HS400))
332 err = mmc_select_hs400(media);
333 else if ((ctrlr->caps & DRVR_CAP_HS200) &&
334 (ext_csd[EXT_CSD_CARD_TYPE] & MMC_HS_200MHZ))
335 err = mmc_select_hs200(media);
336 else
337 err = mmc_select_hs(media);
339 return err;
342 int mmc_set_bus_width(struct storage_media *media)
344 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
345 int err;
346 int width;
348 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, EXT_CSD_SIZE);
349 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, test_csd, EXT_CSD_SIZE);
351 /* Set the bus width */
352 err = 0;
353 for (width = EXT_CSD_BUS_WIDTH_8; width >= 0; width--) {
354 /* If HS200 is switched, Bus Width has been 8-bit */
355 if ((media->caps & DRVR_CAP_HS200) ||
356 (media->caps & DRVR_CAP_HS400))
357 break;
359 /* Set the card to use 4 bit*/
360 err = mmc_switch(media, EXT_CSD_BUS_WIDTH, width);
361 if (err)
362 continue;
364 if (!width) {
365 SET_BUS_WIDTH(ctrlr, 1);
366 break;
368 SET_BUS_WIDTH(ctrlr, 4 * width);
370 err = mmc_send_ext_csd(ctrlr, test_csd);
371 if (!err &&
372 (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] ==
373 test_csd[EXT_CSD_PARTITIONING_SUPPORT]) &&
374 (ext_csd[EXT_CSD_ERASE_GROUP_DEF] ==
375 test_csd[EXT_CSD_ERASE_GROUP_DEF]) &&
376 (ext_csd[EXT_CSD_REV] ==
377 test_csd[EXT_CSD_REV]) &&
378 (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] ==
379 test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
380 memcmp(&ext_csd[EXT_CSD_SEC_CNT],
381 &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
382 media->caps |= width;
383 break;
386 return err;
389 int mmc_update_capacity(struct storage_media *media)
391 uint64_t capacity;
392 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
393 int err;
394 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, EXT_CSD_SIZE);
395 uint32_t erase_size;
396 uint32_t hc_erase_size;
397 uint64_t hc_wp_size;
398 int index;
400 if (media->version < MMC_VERSION_4)
401 return 0;
403 /* check ext_csd version and capacity */
404 err = mmc_send_ext_csd(ctrlr, ext_csd);
405 if (err)
406 return err;
408 if (ext_csd[EXT_CSD_REV] < 2)
409 return 0;
411 /* Determine the eMMC device information */
412 media->partition_config = ext_csd[EXT_CSD_PART_CONF]
413 & EXT_CSD_PART_ACCESS_MASK;
415 /* Determine the user partition size
417 * According to the JEDEC Standard, the value of
418 * ext_csd's capacity is valid if the value is
419 * more than 2GB
421 capacity = (uint32_t)(ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
422 ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
423 ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
424 ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
425 capacity *= 512;
426 if ((capacity >> 20) > 2 * 1024)
427 media->capacity[MMC_PARTITION_USER] = capacity;
429 /* Determine the boot partition sizes */
430 hc_erase_size = ext_csd[224] * 512 * KiB;
431 capacity = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * 128 * KiB;
432 media->capacity[MMC_PARTITION_BOOT_1] = capacity;
433 media->capacity[MMC_PARTITION_BOOT_2] = capacity;
435 /* Determine the RPMB size */
436 hc_wp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE] * hc_erase_size;
437 capacity = 128 * KiB * ext_csd[EXT_CSD_RPMB_SIZE_MULT];
438 media->capacity[MMC_PARTITION_RPMB] = capacity;
440 /* Determine the general partition sizes */
441 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP0 + 2] << 16)
442 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP0 + 1] << 8)
443 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP0];
444 capacity *= hc_wp_size;
445 media->capacity[MMC_PARTITION_GP1] = capacity;
447 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP1 + 2] << 16)
448 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP1 + 1] << 8)
449 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP1];
450 capacity *= hc_wp_size;
451 media->capacity[MMC_PARTITION_GP2] = capacity;
453 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP2 + 2] << 16)
454 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP2 + 1] << 8)
455 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP2];
456 capacity *= hc_wp_size;
457 media->capacity[MMC_PARTITION_GP3] = capacity;
459 capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP3 + 2] << 16)
460 | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP3 + 1] << 8)
461 | ext_csd[EXT_CSD_GP_SIZE_MULT_GP3];
462 capacity *= hc_wp_size;
463 media->capacity[MMC_PARTITION_GP4] = capacity;
465 /* Determine the erase size */
466 erase_size = (sd_mmc_extract_uint32_bits(media->csd,
467 81, 5) + 1) *
468 (sd_mmc_extract_uint32_bits(media->csd, 86, 5)
469 + 1);
470 for (index = MMC_PARTITION_BOOT_1; index <= MMC_PARTITION_GP4;
471 index++) {
472 if (media->capacity[index] != 0) {
473 /* Enable the partitions */
474 err = mmc_switch(media, EXT_CSD_ERASE_GROUP_DEF,
475 EXT_CSD_PARTITION_ENABLE);
476 if (err) {
477 sdhc_error("Failed to enable partition access\n");
478 return err;
481 /* Use HC erase group size */
482 erase_size = hc_erase_size / media->write_bl_len;
483 break;
486 media->erase_blocks = erase_size;
487 media->trim_mult = ext_csd[EXT_CSD_TRIM_MULT];
489 return 0;
492 int mmc_set_partition(struct storage_media *media,
493 unsigned int partition_number)
495 uint8_t partition_config;
497 /* Validate the partition number */
498 if ((partition_number > MMC_PARTITION_GP4)
499 || (!media->capacity[partition_number]))
500 return -1;
502 /* Update the partition register */
503 partition_config = media->partition_config;
504 partition_config &= ~EXT_CSD_PART_ACCESS_MASK;
505 partition_config |= partition_number;
507 /* Select the new partition */
508 int ret = mmc_switch(media, EXT_CSD_PART_CONF, partition_config);
509 if (!ret)
510 media->partition_config = partition_config;
512 return ret;
515 const char *mmc_partition_name(struct storage_media *media,
516 unsigned int partition_number)
518 static const char *const partition_name[8] = {
519 "User", /* 0 */
520 "Boot 1", /* 1 */
521 "Boot 2", /* 2 */
522 "RPMB", /* 3 */
523 "GP 1", /* 4 */
524 "GP 2", /* 5 */
525 "GP 3", /* 6 */
526 "GP 4" /* 7 */
529 if (partition_number >= ARRAY_SIZE(partition_name))
530 return "";
531 return partition_name[partition_number];
534 void mmc_set_early_wake_status(int32_t status)
536 int32_t *ms_cbmem;
538 ms_cbmem = cbmem_add(CBMEM_ID_MMC_STATUS, sizeof(status));
540 if (!ms_cbmem) {
541 printk(BIOS_ERR,
542 "%s: Failed to add early mmc wake status to cbmem!\n",
543 __func__);
544 return;
547 *ms_cbmem = status;
550 int mmc_send_cmd1(struct storage_media *media)
552 int err;
554 /* Reset emmc, send CMD0 */
555 if (sd_mmc_go_idle(media))
556 goto out_err;
558 /* Send CMD1 */
559 err = mmc_send_op_cond(media);
560 if (err == 0) {
561 if (media->op_cond_response & OCR_HCS)
562 mmc_set_early_wake_status(MMC_STATUS_CMD1_READY_HCS);
563 else
564 mmc_set_early_wake_status(MMC_STATUS_CMD1_READY);
565 } else if (err == CARD_IN_PROGRESS) {
566 mmc_set_early_wake_status(MMC_STATUS_CMD1_IN_PROGRESS);
567 } else {
568 goto out_err;
571 return 0;
573 out_err:
574 mmc_set_early_wake_status(MMC_STATUS_NEED_RESET);
575 return -1;