1 // SPDX-License-Identifier: GPL-2.0+
4 * Kyle Harris, kharris@nexus-tech.net
10 #include <display_options.h>
15 #include <sparse_format.h>
16 #include <image-sparse.h>
18 #include <linux/ctype.h>
20 static int curr_device
= -1;
22 static void print_mmcinfo(struct mmc
*mmc
)
26 printf("Device: %s\n", mmc
->cfg
->name
);
27 printf("Manufacturer ID: %x\n", mmc
->cid
[0] >> 24);
29 printf("OEM: %x\n", (mmc
->cid
[0] >> 8) & 0xffff);
30 printf("Name: %c%c%c%c%c \n", mmc
->cid
[0] & 0xff,
31 (mmc
->cid
[1] >> 24), (mmc
->cid
[1] >> 16) & 0xff,
32 (mmc
->cid
[1] >> 8) & 0xff, mmc
->cid
[1] & 0xff);
34 printf("OEM: %x\n", (mmc
->cid
[0] >> 8) & 0xff);
35 printf("Name: %c%c%c%c%c%c \n", mmc
->cid
[0] & 0xff,
36 (mmc
->cid
[1] >> 24), (mmc
->cid
[1] >> 16) & 0xff,
37 (mmc
->cid
[1] >> 8) & 0xff, mmc
->cid
[1] & 0xff,
41 printf("Bus Speed: %d\n", mmc
->clock
);
42 #if CONFIG_IS_ENABLED(MMC_VERBOSE)
43 printf("Mode: %s\n", mmc_mode_name(mmc
->selected_mode
));
44 mmc_dump_capabilities("card capabilities", mmc
->card_caps
);
45 mmc_dump_capabilities("host capabilities", mmc
->host_caps
);
47 printf("Rd Block Len: %d\n", mmc
->read_bl_len
);
49 printf("%s version %d.%d", IS_SD(mmc
) ? "SD" : "MMC",
50 EXTRACT_SDMMC_MAJOR_VERSION(mmc
->version
),
51 EXTRACT_SDMMC_MINOR_VERSION(mmc
->version
));
52 if (EXTRACT_SDMMC_CHANGE_VERSION(mmc
->version
) != 0)
53 printf(".%d", EXTRACT_SDMMC_CHANGE_VERSION(mmc
->version
));
56 printf("High Capacity: %s\n", mmc
->high_capacity
? "Yes" : "No");
58 print_size(mmc
->capacity
, "\n");
60 printf("Bus Width: %d-bit%s\n", mmc
->bus_width
,
61 mmc
->ddr_mode
? " DDR" : "");
63 #if CONFIG_IS_ENABLED(MMC_WRITE)
64 puts("Erase Group Size: ");
65 print_size(((u64
)mmc
->erase_grp_size
) << 9, "\n");
68 if (!IS_SD(mmc
) && mmc
->version
>= MMC_VERSION_4_41
) {
69 bool has_enh
= (mmc
->part_support
& ENHNCD_SUPPORT
) != 0;
70 bool usr_enh
= has_enh
&& (mmc
->part_attr
& EXT_CSD_ENH_USR
);
71 ALLOC_CACHE_ALIGN_BUFFER(u8
, ext_csd
, MMC_MAX_BLOCK_LEN
);
75 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
76 puts("HC WP Group Size: ");
77 print_size(((u64
)mmc
->hc_wp_grp_size
) << 9, "\n");
80 puts("User Capacity: ");
81 print_size(mmc
->capacity_user
, usr_enh
? " ENH" : "");
82 if (mmc
->wr_rel_set
& EXT_CSD_WR_DATA_REL_USR
)
87 puts("User Enhanced Start: ");
88 print_size(mmc
->enh_user_start
, "\n");
89 puts("User Enhanced Size: ");
90 print_size(mmc
->enh_user_size
, "\n");
92 puts("Boot Capacity: ");
93 print_size(mmc
->capacity_boot
, has_enh
? " ENH\n" : "\n");
94 puts("RPMB Capacity: ");
95 print_size(mmc
->capacity_rpmb
, has_enh
? " ENH\n" : "\n");
97 for (i
= 0; i
< ARRAY_SIZE(mmc
->capacity_gp
); i
++) {
98 bool is_enh
= has_enh
&&
99 (mmc
->part_attr
& EXT_CSD_ENH_GP(i
));
100 if (mmc
->capacity_gp
[i
]) {
101 printf("GP%i Capacity: ", i
+1);
102 print_size(mmc
->capacity_gp
[i
],
103 is_enh
? " ENH" : "");
104 if (mmc
->wr_rel_set
& EXT_CSD_WR_DATA_REL_GP(i
))
110 ret
= mmc_send_ext_csd(mmc
, ext_csd
);
113 wp
= ext_csd
[EXT_CSD_BOOT_WP_STATUS
];
114 for (i
= 0; i
< 2; ++i
) {
115 printf("Boot area %d is ", i
);
118 printf("not write protected\n");
121 printf("power on protected\n");
124 printf("permanently protected\n");
127 printf("in reserved protection state\n");
135 static struct mmc
*__init_mmc_device(int dev
, bool force_init
,
136 enum bus_mode speed_mode
)
139 mmc
= find_mmc_device(dev
);
141 printf("no mmc device at slot %x\n", dev
);
151 if (IS_ENABLED(CONFIG_MMC_SPEED_MODE_SET
))
152 mmc
->user_speed_mode
= speed_mode
;
157 #ifdef CONFIG_BLOCK_CACHE
158 struct blk_desc
*bd
= mmc_get_blk_desc(mmc
);
159 blkcache_invalidate(bd
->uclass_id
, bd
->devnum
);
165 static struct mmc
*init_mmc_device(int dev
, bool force_init
)
167 return __init_mmc_device(dev
, force_init
, MMC_MODES_END
);
170 static int do_mmcinfo(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
175 if (curr_device
< 0) {
176 if (get_mmc_num() > 0)
179 puts("No MMC device available\n");
180 return CMD_RET_FAILURE
;
184 mmc
= init_mmc_device(curr_device
, false);
186 return CMD_RET_FAILURE
;
189 return CMD_RET_SUCCESS
;
192 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
193 static int confirm_key_prog(void)
195 puts("Warning: Programming authentication key can be done only once !\n"
196 " Use this command only if you are sure of what you are doing,\n"
197 "Really perform the key programming? <y/N> ");
201 puts("Authentication key programming aborted\n");
205 static int do_mmcrpmb_key(struct cmd_tbl
*cmdtp
, int flag
,
206 int argc
, char *const argv
[])
209 struct mmc
*mmc
= find_mmc_device(curr_device
);
212 return CMD_RET_USAGE
;
214 key_addr
= (void *)hextoul(argv
[1], NULL
);
215 if (!confirm_key_prog())
216 return CMD_RET_FAILURE
;
217 if (mmc_rpmb_set_key(mmc
, key_addr
)) {
218 printf("ERROR - Key already programmed ?\n");
219 return CMD_RET_FAILURE
;
221 return CMD_RET_SUCCESS
;
224 static int do_mmcrpmb_read(struct cmd_tbl
*cmdtp
, int flag
,
225 int argc
, char *const argv
[])
230 void *key_addr
= NULL
;
231 struct mmc
*mmc
= find_mmc_device(curr_device
);
234 return CMD_RET_USAGE
;
236 addr
= (void *)hextoul(argv
[1], NULL
);
237 blk
= hextoul(argv
[2], NULL
);
238 cnt
= hextoul(argv
[3], NULL
);
241 key_addr
= (void *)hextoul(argv
[4], NULL
);
243 printf("MMC RPMB read: dev # %d, block # %d, count %d ... ",
244 curr_device
, blk
, cnt
);
245 n
= mmc_rpmb_read(mmc
, addr
, blk
, cnt
, key_addr
);
247 printf("%d RPMB blocks read: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
249 return CMD_RET_FAILURE
;
250 return CMD_RET_SUCCESS
;
253 static int do_mmcrpmb_write(struct cmd_tbl
*cmdtp
, int flag
,
254 int argc
, char *const argv
[])
260 struct mmc
*mmc
= find_mmc_device(curr_device
);
263 return CMD_RET_USAGE
;
265 addr
= (void *)hextoul(argv
[1], NULL
);
266 blk
= hextoul(argv
[2], NULL
);
267 cnt
= hextoul(argv
[3], NULL
);
268 key_addr
= (void *)hextoul(argv
[4], NULL
);
270 printf("MMC RPMB write: dev # %d, block # %d, count %d ... ",
271 curr_device
, blk
, cnt
);
272 n
= mmc_rpmb_write(mmc
, addr
, blk
, cnt
, key_addr
);
274 printf("%d RPMB blocks written: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
276 return CMD_RET_FAILURE
;
277 return CMD_RET_SUCCESS
;
280 static int do_mmcrpmb_counter(struct cmd_tbl
*cmdtp
, int flag
,
281 int argc
, char *const argv
[])
283 unsigned long counter
;
284 struct mmc
*mmc
= find_mmc_device(curr_device
);
286 if (mmc_rpmb_get_counter(mmc
, &counter
))
287 return CMD_RET_FAILURE
;
288 printf("RPMB Write counter= %lx\n", counter
);
289 return CMD_RET_SUCCESS
;
292 static struct cmd_tbl cmd_rpmb
[] = {
293 U_BOOT_CMD_MKENT(key
, 2, 0, do_mmcrpmb_key
, "", ""),
294 U_BOOT_CMD_MKENT(read
, 5, 1, do_mmcrpmb_read
, "", ""),
295 U_BOOT_CMD_MKENT(write
, 5, 0, do_mmcrpmb_write
, "", ""),
296 U_BOOT_CMD_MKENT(counter
, 1, 1, do_mmcrpmb_counter
, "", ""),
299 static int do_mmcrpmb(struct cmd_tbl
*cmdtp
, int flag
,
300 int argc
, char *const argv
[])
307 cp
= find_cmd_tbl(argv
[1], cmd_rpmb
, ARRAY_SIZE(cmd_rpmb
));
309 /* Drop the rpmb subcommand */
313 if (cp
== NULL
|| argc
> cp
->maxargs
)
314 return CMD_RET_USAGE
;
315 if (flag
== CMD_FLAG_REPEAT
&& !cmd_is_repeatable(cp
))
316 return CMD_RET_SUCCESS
;
318 mmc
= init_mmc_device(curr_device
, false);
320 return CMD_RET_FAILURE
;
322 if (!(mmc
->version
& MMC_VERSION_MMC
)) {
323 printf("It is not an eMMC device\n");
324 return CMD_RET_FAILURE
;
326 if (mmc
->version
< MMC_VERSION_4_41
) {
327 printf("RPMB not supported before version 4.41\n");
328 return CMD_RET_FAILURE
;
330 /* Switch to the RPMB partition */
332 original_part
= mmc
->block_dev
.hwpart
;
334 original_part
= mmc_get_blk_desc(mmc
)->hwpart
;
336 if (blk_select_hwpart_devnum(UCLASS_MMC
, curr_device
, MMC_PART_RPMB
) !=
338 return CMD_RET_FAILURE
;
339 ret
= cp
->cmd(cmdtp
, flag
, argc
, argv
);
341 /* Return to original partition */
342 if (blk_select_hwpart_devnum(UCLASS_MMC
, curr_device
, original_part
) !=
344 return CMD_RET_FAILURE
;
349 static int do_mmc_read(struct cmd_tbl
*cmdtp
, int flag
,
350 int argc
, char *const argv
[])
357 return CMD_RET_USAGE
;
359 ptr
= map_sysmem(hextoul(argv
[1], NULL
), 0);
360 blk
= hextoul(argv
[2], NULL
);
361 cnt
= hextoul(argv
[3], NULL
);
363 mmc
= init_mmc_device(curr_device
, false);
365 return CMD_RET_FAILURE
;
367 printf("MMC read: dev # %d, block # %d, count %d ... ",
368 curr_device
, blk
, cnt
);
370 n
= blk_dread(mmc_get_blk_desc(mmc
), blk
, cnt
, ptr
);
371 printf("%d blocks read: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
374 return (n
== cnt
) ? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;
377 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
378 static lbaint_t
mmc_sparse_write(struct sparse_storage
*info
, lbaint_t blk
,
379 lbaint_t blkcnt
, const void *buffer
)
381 struct blk_desc
*dev_desc
= info
->priv
;
383 return blk_dwrite(dev_desc
, blk
, blkcnt
, buffer
);
386 static lbaint_t
mmc_sparse_reserve(struct sparse_storage
*info
,
387 lbaint_t blk
, lbaint_t blkcnt
)
392 static int do_mmc_sparse_write(struct cmd_tbl
*cmdtp
, int flag
,
393 int argc
, char *const argv
[])
395 struct sparse_storage sparse
;
396 struct blk_desc
*dev_desc
;
403 return CMD_RET_USAGE
;
405 addr
= (void *)hextoul(argv
[1], NULL
);
406 blk
= hextoul(argv
[2], NULL
);
408 if (!is_sparse_image(addr
)) {
409 printf("Not a sparse image\n");
410 return CMD_RET_FAILURE
;
413 mmc
= init_mmc_device(curr_device
, false);
415 return CMD_RET_FAILURE
;
417 printf("MMC Sparse write: dev # %d, block # %d ... ",
420 if (mmc_getwp(mmc
) == 1) {
421 printf("Error: card is write protected!\n");
422 return CMD_RET_FAILURE
;
425 dev_desc
= mmc_get_blk_desc(mmc
);
426 sparse
.priv
= dev_desc
;
429 sparse
.size
= dev_desc
->lba
- blk
;
430 sparse
.write
= mmc_sparse_write
;
431 sparse
.reserve
= mmc_sparse_reserve
;
433 sprintf(dest
, "0x" LBAF
, sparse
.start
* sparse
.blksz
);
435 if (write_sparse_image(&sparse
, dest
, addr
, NULL
))
436 return CMD_RET_FAILURE
;
438 return CMD_RET_SUCCESS
;
442 #if CONFIG_IS_ENABLED(MMC_WRITE)
443 static int do_mmc_write(struct cmd_tbl
*cmdtp
, int flag
,
444 int argc
, char *const argv
[])
451 return CMD_RET_USAGE
;
453 ptr
= map_sysmem(hextoul(argv
[1], NULL
), 0);
454 blk
= hextoul(argv
[2], NULL
);
455 cnt
= hextoul(argv
[3], NULL
);
457 mmc
= init_mmc_device(curr_device
, false);
459 return CMD_RET_FAILURE
;
461 printf("MMC write: dev # %d, block # %d, count %d ... ",
462 curr_device
, blk
, cnt
);
464 if (mmc_getwp(mmc
) == 1) {
465 printf("Error: card is write protected!\n");
466 return CMD_RET_FAILURE
;
468 n
= blk_dwrite(mmc_get_blk_desc(mmc
), blk
, cnt
, ptr
);
469 printf("%d blocks written: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
472 return (n
== cnt
) ? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;
475 static int do_mmc_erase(struct cmd_tbl
*cmdtp
, int flag
,
476 int argc
, char *const argv
[])
479 struct disk_partition info
;
482 if (argc
< 2 || argc
> 3)
483 return CMD_RET_USAGE
;
485 mmc
= init_mmc_device(curr_device
, false);
487 return CMD_RET_FAILURE
;
490 blk
= hextoul(argv
[1], NULL
);
491 cnt
= hextoul(argv
[2], NULL
);
492 } else if (part_get_info_by_name(mmc_get_blk_desc(mmc
), argv
[1], &info
) >= 0) {
496 return CMD_RET_FAILURE
;
499 printf("MMC erase: dev # %d, block # %d, count %d ... ",
500 curr_device
, blk
, cnt
);
502 if (mmc_getwp(mmc
) == 1) {
503 printf("Error: card is write protected!\n");
504 return CMD_RET_FAILURE
;
506 n
= blk_derase(mmc_get_blk_desc(mmc
), blk
, cnt
);
507 printf("%d blocks erased: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
509 return (n
== cnt
) ? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;
513 static int do_mmc_rescan(struct cmd_tbl
*cmdtp
, int flag
,
514 int argc
, char *const argv
[])
519 mmc
= init_mmc_device(curr_device
, true);
520 } else if (argc
== 2) {
521 enum bus_mode speed_mode
;
523 speed_mode
= (int)dectoul(argv
[1], NULL
);
524 mmc
= __init_mmc_device(curr_device
, true, speed_mode
);
526 return CMD_RET_USAGE
;
530 return CMD_RET_FAILURE
;
532 return CMD_RET_SUCCESS
;
535 static int do_mmc_part(struct cmd_tbl
*cmdtp
, int flag
,
536 int argc
, char *const argv
[])
538 struct blk_desc
*mmc_dev
;
541 mmc
= init_mmc_device(curr_device
, false);
543 return CMD_RET_FAILURE
;
545 mmc_dev
= blk_get_devnum_by_uclass_id(UCLASS_MMC
, curr_device
);
546 if (mmc_dev
!= NULL
&& mmc_dev
->type
!= DEV_TYPE_UNKNOWN
) {
548 return CMD_RET_SUCCESS
;
551 puts("get mmc type error!\n");
552 return CMD_RET_FAILURE
;
555 static int do_mmc_dev(struct cmd_tbl
*cmdtp
, int flag
,
556 int argc
, char *const argv
[])
558 int dev
, part
= 0, ret
;
563 mmc
= init_mmc_device(dev
, true);
564 } else if (argc
== 2) {
565 dev
= (int)dectoul(argv
[1], NULL
);
566 mmc
= init_mmc_device(dev
, true);
567 } else if (argc
== 3) {
568 dev
= (int)dectoul(argv
[1], NULL
);
569 part
= (int)dectoul(argv
[2], NULL
);
570 if (part
> PART_ACCESS_MASK
) {
571 printf("#part_num shouldn't be larger than %d\n",
573 return CMD_RET_FAILURE
;
575 mmc
= init_mmc_device(dev
, true);
576 } else if (argc
== 4) {
577 enum bus_mode speed_mode
;
579 dev
= (int)dectoul(argv
[1], NULL
);
580 part
= (int)dectoul(argv
[2], NULL
);
581 if (part
> PART_ACCESS_MASK
) {
582 printf("#part_num shouldn't be larger than %d\n",
584 return CMD_RET_FAILURE
;
586 speed_mode
= (int)dectoul(argv
[3], NULL
);
587 mmc
= __init_mmc_device(dev
, true, speed_mode
);
589 return CMD_RET_USAGE
;
593 return CMD_RET_FAILURE
;
595 ret
= blk_select_hwpart_devnum(UCLASS_MMC
, dev
, part
);
596 printf("switch to partitions #%d, %s\n",
597 part
, (!ret
) ? "OK" : "ERROR");
602 if (mmc
->part_config
== MMCPART_NOAVAILABLE
)
603 printf("mmc%d is current device\n", curr_device
);
605 printf("mmc%d(part %d) is current device\n",
606 curr_device
, mmc_get_blk_desc(mmc
)->hwpart
);
608 return CMD_RET_SUCCESS
;
611 static int do_mmc_list(struct cmd_tbl
*cmdtp
, int flag
,
612 int argc
, char *const argv
[])
614 print_mmc_devices('\n');
615 return CMD_RET_SUCCESS
;
618 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
619 static void parse_hwpart_user_enh_size(struct mmc
*mmc
,
620 struct mmc_hwpart_conf
*pconf
,
625 pconf
->user
.enh_size
= 0;
627 if (!strcmp(argv
, "-")) { /* The rest of eMMC */
628 ALLOC_CACHE_ALIGN_BUFFER(u8
, ext_csd
, MMC_MAX_BLOCK_LEN
);
629 ret
= mmc_send_ext_csd(mmc
, ext_csd
);
632 /* The enh_size value is in 512B block units */
633 pconf
->user
.enh_size
=
634 ((ext_csd
[EXT_CSD_MAX_ENH_SIZE_MULT
+ 2] << 16) +
635 (ext_csd
[EXT_CSD_MAX_ENH_SIZE_MULT
+ 1] << 8) +
636 ext_csd
[EXT_CSD_MAX_ENH_SIZE_MULT
]) * 1024 *
637 ext_csd
[EXT_CSD_HC_ERASE_GRP_SIZE
] *
638 ext_csd
[EXT_CSD_HC_WP_GRP_SIZE
];
639 pconf
->user
.enh_size
-= pconf
->user
.enh_start
;
640 for (i
= 0; i
< ARRAY_SIZE(mmc
->capacity_gp
); i
++) {
642 * If the eMMC already has GP partitions set,
643 * subtract their size from the maximum USER
646 * Else, if the command was used to configure new
647 * GP partitions, subtract their size from maximum
648 * USER partition size.
650 if (mmc
->capacity_gp
[i
]) {
651 /* The capacity_gp is in 1B units */
652 pconf
->user
.enh_size
-= mmc
->capacity_gp
[i
] >> 9;
653 } else if (pconf
->gp_part
[i
].size
) {
654 /* The gp_part[].size is in 512B units */
655 pconf
->user
.enh_size
-= pconf
->gp_part
[i
].size
;
659 pconf
->user
.enh_size
= dectoul(argv
, NULL
);
663 static int parse_hwpart_user(struct mmc
*mmc
, struct mmc_hwpart_conf
*pconf
,
664 int argc
, char *const argv
[])
668 memset(&pconf
->user
, 0, sizeof(pconf
->user
));
671 if (!strcmp(argv
[i
], "enh")) {
674 pconf
->user
.enh_start
=
675 dectoul(argv
[i
+ 1], NULL
);
676 parse_hwpart_user_enh_size(mmc
, pconf
, argv
[i
+ 2]);
678 } else if (!strcmp(argv
[i
], "wrrel")) {
681 pconf
->user
.wr_rel_change
= 1;
682 if (!strcmp(argv
[i
+1], "on"))
683 pconf
->user
.wr_rel_set
= 1;
684 else if (!strcmp(argv
[i
+1], "off"))
685 pconf
->user
.wr_rel_set
= 0;
696 static int parse_hwpart_gp(struct mmc_hwpart_conf
*pconf
, int pidx
,
697 int argc
, char *const argv
[])
701 memset(&pconf
->gp_part
[pidx
], 0, sizeof(pconf
->gp_part
[pidx
]));
705 pconf
->gp_part
[pidx
].size
= dectoul(argv
[0], NULL
);
709 if (!strcmp(argv
[i
], "enh")) {
710 pconf
->gp_part
[pidx
].enhanced
= 1;
712 } else if (!strcmp(argv
[i
], "wrrel")) {
715 pconf
->gp_part
[pidx
].wr_rel_change
= 1;
716 if (!strcmp(argv
[i
+1], "on"))
717 pconf
->gp_part
[pidx
].wr_rel_set
= 1;
718 else if (!strcmp(argv
[i
+1], "off"))
719 pconf
->gp_part
[pidx
].wr_rel_set
= 0;
730 static int do_mmc_hwpartition(struct cmd_tbl
*cmdtp
, int flag
,
731 int argc
, char *const argv
[])
734 struct mmc_hwpart_conf pconf
= { };
735 enum mmc_hwpart_conf_mode mode
= MMC_HWPART_CONF_CHECK
;
738 mmc
= init_mmc_device(curr_device
, false);
740 return CMD_RET_FAILURE
;
743 puts("SD doesn't support partitioning\n");
744 return CMD_RET_FAILURE
;
748 return CMD_RET_USAGE
;
751 if (!strcmp(argv
[i
], "user")) {
753 r
= parse_hwpart_user(mmc
, &pconf
, argc
- i
, &argv
[i
]);
755 return CMD_RET_USAGE
;
757 } else if (!strncmp(argv
[i
], "gp", 2) &&
758 strlen(argv
[i
]) == 3 &&
759 argv
[i
][2] >= '1' && argv
[i
][2] <= '4') {
760 pidx
= argv
[i
][2] - '1';
762 r
= parse_hwpart_gp(&pconf
, pidx
, argc
-i
, &argv
[i
]);
764 return CMD_RET_USAGE
;
766 } else if (!strcmp(argv
[i
], "check")) {
767 mode
= MMC_HWPART_CONF_CHECK
;
769 } else if (!strcmp(argv
[i
], "set")) {
770 mode
= MMC_HWPART_CONF_SET
;
772 } else if (!strcmp(argv
[i
], "complete")) {
773 mode
= MMC_HWPART_CONF_COMPLETE
;
776 return CMD_RET_USAGE
;
780 puts("Partition configuration:\n");
781 if (pconf
.user
.enh_size
) {
782 puts("\tUser Enhanced Start: ");
783 print_size(((u64
)pconf
.user
.enh_start
) << 9, "\n");
784 puts("\tUser Enhanced Size: ");
785 print_size(((u64
)pconf
.user
.enh_size
) << 9, "\n");
787 puts("\tNo enhanced user data area\n");
789 if (pconf
.user
.wr_rel_change
)
790 printf("\tUser partition write reliability: %s\n",
791 pconf
.user
.wr_rel_set
? "on" : "off");
792 for (pidx
= 0; pidx
< 4; pidx
++) {
793 if (pconf
.gp_part
[pidx
].size
) {
794 printf("\tGP%i Capacity: ", pidx
+1);
795 print_size(((u64
)pconf
.gp_part
[pidx
].size
) << 9,
796 pconf
.gp_part
[pidx
].enhanced
?
799 printf("\tNo GP%i partition\n", pidx
+1);
801 if (pconf
.gp_part
[pidx
].wr_rel_change
)
802 printf("\tGP%i write reliability: %s\n", pidx
+1,
803 pconf
.gp_part
[pidx
].wr_rel_set
? "on" : "off");
806 if (!mmc_hwpart_config(mmc
, &pconf
, mode
)) {
807 if (mode
== MMC_HWPART_CONF_COMPLETE
)
808 puts("Partitioning successful, "
809 "power-cycle to make effective\n");
810 return CMD_RET_SUCCESS
;
813 return CMD_RET_FAILURE
;
818 #ifdef CONFIG_SUPPORT_EMMC_BOOT
819 static int do_mmc_bootbus(struct cmd_tbl
*cmdtp
, int flag
,
820 int argc
, char *const argv
[])
824 u8 width
, reset
, mode
;
827 return CMD_RET_USAGE
;
828 dev
= dectoul(argv
[1], NULL
);
829 width
= dectoul(argv
[2], NULL
);
830 reset
= dectoul(argv
[3], NULL
);
831 mode
= dectoul(argv
[4], NULL
);
833 mmc
= init_mmc_device(dev
, false);
835 return CMD_RET_FAILURE
;
838 puts("BOOT_BUS_WIDTH only exists on eMMC\n");
839 return CMD_RET_FAILURE
;
843 * BOOT_BUS_CONDITIONS[177]
845 * 0x0 : Use SDR + Backward compatible timing in boot operation
846 * 0x1 : Use SDR + High Speed Timing in boot operation mode
847 * 0x2 : Use DDR in boot operation
848 * RESET_BOOT_BUS_CONDITIONS
849 * 0x0 : Reset bus width to x1, SDR, Backward compatible
850 * 0x1 : Retain BOOT_BUS_WIDTH and BOOT_MODE
852 * 0x0 : x1(sdr) or x4 (ddr) buswidth
853 * 0x1 : x4(sdr/ddr) buswith
854 * 0x2 : x8(sdr/ddr) buswith
858 printf("boot_bus_width %d is invalid\n", width
);
859 return CMD_RET_FAILURE
;
863 printf("reset_boot_bus_width %d is invalid\n", reset
);
864 return CMD_RET_FAILURE
;
868 printf("reset_boot_bus_width %d is invalid\n", mode
);
869 return CMD_RET_FAILURE
;
872 /* acknowledge to be sent during boot operation */
873 if (mmc_set_boot_bus_width(mmc
, width
, reset
, mode
)) {
874 puts("BOOT_BUS_WIDTH is failed to change.\n");
875 return CMD_RET_FAILURE
;
878 printf("Set to BOOT_BUS_WIDTH = 0x%x, RESET = 0x%x, BOOT_MODE = 0x%x\n",
880 return CMD_RET_SUCCESS
;
883 static int do_mmc_boot_resize(struct cmd_tbl
*cmdtp
, int flag
,
884 int argc
, char *const argv
[])
888 u32 bootsize
, rpmbsize
;
891 return CMD_RET_USAGE
;
892 dev
= dectoul(argv
[1], NULL
);
893 bootsize
= dectoul(argv
[2], NULL
);
894 rpmbsize
= dectoul(argv
[3], NULL
);
896 mmc
= init_mmc_device(dev
, false);
898 return CMD_RET_FAILURE
;
901 printf("It is not an eMMC device\n");
902 return CMD_RET_FAILURE
;
905 if (mmc_boot_partition_size_change(mmc
, bootsize
, rpmbsize
)) {
906 printf("EMMC boot partition Size change Failed.\n");
907 return CMD_RET_FAILURE
;
910 printf("EMMC boot partition Size %d MB\n", bootsize
);
911 printf("EMMC RPMB partition Size %d MB\n", rpmbsize
);
912 return CMD_RET_SUCCESS
;
915 static int mmc_partconf_print(struct mmc
*mmc
, const char *varname
)
917 u8 ack
, access
, part
;
919 if (mmc
->part_config
== MMCPART_NOAVAILABLE
) {
920 printf("No part_config info for ver. 0x%x\n", mmc
->version
);
921 return CMD_RET_FAILURE
;
924 access
= EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc
->part_config
);
925 ack
= EXT_CSD_EXTRACT_BOOT_ACK(mmc
->part_config
);
926 part
= EXT_CSD_EXTRACT_BOOT_PART(mmc
->part_config
);
929 env_set_hex(varname
, part
);
931 printf("EXT_CSD[179], PARTITION_CONFIG:\n"
933 "BOOT_PARTITION_ENABLE: 0x%x (%s)\n"
934 "PARTITION_ACCESS: 0x%x (%s)\n", ack
, part
, emmc_boot_part_names
[part
],
935 access
, emmc_hwpart_names
[access
]);
937 return CMD_RET_SUCCESS
;
940 static int do_mmc_partconf(struct cmd_tbl
*cmdtp
, int flag
,
941 int argc
, char *const argv
[])
945 u8 ack
, part_num
, access
;
947 if (argc
!= 2 && argc
!= 3 && argc
!= 5)
948 return CMD_RET_USAGE
;
950 dev
= dectoul(argv
[1], NULL
);
952 mmc
= init_mmc_device(dev
, false);
954 return CMD_RET_FAILURE
;
957 puts("PARTITION_CONFIG only exists on eMMC\n");
958 return CMD_RET_FAILURE
;
961 if (argc
== 2 || argc
== 3)
962 return mmc_partconf_print(mmc
, cmd_arg2(argc
, argv
));
965 ack
= dectoul(argv
[2], NULL
);
966 /* BOOT_PARTITION_ENABLE */
967 if (!isdigit(*argv
[3])) {
968 for (part_num
= ARRAY_SIZE(emmc_boot_part_names
) - 1; part_num
> 0; part_num
--) {
969 if (!strcmp(argv
[3], emmc_boot_part_names
[part_num
]))
973 part_num
= dectoul(argv
[3], NULL
);
975 /* PARTITION_ACCESS */
976 if (!isdigit(*argv
[4])) {
977 for (access
= ARRAY_SIZE(emmc_hwpart_names
) - 1; access
> 0; access
--) {
978 if (!strcmp(argv
[4], emmc_hwpart_names
[access
]))
982 access
= dectoul(argv
[4], NULL
);
985 /* acknowledge to be sent during boot operation */
986 ret
= mmc_set_part_conf(mmc
, ack
, part_num
, access
);
988 return CMD_RET_FAILURE
;
990 return CMD_RET_SUCCESS
;
993 static int do_mmc_rst_func(struct cmd_tbl
*cmdtp
, int flag
,
994 int argc
, char *const argv
[])
1001 * Set the RST_n_ENABLE bit of RST_n_FUNCTION
1002 * The only valid values are 0x0, 0x1 and 0x2 and writing
1003 * a value of 0x1 or 0x2 sets the value permanently.
1006 return CMD_RET_USAGE
;
1008 dev
= dectoul(argv
[1], NULL
);
1009 enable
= dectoul(argv
[2], NULL
);
1012 puts("Invalid RST_n_ENABLE value\n");
1013 return CMD_RET_USAGE
;
1016 mmc
= init_mmc_device(dev
, false);
1018 return CMD_RET_FAILURE
;
1021 puts("RST_n_FUNCTION only exists on eMMC\n");
1022 return CMD_RET_FAILURE
;
1025 ret
= mmc_set_rst_n_function(mmc
, enable
);
1027 return CMD_RET_FAILURE
;
1029 return CMD_RET_SUCCESS
;
1032 static int do_mmc_setdsr(struct cmd_tbl
*cmdtp
, int flag
,
1033 int argc
, char *const argv
[])
1040 return CMD_RET_USAGE
;
1041 val
= hextoul(argv
[1], NULL
);
1043 mmc
= find_mmc_device(curr_device
);
1045 printf("no mmc device at slot %x\n", curr_device
);
1046 return CMD_RET_FAILURE
;
1048 ret
= mmc_set_dsr(mmc
, val
);
1049 printf("set dsr %s\n", (!ret
) ? "OK, force rescan" : "ERROR");
1053 return CMD_RET_FAILURE
;
1055 return CMD_RET_SUCCESS
;
1060 #ifdef CONFIG_CMD_BKOPS_ENABLE
1061 static int mmc_bkops_common(char *device
, bool autobkops
, bool enable
)
1066 dev
= dectoul(device
, NULL
);
1068 mmc
= init_mmc_device(dev
, false);
1070 return CMD_RET_FAILURE
;
1073 puts("BKOPS_EN only exists on eMMC\n");
1074 return CMD_RET_FAILURE
;
1077 return mmc_set_bkops_enable(mmc
, autobkops
, enable
);
1080 static int do_mmc_bkops(struct cmd_tbl
*cmdtp
, int flag
,
1081 int argc
, char * const argv
[])
1083 bool autobkops
, enable
;
1086 return CMD_RET_USAGE
;
1088 if (!strcmp(argv
[2], "manual"))
1090 else if (!strcmp(argv
[2], "auto"))
1093 return CMD_RET_FAILURE
;
1095 if (!strcmp(argv
[3], "disable"))
1097 else if (!strcmp(argv
[3], "enable"))
1100 return CMD_RET_FAILURE
;
1102 return mmc_bkops_common(argv
[1], autobkops
, enable
);
1105 static int do_mmc_bkops_enable(struct cmd_tbl
*cmdtp
, int flag
,
1106 int argc
, char * const argv
[])
1109 return CMD_RET_USAGE
;
1111 return mmc_bkops_common(argv
[1], false, true);
1115 static int do_mmc_boot_wp(struct cmd_tbl
*cmdtp
, int flag
,
1116 int argc
, char * const argv
[])
1122 mmc
= init_mmc_device(curr_device
, false);
1124 return CMD_RET_FAILURE
;
1126 printf("It is not an eMMC device\n");
1127 return CMD_RET_FAILURE
;
1131 part
= dectoul(argv
[1], NULL
);
1132 err
= mmc_boot_wp_single_partition(mmc
, part
);
1134 err
= mmc_boot_wp(mmc
);
1138 return CMD_RET_FAILURE
;
1139 printf("boot areas protected\n");
1140 return CMD_RET_SUCCESS
;
1143 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1144 static int do_mmc_reg(struct cmd_tbl
*cmdtp
, int flag
,
1145 int argc
, char *const argv
[])
1147 ALLOC_CACHE_ALIGN_BUFFER(u8
, ext_csd
, MMC_MAX_BLOCK_LEN
);
1152 if (argc
< 3 || argc
> 5)
1153 return CMD_RET_USAGE
;
1155 mmc
= find_mmc_device(curr_device
);
1157 printf("no mmc device at slot %x\n", curr_device
);
1158 return CMD_RET_FAILURE
;
1162 printf("SD registers are not supported\n");
1163 return CMD_RET_FAILURE
;
1166 off
= simple_strtoul(argv
[3], NULL
, 10);
1167 if (!strcmp(argv
[2], "cid")) {
1169 return CMD_RET_USAGE
;
1170 printf("CID[%i]: 0x%08x\n", off
, mmc
->cid
[off
]);
1172 env_set_hex(argv
[4], mmc
->cid
[off
]);
1173 return CMD_RET_SUCCESS
;
1175 if (!strcmp(argv
[2], "csd")) {
1177 return CMD_RET_USAGE
;
1178 printf("CSD[%i]: 0x%08x\n", off
, mmc
->csd
[off
]);
1180 env_set_hex(argv
[4], mmc
->csd
[off
]);
1181 return CMD_RET_SUCCESS
;
1183 if (!strcmp(argv
[2], "dsr")) {
1184 printf("DSR: 0x%08x\n", mmc
->dsr
);
1186 env_set_hex(argv
[4], mmc
->dsr
);
1187 return CMD_RET_SUCCESS
;
1189 if (!strcmp(argv
[2], "ocr")) {
1190 printf("OCR: 0x%08x\n", mmc
->ocr
);
1192 env_set_hex(argv
[4], mmc
->ocr
);
1193 return CMD_RET_SUCCESS
;
1195 if (!strcmp(argv
[2], "rca")) {
1196 printf("RCA: 0x%08x\n", mmc
->rca
);
1198 env_set_hex(argv
[4], mmc
->rca
);
1199 return CMD_RET_SUCCESS
;
1201 if (!strcmp(argv
[2], "extcsd") &&
1202 mmc
->version
>= MMC_VERSION_4_41
) {
1203 ret
= mmc_send_ext_csd(mmc
, ext_csd
);
1205 return CMD_RET_FAILURE
;
1206 if (!strcmp(argv
[3], "all")) {
1207 /* Dump the entire register */
1209 for (i
= 0; i
< MMC_MAX_BLOCK_LEN
; i
++) {
1211 printf("\n%03i: ", i
);
1212 printf(" %02x", ext_csd
[i
]);
1215 return CMD_RET_SUCCESS
;
1217 off
= simple_strtoul(argv
[3], NULL
, 10);
1219 return CMD_RET_USAGE
;
1220 printf("EXT_CSD[%i]: 0x%02x\n", off
, ext_csd
[off
]);
1222 env_set_hex(argv
[4], ext_csd
[off
]);
1223 return CMD_RET_SUCCESS
;
1226 return CMD_RET_FAILURE
;
1230 static struct cmd_tbl cmd_mmc
[] = {
1231 U_BOOT_CMD_MKENT(info
, 1, 0, do_mmcinfo
, "", ""),
1232 U_BOOT_CMD_MKENT(read
, 4, 1, do_mmc_read
, "", ""),
1233 U_BOOT_CMD_MKENT(wp
, 2, 0, do_mmc_boot_wp
, "", ""),
1234 #if CONFIG_IS_ENABLED(MMC_WRITE)
1235 U_BOOT_CMD_MKENT(write
, 4, 0, do_mmc_write
, "", ""),
1236 U_BOOT_CMD_MKENT(erase
, 3, 0, do_mmc_erase
, "", ""),
1238 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1239 U_BOOT_CMD_MKENT(swrite
, 3, 0, do_mmc_sparse_write
, "", ""),
1241 U_BOOT_CMD_MKENT(rescan
, 2, 1, do_mmc_rescan
, "", ""),
1242 U_BOOT_CMD_MKENT(part
, 1, 1, do_mmc_part
, "", ""),
1243 U_BOOT_CMD_MKENT(dev
, 4, 0, do_mmc_dev
, "", ""),
1244 U_BOOT_CMD_MKENT(list
, 1, 1, do_mmc_list
, "", ""),
1245 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1246 U_BOOT_CMD_MKENT(hwpartition
, 28, 0, do_mmc_hwpartition
, "", ""),
1248 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1249 U_BOOT_CMD_MKENT(bootbus
, 5, 0, do_mmc_bootbus
, "", ""),
1250 U_BOOT_CMD_MKENT(bootpart
-resize
, 4, 0, do_mmc_boot_resize
, "", ""),
1251 U_BOOT_CMD_MKENT(partconf
, 5, 0, do_mmc_partconf
, "", ""),
1252 U_BOOT_CMD_MKENT(rst
-function
, 3, 0, do_mmc_rst_func
, "", ""),
1254 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1255 U_BOOT_CMD_MKENT(rpmb
, CONFIG_SYS_MAXARGS
, 1, do_mmcrpmb
, "", ""),
1257 U_BOOT_CMD_MKENT(setdsr
, 2, 0, do_mmc_setdsr
, "", ""),
1258 #ifdef CONFIG_CMD_BKOPS_ENABLE
1259 U_BOOT_CMD_MKENT(bkops
-enable
, 2, 0, do_mmc_bkops_enable
, "", ""),
1260 U_BOOT_CMD_MKENT(bkops
, 4, 0, do_mmc_bkops
, "", ""),
1262 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1263 U_BOOT_CMD_MKENT(reg
, 5, 0, do_mmc_reg
, "", ""),
1267 static int do_mmcops(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
1272 cp
= find_cmd_tbl(argv
[1], cmd_mmc
, ARRAY_SIZE(cmd_mmc
));
1274 /* Drop the mmc command */
1278 if (cp
== NULL
|| argc
> cp
->maxargs
)
1279 return CMD_RET_USAGE
;
1280 if (flag
== CMD_FLAG_REPEAT
&& !cmd_is_repeatable(cp
))
1281 return CMD_RET_SUCCESS
;
1283 if (curr_device
< 0) {
1284 if (get_mmc_num() > 0) {
1287 puts("No MMC device available\n");
1288 return CMD_RET_FAILURE
;
1291 return cp
->cmd(cmdtp
, flag
, argc
, argv
);
1295 mmc
, 29, 1, do_mmcops
,
1297 "info - display info of the current MMC device\n"
1298 "mmc read addr blk# cnt\n"
1299 "mmc write addr blk# cnt\n"
1300 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1301 "mmc swrite addr blk#\n"
1303 "mmc erase blk# cnt\n"
1304 "mmc erase partname\n"
1305 "mmc rescan [mode]\n"
1306 "mmc part - lists available partition on current mmc device\n"
1307 "mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode\n"
1308 " - the required speed mode is passed as the index from the following list\n"
1309 " [MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25,\n"
1310 " UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES]\n"
1311 "mmc list - lists available devices\n"
1312 "mmc wp [PART] - power on write protect boot partitions\n"
1315 " : 0 - first boot partition, 1 - second boot partition\n"
1316 " if not assigned, write protect all boot partitions\n"
1317 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1318 "mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning\n"
1319 " arguments (sizes in 512-byte blocks):\n"
1320 " USER - <user> <enh> <start> <cnt> <wrrel> <{on|off}>\n"
1321 " : sets user data area attributes\n"
1322 " GP - <{gp1|gp2|gp3|gp4}> <cnt> <enh> <wrrel> <{on|off}>\n"
1323 " : general purpose partition\n"
1324 " MODE - <{check|set|complete}>\n"
1325 " : mode, complete set partitioning completed\n"
1326 " WARNING: Partitioning is a write-once setting once it is set to complete.\n"
1327 " Power cycling is required to initialize partitions after set to complete.\n"
1329 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1330 "mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode>\n"
1331 " - Set the BOOT_BUS_WIDTH field of the specified device\n"
1332 "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
1333 " - Change sizes of boot and RPMB partitions of specified device\n"
1334 "mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]]\n"
1335 " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n"
1336 " If showing the bits, optionally store the boot_partition field into varname\n"
1337 "mmc rst-function <dev> <value>\n"
1338 " - Change the RST_n_FUNCTION field of the specified device\n"
1339 " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
1341 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1342 "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
1343 "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
1344 "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"
1345 "mmc rpmb counter - read the value of the write counter\n"
1347 "mmc setdsr <value> - set DSR register value\n"
1348 #ifdef CONFIG_CMD_BKOPS_ENABLE
1349 "mmc bkops-enable <dev> - enable background operations handshake on device\n"
1350 " WARNING: This is a write-once setting.\n"
1351 "mmc bkops <dev> [auto|manual] [enable|disable]\n"
1352 " - configure background operations handshake on device\n"
1354 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1355 "mmc reg read <reg> <offset> [env] - read card register <reg> offset <offset>\n"
1356 " (optionally into [env] variable)\n"
1357 " - reg: cid/csd/dsr/ocr/rca/extcsd\n"
1358 " - offset: for cid/csd [0..3], for extcsd [0..511,all]\n"
1362 /* Old command kept for compatibility. Same as 'mmc info' */
1364 mmcinfo
, 1, 0, do_mmcinfo
,
1366 "- display info of the current MMC device"