1 // SPDX-License-Identifier: GPL-2.0+
4 * Kyle Harris, kharris@nexus-tech.net
11 #include <display_options.h>
15 #include <sparse_format.h>
16 #include <image-sparse.h>
18 static int curr_device
= -1;
20 static void print_mmcinfo(struct mmc
*mmc
)
24 printf("Device: %s\n", mmc
->cfg
->name
);
25 printf("Manufacturer ID: %x\n", mmc
->cid
[0] >> 24);
27 printf("OEM: %x\n", (mmc
->cid
[0] >> 8) & 0xffff);
28 printf("Name: %c%c%c%c%c \n", mmc
->cid
[0] & 0xff,
29 (mmc
->cid
[1] >> 24), (mmc
->cid
[1] >> 16) & 0xff,
30 (mmc
->cid
[1] >> 8) & 0xff, mmc
->cid
[1] & 0xff);
32 printf("OEM: %x\n", (mmc
->cid
[0] >> 8) & 0xff);
33 printf("Name: %c%c%c%c%c%c \n", mmc
->cid
[0] & 0xff,
34 (mmc
->cid
[1] >> 24), (mmc
->cid
[1] >> 16) & 0xff,
35 (mmc
->cid
[1] >> 8) & 0xff, mmc
->cid
[1] & 0xff,
39 printf("Bus Speed: %d\n", mmc
->clock
);
40 #if CONFIG_IS_ENABLED(MMC_VERBOSE)
41 printf("Mode: %s\n", mmc_mode_name(mmc
->selected_mode
));
42 mmc_dump_capabilities("card capabilities", mmc
->card_caps
);
43 mmc_dump_capabilities("host capabilities", mmc
->host_caps
);
45 printf("Rd Block Len: %d\n", mmc
->read_bl_len
);
47 printf("%s version %d.%d", IS_SD(mmc
) ? "SD" : "MMC",
48 EXTRACT_SDMMC_MAJOR_VERSION(mmc
->version
),
49 EXTRACT_SDMMC_MINOR_VERSION(mmc
->version
));
50 if (EXTRACT_SDMMC_CHANGE_VERSION(mmc
->version
) != 0)
51 printf(".%d", EXTRACT_SDMMC_CHANGE_VERSION(mmc
->version
));
54 printf("High Capacity: %s\n", mmc
->high_capacity
? "Yes" : "No");
56 print_size(mmc
->capacity
, "\n");
58 printf("Bus Width: %d-bit%s\n", mmc
->bus_width
,
59 mmc
->ddr_mode
? " DDR" : "");
61 #if CONFIG_IS_ENABLED(MMC_WRITE)
62 puts("Erase Group Size: ");
63 print_size(((u64
)mmc
->erase_grp_size
) << 9, "\n");
66 if (!IS_SD(mmc
) && mmc
->version
>= MMC_VERSION_4_41
) {
67 bool has_enh
= (mmc
->part_support
& ENHNCD_SUPPORT
) != 0;
68 bool usr_enh
= has_enh
&& (mmc
->part_attr
& EXT_CSD_ENH_USR
);
69 ALLOC_CACHE_ALIGN_BUFFER(u8
, ext_csd
, MMC_MAX_BLOCK_LEN
);
73 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
74 puts("HC WP Group Size: ");
75 print_size(((u64
)mmc
->hc_wp_grp_size
) << 9, "\n");
78 puts("User Capacity: ");
79 print_size(mmc
->capacity_user
, usr_enh
? " ENH" : "");
80 if (mmc
->wr_rel_set
& EXT_CSD_WR_DATA_REL_USR
)
85 puts("User Enhanced Start: ");
86 print_size(mmc
->enh_user_start
, "\n");
87 puts("User Enhanced Size: ");
88 print_size(mmc
->enh_user_size
, "\n");
90 puts("Boot Capacity: ");
91 print_size(mmc
->capacity_boot
, has_enh
? " ENH\n" : "\n");
92 puts("RPMB Capacity: ");
93 print_size(mmc
->capacity_rpmb
, has_enh
? " ENH\n" : "\n");
95 for (i
= 0; i
< ARRAY_SIZE(mmc
->capacity_gp
); i
++) {
96 bool is_enh
= has_enh
&&
97 (mmc
->part_attr
& EXT_CSD_ENH_GP(i
));
98 if (mmc
->capacity_gp
[i
]) {
99 printf("GP%i Capacity: ", i
+1);
100 print_size(mmc
->capacity_gp
[i
],
101 is_enh
? " ENH" : "");
102 if (mmc
->wr_rel_set
& EXT_CSD_WR_DATA_REL_GP(i
))
108 ret
= mmc_send_ext_csd(mmc
, ext_csd
);
111 wp
= ext_csd
[EXT_CSD_BOOT_WP_STATUS
];
112 for (i
= 0; i
< 2; ++i
) {
113 printf("Boot area %d is ", i
);
116 printf("not write protected\n");
119 printf("power on protected\n");
122 printf("permanently protected\n");
125 printf("in reserved protection state\n");
133 static struct mmc
*__init_mmc_device(int dev
, bool force_init
,
134 enum bus_mode speed_mode
)
137 mmc
= find_mmc_device(dev
);
139 printf("no mmc device at slot %x\n", dev
);
149 if (IS_ENABLED(CONFIG_MMC_SPEED_MODE_SET
))
150 mmc
->user_speed_mode
= speed_mode
;
155 #ifdef CONFIG_BLOCK_CACHE
156 struct blk_desc
*bd
= mmc_get_blk_desc(mmc
);
157 blkcache_invalidate(bd
->uclass_id
, bd
->devnum
);
163 static struct mmc
*init_mmc_device(int dev
, bool force_init
)
165 return __init_mmc_device(dev
, force_init
, MMC_MODES_END
);
168 static int do_mmcinfo(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
173 if (curr_device
< 0) {
174 if (get_mmc_num() > 0)
177 puts("No MMC device available\n");
178 return CMD_RET_FAILURE
;
182 mmc
= init_mmc_device(curr_device
, false);
184 return CMD_RET_FAILURE
;
187 return CMD_RET_SUCCESS
;
190 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
191 static int confirm_key_prog(void)
193 puts("Warning: Programming authentication key can be done only once !\n"
194 " Use this command only if you are sure of what you are doing,\n"
195 "Really perform the key programming? <y/N> ");
199 puts("Authentication key programming aborted\n");
203 static int do_mmcrpmb_key(struct cmd_tbl
*cmdtp
, int flag
,
204 int argc
, char *const argv
[])
207 struct mmc
*mmc
= find_mmc_device(curr_device
);
210 return CMD_RET_USAGE
;
212 key_addr
= (void *)hextoul(argv
[1], NULL
);
213 if (!confirm_key_prog())
214 return CMD_RET_FAILURE
;
215 if (mmc_rpmb_set_key(mmc
, key_addr
)) {
216 printf("ERROR - Key already programmed ?\n");
217 return CMD_RET_FAILURE
;
219 return CMD_RET_SUCCESS
;
222 static int do_mmcrpmb_read(struct cmd_tbl
*cmdtp
, int flag
,
223 int argc
, char *const argv
[])
228 void *key_addr
= NULL
;
229 struct mmc
*mmc
= find_mmc_device(curr_device
);
232 return CMD_RET_USAGE
;
234 addr
= (void *)hextoul(argv
[1], NULL
);
235 blk
= hextoul(argv
[2], NULL
);
236 cnt
= hextoul(argv
[3], NULL
);
239 key_addr
= (void *)hextoul(argv
[4], NULL
);
241 printf("\nMMC RPMB read: dev # %d, block # %d, count %d ... ",
242 curr_device
, blk
, cnt
);
243 n
= mmc_rpmb_read(mmc
, addr
, blk
, cnt
, key_addr
);
245 printf("%d RPMB blocks read: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
247 return CMD_RET_FAILURE
;
248 return CMD_RET_SUCCESS
;
251 static int do_mmcrpmb_write(struct cmd_tbl
*cmdtp
, int flag
,
252 int argc
, char *const argv
[])
258 struct mmc
*mmc
= find_mmc_device(curr_device
);
261 return CMD_RET_USAGE
;
263 addr
= (void *)hextoul(argv
[1], NULL
);
264 blk
= hextoul(argv
[2], NULL
);
265 cnt
= hextoul(argv
[3], NULL
);
266 key_addr
= (void *)hextoul(argv
[4], NULL
);
268 printf("\nMMC RPMB write: dev # %d, block # %d, count %d ... ",
269 curr_device
, blk
, cnt
);
270 n
= mmc_rpmb_write(mmc
, addr
, blk
, cnt
, key_addr
);
272 printf("%d RPMB blocks written: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
274 return CMD_RET_FAILURE
;
275 return CMD_RET_SUCCESS
;
278 static int do_mmcrpmb_counter(struct cmd_tbl
*cmdtp
, int flag
,
279 int argc
, char *const argv
[])
281 unsigned long counter
;
282 struct mmc
*mmc
= find_mmc_device(curr_device
);
284 if (mmc_rpmb_get_counter(mmc
, &counter
))
285 return CMD_RET_FAILURE
;
286 printf("RPMB Write counter= %lx\n", counter
);
287 return CMD_RET_SUCCESS
;
290 static struct cmd_tbl cmd_rpmb
[] = {
291 U_BOOT_CMD_MKENT(key
, 2, 0, do_mmcrpmb_key
, "", ""),
292 U_BOOT_CMD_MKENT(read
, 5, 1, do_mmcrpmb_read
, "", ""),
293 U_BOOT_CMD_MKENT(write
, 5, 0, do_mmcrpmb_write
, "", ""),
294 U_BOOT_CMD_MKENT(counter
, 1, 1, do_mmcrpmb_counter
, "", ""),
297 static int do_mmcrpmb(struct cmd_tbl
*cmdtp
, int flag
,
298 int argc
, char *const argv
[])
305 cp
= find_cmd_tbl(argv
[1], cmd_rpmb
, ARRAY_SIZE(cmd_rpmb
));
307 /* Drop the rpmb subcommand */
311 if (cp
== NULL
|| argc
> cp
->maxargs
)
312 return CMD_RET_USAGE
;
313 if (flag
== CMD_FLAG_REPEAT
&& !cmd_is_repeatable(cp
))
314 return CMD_RET_SUCCESS
;
316 mmc
= init_mmc_device(curr_device
, false);
318 return CMD_RET_FAILURE
;
320 if (!(mmc
->version
& MMC_VERSION_MMC
)) {
321 printf("It is not an eMMC device\n");
322 return CMD_RET_FAILURE
;
324 if (mmc
->version
< MMC_VERSION_4_41
) {
325 printf("RPMB not supported before version 4.41\n");
326 return CMD_RET_FAILURE
;
328 /* Switch to the RPMB partition */
330 original_part
= mmc
->block_dev
.hwpart
;
332 original_part
= mmc_get_blk_desc(mmc
)->hwpart
;
334 if (blk_select_hwpart_devnum(UCLASS_MMC
, curr_device
, MMC_PART_RPMB
) !=
336 return CMD_RET_FAILURE
;
337 ret
= cp
->cmd(cmdtp
, flag
, argc
, argv
);
339 /* Return to original partition */
340 if (blk_select_hwpart_devnum(UCLASS_MMC
, curr_device
, original_part
) !=
342 return CMD_RET_FAILURE
;
347 static int do_mmc_read(struct cmd_tbl
*cmdtp
, int flag
,
348 int argc
, char *const argv
[])
355 return CMD_RET_USAGE
;
357 addr
= (void *)hextoul(argv
[1], NULL
);
358 blk
= hextoul(argv
[2], NULL
);
359 cnt
= hextoul(argv
[3], NULL
);
361 mmc
= init_mmc_device(curr_device
, false);
363 return CMD_RET_FAILURE
;
365 printf("\nMMC read: dev # %d, block # %d, count %d ... ",
366 curr_device
, blk
, cnt
);
368 n
= blk_dread(mmc_get_blk_desc(mmc
), blk
, cnt
, addr
);
369 printf("%d blocks read: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
371 return (n
== cnt
) ? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;
374 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
375 static lbaint_t
mmc_sparse_write(struct sparse_storage
*info
, lbaint_t blk
,
376 lbaint_t blkcnt
, const void *buffer
)
378 struct blk_desc
*dev_desc
= info
->priv
;
380 return blk_dwrite(dev_desc
, blk
, blkcnt
, buffer
);
383 static lbaint_t
mmc_sparse_reserve(struct sparse_storage
*info
,
384 lbaint_t blk
, lbaint_t blkcnt
)
389 static int do_mmc_sparse_write(struct cmd_tbl
*cmdtp
, int flag
,
390 int argc
, char *const argv
[])
392 struct sparse_storage sparse
;
393 struct blk_desc
*dev_desc
;
400 return CMD_RET_USAGE
;
402 addr
= (void *)hextoul(argv
[1], NULL
);
403 blk
= hextoul(argv
[2], NULL
);
405 if (!is_sparse_image(addr
)) {
406 printf("Not a sparse image\n");
407 return CMD_RET_FAILURE
;
410 mmc
= init_mmc_device(curr_device
, false);
412 return CMD_RET_FAILURE
;
414 printf("\nMMC Sparse write: dev # %d, block # %d ... ",
417 if (mmc_getwp(mmc
) == 1) {
418 printf("Error: card is write protected!\n");
419 return CMD_RET_FAILURE
;
422 dev_desc
= mmc_get_blk_desc(mmc
);
423 sparse
.priv
= dev_desc
;
426 sparse
.size
= dev_desc
->lba
- blk
;
427 sparse
.write
= mmc_sparse_write
;
428 sparse
.reserve
= mmc_sparse_reserve
;
430 sprintf(dest
, "0x" LBAF
, sparse
.start
* sparse
.blksz
);
432 if (write_sparse_image(&sparse
, dest
, addr
, NULL
))
433 return CMD_RET_FAILURE
;
435 return CMD_RET_SUCCESS
;
439 #if CONFIG_IS_ENABLED(MMC_WRITE)
440 static int do_mmc_write(struct cmd_tbl
*cmdtp
, int flag
,
441 int argc
, char *const argv
[])
448 return CMD_RET_USAGE
;
450 addr
= (void *)hextoul(argv
[1], NULL
);
451 blk
= hextoul(argv
[2], NULL
);
452 cnt
= hextoul(argv
[3], NULL
);
454 mmc
= init_mmc_device(curr_device
, false);
456 return CMD_RET_FAILURE
;
458 printf("\nMMC write: dev # %d, block # %d, count %d ... ",
459 curr_device
, blk
, cnt
);
461 if (mmc_getwp(mmc
) == 1) {
462 printf("Error: card is write protected!\n");
463 return CMD_RET_FAILURE
;
465 n
= blk_dwrite(mmc_get_blk_desc(mmc
), blk
, cnt
, addr
);
466 printf("%d blocks written: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
468 return (n
== cnt
) ? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;
471 static int do_mmc_erase(struct cmd_tbl
*cmdtp
, int flag
,
472 int argc
, char *const argv
[])
478 return CMD_RET_USAGE
;
480 blk
= hextoul(argv
[1], NULL
);
481 cnt
= hextoul(argv
[2], NULL
);
483 mmc
= init_mmc_device(curr_device
, false);
485 return CMD_RET_FAILURE
;
487 printf("\nMMC erase: dev # %d, block # %d, count %d ... ",
488 curr_device
, blk
, cnt
);
490 if (mmc_getwp(mmc
) == 1) {
491 printf("Error: card is write protected!\n");
492 return CMD_RET_FAILURE
;
494 n
= blk_derase(mmc_get_blk_desc(mmc
), blk
, cnt
);
495 printf("%d blocks erased: %s\n", n
, (n
== cnt
) ? "OK" : "ERROR");
497 return (n
== cnt
) ? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;
501 static int do_mmc_rescan(struct cmd_tbl
*cmdtp
, int flag
,
502 int argc
, char *const argv
[])
507 mmc
= init_mmc_device(curr_device
, true);
508 } else if (argc
== 2) {
509 enum bus_mode speed_mode
;
511 speed_mode
= (int)dectoul(argv
[1], NULL
);
512 mmc
= __init_mmc_device(curr_device
, true, speed_mode
);
514 return CMD_RET_USAGE
;
518 return CMD_RET_FAILURE
;
520 return CMD_RET_SUCCESS
;
523 static int do_mmc_part(struct cmd_tbl
*cmdtp
, int flag
,
524 int argc
, char *const argv
[])
526 struct blk_desc
*mmc_dev
;
529 mmc
= init_mmc_device(curr_device
, false);
531 return CMD_RET_FAILURE
;
533 mmc_dev
= blk_get_devnum_by_uclass_id(UCLASS_MMC
, curr_device
);
534 if (mmc_dev
!= NULL
&& mmc_dev
->type
!= DEV_TYPE_UNKNOWN
) {
536 return CMD_RET_SUCCESS
;
539 puts("get mmc type error!\n");
540 return CMD_RET_FAILURE
;
543 static int do_mmc_dev(struct cmd_tbl
*cmdtp
, int flag
,
544 int argc
, char *const argv
[])
546 int dev
, part
= 0, ret
;
551 mmc
= init_mmc_device(dev
, true);
552 } else if (argc
== 2) {
553 dev
= (int)dectoul(argv
[1], NULL
);
554 mmc
= init_mmc_device(dev
, true);
555 } else if (argc
== 3) {
556 dev
= (int)dectoul(argv
[1], NULL
);
557 part
= (int)dectoul(argv
[2], NULL
);
558 if (part
> PART_ACCESS_MASK
) {
559 printf("#part_num shouldn't be larger than %d\n",
561 return CMD_RET_FAILURE
;
563 mmc
= init_mmc_device(dev
, true);
564 } else if (argc
== 4) {
565 enum bus_mode speed_mode
;
567 dev
= (int)dectoul(argv
[1], NULL
);
568 part
= (int)dectoul(argv
[2], NULL
);
569 if (part
> PART_ACCESS_MASK
) {
570 printf("#part_num shouldn't be larger than %d\n",
572 return CMD_RET_FAILURE
;
574 speed_mode
= (int)dectoul(argv
[3], NULL
);
575 mmc
= __init_mmc_device(dev
, true, speed_mode
);
577 return CMD_RET_USAGE
;
581 return CMD_RET_FAILURE
;
583 ret
= blk_select_hwpart_devnum(UCLASS_MMC
, dev
, part
);
584 printf("switch to partitions #%d, %s\n",
585 part
, (!ret
) ? "OK" : "ERROR");
590 if (mmc
->part_config
== MMCPART_NOAVAILABLE
)
591 printf("mmc%d is current device\n", curr_device
);
593 printf("mmc%d(part %d) is current device\n",
594 curr_device
, mmc_get_blk_desc(mmc
)->hwpart
);
596 return CMD_RET_SUCCESS
;
599 static int do_mmc_list(struct cmd_tbl
*cmdtp
, int flag
,
600 int argc
, char *const argv
[])
602 print_mmc_devices('\n');
603 return CMD_RET_SUCCESS
;
606 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
607 static void parse_hwpart_user_enh_size(struct mmc
*mmc
,
608 struct mmc_hwpart_conf
*pconf
,
613 pconf
->user
.enh_size
= 0;
615 if (!strcmp(argv
, "-")) { /* The rest of eMMC */
616 ALLOC_CACHE_ALIGN_BUFFER(u8
, ext_csd
, MMC_MAX_BLOCK_LEN
);
617 ret
= mmc_send_ext_csd(mmc
, ext_csd
);
620 /* The enh_size value is in 512B block units */
621 pconf
->user
.enh_size
=
622 ((ext_csd
[EXT_CSD_MAX_ENH_SIZE_MULT
+ 2] << 16) +
623 (ext_csd
[EXT_CSD_MAX_ENH_SIZE_MULT
+ 1] << 8) +
624 ext_csd
[EXT_CSD_MAX_ENH_SIZE_MULT
]) * 1024 *
625 ext_csd
[EXT_CSD_HC_ERASE_GRP_SIZE
] *
626 ext_csd
[EXT_CSD_HC_WP_GRP_SIZE
];
627 pconf
->user
.enh_size
-= pconf
->user
.enh_start
;
628 for (i
= 0; i
< ARRAY_SIZE(mmc
->capacity_gp
); i
++) {
630 * If the eMMC already has GP partitions set,
631 * subtract their size from the maximum USER
634 * Else, if the command was used to configure new
635 * GP partitions, subtract their size from maximum
636 * USER partition size.
638 if (mmc
->capacity_gp
[i
]) {
639 /* The capacity_gp is in 1B units */
640 pconf
->user
.enh_size
-= mmc
->capacity_gp
[i
] >> 9;
641 } else if (pconf
->gp_part
[i
].size
) {
642 /* The gp_part[].size is in 512B units */
643 pconf
->user
.enh_size
-= pconf
->gp_part
[i
].size
;
647 pconf
->user
.enh_size
= dectoul(argv
, NULL
);
651 static int parse_hwpart_user(struct mmc
*mmc
, struct mmc_hwpart_conf
*pconf
,
652 int argc
, char *const argv
[])
656 memset(&pconf
->user
, 0, sizeof(pconf
->user
));
659 if (!strcmp(argv
[i
], "enh")) {
662 pconf
->user
.enh_start
=
663 dectoul(argv
[i
+ 1], NULL
);
664 parse_hwpart_user_enh_size(mmc
, pconf
, argv
[i
+ 2]);
666 } else if (!strcmp(argv
[i
], "wrrel")) {
669 pconf
->user
.wr_rel_change
= 1;
670 if (!strcmp(argv
[i
+1], "on"))
671 pconf
->user
.wr_rel_set
= 1;
672 else if (!strcmp(argv
[i
+1], "off"))
673 pconf
->user
.wr_rel_set
= 0;
684 static int parse_hwpart_gp(struct mmc_hwpart_conf
*pconf
, int pidx
,
685 int argc
, char *const argv
[])
689 memset(&pconf
->gp_part
[pidx
], 0, sizeof(pconf
->gp_part
[pidx
]));
693 pconf
->gp_part
[pidx
].size
= dectoul(argv
[0], NULL
);
697 if (!strcmp(argv
[i
], "enh")) {
698 pconf
->gp_part
[pidx
].enhanced
= 1;
700 } else if (!strcmp(argv
[i
], "wrrel")) {
703 pconf
->gp_part
[pidx
].wr_rel_change
= 1;
704 if (!strcmp(argv
[i
+1], "on"))
705 pconf
->gp_part
[pidx
].wr_rel_set
= 1;
706 else if (!strcmp(argv
[i
+1], "off"))
707 pconf
->gp_part
[pidx
].wr_rel_set
= 0;
718 static int do_mmc_hwpartition(struct cmd_tbl
*cmdtp
, int flag
,
719 int argc
, char *const argv
[])
722 struct mmc_hwpart_conf pconf
= { };
723 enum mmc_hwpart_conf_mode mode
= MMC_HWPART_CONF_CHECK
;
726 mmc
= init_mmc_device(curr_device
, false);
728 return CMD_RET_FAILURE
;
731 puts("SD doesn't support partitioning\n");
732 return CMD_RET_FAILURE
;
736 return CMD_RET_USAGE
;
739 if (!strcmp(argv
[i
], "user")) {
741 r
= parse_hwpart_user(mmc
, &pconf
, argc
- i
, &argv
[i
]);
743 return CMD_RET_USAGE
;
745 } else if (!strncmp(argv
[i
], "gp", 2) &&
746 strlen(argv
[i
]) == 3 &&
747 argv
[i
][2] >= '1' && argv
[i
][2] <= '4') {
748 pidx
= argv
[i
][2] - '1';
750 r
= parse_hwpart_gp(&pconf
, pidx
, argc
-i
, &argv
[i
]);
752 return CMD_RET_USAGE
;
754 } else if (!strcmp(argv
[i
], "check")) {
755 mode
= MMC_HWPART_CONF_CHECK
;
757 } else if (!strcmp(argv
[i
], "set")) {
758 mode
= MMC_HWPART_CONF_SET
;
760 } else if (!strcmp(argv
[i
], "complete")) {
761 mode
= MMC_HWPART_CONF_COMPLETE
;
764 return CMD_RET_USAGE
;
768 puts("Partition configuration:\n");
769 if (pconf
.user
.enh_size
) {
770 puts("\tUser Enhanced Start: ");
771 print_size(((u64
)pconf
.user
.enh_start
) << 9, "\n");
772 puts("\tUser Enhanced Size: ");
773 print_size(((u64
)pconf
.user
.enh_size
) << 9, "\n");
775 puts("\tNo enhanced user data area\n");
777 if (pconf
.user
.wr_rel_change
)
778 printf("\tUser partition write reliability: %s\n",
779 pconf
.user
.wr_rel_set
? "on" : "off");
780 for (pidx
= 0; pidx
< 4; pidx
++) {
781 if (pconf
.gp_part
[pidx
].size
) {
782 printf("\tGP%i Capacity: ", pidx
+1);
783 print_size(((u64
)pconf
.gp_part
[pidx
].size
) << 9,
784 pconf
.gp_part
[pidx
].enhanced
?
787 printf("\tNo GP%i partition\n", pidx
+1);
789 if (pconf
.gp_part
[pidx
].wr_rel_change
)
790 printf("\tGP%i write reliability: %s\n", pidx
+1,
791 pconf
.gp_part
[pidx
].wr_rel_set
? "on" : "off");
794 if (!mmc_hwpart_config(mmc
, &pconf
, mode
)) {
795 if (mode
== MMC_HWPART_CONF_COMPLETE
)
796 puts("Partitioning successful, "
797 "power-cycle to make effective\n");
798 return CMD_RET_SUCCESS
;
801 return CMD_RET_FAILURE
;
806 #ifdef CONFIG_SUPPORT_EMMC_BOOT
807 static int do_mmc_bootbus(struct cmd_tbl
*cmdtp
, int flag
,
808 int argc
, char *const argv
[])
812 u8 width
, reset
, mode
;
815 return CMD_RET_USAGE
;
816 dev
= dectoul(argv
[1], NULL
);
817 width
= dectoul(argv
[2], NULL
);
818 reset
= dectoul(argv
[3], NULL
);
819 mode
= dectoul(argv
[4], NULL
);
821 mmc
= init_mmc_device(dev
, false);
823 return CMD_RET_FAILURE
;
826 puts("BOOT_BUS_WIDTH only exists on eMMC\n");
827 return CMD_RET_FAILURE
;
831 * BOOT_BUS_CONDITIONS[177]
833 * 0x0 : Use SDR + Backward compatible timing in boot operation
834 * 0x1 : Use SDR + High Speed Timing in boot operation mode
835 * 0x2 : Use DDR in boot operation
836 * RESET_BOOT_BUS_CONDITIONS
837 * 0x0 : Reset bus width to x1, SDR, Backward compatible
838 * 0x1 : Retain BOOT_BUS_WIDTH and BOOT_MODE
840 * 0x0 : x1(sdr) or x4 (ddr) buswidth
841 * 0x1 : x4(sdr/ddr) buswith
842 * 0x2 : x8(sdr/ddr) buswith
846 printf("boot_bus_width %d is invalid\n", width
);
847 return CMD_RET_FAILURE
;
851 printf("reset_boot_bus_width %d is invalid\n", reset
);
852 return CMD_RET_FAILURE
;
856 printf("reset_boot_bus_width %d is invalid\n", mode
);
857 return CMD_RET_FAILURE
;
860 /* acknowledge to be sent during boot operation */
861 if (mmc_set_boot_bus_width(mmc
, width
, reset
, mode
)) {
862 puts("BOOT_BUS_WIDTH is failed to change.\n");
863 return CMD_RET_FAILURE
;
866 printf("Set to BOOT_BUS_WIDTH = 0x%x, RESET = 0x%x, BOOT_MODE = 0x%x\n",
868 return CMD_RET_SUCCESS
;
871 static int do_mmc_boot_resize(struct cmd_tbl
*cmdtp
, int flag
,
872 int argc
, char *const argv
[])
876 u32 bootsize
, rpmbsize
;
879 return CMD_RET_USAGE
;
880 dev
= dectoul(argv
[1], NULL
);
881 bootsize
= dectoul(argv
[2], NULL
);
882 rpmbsize
= dectoul(argv
[3], NULL
);
884 mmc
= init_mmc_device(dev
, false);
886 return CMD_RET_FAILURE
;
889 printf("It is not an eMMC device\n");
890 return CMD_RET_FAILURE
;
893 if (mmc_boot_partition_size_change(mmc
, bootsize
, rpmbsize
)) {
894 printf("EMMC boot partition Size change Failed.\n");
895 return CMD_RET_FAILURE
;
898 printf("EMMC boot partition Size %d MB\n", bootsize
);
899 printf("EMMC RPMB partition Size %d MB\n", rpmbsize
);
900 return CMD_RET_SUCCESS
;
903 static int mmc_partconf_print(struct mmc
*mmc
, const char *varname
)
905 u8 ack
, access
, part
;
907 if (mmc
->part_config
== MMCPART_NOAVAILABLE
) {
908 printf("No part_config info for ver. 0x%x\n", mmc
->version
);
909 return CMD_RET_FAILURE
;
912 access
= EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc
->part_config
);
913 ack
= EXT_CSD_EXTRACT_BOOT_ACK(mmc
->part_config
);
914 part
= EXT_CSD_EXTRACT_BOOT_PART(mmc
->part_config
);
917 env_set_hex(varname
, part
);
919 printf("EXT_CSD[179], PARTITION_CONFIG:\n"
921 "BOOT_PARTITION_ENABLE: 0x%x\n"
922 "PARTITION_ACCESS: 0x%x\n", ack
, part
, access
);
924 return CMD_RET_SUCCESS
;
927 static int do_mmc_partconf(struct cmd_tbl
*cmdtp
, int flag
,
928 int argc
, char *const argv
[])
932 u8 ack
, part_num
, access
;
934 if (argc
!= 2 && argc
!= 3 && argc
!= 5)
935 return CMD_RET_USAGE
;
937 dev
= dectoul(argv
[1], NULL
);
939 mmc
= init_mmc_device(dev
, false);
941 return CMD_RET_FAILURE
;
944 puts("PARTITION_CONFIG only exists on eMMC\n");
945 return CMD_RET_FAILURE
;
948 if (argc
== 2 || argc
== 3)
949 return mmc_partconf_print(mmc
, cmd_arg2(argc
, argv
));
951 ack
= dectoul(argv
[2], NULL
);
952 part_num
= dectoul(argv
[3], NULL
);
953 access
= dectoul(argv
[4], NULL
);
955 /* acknowledge to be sent during boot operation */
956 ret
= mmc_set_part_conf(mmc
, ack
, part_num
, access
);
958 return CMD_RET_FAILURE
;
960 return CMD_RET_SUCCESS
;
963 static int do_mmc_rst_func(struct cmd_tbl
*cmdtp
, int flag
,
964 int argc
, char *const argv
[])
971 * Set the RST_n_ENABLE bit of RST_n_FUNCTION
972 * The only valid values are 0x0, 0x1 and 0x2 and writing
973 * a value of 0x1 or 0x2 sets the value permanently.
976 return CMD_RET_USAGE
;
978 dev
= dectoul(argv
[1], NULL
);
979 enable
= dectoul(argv
[2], NULL
);
982 puts("Invalid RST_n_ENABLE value\n");
983 return CMD_RET_USAGE
;
986 mmc
= init_mmc_device(dev
, false);
988 return CMD_RET_FAILURE
;
991 puts("RST_n_FUNCTION only exists on eMMC\n");
992 return CMD_RET_FAILURE
;
995 ret
= mmc_set_rst_n_function(mmc
, enable
);
997 return CMD_RET_FAILURE
;
999 return CMD_RET_SUCCESS
;
1002 static int do_mmc_setdsr(struct cmd_tbl
*cmdtp
, int flag
,
1003 int argc
, char *const argv
[])
1010 return CMD_RET_USAGE
;
1011 val
= hextoul(argv
[1], NULL
);
1013 mmc
= find_mmc_device(curr_device
);
1015 printf("no mmc device at slot %x\n", curr_device
);
1016 return CMD_RET_FAILURE
;
1018 ret
= mmc_set_dsr(mmc
, val
);
1019 printf("set dsr %s\n", (!ret
) ? "OK, force rescan" : "ERROR");
1023 return CMD_RET_FAILURE
;
1025 return CMD_RET_SUCCESS
;
1030 #ifdef CONFIG_CMD_BKOPS_ENABLE
1031 static int mmc_bkops_common(char *device
, bool autobkops
, bool enable
)
1036 dev
= dectoul(device
, NULL
);
1038 mmc
= init_mmc_device(dev
, false);
1040 return CMD_RET_FAILURE
;
1043 puts("BKOPS_EN only exists on eMMC\n");
1044 return CMD_RET_FAILURE
;
1047 return mmc_set_bkops_enable(mmc
, autobkops
, enable
);
1050 static int do_mmc_bkops(struct cmd_tbl
*cmdtp
, int flag
,
1051 int argc
, char * const argv
[])
1053 bool autobkops
, enable
;
1056 return CMD_RET_USAGE
;
1058 if (!strcmp(argv
[2], "manual"))
1060 else if (!strcmp(argv
[2], "auto"))
1063 return CMD_RET_FAILURE
;
1065 if (!strcmp(argv
[3], "disable"))
1067 else if (!strcmp(argv
[3], "enable"))
1070 return CMD_RET_FAILURE
;
1072 return mmc_bkops_common(argv
[1], autobkops
, enable
);
1075 static int do_mmc_bkops_enable(struct cmd_tbl
*cmdtp
, int flag
,
1076 int argc
, char * const argv
[])
1079 return CMD_RET_USAGE
;
1081 return mmc_bkops_common(argv
[1], false, true);
1085 static int do_mmc_boot_wp(struct cmd_tbl
*cmdtp
, int flag
,
1086 int argc
, char * const argv
[])
1092 mmc
= init_mmc_device(curr_device
, false);
1094 return CMD_RET_FAILURE
;
1096 printf("It is not an eMMC device\n");
1097 return CMD_RET_FAILURE
;
1101 part
= dectoul(argv
[1], NULL
);
1102 err
= mmc_boot_wp_single_partition(mmc
, part
);
1104 err
= mmc_boot_wp(mmc
);
1108 return CMD_RET_FAILURE
;
1109 printf("boot areas protected\n");
1110 return CMD_RET_SUCCESS
;
1113 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1114 static int do_mmc_reg(struct cmd_tbl
*cmdtp
, int flag
,
1115 int argc
, char *const argv
[])
1117 ALLOC_CACHE_ALIGN_BUFFER(u8
, ext_csd
, MMC_MAX_BLOCK_LEN
);
1122 if (argc
< 3 || argc
> 5)
1123 return CMD_RET_USAGE
;
1125 mmc
= find_mmc_device(curr_device
);
1127 printf("no mmc device at slot %x\n", curr_device
);
1128 return CMD_RET_FAILURE
;
1132 printf("SD registers are not supported\n");
1133 return CMD_RET_FAILURE
;
1136 off
= simple_strtoul(argv
[3], NULL
, 10);
1137 if (!strcmp(argv
[2], "cid")) {
1139 return CMD_RET_USAGE
;
1140 printf("CID[%i]: 0x%08x\n", off
, mmc
->cid
[off
]);
1142 env_set_hex(argv
[4], mmc
->cid
[off
]);
1143 return CMD_RET_SUCCESS
;
1145 if (!strcmp(argv
[2], "csd")) {
1147 return CMD_RET_USAGE
;
1148 printf("CSD[%i]: 0x%08x\n", off
, mmc
->csd
[off
]);
1150 env_set_hex(argv
[4], mmc
->csd
[off
]);
1151 return CMD_RET_SUCCESS
;
1153 if (!strcmp(argv
[2], "dsr")) {
1154 printf("DSR: 0x%08x\n", mmc
->dsr
);
1156 env_set_hex(argv
[4], mmc
->dsr
);
1157 return CMD_RET_SUCCESS
;
1159 if (!strcmp(argv
[2], "ocr")) {
1160 printf("OCR: 0x%08x\n", mmc
->ocr
);
1162 env_set_hex(argv
[4], mmc
->ocr
);
1163 return CMD_RET_SUCCESS
;
1165 if (!strcmp(argv
[2], "rca")) {
1166 printf("RCA: 0x%08x\n", mmc
->rca
);
1168 env_set_hex(argv
[4], mmc
->rca
);
1169 return CMD_RET_SUCCESS
;
1171 if (!strcmp(argv
[2], "extcsd") &&
1172 mmc
->version
>= MMC_VERSION_4_41
) {
1173 ret
= mmc_send_ext_csd(mmc
, ext_csd
);
1175 return CMD_RET_FAILURE
;
1176 if (!strcmp(argv
[3], "all")) {
1177 /* Dump the entire register */
1179 for (i
= 0; i
< MMC_MAX_BLOCK_LEN
; i
++) {
1181 printf("\n%03i: ", i
);
1182 printf(" %02x", ext_csd
[i
]);
1185 return CMD_RET_SUCCESS
;
1187 off
= simple_strtoul(argv
[3], NULL
, 10);
1189 return CMD_RET_USAGE
;
1190 printf("EXT_CSD[%i]: 0x%02x\n", off
, ext_csd
[off
]);
1192 env_set_hex(argv
[4], ext_csd
[off
]);
1193 return CMD_RET_SUCCESS
;
1196 return CMD_RET_FAILURE
;
1200 static struct cmd_tbl cmd_mmc
[] = {
1201 U_BOOT_CMD_MKENT(info
, 1, 0, do_mmcinfo
, "", ""),
1202 U_BOOT_CMD_MKENT(read
, 4, 1, do_mmc_read
, "", ""),
1203 U_BOOT_CMD_MKENT(wp
, 2, 0, do_mmc_boot_wp
, "", ""),
1204 #if CONFIG_IS_ENABLED(MMC_WRITE)
1205 U_BOOT_CMD_MKENT(write
, 4, 0, do_mmc_write
, "", ""),
1206 U_BOOT_CMD_MKENT(erase
, 3, 0, do_mmc_erase
, "", ""),
1208 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1209 U_BOOT_CMD_MKENT(swrite
, 3, 0, do_mmc_sparse_write
, "", ""),
1211 U_BOOT_CMD_MKENT(rescan
, 2, 1, do_mmc_rescan
, "", ""),
1212 U_BOOT_CMD_MKENT(part
, 1, 1, do_mmc_part
, "", ""),
1213 U_BOOT_CMD_MKENT(dev
, 4, 0, do_mmc_dev
, "", ""),
1214 U_BOOT_CMD_MKENT(list
, 1, 1, do_mmc_list
, "", ""),
1215 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1216 U_BOOT_CMD_MKENT(hwpartition
, 28, 0, do_mmc_hwpartition
, "", ""),
1218 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1219 U_BOOT_CMD_MKENT(bootbus
, 5, 0, do_mmc_bootbus
, "", ""),
1220 U_BOOT_CMD_MKENT(bootpart
-resize
, 4, 0, do_mmc_boot_resize
, "", ""),
1221 U_BOOT_CMD_MKENT(partconf
, 5, 0, do_mmc_partconf
, "", ""),
1222 U_BOOT_CMD_MKENT(rst
-function
, 3, 0, do_mmc_rst_func
, "", ""),
1224 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1225 U_BOOT_CMD_MKENT(rpmb
, CONFIG_SYS_MAXARGS
, 1, do_mmcrpmb
, "", ""),
1227 U_BOOT_CMD_MKENT(setdsr
, 2, 0, do_mmc_setdsr
, "", ""),
1228 #ifdef CONFIG_CMD_BKOPS_ENABLE
1229 U_BOOT_CMD_MKENT(bkops
-enable
, 2, 0, do_mmc_bkops_enable
, "", ""),
1230 U_BOOT_CMD_MKENT(bkops
, 4, 0, do_mmc_bkops
, "", ""),
1232 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1233 U_BOOT_CMD_MKENT(reg
, 5, 0, do_mmc_reg
, "", ""),
1237 static int do_mmcops(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
1242 cp
= find_cmd_tbl(argv
[1], cmd_mmc
, ARRAY_SIZE(cmd_mmc
));
1244 /* Drop the mmc command */
1248 if (cp
== NULL
|| argc
> cp
->maxargs
)
1249 return CMD_RET_USAGE
;
1250 if (flag
== CMD_FLAG_REPEAT
&& !cmd_is_repeatable(cp
))
1251 return CMD_RET_SUCCESS
;
1253 if (curr_device
< 0) {
1254 if (get_mmc_num() > 0) {
1257 puts("No MMC device available\n");
1258 return CMD_RET_FAILURE
;
1261 return cp
->cmd(cmdtp
, flag
, argc
, argv
);
1265 mmc
, 29, 1, do_mmcops
,
1267 "info - display info of the current MMC device\n"
1268 "mmc read addr blk# cnt\n"
1269 "mmc write addr blk# cnt\n"
1270 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1271 "mmc swrite addr blk#\n"
1273 "mmc erase blk# cnt\n"
1274 "mmc rescan [mode]\n"
1275 "mmc part - lists available partition on current mmc device\n"
1276 "mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode\n"
1277 " - the required speed mode is passed as the index from the following list\n"
1278 " [MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25,\n"
1279 " UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES]\n"
1280 "mmc list - lists available devices\n"
1281 "mmc wp [PART] - power on write protect boot partitions\n"
1284 " : 0 - first boot partition, 1 - second boot partition\n"
1285 " if not assigned, write protect all boot partitions\n"
1286 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1287 "mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning\n"
1288 " arguments (sizes in 512-byte blocks):\n"
1289 " USER - <user> <enh> <start> <cnt> <wrrel> <{on|off}>\n"
1290 " : sets user data area attributes\n"
1291 " GP - <{gp1|gp2|gp3|gp4}> <cnt> <enh> <wrrel> <{on|off}>\n"
1292 " : general purpose partition\n"
1293 " MODE - <{check|set|complete}>\n"
1294 " : mode, complete set partitioning completed\n"
1295 " WARNING: Partitioning is a write-once setting once it is set to complete.\n"
1296 " Power cycling is required to initialize partitions after set to complete.\n"
1298 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1299 "mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode>\n"
1300 " - Set the BOOT_BUS_WIDTH field of the specified device\n"
1301 "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
1302 " - Change sizes of boot and RPMB partitions of specified device\n"
1303 "mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]]\n"
1304 " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n"
1305 " If showing the bits, optionally store the boot_partition field into varname\n"
1306 "mmc rst-function <dev> <value>\n"
1307 " - Change the RST_n_FUNCTION field of the specified device\n"
1308 " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
1310 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1311 "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
1312 "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
1313 "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"
1314 "mmc rpmb counter - read the value of the write counter\n"
1316 "mmc setdsr <value> - set DSR register value\n"
1317 #ifdef CONFIG_CMD_BKOPS_ENABLE
1318 "mmc bkops-enable <dev> - enable background operations handshake on device\n"
1319 " WARNING: This is a write-once setting.\n"
1320 "mmc bkops <dev> [auto|manual] [enable|disable]\n"
1321 " - configure background operations handshake on device\n"
1323 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1324 "mmc reg read <reg> <offset> [env] - read card register <reg> offset <offset>\n"
1325 " (optionally into [env] variable)\n"
1326 " - reg: cid/csd/dsr/ocr/rca/extcsd\n"
1327 " - offset: for cid/csd [0..3], for extcsd [0..511,all]\n"
1331 /* Old command kept for compatibility. Same as 'mmc info' */
1333 mmcinfo
, 1, 0, do_mmcinfo
,
1335 "- display info of the current MMC device"