]> Git Repo - J-u-boot.git/blob - cmd/mmc.c
Merge patch series "provide names for emmc hardware partitions"
[J-u-boot.git] / cmd / mmc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2003
4  * Kyle Harris, [email protected]
5  */
6
7 #include <blk.h>
8 #include <command.h>
9 #include <console.h>
10 #include <display_options.h>
11 #include <memalign.h>
12 #include <mmc.h>
13 #include <part.h>
14 #include <sparse_format.h>
15 #include <image-sparse.h>
16 #include <vsprintf.h>
17 #include <linux/ctype.h>
18
19 static int curr_device = -1;
20
21 static void print_mmcinfo(struct mmc *mmc)
22 {
23         int i;
24
25         printf("Device: %s\n", mmc->cfg->name);
26         printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
27         if (IS_SD(mmc)) {
28                 printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
29                 printf("Name: %c%c%c%c%c \n", mmc->cid[0] & 0xff,
30                 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
31                 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
32         } else {
33                 printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xff);
34                 printf("Name: %c%c%c%c%c%c \n", mmc->cid[0] & 0xff,
35                 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
36                 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
37                 (mmc->cid[2] >> 24));
38         }
39
40         printf("Bus Speed: %d\n", mmc->clock);
41 #if CONFIG_IS_ENABLED(MMC_VERBOSE)
42         printf("Mode: %s\n", mmc_mode_name(mmc->selected_mode));
43         mmc_dump_capabilities("card capabilities", mmc->card_caps);
44         mmc_dump_capabilities("host capabilities", mmc->host_caps);
45 #endif
46         printf("Rd Block Len: %d\n", mmc->read_bl_len);
47
48         printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC",
49                         EXTRACT_SDMMC_MAJOR_VERSION(mmc->version),
50                         EXTRACT_SDMMC_MINOR_VERSION(mmc->version));
51         if (EXTRACT_SDMMC_CHANGE_VERSION(mmc->version) != 0)
52                 printf(".%d", EXTRACT_SDMMC_CHANGE_VERSION(mmc->version));
53         printf("\n");
54
55         printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
56         puts("Capacity: ");
57         print_size(mmc->capacity, "\n");
58
59         printf("Bus Width: %d-bit%s\n", mmc->bus_width,
60                         mmc->ddr_mode ? " DDR" : "");
61
62 #if CONFIG_IS_ENABLED(MMC_WRITE)
63         puts("Erase Group Size: ");
64         print_size(((u64)mmc->erase_grp_size) << 9, "\n");
65 #endif
66
67         if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
68                 bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
69                 bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
70                 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
71                 u8 wp;
72                 int ret;
73
74 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
75                 puts("HC WP Group Size: ");
76                 print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
77 #endif
78
79                 puts("User Capacity: ");
80                 print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
81                 if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR)
82                         puts(" WRREL\n");
83                 else
84                         putc('\n');
85                 if (usr_enh) {
86                         puts("User Enhanced Start: ");
87                         print_size(mmc->enh_user_start, "\n");
88                         puts("User Enhanced Size: ");
89                         print_size(mmc->enh_user_size, "\n");
90                 }
91                 puts("Boot Capacity: ");
92                 print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n");
93                 puts("RPMB Capacity: ");
94                 print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n");
95
96                 for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
97                         bool is_enh = has_enh &&
98                                 (mmc->part_attr & EXT_CSD_ENH_GP(i));
99                         if (mmc->capacity_gp[i]) {
100                                 printf("GP%i Capacity: ", i+1);
101                                 print_size(mmc->capacity_gp[i],
102                                            is_enh ? " ENH" : "");
103                                 if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i))
104                                         puts(" WRREL\n");
105                                 else
106                                         putc('\n');
107                         }
108                 }
109                 ret = mmc_send_ext_csd(mmc, ext_csd);
110                 if (ret)
111                         return;
112                 wp = ext_csd[EXT_CSD_BOOT_WP_STATUS];
113                 for (i = 0; i < 2; ++i) {
114                         printf("Boot area %d is ", i);
115                         switch (wp & 3) {
116                         case 0:
117                                 printf("not write protected\n");
118                                 break;
119                         case 1:
120                                 printf("power on protected\n");
121                                 break;
122                         case 2:
123                                 printf("permanently protected\n");
124                                 break;
125                         default:
126                                 printf("in reserved protection state\n");
127                                 break;
128                         }
129                         wp >>= 2;
130                 }
131         }
132 }
133
134 static struct mmc *__init_mmc_device(int dev, bool force_init,
135                                      enum bus_mode speed_mode)
136 {
137         struct mmc *mmc;
138         mmc = find_mmc_device(dev);
139         if (!mmc) {
140                 printf("no mmc device at slot %x\n", dev);
141                 return NULL;
142         }
143
144         if (!mmc_getcd(mmc))
145                 force_init = true;
146
147         if (force_init)
148                 mmc->has_init = 0;
149
150         if (IS_ENABLED(CONFIG_MMC_SPEED_MODE_SET))
151                 mmc->user_speed_mode = speed_mode;
152
153         if (mmc_init(mmc))
154                 return NULL;
155
156 #ifdef CONFIG_BLOCK_CACHE
157         struct blk_desc *bd = mmc_get_blk_desc(mmc);
158         blkcache_invalidate(bd->uclass_id, bd->devnum);
159 #endif
160
161         return mmc;
162 }
163
164 static struct mmc *init_mmc_device(int dev, bool force_init)
165 {
166         return __init_mmc_device(dev, force_init, MMC_MODES_END);
167 }
168
169 static int do_mmcinfo(struct cmd_tbl *cmdtp, int flag, int argc,
170                       char *const argv[])
171 {
172         struct mmc *mmc;
173
174         if (curr_device < 0) {
175                 if (get_mmc_num() > 0)
176                         curr_device = 0;
177                 else {
178                         puts("No MMC device available\n");
179                         return CMD_RET_FAILURE;
180                 }
181         }
182
183         mmc = init_mmc_device(curr_device, false);
184         if (!mmc)
185                 return CMD_RET_FAILURE;
186
187         print_mmcinfo(mmc);
188         return CMD_RET_SUCCESS;
189 }
190
191 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
192 static int confirm_key_prog(void)
193 {
194         puts("Warning: Programming authentication key can be done only once !\n"
195              "         Use this command only if you are sure of what you are doing,\n"
196              "Really perform the key programming? <y/N> ");
197         if (confirm_yesno())
198                 return 1;
199
200         puts("Authentication key programming aborted\n");
201         return 0;
202 }
203
204 static int do_mmcrpmb_key(struct cmd_tbl *cmdtp, int flag,
205                           int argc, char *const argv[])
206 {
207         void *key_addr;
208         struct mmc *mmc = find_mmc_device(curr_device);
209
210         if (argc != 2)
211                 return CMD_RET_USAGE;
212
213         key_addr = (void *)hextoul(argv[1], NULL);
214         if (!confirm_key_prog())
215                 return CMD_RET_FAILURE;
216         if (mmc_rpmb_set_key(mmc, key_addr)) {
217                 printf("ERROR - Key already programmed ?\n");
218                 return CMD_RET_FAILURE;
219         }
220         return CMD_RET_SUCCESS;
221 }
222
223 static int do_mmcrpmb_read(struct cmd_tbl *cmdtp, int flag,
224                            int argc, char *const argv[])
225 {
226         u16 blk, cnt;
227         void *addr;
228         int n;
229         void *key_addr = NULL;
230         struct mmc *mmc = find_mmc_device(curr_device);
231
232         if (argc < 4)
233                 return CMD_RET_USAGE;
234
235         addr = (void *)hextoul(argv[1], NULL);
236         blk = hextoul(argv[2], NULL);
237         cnt = hextoul(argv[3], NULL);
238
239         if (argc == 5)
240                 key_addr = (void *)hextoul(argv[4], NULL);
241
242         printf("MMC RPMB read: dev # %d, block # %d, count %d ... ",
243                curr_device, blk, cnt);
244         n =  mmc_rpmb_read(mmc, addr, blk, cnt, key_addr);
245
246         printf("%d RPMB blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
247         if (n != cnt)
248                 return CMD_RET_FAILURE;
249         return CMD_RET_SUCCESS;
250 }
251
252 static int do_mmcrpmb_write(struct cmd_tbl *cmdtp, int flag,
253                             int argc, char *const argv[])
254 {
255         u16 blk, cnt;
256         void *addr;
257         int n;
258         void *key_addr;
259         struct mmc *mmc = find_mmc_device(curr_device);
260
261         if (argc != 5)
262                 return CMD_RET_USAGE;
263
264         addr = (void *)hextoul(argv[1], NULL);
265         blk = hextoul(argv[2], NULL);
266         cnt = hextoul(argv[3], NULL);
267         key_addr = (void *)hextoul(argv[4], NULL);
268
269         printf("MMC RPMB write: dev # %d, block # %d, count %d ... ",
270                curr_device, blk, cnt);
271         n =  mmc_rpmb_write(mmc, addr, blk, cnt, key_addr);
272
273         printf("%d RPMB blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
274         if (n != cnt)
275                 return CMD_RET_FAILURE;
276         return CMD_RET_SUCCESS;
277 }
278
279 static int do_mmcrpmb_counter(struct cmd_tbl *cmdtp, int flag,
280                               int argc, char *const argv[])
281 {
282         unsigned long counter;
283         struct mmc *mmc = find_mmc_device(curr_device);
284
285         if (mmc_rpmb_get_counter(mmc, &counter))
286                 return CMD_RET_FAILURE;
287         printf("RPMB Write counter= %lx\n", counter);
288         return CMD_RET_SUCCESS;
289 }
290
291 static struct cmd_tbl cmd_rpmb[] = {
292         U_BOOT_CMD_MKENT(key, 2, 0, do_mmcrpmb_key, "", ""),
293         U_BOOT_CMD_MKENT(read, 5, 1, do_mmcrpmb_read, "", ""),
294         U_BOOT_CMD_MKENT(write, 5, 0, do_mmcrpmb_write, "", ""),
295         U_BOOT_CMD_MKENT(counter, 1, 1, do_mmcrpmb_counter, "", ""),
296 };
297
298 static int do_mmcrpmb(struct cmd_tbl *cmdtp, int flag,
299                       int argc, char *const argv[])
300 {
301         struct cmd_tbl *cp;
302         struct mmc *mmc;
303         char original_part;
304         int ret;
305
306         cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb));
307
308         /* Drop the rpmb subcommand */
309         argc--;
310         argv++;
311
312         if (cp == NULL || argc > cp->maxargs)
313                 return CMD_RET_USAGE;
314         if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
315                 return CMD_RET_SUCCESS;
316
317         mmc = init_mmc_device(curr_device, false);
318         if (!mmc)
319                 return CMD_RET_FAILURE;
320
321         if (!(mmc->version & MMC_VERSION_MMC)) {
322                 printf("It is not an eMMC device\n");
323                 return CMD_RET_FAILURE;
324         }
325         if (mmc->version < MMC_VERSION_4_41) {
326                 printf("RPMB not supported before version 4.41\n");
327                 return CMD_RET_FAILURE;
328         }
329         /* Switch to the RPMB partition */
330 #ifndef CONFIG_BLK
331         original_part = mmc->block_dev.hwpart;
332 #else
333         original_part = mmc_get_blk_desc(mmc)->hwpart;
334 #endif
335         if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, MMC_PART_RPMB) !=
336             0)
337                 return CMD_RET_FAILURE;
338         ret = cp->cmd(cmdtp, flag, argc, argv);
339
340         /* Return to original partition */
341         if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, original_part) !=
342             0)
343                 return CMD_RET_FAILURE;
344         return ret;
345 }
346 #endif
347
348 static int do_mmc_read(struct cmd_tbl *cmdtp, int flag,
349                        int argc, char *const argv[])
350 {
351         struct mmc *mmc;
352         u32 blk, cnt, n;
353         void *addr;
354
355         if (argc != 4)
356                 return CMD_RET_USAGE;
357
358         addr = (void *)hextoul(argv[1], NULL);
359         blk = hextoul(argv[2], NULL);
360         cnt = hextoul(argv[3], NULL);
361
362         mmc = init_mmc_device(curr_device, false);
363         if (!mmc)
364                 return CMD_RET_FAILURE;
365
366         printf("MMC read: dev # %d, block # %d, count %d ... ",
367                curr_device, blk, cnt);
368
369         n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
370         printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
371
372         return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
373 }
374
375 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
376 static lbaint_t mmc_sparse_write(struct sparse_storage *info, lbaint_t blk,
377                                  lbaint_t blkcnt, const void *buffer)
378 {
379         struct blk_desc *dev_desc = info->priv;
380
381         return blk_dwrite(dev_desc, blk, blkcnt, buffer);
382 }
383
384 static lbaint_t mmc_sparse_reserve(struct sparse_storage *info,
385                                    lbaint_t blk, lbaint_t blkcnt)
386 {
387         return blkcnt;
388 }
389
390 static int do_mmc_sparse_write(struct cmd_tbl *cmdtp, int flag,
391                                int argc, char *const argv[])
392 {
393         struct sparse_storage sparse;
394         struct blk_desc *dev_desc;
395         struct mmc *mmc;
396         char dest[11];
397         void *addr;
398         u32 blk;
399
400         if (argc != 3)
401                 return CMD_RET_USAGE;
402
403         addr = (void *)hextoul(argv[1], NULL);
404         blk = hextoul(argv[2], NULL);
405
406         if (!is_sparse_image(addr)) {
407                 printf("Not a sparse image\n");
408                 return CMD_RET_FAILURE;
409         }
410
411         mmc = init_mmc_device(curr_device, false);
412         if (!mmc)
413                 return CMD_RET_FAILURE;
414
415         printf("MMC Sparse write: dev # %d, block # %d ... ",
416                curr_device, blk);
417
418         if (mmc_getwp(mmc) == 1) {
419                 printf("Error: card is write protected!\n");
420                 return CMD_RET_FAILURE;
421         }
422
423         dev_desc = mmc_get_blk_desc(mmc);
424         sparse.priv = dev_desc;
425         sparse.blksz = 512;
426         sparse.start = blk;
427         sparse.size = dev_desc->lba - blk;
428         sparse.write = mmc_sparse_write;
429         sparse.reserve = mmc_sparse_reserve;
430         sparse.mssg = NULL;
431         sprintf(dest, "0x" LBAF, sparse.start * sparse.blksz);
432
433         if (write_sparse_image(&sparse, dest, addr, NULL))
434                 return CMD_RET_FAILURE;
435         else
436                 return CMD_RET_SUCCESS;
437 }
438 #endif
439
440 #if CONFIG_IS_ENABLED(MMC_WRITE)
441 static int do_mmc_write(struct cmd_tbl *cmdtp, int flag,
442                         int argc, char *const argv[])
443 {
444         struct mmc *mmc;
445         u32 blk, cnt, n;
446         void *addr;
447
448         if (argc != 4)
449                 return CMD_RET_USAGE;
450
451         addr = (void *)hextoul(argv[1], NULL);
452         blk = hextoul(argv[2], NULL);
453         cnt = hextoul(argv[3], NULL);
454
455         mmc = init_mmc_device(curr_device, false);
456         if (!mmc)
457                 return CMD_RET_FAILURE;
458
459         printf("MMC write: dev # %d, block # %d, count %d ... ",
460                curr_device, blk, cnt);
461
462         if (mmc_getwp(mmc) == 1) {
463                 printf("Error: card is write protected!\n");
464                 return CMD_RET_FAILURE;
465         }
466         n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
467         printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
468
469         return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
470 }
471
472 static int do_mmc_erase(struct cmd_tbl *cmdtp, int flag,
473                         int argc, char *const argv[])
474 {
475         struct mmc *mmc;
476         u32 blk, cnt, n;
477
478         if (argc != 3)
479                 return CMD_RET_USAGE;
480
481         blk = hextoul(argv[1], NULL);
482         cnt = hextoul(argv[2], NULL);
483
484         mmc = init_mmc_device(curr_device, false);
485         if (!mmc)
486                 return CMD_RET_FAILURE;
487
488         printf("MMC erase: dev # %d, block # %d, count %d ... ",
489                curr_device, blk, cnt);
490
491         if (mmc_getwp(mmc) == 1) {
492                 printf("Error: card is write protected!\n");
493                 return CMD_RET_FAILURE;
494         }
495         n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt);
496         printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
497
498         return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
499 }
500 #endif
501
502 static int do_mmc_rescan(struct cmd_tbl *cmdtp, int flag,
503                          int argc, char *const argv[])
504 {
505         struct mmc *mmc;
506
507         if (argc == 1) {
508                 mmc = init_mmc_device(curr_device, true);
509         } else if (argc == 2) {
510                 enum bus_mode speed_mode;
511
512                 speed_mode = (int)dectoul(argv[1], NULL);
513                 mmc = __init_mmc_device(curr_device, true, speed_mode);
514         } else {
515                 return CMD_RET_USAGE;
516         }
517
518         if (!mmc)
519                 return CMD_RET_FAILURE;
520
521         return CMD_RET_SUCCESS;
522 }
523
524 static int do_mmc_part(struct cmd_tbl *cmdtp, int flag,
525                        int argc, char *const argv[])
526 {
527         struct blk_desc *mmc_dev;
528         struct mmc *mmc;
529
530         mmc = init_mmc_device(curr_device, false);
531         if (!mmc)
532                 return CMD_RET_FAILURE;
533
534         mmc_dev = blk_get_devnum_by_uclass_id(UCLASS_MMC, curr_device);
535         if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
536                 part_print(mmc_dev);
537                 return CMD_RET_SUCCESS;
538         }
539
540         puts("get mmc type error!\n");
541         return CMD_RET_FAILURE;
542 }
543
544 static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag,
545                       int argc, char *const argv[])
546 {
547         int dev, part = 0, ret;
548         struct mmc *mmc;
549
550         if (argc == 1) {
551                 dev = curr_device;
552                 mmc = init_mmc_device(dev, true);
553         } else if (argc == 2) {
554                 dev = (int)dectoul(argv[1], NULL);
555                 mmc = init_mmc_device(dev, true);
556         } else if (argc == 3) {
557                 dev = (int)dectoul(argv[1], NULL);
558                 part = (int)dectoul(argv[2], NULL);
559                 if (part > PART_ACCESS_MASK) {
560                         printf("#part_num shouldn't be larger than %d\n",
561                                PART_ACCESS_MASK);
562                         return CMD_RET_FAILURE;
563                 }
564                 mmc = init_mmc_device(dev, true);
565         } else if (argc == 4) {
566                 enum bus_mode speed_mode;
567
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",
572                                PART_ACCESS_MASK);
573                         return CMD_RET_FAILURE;
574                 }
575                 speed_mode = (int)dectoul(argv[3], NULL);
576                 mmc = __init_mmc_device(dev, true, speed_mode);
577         } else {
578                 return CMD_RET_USAGE;
579         }
580
581         if (!mmc)
582                 return CMD_RET_FAILURE;
583
584         ret = blk_select_hwpart_devnum(UCLASS_MMC, dev, part);
585         printf("switch to partitions #%d, %s\n",
586                part, (!ret) ? "OK" : "ERROR");
587         if (ret)
588                 return 1;
589
590         curr_device = dev;
591         if (mmc->part_config == MMCPART_NOAVAILABLE)
592                 printf("mmc%d is current device\n", curr_device);
593         else
594                 printf("mmc%d(part %d) is current device\n",
595                        curr_device, mmc_get_blk_desc(mmc)->hwpart);
596
597         return CMD_RET_SUCCESS;
598 }
599
600 static int do_mmc_list(struct cmd_tbl *cmdtp, int flag,
601                        int argc, char *const argv[])
602 {
603         print_mmc_devices('\n');
604         return CMD_RET_SUCCESS;
605 }
606
607 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
608 static void parse_hwpart_user_enh_size(struct mmc *mmc,
609                                        struct mmc_hwpart_conf *pconf,
610                                        char *argv)
611 {
612         int i, ret;
613
614         pconf->user.enh_size = 0;
615
616         if (!strcmp(argv, "-")) { /* The rest of eMMC */
617                 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
618                 ret = mmc_send_ext_csd(mmc, ext_csd);
619                 if (ret)
620                         return;
621                 /* The enh_size value is in 512B block units */
622                 pconf->user.enh_size =
623                         ((ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16) +
624                         (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) +
625                         ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT]) * 1024 *
626                         ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
627                         ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
628                 pconf->user.enh_size -= pconf->user.enh_start;
629                 for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
630                         /*
631                          * If the eMMC already has GP partitions set,
632                          * subtract their size from the maximum USER
633                          * partition size.
634                          *
635                          * Else, if the command was used to configure new
636                          * GP partitions, subtract their size from maximum
637                          * USER partition size.
638                          */
639                         if (mmc->capacity_gp[i]) {
640                                 /* The capacity_gp is in 1B units */
641                                 pconf->user.enh_size -= mmc->capacity_gp[i] >> 9;
642                         } else if (pconf->gp_part[i].size) {
643                                 /* The gp_part[].size is in 512B units */
644                                 pconf->user.enh_size -= pconf->gp_part[i].size;
645                         }
646                 }
647         } else {
648                 pconf->user.enh_size = dectoul(argv, NULL);
649         }
650 }
651
652 static int parse_hwpart_user(struct mmc *mmc, struct mmc_hwpart_conf *pconf,
653                              int argc, char *const argv[])
654 {
655         int i = 0;
656
657         memset(&pconf->user, 0, sizeof(pconf->user));
658
659         while (i < argc) {
660                 if (!strcmp(argv[i], "enh")) {
661                         if (i + 2 >= argc)
662                                 return -1;
663                         pconf->user.enh_start =
664                                 dectoul(argv[i + 1], NULL);
665                         parse_hwpart_user_enh_size(mmc, pconf, argv[i + 2]);
666                         i += 3;
667                 } else if (!strcmp(argv[i], "wrrel")) {
668                         if (i + 1 >= argc)
669                                 return -1;
670                         pconf->user.wr_rel_change = 1;
671                         if (!strcmp(argv[i+1], "on"))
672                                 pconf->user.wr_rel_set = 1;
673                         else if (!strcmp(argv[i+1], "off"))
674                                 pconf->user.wr_rel_set = 0;
675                         else
676                                 return -1;
677                         i += 2;
678                 } else {
679                         break;
680                 }
681         }
682         return i;
683 }
684
685 static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx,
686                            int argc, char *const argv[])
687 {
688         int i;
689
690         memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx]));
691
692         if (1 >= argc)
693                 return -1;
694         pconf->gp_part[pidx].size = dectoul(argv[0], NULL);
695
696         i = 1;
697         while (i < argc) {
698                 if (!strcmp(argv[i], "enh")) {
699                         pconf->gp_part[pidx].enhanced = 1;
700                         i += 1;
701                 } else if (!strcmp(argv[i], "wrrel")) {
702                         if (i + 1 >= argc)
703                                 return -1;
704                         pconf->gp_part[pidx].wr_rel_change = 1;
705                         if (!strcmp(argv[i+1], "on"))
706                                 pconf->gp_part[pidx].wr_rel_set = 1;
707                         else if (!strcmp(argv[i+1], "off"))
708                                 pconf->gp_part[pidx].wr_rel_set = 0;
709                         else
710                                 return -1;
711                         i += 2;
712                 } else {
713                         break;
714                 }
715         }
716         return i;
717 }
718
719 static int do_mmc_hwpartition(struct cmd_tbl *cmdtp, int flag,
720                               int argc, char *const argv[])
721 {
722         struct mmc *mmc;
723         struct mmc_hwpart_conf pconf = { };
724         enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK;
725         int i, r, pidx;
726
727         mmc = init_mmc_device(curr_device, false);
728         if (!mmc)
729                 return CMD_RET_FAILURE;
730
731         if (IS_SD(mmc)) {
732                 puts("SD doesn't support partitioning\n");
733                 return CMD_RET_FAILURE;
734         }
735
736         if (argc < 1)
737                 return CMD_RET_USAGE;
738         i = 1;
739         while (i < argc) {
740                 if (!strcmp(argv[i], "user")) {
741                         i++;
742                         r = parse_hwpart_user(mmc, &pconf, argc - i, &argv[i]);
743                         if (r < 0)
744                                 return CMD_RET_USAGE;
745                         i += r;
746                 } else if (!strncmp(argv[i], "gp", 2) &&
747                            strlen(argv[i]) == 3 &&
748                            argv[i][2] >= '1' && argv[i][2] <= '4') {
749                         pidx = argv[i][2] - '1';
750                         i++;
751                         r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]);
752                         if (r < 0)
753                                 return CMD_RET_USAGE;
754                         i += r;
755                 } else if (!strcmp(argv[i], "check")) {
756                         mode = MMC_HWPART_CONF_CHECK;
757                         i++;
758                 } else if (!strcmp(argv[i], "set")) {
759                         mode = MMC_HWPART_CONF_SET;
760                         i++;
761                 } else if (!strcmp(argv[i], "complete")) {
762                         mode = MMC_HWPART_CONF_COMPLETE;
763                         i++;
764                 } else {
765                         return CMD_RET_USAGE;
766                 }
767         }
768
769         puts("Partition configuration:\n");
770         if (pconf.user.enh_size) {
771                 puts("\tUser Enhanced Start: ");
772                 print_size(((u64)pconf.user.enh_start) << 9, "\n");
773                 puts("\tUser Enhanced Size: ");
774                 print_size(((u64)pconf.user.enh_size) << 9, "\n");
775         } else {
776                 puts("\tNo enhanced user data area\n");
777         }
778         if (pconf.user.wr_rel_change)
779                 printf("\tUser partition write reliability: %s\n",
780                        pconf.user.wr_rel_set ? "on" : "off");
781         for (pidx = 0; pidx < 4; pidx++) {
782                 if (pconf.gp_part[pidx].size) {
783                         printf("\tGP%i Capacity: ", pidx+1);
784                         print_size(((u64)pconf.gp_part[pidx].size) << 9,
785                                    pconf.gp_part[pidx].enhanced ?
786                                    " ENH\n" : "\n");
787                 } else {
788                         printf("\tNo GP%i partition\n", pidx+1);
789                 }
790                 if (pconf.gp_part[pidx].wr_rel_change)
791                         printf("\tGP%i write reliability: %s\n", pidx+1,
792                                pconf.gp_part[pidx].wr_rel_set ? "on" : "off");
793         }
794
795         if (!mmc_hwpart_config(mmc, &pconf, mode)) {
796                 if (mode == MMC_HWPART_CONF_COMPLETE)
797                         puts("Partitioning successful, "
798                              "power-cycle to make effective\n");
799                 return CMD_RET_SUCCESS;
800         } else {
801                 puts("Failed!\n");
802                 return CMD_RET_FAILURE;
803         }
804 }
805 #endif
806
807 #ifdef CONFIG_SUPPORT_EMMC_BOOT
808 static int do_mmc_bootbus(struct cmd_tbl *cmdtp, int flag,
809                           int argc, char *const argv[])
810 {
811         int dev;
812         struct mmc *mmc;
813         u8 width, reset, mode;
814
815         if (argc != 5)
816                 return CMD_RET_USAGE;
817         dev = dectoul(argv[1], NULL);
818         width = dectoul(argv[2], NULL);
819         reset = dectoul(argv[3], NULL);
820         mode = dectoul(argv[4], NULL);
821
822         mmc = init_mmc_device(dev, false);
823         if (!mmc)
824                 return CMD_RET_FAILURE;
825
826         if (IS_SD(mmc)) {
827                 puts("BOOT_BUS_WIDTH only exists on eMMC\n");
828                 return CMD_RET_FAILURE;
829         }
830
831         /*
832          * BOOT_BUS_CONDITIONS[177]
833          * BOOT_MODE[4:3]
834          * 0x0 : Use SDR + Backward compatible timing in boot operation
835          * 0x1 : Use SDR + High Speed Timing in boot operation mode
836          * 0x2 : Use DDR in boot operation
837          * RESET_BOOT_BUS_CONDITIONS
838          * 0x0 : Reset bus width to x1, SDR, Backward compatible
839          * 0x1 : Retain BOOT_BUS_WIDTH and BOOT_MODE
840          * BOOT_BUS_WIDTH
841          * 0x0 : x1(sdr) or x4 (ddr) buswidth
842          * 0x1 : x4(sdr/ddr) buswith
843          * 0x2 : x8(sdr/ddr) buswith
844          *
845          */
846         if (width >= 0x3) {
847                 printf("boot_bus_width %d is invalid\n", width);
848                 return CMD_RET_FAILURE;
849         }
850
851         if (reset >= 0x2) {
852                 printf("reset_boot_bus_width %d is invalid\n", reset);
853                 return CMD_RET_FAILURE;
854         }
855
856         if (mode >= 0x3) {
857                 printf("reset_boot_bus_width %d is invalid\n", mode);
858                 return CMD_RET_FAILURE;
859         }
860
861         /* acknowledge to be sent during boot operation */
862         if (mmc_set_boot_bus_width(mmc, width, reset, mode)) {
863                 puts("BOOT_BUS_WIDTH is failed to change.\n");
864                 return CMD_RET_FAILURE;
865         }
866
867         printf("Set to BOOT_BUS_WIDTH = 0x%x, RESET = 0x%x, BOOT_MODE = 0x%x\n",
868                         width, reset, mode);
869         return CMD_RET_SUCCESS;
870 }
871
872 static int do_mmc_boot_resize(struct cmd_tbl *cmdtp, int flag,
873                               int argc, char *const argv[])
874 {
875         int dev;
876         struct mmc *mmc;
877         u32 bootsize, rpmbsize;
878
879         if (argc != 4)
880                 return CMD_RET_USAGE;
881         dev = dectoul(argv[1], NULL);
882         bootsize = dectoul(argv[2], NULL);
883         rpmbsize = dectoul(argv[3], NULL);
884
885         mmc = init_mmc_device(dev, false);
886         if (!mmc)
887                 return CMD_RET_FAILURE;
888
889         if (IS_SD(mmc)) {
890                 printf("It is not an eMMC device\n");
891                 return CMD_RET_FAILURE;
892         }
893
894         if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) {
895                 printf("EMMC boot partition Size change Failed.\n");
896                 return CMD_RET_FAILURE;
897         }
898
899         printf("EMMC boot partition Size %d MB\n", bootsize);
900         printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
901         return CMD_RET_SUCCESS;
902 }
903
904 static int mmc_partconf_print(struct mmc *mmc, const char *varname)
905 {
906         u8 ack, access, part;
907
908         if (mmc->part_config == MMCPART_NOAVAILABLE) {
909                 printf("No part_config info for ver. 0x%x\n", mmc->version);
910                 return CMD_RET_FAILURE;
911         }
912
913         access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config);
914         ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config);
915         part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
916
917         if(varname)
918                 env_set_hex(varname, part);
919
920         printf("EXT_CSD[179], PARTITION_CONFIG:\n"
921                 "BOOT_ACK: 0x%x\n"
922                 "BOOT_PARTITION_ENABLE: 0x%x (%s)\n"
923                 "PARTITION_ACCESS: 0x%x (%s)\n", ack, part, emmc_boot_part_names[part],
924                 access, emmc_hwpart_names[access]);
925
926         return CMD_RET_SUCCESS;
927 }
928
929 static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
930                            int argc, char *const argv[])
931 {
932         int ret, dev;
933         struct mmc *mmc;
934         u8 ack, part_num, access;
935
936         if (argc != 2 && argc != 3 && argc != 5)
937                 return CMD_RET_USAGE;
938
939         dev = dectoul(argv[1], NULL);
940
941         mmc = init_mmc_device(dev, false);
942         if (!mmc)
943                 return CMD_RET_FAILURE;
944
945         if (IS_SD(mmc)) {
946                 puts("PARTITION_CONFIG only exists on eMMC\n");
947                 return CMD_RET_FAILURE;
948         }
949
950         if (argc == 2 || argc == 3)
951                 return mmc_partconf_print(mmc, cmd_arg2(argc, argv));
952
953         /* BOOT_ACK */
954         ack = dectoul(argv[2], NULL);
955         /* BOOT_PARTITION_ENABLE */
956         if (!isdigit(*argv[3])) {
957                 for (part_num = ARRAY_SIZE(emmc_boot_part_names) - 1; part_num > 0; part_num--) {
958                         if (!strcmp(argv[3], emmc_boot_part_names[part_num]))
959                                 break;
960                 }
961         } else {
962                 part_num = dectoul(argv[3], NULL);
963         }
964         /* PARTITION_ACCESS */
965         if (!isdigit(*argv[4])) {
966                 for (access = ARRAY_SIZE(emmc_hwpart_names) - 1; access > 0; access--) {
967                         if (!strcmp(argv[4], emmc_hwpart_names[access]))
968                                 break;
969                 }
970         } else {
971                 access = dectoul(argv[4], NULL);
972         }
973
974         /* acknowledge to be sent during boot operation */
975         ret = mmc_set_part_conf(mmc, ack, part_num, access);
976         if (ret != 0)
977                 return CMD_RET_FAILURE;
978
979         return CMD_RET_SUCCESS;
980 }
981
982 static int do_mmc_rst_func(struct cmd_tbl *cmdtp, int flag,
983                            int argc, char *const argv[])
984 {
985         int ret, dev;
986         struct mmc *mmc;
987         u8 enable;
988
989         /*
990          * Set the RST_n_ENABLE bit of RST_n_FUNCTION
991          * The only valid values are 0x0, 0x1 and 0x2 and writing
992          * a value of 0x1 or 0x2 sets the value permanently.
993          */
994         if (argc != 3)
995                 return CMD_RET_USAGE;
996
997         dev = dectoul(argv[1], NULL);
998         enable = dectoul(argv[2], NULL);
999
1000         if (enable > 2) {
1001                 puts("Invalid RST_n_ENABLE value\n");
1002                 return CMD_RET_USAGE;
1003         }
1004
1005         mmc = init_mmc_device(dev, false);
1006         if (!mmc)
1007                 return CMD_RET_FAILURE;
1008
1009         if (IS_SD(mmc)) {
1010                 puts("RST_n_FUNCTION only exists on eMMC\n");
1011                 return CMD_RET_FAILURE;
1012         }
1013
1014         ret = mmc_set_rst_n_function(mmc, enable);
1015         if (ret != 0)
1016                 return CMD_RET_FAILURE;
1017
1018         return CMD_RET_SUCCESS;
1019 }
1020 #endif
1021 static int do_mmc_setdsr(struct cmd_tbl *cmdtp, int flag,
1022                          int argc, char *const argv[])
1023 {
1024         struct mmc *mmc;
1025         u32 val;
1026         int ret;
1027
1028         if (argc != 2)
1029                 return CMD_RET_USAGE;
1030         val = hextoul(argv[1], NULL);
1031
1032         mmc = find_mmc_device(curr_device);
1033         if (!mmc) {
1034                 printf("no mmc device at slot %x\n", curr_device);
1035                 return CMD_RET_FAILURE;
1036         }
1037         ret = mmc_set_dsr(mmc, val);
1038         printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR");
1039         if (!ret) {
1040                 mmc->has_init = 0;
1041                 if (mmc_init(mmc))
1042                         return CMD_RET_FAILURE;
1043                 else
1044                         return CMD_RET_SUCCESS;
1045         }
1046         return ret;
1047 }
1048
1049 #ifdef CONFIG_CMD_BKOPS_ENABLE
1050 static int mmc_bkops_common(char *device, bool autobkops, bool enable)
1051 {
1052         struct mmc *mmc;
1053         int dev;
1054
1055         dev = dectoul(device, NULL);
1056
1057         mmc = init_mmc_device(dev, false);
1058         if (!mmc)
1059                 return CMD_RET_FAILURE;
1060
1061         if (IS_SD(mmc)) {
1062                 puts("BKOPS_EN only exists on eMMC\n");
1063                 return CMD_RET_FAILURE;
1064         }
1065
1066         return mmc_set_bkops_enable(mmc, autobkops, enable);
1067 }
1068
1069 static int do_mmc_bkops(struct cmd_tbl *cmdtp, int flag,
1070                         int argc, char * const argv[])
1071 {
1072         bool autobkops, enable;
1073
1074         if (argc != 4)
1075                 return CMD_RET_USAGE;
1076
1077         if (!strcmp(argv[2], "manual"))
1078                 autobkops = false;
1079         else if (!strcmp(argv[2], "auto"))
1080                 autobkops = true;
1081         else
1082                 return CMD_RET_FAILURE;
1083
1084         if (!strcmp(argv[3], "disable"))
1085                 enable = false;
1086         else if (!strcmp(argv[3], "enable"))
1087                 enable = true;
1088         else
1089                 return CMD_RET_FAILURE;
1090
1091         return mmc_bkops_common(argv[1], autobkops, enable);
1092 }
1093
1094 static int do_mmc_bkops_enable(struct cmd_tbl *cmdtp, int flag,
1095                                int argc, char * const argv[])
1096 {
1097         if (argc != 2)
1098                 return CMD_RET_USAGE;
1099
1100         return mmc_bkops_common(argv[1], false, true);
1101 }
1102 #endif
1103
1104 static int do_mmc_boot_wp(struct cmd_tbl *cmdtp, int flag,
1105                           int argc, char * const argv[])
1106 {
1107         int err;
1108         struct mmc *mmc;
1109         int part;
1110
1111         mmc = init_mmc_device(curr_device, false);
1112         if (!mmc)
1113                 return CMD_RET_FAILURE;
1114         if (IS_SD(mmc)) {
1115                 printf("It is not an eMMC device\n");
1116                 return CMD_RET_FAILURE;
1117         }
1118
1119         if (argc == 2) {
1120                 part = dectoul(argv[1], NULL);
1121                 err = mmc_boot_wp_single_partition(mmc, part);
1122         } else {
1123                 err = mmc_boot_wp(mmc);
1124         }
1125
1126         if (err)
1127                 return CMD_RET_FAILURE;
1128         printf("boot areas protected\n");
1129         return CMD_RET_SUCCESS;
1130 }
1131
1132 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1133 static int do_mmc_reg(struct cmd_tbl *cmdtp, int flag,
1134                       int argc, char *const argv[])
1135 {
1136         ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1137         struct mmc *mmc;
1138         int i, ret;
1139         u32 off;
1140
1141         if (argc < 3 || argc > 5)
1142                 return CMD_RET_USAGE;
1143
1144         mmc = find_mmc_device(curr_device);
1145         if (!mmc) {
1146                 printf("no mmc device at slot %x\n", curr_device);
1147                 return CMD_RET_FAILURE;
1148         }
1149
1150         if (IS_SD(mmc)) {
1151                 printf("SD registers are not supported\n");
1152                 return CMD_RET_FAILURE;
1153         }
1154
1155         off = simple_strtoul(argv[3], NULL, 10);
1156         if (!strcmp(argv[2], "cid")) {
1157                 if (off > 3)
1158                         return CMD_RET_USAGE;
1159                 printf("CID[%i]: 0x%08x\n", off, mmc->cid[off]);
1160                 if (argv[4])
1161                         env_set_hex(argv[4], mmc->cid[off]);
1162                 return CMD_RET_SUCCESS;
1163         }
1164         if (!strcmp(argv[2], "csd")) {
1165                 if (off > 3)
1166                         return CMD_RET_USAGE;
1167                 printf("CSD[%i]: 0x%08x\n", off, mmc->csd[off]);
1168                 if (argv[4])
1169                         env_set_hex(argv[4], mmc->csd[off]);
1170                 return CMD_RET_SUCCESS;
1171         }
1172         if (!strcmp(argv[2], "dsr")) {
1173                 printf("DSR: 0x%08x\n", mmc->dsr);
1174                 if (argv[4])
1175                         env_set_hex(argv[4], mmc->dsr);
1176                 return CMD_RET_SUCCESS;
1177         }
1178         if (!strcmp(argv[2], "ocr")) {
1179                 printf("OCR: 0x%08x\n", mmc->ocr);
1180                 if (argv[4])
1181                         env_set_hex(argv[4], mmc->ocr);
1182                 return CMD_RET_SUCCESS;
1183         }
1184         if (!strcmp(argv[2], "rca")) {
1185                 printf("RCA: 0x%08x\n", mmc->rca);
1186                 if (argv[4])
1187                         env_set_hex(argv[4], mmc->rca);
1188                 return CMD_RET_SUCCESS;
1189         }
1190         if (!strcmp(argv[2], "extcsd") &&
1191             mmc->version >= MMC_VERSION_4_41) {
1192                 ret = mmc_send_ext_csd(mmc, ext_csd);
1193                 if (ret)
1194                         return CMD_RET_FAILURE;
1195                 if (!strcmp(argv[3], "all")) {
1196                         /* Dump the entire register */
1197                         printf("EXT_CSD:");
1198                         for (i = 0; i < MMC_MAX_BLOCK_LEN; i++) {
1199                                 if (!(i % 10))
1200                                         printf("\n%03i: ", i);
1201                                 printf(" %02x", ext_csd[i]);
1202                         }
1203                         printf("\n");
1204                         return CMD_RET_SUCCESS;
1205                 }
1206                 off = simple_strtoul(argv[3], NULL, 10);
1207                 if (off > 512)
1208                         return CMD_RET_USAGE;
1209                 printf("EXT_CSD[%i]: 0x%02x\n", off, ext_csd[off]);
1210                 if (argv[4])
1211                         env_set_hex(argv[4], ext_csd[off]);
1212                 return CMD_RET_SUCCESS;
1213         }
1214
1215         return CMD_RET_FAILURE;
1216 }
1217 #endif
1218
1219 static struct cmd_tbl cmd_mmc[] = {
1220         U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
1221         U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
1222         U_BOOT_CMD_MKENT(wp, 2, 0, do_mmc_boot_wp, "", ""),
1223 #if CONFIG_IS_ENABLED(MMC_WRITE)
1224         U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
1225         U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
1226 #endif
1227 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1228         U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
1229 #endif
1230         U_BOOT_CMD_MKENT(rescan, 2, 1, do_mmc_rescan, "", ""),
1231         U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
1232         U_BOOT_CMD_MKENT(dev, 4, 0, do_mmc_dev, "", ""),
1233         U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
1234 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1235         U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
1236 #endif
1237 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1238         U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
1239         U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
1240         U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
1241         U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
1242 #endif
1243 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1244         U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""),
1245 #endif
1246         U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
1247 #ifdef CONFIG_CMD_BKOPS_ENABLE
1248         U_BOOT_CMD_MKENT(bkops-enable, 2, 0, do_mmc_bkops_enable, "", ""),
1249         U_BOOT_CMD_MKENT(bkops, 4, 0, do_mmc_bkops, "", ""),
1250 #endif
1251 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1252         U_BOOT_CMD_MKENT(reg, 5, 0, do_mmc_reg, "", ""),
1253 #endif
1254 };
1255
1256 static int do_mmcops(struct cmd_tbl *cmdtp, int flag, int argc,
1257                      char *const argv[])
1258 {
1259         struct cmd_tbl *cp;
1260
1261         cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc));
1262
1263         /* Drop the mmc command */
1264         argc--;
1265         argv++;
1266
1267         if (cp == NULL || argc > cp->maxargs)
1268                 return CMD_RET_USAGE;
1269         if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
1270                 return CMD_RET_SUCCESS;
1271
1272         if (curr_device < 0) {
1273                 if (get_mmc_num() > 0) {
1274                         curr_device = 0;
1275                 } else {
1276                         puts("No MMC device available\n");
1277                         return CMD_RET_FAILURE;
1278                 }
1279         }
1280         return cp->cmd(cmdtp, flag, argc, argv);
1281 }
1282
1283 U_BOOT_CMD(
1284         mmc, 29, 1, do_mmcops,
1285         "MMC sub system",
1286         "info - display info of the current MMC device\n"
1287         "mmc read addr blk# cnt\n"
1288         "mmc write addr blk# cnt\n"
1289 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1290         "mmc swrite addr blk#\n"
1291 #endif
1292         "mmc erase blk# cnt\n"
1293         "mmc rescan [mode]\n"
1294         "mmc part - lists available partition on current mmc device\n"
1295         "mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode\n"
1296         "  - the required speed mode is passed as the index from the following list\n"
1297         "    [MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25,\n"
1298         "    UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES]\n"
1299         "mmc list - lists available devices\n"
1300         "mmc wp [PART] - power on write protect boot partitions\n"
1301         "  arguments:\n"
1302         "   PART - [0|1]\n"
1303         "       : 0 - first boot partition, 1 - second boot partition\n"
1304         "         if not assigned, write protect all boot partitions\n"
1305 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1306         "mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning\n"
1307         "  arguments (sizes in 512-byte blocks):\n"
1308         "   USER - <user> <enh> <start> <cnt> <wrrel> <{on|off}>\n"
1309         "       : sets user data area attributes\n"
1310         "   GP - <{gp1|gp2|gp3|gp4}> <cnt> <enh> <wrrel> <{on|off}>\n"
1311         "       : general purpose partition\n"
1312         "   MODE - <{check|set|complete}>\n"
1313         "       : mode, complete set partitioning completed\n"
1314         "  WARNING: Partitioning is a write-once setting once it is set to complete.\n"
1315         "  Power cycling is required to initialize partitions after set to complete.\n"
1316 #endif
1317 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1318         "mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode>\n"
1319         " - Set the BOOT_BUS_WIDTH field of the specified device\n"
1320         "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
1321         " - Change sizes of boot and RPMB partitions of specified device\n"
1322         "mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]]\n"
1323         " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n"
1324         "   If showing the bits, optionally store the boot_partition field into varname\n"
1325         "mmc rst-function <dev> <value>\n"
1326         " - Change the RST_n_FUNCTION field of the specified device\n"
1327         "   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
1328 #endif
1329 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1330         "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
1331         "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
1332         "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"
1333         "mmc rpmb counter - read the value of the write counter\n"
1334 #endif
1335         "mmc setdsr <value> - set DSR register value\n"
1336 #ifdef CONFIG_CMD_BKOPS_ENABLE
1337         "mmc bkops-enable <dev> - enable background operations handshake on device\n"
1338         "   WARNING: This is a write-once setting.\n"
1339         "mmc bkops <dev> [auto|manual] [enable|disable]\n"
1340         " - configure background operations handshake on device\n"
1341 #endif
1342 #if CONFIG_IS_ENABLED(CMD_MMC_REG)
1343         "mmc reg read <reg> <offset> [env] - read card register <reg> offset <offset>\n"
1344         "                                    (optionally into [env] variable)\n"
1345         " - reg: cid/csd/dsr/ocr/rca/extcsd\n"
1346         " - offset: for cid/csd [0..3], for extcsd [0..511,all]\n"
1347 #endif
1348         );
1349
1350 /* Old command kept for compatibility. Same as 'mmc info' */
1351 U_BOOT_CMD(
1352         mmcinfo, 1, 0, do_mmcinfo,
1353         "display MMC info",
1354         "- display info of the current MMC device"
1355 );
This page took 0.11072 seconds and 4 git commands to generate.