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