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
);
149 static void mmc_recalculate_clock(struct storage_media
*media
)
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
)
161 SET_CLOCK(media
->ctrlr
, clock
);
164 static int mmc_select_hs(struct storage_media
*media
)
168 /* Switch the MMC device into high speed mode */
169 ret
= mmc_switch(media
, EXT_CSD_HS_TIMING
, EXT_CSD_TIMING_HS
);
171 sd_mmc_error("Timing switch to high speed failed\n");
174 sdhc_debug("SDHCI switched MMC to high speed\n");
176 /* Increase the controller clock speed */
177 SET_TIMING(media
->ctrlr
, BUS_TIMING_MMC_HS
);
178 media
->caps
&= ~(DRVR_CAP_HS200
| DRVR_CAP_HS400
);
179 media
->caps
|= DRVR_CAP_HS52
| DRVR_CAP_HS
;
180 mmc_recalculate_clock(media
);
181 ret
= sd_mmc_send_status(media
, SD_MMC_IO_RETRIES
);
185 static int mmc_send_tuning_seq(struct sd_mmc_ctrlr
*ctrlr
, char *buffer
)
187 struct mmc_command cmd
;
188 struct mmc_data data
;
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
;
194 cmd
.flags
= CMD_FLAG_IGNORE_INHIBIT
;
198 data
.blocksize
= (ctrlr
->bus_width
== 8) ? 128 : 64;
199 data
.flags
= DATA_FLAG_READ
;
200 return ctrlr
->send_cmd(ctrlr
, &cmd
, &data
);
203 static int mmc_bus_tuning(struct storage_media
*media
)
205 ALLOC_CACHE_ALIGN_BUFFER(char, buffer
, 128);
206 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
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
++) {
213 mmc_send_tuning_seq(ctrlr
, buffer
);
214 if (ctrlr
->is_tuning_complete(ctrlr
, &successful
)) {
220 sd_mmc_error("Bus tuning failed!\n");
224 static int mmc_select_hs400(struct storage_media
*media
)
228 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
232 /* Switch the MMC device into high speed mode */
233 ret
= mmc_select_hs(media
);
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
;
247 ret
= mmc_switch(media
, EXT_CSD_BUS_WIDTH
, bus_width
);
249 sd_mmc_error("Switching bus width for HS400 failed\n");
252 sdhc_debug("SDHCI switched MMC to 8-bit DDR\n");
254 /* Set controller to 8-bit mode */
255 SET_BUS_WIDTH(ctrlr
, 8);
256 media
->caps
|= EXT_CSD_BUS_WIDTH_8
;
258 /* Switch MMC device to HS400 */
259 ret
= mmc_switch(media
, EXT_CSD_HS_TIMING
, EXT_CSD_TIMING_HS400
);
261 sd_mmc_error("Switch to HS400 timing failed\n");
265 /* Set controller to 200 MHz and use receive strobe */
266 SET_TIMING(ctrlr
, timing
);
268 mmc_recalculate_clock(media
);
269 ret
= sd_mmc_send_status(media
, SD_MMC_IO_RETRIES
);
273 static int mmc_select_hs200(struct storage_media
*media
)
275 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
278 /* Switch the MMC device to 8-bit SDR */
279 ret
= mmc_switch(media
, EXT_CSD_BUS_WIDTH
, EXT_CSD_BUS_WIDTH_8
);
281 sd_mmc_error("Switching bus width for HS200 failed\n");
285 /* Set controller to 8-bit mode */
286 SET_BUS_WIDTH(ctrlr
, 8);
287 media
->caps
|= EXT_CSD_BUS_WIDTH_8
;
289 /* Switch to HS200 */
290 ret
= mmc_switch(media
, EXT_CSD_HS_TIMING
, EXT_CSD_TIMING_HS200
);
293 sd_mmc_error("Switch to HS200 failed\n");
296 sdhc_debug("SDHCI switched MMC to 8-bit SDR\n");
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
);
303 /* Tune the receive sampling point for the bus */
304 if ((!ret
) && (ctrlr
->caps
& DRVR_CAP_HS200_TUNING
))
305 ret
= mmc_bus_tuning(media
);
309 int mmc_change_freq(struct storage_media
*media
)
311 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
313 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd
, 512);
317 /* Only version 4 supports high-speed */
318 if (media
->version
< MMC_VERSION_4
)
321 err
= mmc_send_ext_csd(ctrlr
, ext_csd
);
325 /* Determine if the device supports enhanced strobe */
326 media
->caps
|= ext_csd
[EXT_CSD_STROBE_SUPPORT
]
327 ? DRVR_CAP_ENHANCED_STROBE
: 0;
329 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
);
336 err
= mmc_select_hs(media
);
341 int mmc_set_bus_width(struct storage_media
*media
)
343 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
347 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd
, EXT_CSD_SIZE
);
348 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, test_csd
, EXT_CSD_SIZE
);
350 /* Set the bus width */
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
))
358 /* Set the card to use 4 bit*/
359 err
= mmc_switch(media
, EXT_CSD_BUS_WIDTH
, width
);
364 SET_BUS_WIDTH(ctrlr
, 1);
367 SET_BUS_WIDTH(ctrlr
, 4 * width
);
369 err
= mmc_send_ext_csd(ctrlr
, test_csd
);
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
;
388 int mmc_update_capacity(struct storage_media
*media
)
391 struct sd_mmc_ctrlr
*ctrlr
= media
->ctrlr
;
393 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd
, EXT_CSD_SIZE
);
395 uint32_t hc_erase_size
;
399 if (media
->version
< MMC_VERSION_4
)
402 /* check ext_csd version and capacity */
403 err
= mmc_send_ext_csd(ctrlr
, ext_csd
);
407 if (ext_csd
[EXT_CSD_REV
] < 2)
410 /* Determine the eMMC device information */
411 media
->partition_config
= ext_csd
[EXT_CSD_PART_CONF
]
412 & EXT_CSD_PART_ACCESS_MASK
;
414 /* Determine the user partition size
416 * According to the JEDEC Standard, the value of
417 * ext_csd's capacity is valid if the value is
420 capacity
= (uint32_t)(ext_csd
[EXT_CSD_SEC_CNT
+ 0] << 0 |
421 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);
425 if ((capacity
>> 20) > 2 * 1024)
426 media
->capacity
[MMC_PARTITION_USER
] = capacity
;
428 /* Determine the boot partition sizes */
429 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
;
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
;
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
;
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
;
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
;
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
;
464 /* Determine the erase size */
465 erase_size
= (sd_mmc_extract_uint32_bits(media
->csd
,
467 (sd_mmc_extract_uint32_bits(media
->csd
, 86, 5)
469 for (index
= MMC_PARTITION_BOOT_1
; index
<= MMC_PARTITION_GP4
;
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
);
476 sdhc_error("Failed to enable partition access\n");
480 /* Use HC erase group size */
481 erase_size
= hc_erase_size
/ media
->write_bl_len
;
485 media
->erase_blocks
= erase_size
;
486 media
->trim_mult
= ext_csd
[EXT_CSD_TRIM_MULT
];
491 int mmc_set_partition(struct storage_media
*media
,
492 unsigned int partition_number
)
494 uint8_t partition_config
;
496 /* Validate the partition number */
497 if ((partition_number
> MMC_PARTITION_GP4
)
498 || (!media
->capacity
[partition_number
]))
501 /* Update the partition register */
502 partition_config
= media
->partition_config
;
503 partition_config
&= ~EXT_CSD_PART_ACCESS_MASK
;
504 partition_config
|= partition_number
;
506 /* Select the new partition */
507 int ret
= mmc_switch(media
, EXT_CSD_PART_CONF
, partition_config
);
509 media
->partition_config
= partition_config
;
514 const char *mmc_partition_name(struct storage_media
*media
,
515 unsigned int partition_number
)
517 static const char *const partition_name
[8] = {
528 if (partition_number
>= ARRAY_SIZE(partition_name
))
530 return partition_name
[partition_number
];
533 void mmc_set_early_wake_status(int32_t status
)
537 ms_cbmem
= cbmem_add(CBMEM_ID_MMC_STATUS
, sizeof(status
));
541 "%s: Failed to add early mmc wake status to cbmem!\n",
549 int mmc_send_cmd1(struct storage_media
*media
)
553 /* Reset emmc, send CMD0 */
554 if (sd_mmc_go_idle(media
))
558 err
= mmc_send_op_cond(media
);
560 if (media
->op_cond_response
& OCR_HCS
)
561 mmc_set_early_wake_status(MMC_STATUS_CMD1_READY_HCS
);
563 mmc_set_early_wake_status(MMC_STATUS_CMD1_READY
);
564 } else if (err
== CARD_IN_PROGRESS
) {
565 mmc_set_early_wake_status(MMC_STATUS_CMD1_IN_PROGRESS
);
573 mmc_set_early_wake_status(MMC_STATUS_NEED_RESET
);