1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * MultiMediaCard (MMC) and eMMC specific support code
4 * This code is controller independent
8 #include <commonlib/storage.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 */
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
34 if (ctrlr
->caps
& DRVR_CAP_HC
)
35 cmd
->cmdarg
|= OCR_HCS
;
38 int err
= ctrlr
->send_cmd(ctrlr
, cmd
, NULL
);
42 media
->op_cond_response
= cmd
->response
[0];
46 int mmc_send_op_cond(struct storage_media
*media
)
48 struct mmc_command cmd
;
51 /* Ask the card for its operating conditions */
53 for (int i
= 0; i
< max_iters
; i
++) {
54 int err
= mmc_send_op_cond_iter(media
, &cmd
, i
!= 0);
58 // OCR_BUSY is active low, this bit set means
59 // "initialization complete".
60 if (media
->op_cond_response
& OCR_BUSY
)
63 return CARD_IN_PROGRESS
;
66 int mmc_complete_op_cond(struct storage_media
*media
)
68 struct mmc_command cmd
;
71 stopwatch_init_msecs_expire(&sw
, MMC_INIT_TIMEOUT_US_MS
);
73 // CMD1 queries whether initialization is done.
74 int err
= mmc_send_op_cond_iter(media
, &cmd
, 1);
78 // OCR_BUSY means "initialization complete".
79 if (media
->op_cond_response
& OCR_BUSY
)
82 // Check if init timeout has expired.
83 if (stopwatch_expired(&sw
))
84 return CARD_UNUSABLE_ERR
;
89 media
->version
= MMC_VERSION_UNKNOWN
;
90 media
->ocr
= cmd
.response
[0];
92 media
->high_capacity
= ((media
->ocr
& OCR_HCS
) == OCR_HCS
);
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
;
103 /* Get the Card Status Register */
104 cmd
.cmdidx
= MMC_CMD_SEND_EXT_CSD
;
105 cmd
.resp_type
= CARD_RSP_R1
;
109 data
.dest
= (char *)ext_csd
;
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
)) {
119 size
= data
.blocks
* data
.blocksize
;
120 sd_mmc_trace("\t%p ext_csd:", ctrlr
);
121 for (i
= 0; i
< size
; i
++) {
124 sd_mmc_trace(" %2.2x", ext_csd
[i
]);
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));
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
);
150 static void mmc_recalculate_clock(struct storage_media
*media
)
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
)
162 SET_CLOCK(media
->ctrlr
, clock
);
165 static int mmc_select_hs(struct storage_media
*media
)
169 /* Switch the MMC device into high speed mode */
170 ret
= mmc_switch(media
, EXT_CSD_HS_TIMING
, EXT_CSD_TIMING_HS
);
172 sd_mmc_error("Timing switch to high speed failed\n");
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
);
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
;
195 cmd
.flags
= CMD_FLAG_IGNORE_INHIBIT
;
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
;
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
)) {
221 sd_mmc_error("Bus tuning failed!\n");
225 static int mmc_select_hs400(struct storage_media
*media
)
229 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
233 /* Switch the MMC device into high speed mode */
234 ret
= mmc_select_hs(media
);
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
);
250 sd_mmc_error("Switching bus width for HS400 failed\n");
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
);
262 sd_mmc_error("Switch to HS400 timing failed\n");
266 /* Set controller to 200 MHz and use receive strobe */
267 SET_TIMING(ctrlr
, timing
);
269 mmc_recalculate_clock(media
);
270 ret
= sd_mmc_send_status(media
, SD_MMC_IO_RETRIES
);
274 static int mmc_select_hs200(struct storage_media
*media
)
276 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
279 /* Switch the MMC device to 8-bit SDR */
280 ret
= mmc_switch(media
, EXT_CSD_BUS_WIDTH
, EXT_CSD_BUS_WIDTH_8
);
282 sd_mmc_error("Switching bus width for HS200 failed\n");
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
);
294 sd_mmc_error("Switch to HS200 failed\n");
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
);
310 int mmc_change_freq(struct storage_media
*media
)
312 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
314 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd
, 512);
318 /* Only version 4 supports high-speed */
319 if (media
->version
< MMC_VERSION_4
)
322 err
= mmc_send_ext_csd(ctrlr
, ext_csd
);
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
);
337 err
= mmc_select_hs(media
);
342 int mmc_set_bus_width(struct storage_media
*media
)
344 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
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 */
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
))
359 /* Set the card to use 4 bit*/
360 err
= mmc_switch(media
, EXT_CSD_BUS_WIDTH
, width
);
365 SET_BUS_WIDTH(ctrlr
, 1);
368 SET_BUS_WIDTH(ctrlr
, 4 * width
);
370 err
= mmc_send_ext_csd(ctrlr
, test_csd
);
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
;
389 int mmc_update_capacity(struct storage_media
*media
)
392 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
394 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd
, EXT_CSD_SIZE
);
396 uint32_t hc_erase_size
;
400 if (media
->version
< MMC_VERSION_4
)
403 /* check ext_csd version and capacity */
404 err
= mmc_send_ext_csd(ctrlr
, ext_csd
);
408 if (ext_csd
[EXT_CSD_REV
] < 2)
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
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);
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
,
468 (sd_mmc_extract_uint32_bits(media
->csd
, 86, 5)
470 for (index
= MMC_PARTITION_BOOT_1
; index
<= MMC_PARTITION_GP4
;
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
);
477 sdhc_error("Failed to enable partition access\n");
481 /* Use HC erase group size */
482 erase_size
= hc_erase_size
/ media
->write_bl_len
;
486 media
->erase_blocks
= erase_size
;
487 media
->trim_mult
= ext_csd
[EXT_CSD_TRIM_MULT
];
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
]))
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
);
510 media
->partition_config
= partition_config
;
515 const char *mmc_partition_name(struct storage_media
*media
,
516 unsigned int partition_number
)
518 static const char *const partition_name
[8] = {
529 if (partition_number
>= ARRAY_SIZE(partition_name
))
531 return partition_name
[partition_number
];
534 void mmc_set_early_wake_status(int32_t status
)
538 ms_cbmem
= cbmem_add(CBMEM_ID_MMC_STATUS
, sizeof(status
));
542 "%s: Failed to add early mmc wake status to cbmem!\n",
550 int mmc_send_cmd1(struct storage_media
*media
)
554 /* Reset emmc, send CMD0 */
555 if (sd_mmc_go_idle(media
))
559 err
= mmc_send_op_cond(media
);
561 if (media
->op_cond_response
& OCR_HCS
)
562 mmc_set_early_wake_status(MMC_STATUS_CMD1_READY_HCS
);
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
);
574 mmc_set_early_wake_status(MMC_STATUS_NEED_RESET
);