1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2003 4 * Kyle Harris, kharris@nexus-tech.net 5 */ 6 7#include <common.h> 8#include <blk.h> 9#include <command.h> 10#include <console.h> 11#include <display_options.h> 12#include <memalign.h> 13#include <mmc.h> 14#include <part.h> 15#include <sparse_format.h> 16#include <image-sparse.h> 17 18static int curr_device = -1; 19 20static void print_mmcinfo(struct mmc *mmc) 21{ 22 int i; 23 24 printf("Device: %s\n", mmc->cfg->name); 25 printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24); 26 if (IS_SD(mmc)) { 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); 31 } else { 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, 36 (mmc->cid[2] >> 24)); 37 } 38 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); 44#endif 45 printf("Rd Block Len: %d\n", mmc->read_bl_len); 46 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)); 52 printf("\n"); 53 54 printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No"); 55 puts("Capacity: "); 56 print_size(mmc->capacity, "\n"); 57 58 printf("Bus Width: %d-bit%s\n", mmc->bus_width, 59 mmc->ddr_mode ? " DDR" : ""); 60 61#if CONFIG_IS_ENABLED(MMC_WRITE) 62 puts("Erase Group Size: "); 63 print_size(((u64)mmc->erase_grp_size) << 9, "\n"); 64#endif 65 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); 70 u8 wp; 71 int ret; 72 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"); 76#endif 77 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) 81 puts(" WRREL\n"); 82 else 83 putc('\n'); 84 if (usr_enh) { 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"); 89 } 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"); 94 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)) 103 puts(" WRREL\n"); 104 else 105 putc('\n'); 106 } 107 } 108 ret = mmc_send_ext_csd(mmc, ext_csd); 109 if (ret) 110 return; 111 wp = ext_csd[EXT_CSD_BOOT_WP_STATUS]; 112 for (i = 0; i < 2; ++i) { 113 printf("Boot area %d is ", i); 114 switch (wp & 3) { 115 case 0: 116 printf("not write protected\n"); 117 break; 118 case 1: 119 printf("power on protected\n"); 120 break; 121 case 2: 122 printf("permanently protected\n"); 123 break; 124 default: 125 printf("in reserved protection state\n"); 126 break; 127 } 128 wp >>= 2; 129 } 130 } 131} 132 133static struct mmc *__init_mmc_device(int dev, bool force_init, 134 enum bus_mode speed_mode) 135{ 136 struct mmc *mmc; 137 mmc = find_mmc_device(dev); 138 if (!mmc) { 139 printf("no mmc device at slot %x\n", dev); 140 return NULL; 141 } 142 143 if (!mmc_getcd(mmc)) 144 force_init = true; 145 146 if (force_init) 147 mmc->has_init = 0; 148 149 if (IS_ENABLED(CONFIG_MMC_SPEED_MODE_SET)) 150 mmc->user_speed_mode = speed_mode; 151 152 if (mmc_init(mmc)) 153 return NULL; 154 155#ifdef CONFIG_BLOCK_CACHE 156 struct blk_desc *bd = mmc_get_blk_desc(mmc); 157 blkcache_invalidate(bd->uclass_id, bd->devnum); 158#endif 159 160 return mmc; 161} 162 163static struct mmc *init_mmc_device(int dev, bool force_init) 164{ 165 return __init_mmc_device(dev, force_init, MMC_MODES_END); 166} 167 168static int do_mmcinfo(struct cmd_tbl *cmdtp, int flag, int argc, 169 char *const argv[]) 170{ 171 struct mmc *mmc; 172 173 if (curr_device < 0) { 174 if (get_mmc_num() > 0) 175 curr_device = 0; 176 else { 177 puts("No MMC device available\n"); 178 return CMD_RET_FAILURE; 179 } 180 } 181 182 mmc = init_mmc_device(curr_device, false); 183 if (!mmc) 184 return CMD_RET_FAILURE; 185 186 print_mmcinfo(mmc); 187 return CMD_RET_SUCCESS; 188} 189 190#if CONFIG_IS_ENABLED(CMD_MMC_RPMB) 191static int confirm_key_prog(void) 192{ 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> "); 196 if (confirm_yesno()) 197 return 1; 198 199 puts("Authentication key programming aborted\n"); 200 return 0; 201} 202 203static int do_mmcrpmb_key(struct cmd_tbl *cmdtp, int flag, 204 int argc, char *const argv[]) 205{ 206 void *key_addr; 207 struct mmc *mmc = find_mmc_device(curr_device); 208 209 if (argc != 2) 210 return CMD_RET_USAGE; 211 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; 218 } 219 return CMD_RET_SUCCESS; 220} 221 222static int do_mmcrpmb_read(struct cmd_tbl *cmdtp, int flag, 223 int argc, char *const argv[]) 224{ 225 u16 blk, cnt; 226 void *addr; 227 int n; 228 void *key_addr = NULL; 229 struct mmc *mmc = find_mmc_device(curr_device); 230 231 if (argc < 4) 232 return CMD_RET_USAGE; 233 234 addr = (void *)hextoul(argv[1], NULL); 235 blk = hextoul(argv[2], NULL); 236 cnt = hextoul(argv[3], NULL); 237 238 if (argc == 5) 239 key_addr = (void *)hextoul(argv[4], NULL); 240 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); 244 245 printf("%d RPMB blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 246 if (n != cnt) 247 return CMD_RET_FAILURE; 248 return CMD_RET_SUCCESS; 249} 250 251static int do_mmcrpmb_write(struct cmd_tbl *cmdtp, int flag, 252 int argc, char *const argv[]) 253{ 254 u16 blk, cnt; 255 void *addr; 256 int n; 257 void *key_addr; 258 struct mmc *mmc = find_mmc_device(curr_device); 259 260 if (argc != 5) 261 return CMD_RET_USAGE; 262 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); 267 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); 271 272 printf("%d RPMB blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 273 if (n != cnt) 274 return CMD_RET_FAILURE; 275 return CMD_RET_SUCCESS; 276} 277 278static int do_mmcrpmb_counter(struct cmd_tbl *cmdtp, int flag, 279 int argc, char *const argv[]) 280{ 281 unsigned long counter; 282 struct mmc *mmc = find_mmc_device(curr_device); 283 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; 288} 289 290static 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, "", ""), 295}; 296 297static int do_mmcrpmb(struct cmd_tbl *cmdtp, int flag, 298 int argc, char *const argv[]) 299{ 300 struct cmd_tbl *cp; 301 struct mmc *mmc; 302 char original_part; 303 int ret; 304 305 cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb)); 306 307 /* Drop the rpmb subcommand */ 308 argc--; 309 argv++; 310 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; 315 316 mmc = init_mmc_device(curr_device, false); 317 if (!mmc) 318 return CMD_RET_FAILURE; 319 320 if (!(mmc->version & MMC_VERSION_MMC)) { 321 printf("It is not an eMMC device\n"); 322 return CMD_RET_FAILURE; 323 } 324 if (mmc->version < MMC_VERSION_4_41) { 325 printf("RPMB not supported before version 4.41\n"); 326 return CMD_RET_FAILURE; 327 } 328 /* Switch to the RPMB partition */ 329#ifndef CONFIG_BLK 330 original_part = mmc->block_dev.hwpart; 331#else 332 original_part = mmc_get_blk_desc(mmc)->hwpart; 333#endif 334 if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, MMC_PART_RPMB) != 335 0) 336 return CMD_RET_FAILURE; 337 ret = cp->cmd(cmdtp, flag, argc, argv); 338 339 /* Return to original partition */ 340 if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, original_part) != 341 0) 342 return CMD_RET_FAILURE; 343 return ret; 344} 345#endif 346 347static int do_mmc_read(struct cmd_tbl *cmdtp, int flag, 348 int argc, char *const argv[]) 349{ 350 struct mmc *mmc; 351 u32 blk, cnt, n; 352 void *addr; 353 354 if (argc != 4) 355 return CMD_RET_USAGE; 356 357 addr = (void *)hextoul(argv[1], NULL); 358 blk = hextoul(argv[2], NULL); 359 cnt = hextoul(argv[3], NULL); 360 361 mmc = init_mmc_device(curr_device, false); 362 if (!mmc) 363 return CMD_RET_FAILURE; 364 365 printf("\nMMC read: dev # %d, block # %d, count %d ... ", 366 curr_device, blk, cnt); 367 368 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr); 369 printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 370 371 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 372} 373 374#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE) 375static lbaint_t mmc_sparse_write(struct sparse_storage *info, lbaint_t blk, 376 lbaint_t blkcnt, const void *buffer) 377{ 378 struct blk_desc *dev_desc = info->priv; 379 380 return blk_dwrite(dev_desc, blk, blkcnt, buffer); 381} 382 383static lbaint_t mmc_sparse_reserve(struct sparse_storage *info, 384 lbaint_t blk, lbaint_t blkcnt) 385{ 386 return blkcnt; 387} 388 389static int do_mmc_sparse_write(struct cmd_tbl *cmdtp, int flag, 390 int argc, char *const argv[]) 391{ 392 struct sparse_storage sparse; 393 struct blk_desc *dev_desc; 394 struct mmc *mmc; 395 char dest[11]; 396 void *addr; 397 u32 blk; 398 399 if (argc != 3) 400 return CMD_RET_USAGE; 401 402 addr = (void *)hextoul(argv[1], NULL); 403 blk = hextoul(argv[2], NULL); 404 405 if (!is_sparse_image(addr)) { 406 printf("Not a sparse image\n"); 407 return CMD_RET_FAILURE; 408 } 409 410 mmc = init_mmc_device(curr_device, false); 411 if (!mmc) 412 return CMD_RET_FAILURE; 413 414 printf("\nMMC Sparse write: dev # %d, block # %d ... ", 415 curr_device, blk); 416 417 if (mmc_getwp(mmc) == 1) { 418 printf("Error: card is write protected!\n"); 419 return CMD_RET_FAILURE; 420 } 421 422 dev_desc = mmc_get_blk_desc(mmc); 423 sparse.priv = dev_desc; 424 sparse.blksz = 512; 425 sparse.start = blk; 426 sparse.size = dev_desc->lba - blk; 427 sparse.write = mmc_sparse_write; 428 sparse.reserve = mmc_sparse_reserve; 429 sparse.mssg = NULL; 430 sprintf(dest, "0x" LBAF, sparse.start * sparse.blksz); 431 432 if (write_sparse_image(&sparse, dest, addr, NULL)) 433 return CMD_RET_FAILURE; 434 else 435 return CMD_RET_SUCCESS; 436} 437#endif 438 439#if CONFIG_IS_ENABLED(MMC_WRITE) 440static int do_mmc_write(struct cmd_tbl *cmdtp, int flag, 441 int argc, char *const argv[]) 442{ 443 struct mmc *mmc; 444 u32 blk, cnt, n; 445 void *addr; 446 447 if (argc != 4) 448 return CMD_RET_USAGE; 449 450 addr = (void *)hextoul(argv[1], NULL); 451 blk = hextoul(argv[2], NULL); 452 cnt = hextoul(argv[3], NULL); 453 454 mmc = init_mmc_device(curr_device, false); 455 if (!mmc) 456 return CMD_RET_FAILURE; 457 458 printf("\nMMC write: dev # %d, block # %d, count %d ... ", 459 curr_device, blk, cnt); 460 461 if (mmc_getwp(mmc) == 1) { 462 printf("Error: card is write protected!\n"); 463 return CMD_RET_FAILURE; 464 } 465 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr); 466 printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 467 468 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 469} 470 471static int do_mmc_erase(struct cmd_tbl *cmdtp, int flag, 472 int argc, char *const argv[]) 473{ 474 struct mmc *mmc; 475 u32 blk, cnt, n; 476 477 if (argc != 3) 478 return CMD_RET_USAGE; 479 480 blk = hextoul(argv[1], NULL); 481 cnt = hextoul(argv[2], NULL); 482 483 mmc = init_mmc_device(curr_device, false); 484 if (!mmc) 485 return CMD_RET_FAILURE; 486 487 printf("\nMMC erase: dev # %d, block # %d, count %d ... ", 488 curr_device, blk, cnt); 489 490 if (mmc_getwp(mmc) == 1) { 491 printf("Error: card is write protected!\n"); 492 return CMD_RET_FAILURE; 493 } 494 n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt); 495 printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 496 497 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 498} 499#endif 500 501static int do_mmc_rescan(struct cmd_tbl *cmdtp, int flag, 502 int argc, char *const argv[]) 503{ 504 struct mmc *mmc; 505 506 if (argc == 1) { 507 mmc = init_mmc_device(curr_device, true); 508 } else if (argc == 2) { 509 enum bus_mode speed_mode; 510 511 speed_mode = (int)dectoul(argv[1], NULL); 512 mmc = __init_mmc_device(curr_device, true, speed_mode); 513 } else { 514 return CMD_RET_USAGE; 515 } 516 517 if (!mmc) 518 return CMD_RET_FAILURE; 519 520 return CMD_RET_SUCCESS; 521} 522 523static int do_mmc_part(struct cmd_tbl *cmdtp, int flag, 524 int argc, char *const argv[]) 525{ 526 struct blk_desc *mmc_dev; 527 struct mmc *mmc; 528 529 mmc = init_mmc_device(curr_device, false); 530 if (!mmc) 531 return CMD_RET_FAILURE; 532 533 mmc_dev = blk_get_devnum_by_uclass_id(UCLASS_MMC, curr_device); 534 if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) { 535 part_print(mmc_dev); 536 return CMD_RET_SUCCESS; 537 } 538 539 puts("get mmc type error!\n"); 540 return CMD_RET_FAILURE; 541} 542 543static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag, 544 int argc, char *const argv[]) 545{ 546 int dev, part = 0, ret; 547 struct mmc *mmc; 548 549 if (argc == 1) { 550 dev = curr_device; 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", 560 PART_ACCESS_MASK); 561 return CMD_RET_FAILURE; 562 } 563 mmc = init_mmc_device(dev, true); 564 } else if (argc == 4) { 565 enum bus_mode speed_mode; 566 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", 571 PART_ACCESS_MASK); 572 return CMD_RET_FAILURE; 573 } 574 speed_mode = (int)dectoul(argv[3], NULL); 575 mmc = __init_mmc_device(dev, true, speed_mode); 576 } else { 577 return CMD_RET_USAGE; 578 } 579 580 if (!mmc) 581 return CMD_RET_FAILURE; 582 583 ret = blk_select_hwpart_devnum(UCLASS_MMC, dev, part); 584 printf("switch to partitions #%d, %s\n", 585 part, (!ret) ? "OK" : "ERROR"); 586 if (ret) 587 return 1; 588 589 curr_device = dev; 590 if (mmc->part_config == MMCPART_NOAVAILABLE) 591 printf("mmc%d is current device\n", curr_device); 592 else 593 printf("mmc%d(part %d) is current device\n", 594 curr_device, mmc_get_blk_desc(mmc)->hwpart); 595 596 return CMD_RET_SUCCESS; 597} 598 599static int do_mmc_list(struct cmd_tbl *cmdtp, int flag, 600 int argc, char *const argv[]) 601{ 602 print_mmc_devices('\n'); 603 return CMD_RET_SUCCESS; 604} 605 606#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING) 607static void parse_hwpart_user_enh_size(struct mmc *mmc, 608 struct mmc_hwpart_conf *pconf, 609 char *argv) 610{ 611 int i, ret; 612 613 pconf->user.enh_size = 0; 614 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); 618 if (ret) 619 return; 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++) { 629 /* 630 * If the eMMC already has GP partitions set, 631 * subtract their size from the maximum USER 632 * partition size. 633 * 634 * Else, if the command was used to configure new 635 * GP partitions, subtract their size from maximum 636 * USER partition size. 637 */ 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; 644 } 645 } 646 } else { 647 pconf->user.enh_size = dectoul(argv, NULL); 648 } 649} 650 651static int parse_hwpart_user(struct mmc *mmc, struct mmc_hwpart_conf *pconf, 652 int argc, char *const argv[]) 653{ 654 int i = 0; 655 656 memset(&pconf->user, 0, sizeof(pconf->user)); 657 658 while (i < argc) { 659 if (!strcmp(argv[i], "enh")) { 660 if (i + 2 >= argc) 661 return -1; 662 pconf->user.enh_start = 663 dectoul(argv[i + 1], NULL); 664 parse_hwpart_user_enh_size(mmc, pconf, argv[i + 2]); 665 i += 3; 666 } else if (!strcmp(argv[i], "wrrel")) { 667 if (i + 1 >= argc) 668 return -1; 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; 674 else 675 return -1; 676 i += 2; 677 } else { 678 break; 679 } 680 } 681 return i; 682} 683 684static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx, 685 int argc, char *const argv[]) 686{ 687 int i; 688 689 memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx])); 690 691 if (1 >= argc) 692 return -1; 693 pconf->gp_part[pidx].size = dectoul(argv[0], NULL); 694 695 i = 1; 696 while (i < argc) { 697 if (!strcmp(argv[i], "enh")) { 698 pconf->gp_part[pidx].enhanced = 1; 699 i += 1; 700 } else if (!strcmp(argv[i], "wrrel")) { 701 if (i + 1 >= argc) 702 return -1; 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; 708 else 709 return -1; 710 i += 2; 711 } else { 712 break; 713 } 714 } 715 return i; 716} 717 718static int do_mmc_hwpartition(struct cmd_tbl *cmdtp, int flag, 719 int argc, char *const argv[]) 720{ 721 struct mmc *mmc; 722 struct mmc_hwpart_conf pconf = { }; 723 enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK; 724 int i, r, pidx; 725 726 mmc = init_mmc_device(curr_device, false); 727 if (!mmc) 728 return CMD_RET_FAILURE; 729 730 if (IS_SD(mmc)) { 731 puts("SD doesn't support partitioning\n"); 732 return CMD_RET_FAILURE; 733 } 734 735 if (argc < 1) 736 return CMD_RET_USAGE; 737 i = 1; 738 while (i < argc) { 739 if (!strcmp(argv[i], "user")) { 740 i++; 741 r = parse_hwpart_user(mmc, &pconf, argc - i, &argv[i]); 742 if (r < 0) 743 return CMD_RET_USAGE; 744 i += r; 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'; 749 i++; 750 r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]); 751 if (r < 0) 752 return CMD_RET_USAGE; 753 i += r; 754 } else if (!strcmp(argv[i], "check")) { 755 mode = MMC_HWPART_CONF_CHECK; 756 i++; 757 } else if (!strcmp(argv[i], "set")) { 758 mode = MMC_HWPART_CONF_SET; 759 i++; 760 } else if (!strcmp(argv[i], "complete")) { 761 mode = MMC_HWPART_CONF_COMPLETE; 762 i++; 763 } else { 764 return CMD_RET_USAGE; 765 } 766 } 767 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"); 774 } else { 775 puts("\tNo enhanced user data area\n"); 776 } 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 ? 785 " ENH\n" : "\n"); 786 } else { 787 printf("\tNo GP%i partition\n", pidx+1); 788 } 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"); 792 } 793 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; 799 } else { 800 puts("Failed!\n"); 801 return CMD_RET_FAILURE; 802 } 803} 804#endif 805 806#ifdef CONFIG_SUPPORT_EMMC_BOOT 807static int do_mmc_bootbus(struct cmd_tbl *cmdtp, int flag, 808 int argc, char *const argv[]) 809{ 810 int dev; 811 struct mmc *mmc; 812 u8 width, reset, mode; 813 814 if (argc != 5) 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); 820 821 mmc = init_mmc_device(dev, false); 822 if (!mmc) 823 return CMD_RET_FAILURE; 824 825 if (IS_SD(mmc)) { 826 puts("BOOT_BUS_WIDTH only exists on eMMC\n"); 827 return CMD_RET_FAILURE; 828 } 829 830 /* 831 * BOOT_BUS_CONDITIONS[177] 832 * BOOT_MODE[4:3] 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 839 * BOOT_BUS_WIDTH 840 * 0x0 : x1(sdr) or x4 (ddr) buswidth 841 * 0x1 : x4(sdr/ddr) buswith 842 * 0x2 : x8(sdr/ddr) buswith 843 * 844 */ 845 if (width >= 0x3) { 846 printf("boot_bus_width %d is invalid\n", width); 847 return CMD_RET_FAILURE; 848 } 849 850 if (reset >= 0x2) { 851 printf("reset_boot_bus_width %d is invalid\n", reset); 852 return CMD_RET_FAILURE; 853 } 854 855 if (mode >= 0x3) { 856 printf("reset_boot_bus_width %d is invalid\n", mode); 857 return CMD_RET_FAILURE; 858 } 859 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; 864 } 865 866 printf("Set to BOOT_BUS_WIDTH = 0x%x, RESET = 0x%x, BOOT_MODE = 0x%x\n", 867 width, reset, mode); 868 return CMD_RET_SUCCESS; 869} 870 871static int do_mmc_boot_resize(struct cmd_tbl *cmdtp, int flag, 872 int argc, char *const argv[]) 873{ 874 int dev; 875 struct mmc *mmc; 876 u32 bootsize, rpmbsize; 877 878 if (argc != 4) 879 return CMD_RET_USAGE; 880 dev = dectoul(argv[1], NULL); 881 bootsize = dectoul(argv[2], NULL); 882 rpmbsize = dectoul(argv[3], NULL); 883 884 mmc = init_mmc_device(dev, false); 885 if (!mmc) 886 return CMD_RET_FAILURE; 887 888 if (IS_SD(mmc)) { 889 printf("It is not an eMMC device\n"); 890 return CMD_RET_FAILURE; 891 } 892 893 if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) { 894 printf("EMMC boot partition Size change Failed.\n"); 895 return CMD_RET_FAILURE; 896 } 897 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; 901} 902 903static int mmc_partconf_print(struct mmc *mmc, const char *varname) 904{ 905 u8 ack, access, part; 906 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; 910 } 911 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); 915 916 if(varname) 917 env_set_hex(varname, part); 918 919 printf("EXT_CSD[179], PARTITION_CONFIG:\n" 920 "BOOT_ACK: 0x%x\n" 921 "BOOT_PARTITION_ENABLE: 0x%x\n" 922 "PARTITION_ACCESS: 0x%x\n", ack, part, access); 923 924 return CMD_RET_SUCCESS; 925} 926 927static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag, 928 int argc, char *const argv[]) 929{ 930 int ret, dev; 931 struct mmc *mmc; 932 u8 ack, part_num, access; 933 934 if (argc != 2 && argc != 3 && argc != 5) 935 return CMD_RET_USAGE; 936 937 dev = dectoul(argv[1], NULL); 938 939 mmc = init_mmc_device(dev, false); 940 if (!mmc) 941 return CMD_RET_FAILURE; 942 943 if (IS_SD(mmc)) { 944 puts("PARTITION_CONFIG only exists on eMMC\n"); 945 return CMD_RET_FAILURE; 946 } 947 948 if (argc == 2 || argc == 3) 949 return mmc_partconf_print(mmc, cmd_arg2(argc, argv)); 950 951 ack = dectoul(argv[2], NULL); 952 part_num = dectoul(argv[3], NULL); 953 access = dectoul(argv[4], NULL); 954 955 /* acknowledge to be sent during boot operation */ 956 ret = mmc_set_part_conf(mmc, ack, part_num, access); 957 if (ret != 0) 958 return CMD_RET_FAILURE; 959 960 return CMD_RET_SUCCESS; 961} 962 963static int do_mmc_rst_func(struct cmd_tbl *cmdtp, int flag, 964 int argc, char *const argv[]) 965{ 966 int ret, dev; 967 struct mmc *mmc; 968 u8 enable; 969 970 /* 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. 974 */ 975 if (argc != 3) 976 return CMD_RET_USAGE; 977 978 dev = dectoul(argv[1], NULL); 979 enable = dectoul(argv[2], NULL); 980 981 if (enable > 2) { 982 puts("Invalid RST_n_ENABLE value\n"); 983 return CMD_RET_USAGE; 984 } 985 986 mmc = init_mmc_device(dev, false); 987 if (!mmc) 988 return CMD_RET_FAILURE; 989 990 if (IS_SD(mmc)) { 991 puts("RST_n_FUNCTION only exists on eMMC\n"); 992 return CMD_RET_FAILURE; 993 } 994 995 ret = mmc_set_rst_n_function(mmc, enable); 996 if (ret != 0) 997 return CMD_RET_FAILURE; 998 999 return CMD_RET_SUCCESS; 1000} 1001#endif 1002static int do_mmc_setdsr(struct cmd_tbl *cmdtp, int flag, 1003 int argc, char *const argv[]) 1004{ 1005 struct mmc *mmc; 1006 u32 val; 1007 int ret; 1008 1009 if (argc != 2) 1010 return CMD_RET_USAGE; 1011 val = hextoul(argv[1], NULL); 1012 1013 mmc = find_mmc_device(curr_device); 1014 if (!mmc) { 1015 printf("no mmc device at slot %x\n", curr_device); 1016 return CMD_RET_FAILURE; 1017 } 1018 ret = mmc_set_dsr(mmc, val); 1019 printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR"); 1020 if (!ret) { 1021 mmc->has_init = 0; 1022 if (mmc_init(mmc)) 1023 return CMD_RET_FAILURE; 1024 else 1025 return CMD_RET_SUCCESS; 1026 } 1027 return ret; 1028} 1029 1030#ifdef CONFIG_CMD_BKOPS_ENABLE 1031static int mmc_bkops_common(char *device, bool autobkops, bool enable) 1032{ 1033 struct mmc *mmc; 1034 int dev; 1035 1036 dev = dectoul(device, NULL); 1037 1038 mmc = init_mmc_device(dev, false); 1039 if (!mmc) 1040 return CMD_RET_FAILURE; 1041 1042 if (IS_SD(mmc)) { 1043 puts("BKOPS_EN only exists on eMMC\n"); 1044 return CMD_RET_FAILURE; 1045 } 1046 1047 return mmc_set_bkops_enable(mmc, autobkops, enable); 1048} 1049 1050static int do_mmc_bkops(struct cmd_tbl *cmdtp, int flag, 1051 int argc, char * const argv[]) 1052{ 1053 bool autobkops, enable; 1054 1055 if (argc != 4) 1056 return CMD_RET_USAGE; 1057 1058 if (!strcmp(argv[2], "manual")) 1059 autobkops = false; 1060 else if (!strcmp(argv[2], "auto")) 1061 autobkops = true; 1062 else 1063 return CMD_RET_FAILURE; 1064 1065 if (!strcmp(argv[3], "disable")) 1066 enable = false; 1067 else if (!strcmp(argv[3], "enable")) 1068 enable = true; 1069 else 1070 return CMD_RET_FAILURE; 1071 1072 return mmc_bkops_common(argv[1], autobkops, enable); 1073} 1074 1075static int do_mmc_bkops_enable(struct cmd_tbl *cmdtp, int flag, 1076 int argc, char * const argv[]) 1077{ 1078 if (argc != 2) 1079 return CMD_RET_USAGE; 1080 1081 return mmc_bkops_common(argv[1], false, true); 1082} 1083#endif 1084 1085static int do_mmc_boot_wp(struct cmd_tbl *cmdtp, int flag, 1086 int argc, char * const argv[]) 1087{ 1088 int err; 1089 struct mmc *mmc; 1090 int part; 1091 1092 mmc = init_mmc_device(curr_device, false); 1093 if (!mmc) 1094 return CMD_RET_FAILURE; 1095 if (IS_SD(mmc)) { 1096 printf("It is not an eMMC device\n"); 1097 return CMD_RET_FAILURE; 1098 } 1099 1100 if (argc == 2) { 1101 part = dectoul(argv[1], NULL); 1102 err = mmc_boot_wp_single_partition(mmc, part); 1103 } else { 1104 err = mmc_boot_wp(mmc); 1105 } 1106 1107 if (err) 1108 return CMD_RET_FAILURE; 1109 printf("boot areas protected\n"); 1110 return CMD_RET_SUCCESS; 1111} 1112 1113#if CONFIG_IS_ENABLED(CMD_MMC_REG) 1114static int do_mmc_reg(struct cmd_tbl *cmdtp, int flag, 1115 int argc, char *const argv[]) 1116{ 1117 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); 1118 struct mmc *mmc; 1119 int i, ret; 1120 u32 off; 1121 1122 if (argc < 3 || argc > 5) 1123 return CMD_RET_USAGE; 1124 1125 mmc = find_mmc_device(curr_device); 1126 if (!mmc) { 1127 printf("no mmc device at slot %x\n", curr_device); 1128 return CMD_RET_FAILURE; 1129 } 1130 1131 if (IS_SD(mmc)) { 1132 printf("SD registers are not supported\n"); 1133 return CMD_RET_FAILURE; 1134 } 1135 1136 off = simple_strtoul(argv[3], NULL, 10); 1137 if (!strcmp(argv[2], "cid")) { 1138 if (off > 3) 1139 return CMD_RET_USAGE; 1140 printf("CID[%i]: 0x%08x\n", off, mmc->cid[off]); 1141 if (argv[4]) 1142 env_set_hex(argv[4], mmc->cid[off]); 1143 return CMD_RET_SUCCESS; 1144 } 1145 if (!strcmp(argv[2], "csd")) { 1146 if (off > 3) 1147 return CMD_RET_USAGE; 1148 printf("CSD[%i]: 0x%08x\n", off, mmc->csd[off]); 1149 if (argv[4]) 1150 env_set_hex(argv[4], mmc->csd[off]); 1151 return CMD_RET_SUCCESS; 1152 } 1153 if (!strcmp(argv[2], "dsr")) { 1154 printf("DSR: 0x%08x\n", mmc->dsr); 1155 if (argv[4]) 1156 env_set_hex(argv[4], mmc->dsr); 1157 return CMD_RET_SUCCESS; 1158 } 1159 if (!strcmp(argv[2], "ocr")) { 1160 printf("OCR: 0x%08x\n", mmc->ocr); 1161 if (argv[4]) 1162 env_set_hex(argv[4], mmc->ocr); 1163 return CMD_RET_SUCCESS; 1164 } 1165 if (!strcmp(argv[2], "rca")) { 1166 printf("RCA: 0x%08x\n", mmc->rca); 1167 if (argv[4]) 1168 env_set_hex(argv[4], mmc->rca); 1169 return CMD_RET_SUCCESS; 1170 } 1171 if (!strcmp(argv[2], "extcsd") && 1172 mmc->version >= MMC_VERSION_4_41) { 1173 ret = mmc_send_ext_csd(mmc, ext_csd); 1174 if (ret) 1175 return CMD_RET_FAILURE; 1176 if (!strcmp(argv[3], "all")) { 1177 /* Dump the entire register */ 1178 printf("EXT_CSD:"); 1179 for (i = 0; i < MMC_MAX_BLOCK_LEN; i++) { 1180 if (!(i % 10)) 1181 printf("\n%03i: ", i); 1182 printf(" %02x", ext_csd[i]); 1183 } 1184 printf("\n"); 1185 return CMD_RET_SUCCESS; 1186 } 1187 off = simple_strtoul(argv[3], NULL, 10); 1188 if (off > 512) 1189 return CMD_RET_USAGE; 1190 printf("EXT_CSD[%i]: 0x%02x\n", off, ext_csd[off]); 1191 if (argv[4]) 1192 env_set_hex(argv[4], ext_csd[off]); 1193 return CMD_RET_SUCCESS; 1194 } 1195 1196 return CMD_RET_FAILURE; 1197} 1198#endif 1199 1200static 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, "", ""), 1207#endif 1208#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE) 1209 U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""), 1210#endif 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, "", ""), 1217#endif 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, "", ""), 1223#endif 1224#if CONFIG_IS_ENABLED(CMD_MMC_RPMB) 1225 U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""), 1226#endif 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, "", ""), 1231#endif 1232#if CONFIG_IS_ENABLED(CMD_MMC_REG) 1233 U_BOOT_CMD_MKENT(reg, 5, 0, do_mmc_reg, "", ""), 1234#endif 1235}; 1236 1237static int do_mmcops(struct cmd_tbl *cmdtp, int flag, int argc, 1238 char *const argv[]) 1239{ 1240 struct cmd_tbl *cp; 1241 1242 cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc)); 1243 1244 /* Drop the mmc command */ 1245 argc--; 1246 argv++; 1247 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; 1252 1253 if (curr_device < 0) { 1254 if (get_mmc_num() > 0) { 1255 curr_device = 0; 1256 } else { 1257 puts("No MMC device available\n"); 1258 return CMD_RET_FAILURE; 1259 } 1260 } 1261 return cp->cmd(cmdtp, flag, argc, argv); 1262} 1263 1264U_BOOT_CMD( 1265 mmc, 29, 1, do_mmcops, 1266 "MMC sub system", 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" 1272#endif 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" 1282 " arguments:\n" 1283 " PART - [0|1]\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" 1297#endif 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" 1309#endif 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" 1315#endif 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" 1322#endif 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" 1328#endif 1329 ); 1330 1331/* Old command kept for compatibility. Same as 'mmc info' */ 1332U_BOOT_CMD( 1333 mmcinfo, 1, 0, do_mmcinfo, 1334 "display MMC info", 1335 "- display info of the current MMC device" 1336); 1337