Merge https://source.denx.de/u-boot/custodians/u-boot-mmc
[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         enum bus_mode speed_mode = MMC_MODES_END;
505
506         if (argc == 1) {
507                 mmc = init_mmc_device(curr_device, true);
508         } else if (argc == 2) {
509                 speed_mode = (int)dectoul(argv[1], NULL);
510                 mmc = __init_mmc_device(curr_device, true, speed_mode);
511         } else {
512                 return CMD_RET_USAGE;
513         }
514
515         if (!mmc)
516                 return CMD_RET_FAILURE;
517
518         return CMD_RET_SUCCESS;
519 }
520
521 static int do_mmc_part(struct cmd_tbl *cmdtp, int flag,
522                        int argc, char *const argv[])
523 {
524         struct blk_desc *mmc_dev;
525         struct mmc *mmc;
526
527         mmc = init_mmc_device(curr_device, false);
528         if (!mmc)
529                 return CMD_RET_FAILURE;
530
531         mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device);
532         if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
533                 part_print(mmc_dev);
534                 return CMD_RET_SUCCESS;
535         }
536
537         puts("get mmc type error!\n");
538         return CMD_RET_FAILURE;
539 }
540
541 static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag,
542                       int argc, char *const argv[])
543 {
544         int dev, part = 0, ret;
545         struct mmc *mmc;
546         enum bus_mode speed_mode = MMC_MODES_END;
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                 dev = (int)dectoul(argv[1], NULL);
565                 part = (int)dectoul(argv[2], NULL);
566                 if (part > PART_ACCESS_MASK) {
567                         printf("#part_num shouldn't be larger than %d\n",
568                                PART_ACCESS_MASK);
569                         return CMD_RET_FAILURE;
570                 }
571                 speed_mode = (int)dectoul(argv[3], NULL);
572                 mmc = __init_mmc_device(dev, true, speed_mode);
573         } else {
574                 return CMD_RET_USAGE;
575         }
576
577         if (!mmc)
578                 return CMD_RET_FAILURE;
579
580         ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
581         printf("switch to partitions #%d, %s\n",
582                part, (!ret) ? "OK" : "ERROR");
583         if (ret)
584                 return 1;
585
586         curr_device = dev;
587         if (mmc->part_config == MMCPART_NOAVAILABLE)
588                 printf("mmc%d is current device\n", curr_device);
589         else
590                 printf("mmc%d(part %d) is current device\n",
591                        curr_device, mmc_get_blk_desc(mmc)->hwpart);
592
593         return CMD_RET_SUCCESS;
594 }
595
596 static int do_mmc_list(struct cmd_tbl *cmdtp, int flag,
597                        int argc, char *const argv[])
598 {
599         print_mmc_devices('\n');
600         return CMD_RET_SUCCESS;
601 }
602
603 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
604 static void parse_hwpart_user_enh_size(struct mmc *mmc,
605                                        struct mmc_hwpart_conf *pconf,
606                                        char *argv)
607 {
608         int i, ret;
609
610         pconf->user.enh_size = 0;
611
612         if (!strcmp(argv, "-")) { /* The rest of eMMC */
613                 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
614                 ret = mmc_send_ext_csd(mmc, ext_csd);
615                 if (ret)
616                         return;
617                 /* The enh_size value is in 512B block units */
618                 pconf->user.enh_size =
619                         ((ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16) +
620                         (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) +
621                         ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT]) * 1024 *
622                         ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
623                         ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
624                 pconf->user.enh_size -= pconf->user.enh_start;
625                 for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
626                         /*
627                          * If the eMMC already has GP partitions set,
628                          * subtract their size from the maximum USER
629                          * partition size.
630                          *
631                          * Else, if the command was used to configure new
632                          * GP partitions, subtract their size from maximum
633                          * USER partition size.
634                          */
635                         if (mmc->capacity_gp[i]) {
636                                 /* The capacity_gp is in 1B units */
637                                 pconf->user.enh_size -= mmc->capacity_gp[i] >> 9;
638                         } else if (pconf->gp_part[i].size) {
639                                 /* The gp_part[].size is in 512B units */
640                                 pconf->user.enh_size -= pconf->gp_part[i].size;
641                         }
642                 }
643         } else {
644                 pconf->user.enh_size = dectoul(argv, NULL);
645         }
646 }
647
648 static int parse_hwpart_user(struct mmc *mmc, struct mmc_hwpart_conf *pconf,
649                              int argc, char *const argv[])
650 {
651         int i = 0;
652
653         memset(&pconf->user, 0, sizeof(pconf->user));
654
655         while (i < argc) {
656                 if (!strcmp(argv[i], "enh")) {
657                         if (i + 2 >= argc)
658                                 return -1;
659                         pconf->user.enh_start =
660                                 dectoul(argv[i + 1], NULL);
661                         parse_hwpart_user_enh_size(mmc, pconf, argv[i + 2]);
662                         i += 3;
663                 } else if (!strcmp(argv[i], "wrrel")) {
664                         if (i + 1 >= argc)
665                                 return -1;
666                         pconf->user.wr_rel_change = 1;
667                         if (!strcmp(argv[i+1], "on"))
668                                 pconf->user.wr_rel_set = 1;
669                         else if (!strcmp(argv[i+1], "off"))
670                                 pconf->user.wr_rel_set = 0;
671                         else
672                                 return -1;
673                         i += 2;
674                 } else {
675                         break;
676                 }
677         }
678         return i;
679 }
680
681 static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx,
682                            int argc, char *const argv[])
683 {
684         int i;
685
686         memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx]));
687
688         if (1 >= argc)
689                 return -1;
690         pconf->gp_part[pidx].size = dectoul(argv[0], NULL);
691
692         i = 1;
693         while (i < argc) {
694                 if (!strcmp(argv[i], "enh")) {
695                         pconf->gp_part[pidx].enhanced = 1;
696                         i += 1;
697                 } else if (!strcmp(argv[i], "wrrel")) {
698                         if (i + 1 >= argc)
699                                 return -1;
700                         pconf->gp_part[pidx].wr_rel_change = 1;
701                         if (!strcmp(argv[i+1], "on"))
702                                 pconf->gp_part[pidx].wr_rel_set = 1;
703                         else if (!strcmp(argv[i+1], "off"))
704                                 pconf->gp_part[pidx].wr_rel_set = 0;
705                         else
706                                 return -1;
707                         i += 2;
708                 } else {
709                         break;
710                 }
711         }
712         return i;
713 }
714
715 static int do_mmc_hwpartition(struct cmd_tbl *cmdtp, int flag,
716                               int argc, char *const argv[])
717 {
718         struct mmc *mmc;
719         struct mmc_hwpart_conf pconf = { };
720         enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK;
721         int i, r, pidx;
722
723         mmc = init_mmc_device(curr_device, false);
724         if (!mmc)
725                 return CMD_RET_FAILURE;
726
727         if (IS_SD(mmc)) {
728                 puts("SD doesn't support partitioning\n");
729                 return CMD_RET_FAILURE;
730         }
731
732         if (argc < 1)
733                 return CMD_RET_USAGE;
734         i = 1;
735         while (i < argc) {
736                 if (!strcmp(argv[i], "user")) {
737                         i++;
738                         r = parse_hwpart_user(mmc, &pconf, argc - i, &argv[i]);
739                         if (r < 0)
740                                 return CMD_RET_USAGE;
741                         i += r;
742                 } else if (!strncmp(argv[i], "gp", 2) &&
743                            strlen(argv[i]) == 3 &&
744                            argv[i][2] >= '1' && argv[i][2] <= '4') {
745                         pidx = argv[i][2] - '1';
746                         i++;
747                         r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]);
748                         if (r < 0)
749                                 return CMD_RET_USAGE;
750                         i += r;
751                 } else if (!strcmp(argv[i], "check")) {
752                         mode = MMC_HWPART_CONF_CHECK;
753                         i++;
754                 } else if (!strcmp(argv[i], "set")) {
755                         mode = MMC_HWPART_CONF_SET;
756                         i++;
757                 } else if (!strcmp(argv[i], "complete")) {
758                         mode = MMC_HWPART_CONF_COMPLETE;
759                         i++;
760                 } else {
761                         return CMD_RET_USAGE;
762                 }
763         }
764
765         puts("Partition configuration:\n");
766         if (pconf.user.enh_size) {
767                 puts("\tUser Enhanced Start: ");
768                 print_size(((u64)pconf.user.enh_start) << 9, "\n");
769                 puts("\tUser Enhanced Size: ");
770                 print_size(((u64)pconf.user.enh_size) << 9, "\n");
771         } else {
772                 puts("\tNo enhanced user data area\n");
773         }
774         if (pconf.user.wr_rel_change)
775                 printf("\tUser partition write reliability: %s\n",
776                        pconf.user.wr_rel_set ? "on" : "off");
777         for (pidx = 0; pidx < 4; pidx++) {
778                 if (pconf.gp_part[pidx].size) {
779                         printf("\tGP%i Capacity: ", pidx+1);
780                         print_size(((u64)pconf.gp_part[pidx].size) << 9,
781                                    pconf.gp_part[pidx].enhanced ?
782                                    " ENH\n" : "\n");
783                 } else {
784                         printf("\tNo GP%i partition\n", pidx+1);
785                 }
786                 if (pconf.gp_part[pidx].wr_rel_change)
787                         printf("\tGP%i write reliability: %s\n", pidx+1,
788                                pconf.gp_part[pidx].wr_rel_set ? "on" : "off");
789         }
790
791         if (!mmc_hwpart_config(mmc, &pconf, mode)) {
792                 if (mode == MMC_HWPART_CONF_COMPLETE)
793                         puts("Partitioning successful, "
794                              "power-cycle to make effective\n");
795                 return CMD_RET_SUCCESS;
796         } else {
797                 puts("Failed!\n");
798                 return CMD_RET_FAILURE;
799         }
800 }
801 #endif
802
803 #ifdef CONFIG_SUPPORT_EMMC_BOOT
804 static int do_mmc_bootbus(struct cmd_tbl *cmdtp, int flag,
805                           int argc, char *const argv[])
806 {
807         int dev;
808         struct mmc *mmc;
809         u8 width, reset, mode;
810
811         if (argc != 5)
812                 return CMD_RET_USAGE;
813         dev = dectoul(argv[1], NULL);
814         width = dectoul(argv[2], NULL);
815         reset = dectoul(argv[3], NULL);
816         mode = dectoul(argv[4], NULL);
817
818         mmc = init_mmc_device(dev, false);
819         if (!mmc)
820                 return CMD_RET_FAILURE;
821
822         if (IS_SD(mmc)) {
823                 puts("BOOT_BUS_WIDTH only exists on eMMC\n");
824                 return CMD_RET_FAILURE;
825         }
826
827         /*
828          * BOOT_BUS_CONDITIONS[177]
829          * BOOT_MODE[4:3]
830          * 0x0 : Use SDR + Backward compatible timing in boot operation
831          * 0x1 : Use SDR + High Speed Timing in boot operation mode
832          * 0x2 : Use DDR in boot operation
833          * RESET_BOOT_BUS_CONDITIONS
834          * 0x0 : Reset bus width to x1, SDR, Backward compatible
835          * 0x1 : Retain BOOT_BUS_WIDTH and BOOT_MODE
836          * BOOT_BUS_WIDTH
837          * 0x0 : x1(sdr) or x4 (ddr) buswidth
838          * 0x1 : x4(sdr/ddr) buswith
839          * 0x2 : x8(sdr/ddr) buswith
840          *
841          */
842         if (width >= 0x3) {
843                 printf("boot_bus_width %d is invalid\n", width);
844                 return CMD_RET_FAILURE;
845         }
846
847         if (reset >= 0x2) {
848                 printf("reset_boot_bus_width %d is invalid\n", reset);
849                 return CMD_RET_FAILURE;
850         }
851
852         if (mode >= 0x3) {
853                 printf("reset_boot_bus_width %d is invalid\n", mode);
854                 return CMD_RET_FAILURE;
855         }
856
857         /* acknowledge to be sent during boot operation */
858         if (mmc_set_boot_bus_width(mmc, width, reset, mode)) {
859                 puts("BOOT_BUS_WIDTH is failed to change.\n");
860                 return CMD_RET_FAILURE;
861         }
862
863         printf("Set to BOOT_BUS_WIDTH = 0x%x, RESET = 0x%x, BOOT_MODE = 0x%x\n",
864                         width, reset, mode);
865         return CMD_RET_SUCCESS;
866 }
867
868 static int do_mmc_boot_resize(struct cmd_tbl *cmdtp, int flag,
869                               int argc, char *const argv[])
870 {
871         int dev;
872         struct mmc *mmc;
873         u32 bootsize, rpmbsize;
874
875         if (argc != 4)
876                 return CMD_RET_USAGE;
877         dev = dectoul(argv[1], NULL);
878         bootsize = dectoul(argv[2], NULL);
879         rpmbsize = dectoul(argv[3], NULL);
880
881         mmc = init_mmc_device(dev, false);
882         if (!mmc)
883                 return CMD_RET_FAILURE;
884
885         if (IS_SD(mmc)) {
886                 printf("It is not an eMMC device\n");
887                 return CMD_RET_FAILURE;
888         }
889
890         if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) {
891                 printf("EMMC boot partition Size change Failed.\n");
892                 return CMD_RET_FAILURE;
893         }
894
895         printf("EMMC boot partition Size %d MB\n", bootsize);
896         printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
897         return CMD_RET_SUCCESS;
898 }
899
900 static int mmc_partconf_print(struct mmc *mmc, const char *varname)
901 {
902         u8 ack, access, part;
903
904         if (mmc->part_config == MMCPART_NOAVAILABLE) {
905                 printf("No part_config info for ver. 0x%x\n", mmc->version);
906                 return CMD_RET_FAILURE;
907         }
908
909         access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config);
910         ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config);
911         part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
912
913         if(varname)
914                 env_set_hex(varname, part);
915
916         printf("EXT_CSD[179], PARTITION_CONFIG:\n"
917                 "BOOT_ACK: 0x%x\n"
918                 "BOOT_PARTITION_ENABLE: 0x%x\n"
919                 "PARTITION_ACCESS: 0x%x\n", ack, part, access);
920
921         return CMD_RET_SUCCESS;
922 }
923
924 static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
925                            int argc, char *const argv[])
926 {
927         int dev;
928         struct mmc *mmc;
929         u8 ack, part_num, access;
930
931         if (argc != 2 && argc != 3 && argc != 5)
932                 return CMD_RET_USAGE;
933
934         dev = dectoul(argv[1], NULL);
935
936         mmc = init_mmc_device(dev, false);
937         if (!mmc)
938                 return CMD_RET_FAILURE;
939
940         if (IS_SD(mmc)) {
941                 puts("PARTITION_CONFIG only exists on eMMC\n");
942                 return CMD_RET_FAILURE;
943         }
944
945         if (argc == 2 || argc == 3)
946                 return mmc_partconf_print(mmc, argc == 3 ? argv[2] : NULL);
947
948         ack = dectoul(argv[2], NULL);
949         part_num = dectoul(argv[3], NULL);
950         access = dectoul(argv[4], NULL);
951
952         /* acknowledge to be sent during boot operation */
953         return mmc_set_part_conf(mmc, ack, part_num, access);
954 }
955
956 static int do_mmc_rst_func(struct cmd_tbl *cmdtp, int flag,
957                            int argc, char *const argv[])
958 {
959         int dev;
960         struct mmc *mmc;
961         u8 enable;
962
963         /*
964          * Set the RST_n_ENABLE bit of RST_n_FUNCTION
965          * The only valid values are 0x0, 0x1 and 0x2 and writing
966          * a value of 0x1 or 0x2 sets the value permanently.
967          */
968         if (argc != 3)
969                 return CMD_RET_USAGE;
970
971         dev = dectoul(argv[1], NULL);
972         enable = dectoul(argv[2], NULL);
973
974         if (enable > 2) {
975                 puts("Invalid RST_n_ENABLE value\n");
976                 return CMD_RET_USAGE;
977         }
978
979         mmc = init_mmc_device(dev, false);
980         if (!mmc)
981                 return CMD_RET_FAILURE;
982
983         if (IS_SD(mmc)) {
984                 puts("RST_n_FUNCTION only exists on eMMC\n");
985                 return CMD_RET_FAILURE;
986         }
987
988         return mmc_set_rst_n_function(mmc, enable);
989 }
990 #endif
991 static int do_mmc_setdsr(struct cmd_tbl *cmdtp, int flag,
992                          int argc, char *const argv[])
993 {
994         struct mmc *mmc;
995         u32 val;
996         int ret;
997
998         if (argc != 2)
999                 return CMD_RET_USAGE;
1000         val = hextoul(argv[1], NULL);
1001
1002         mmc = find_mmc_device(curr_device);
1003         if (!mmc) {
1004                 printf("no mmc device at slot %x\n", curr_device);
1005                 return CMD_RET_FAILURE;
1006         }
1007         ret = mmc_set_dsr(mmc, val);
1008         printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR");
1009         if (!ret) {
1010                 mmc->has_init = 0;
1011                 if (mmc_init(mmc))
1012                         return CMD_RET_FAILURE;
1013                 else
1014                         return CMD_RET_SUCCESS;
1015         }
1016         return ret;
1017 }
1018
1019 #ifdef CONFIG_CMD_BKOPS_ENABLE
1020 static int do_mmc_bkops_enable(struct cmd_tbl *cmdtp, int flag,
1021                                int argc, char *const argv[])
1022 {
1023         int dev;
1024         struct mmc *mmc;
1025
1026         if (argc != 2)
1027                 return CMD_RET_USAGE;
1028
1029         dev = dectoul(argv[1], NULL);
1030
1031         mmc = init_mmc_device(dev, false);
1032         if (!mmc)
1033                 return CMD_RET_FAILURE;
1034
1035         if (IS_SD(mmc)) {
1036                 puts("BKOPS_EN only exists on eMMC\n");
1037                 return CMD_RET_FAILURE;
1038         }
1039
1040         return mmc_set_bkops_enable(mmc);
1041 }
1042 #endif
1043
1044 static int do_mmc_boot_wp(struct cmd_tbl *cmdtp, int flag,
1045                           int argc, char * const argv[])
1046 {
1047         int err;
1048         struct mmc *mmc;
1049
1050         mmc = init_mmc_device(curr_device, false);
1051         if (!mmc)
1052                 return CMD_RET_FAILURE;
1053         if (IS_SD(mmc)) {
1054                 printf("It is not an eMMC device\n");
1055                 return CMD_RET_FAILURE;
1056         }
1057         err = mmc_boot_wp(mmc);
1058         if (err)
1059                 return CMD_RET_FAILURE;
1060         printf("boot areas protected\n");
1061         return CMD_RET_SUCCESS;
1062 }
1063
1064 static struct cmd_tbl cmd_mmc[] = {
1065         U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
1066         U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
1067         U_BOOT_CMD_MKENT(wp, 1, 0, do_mmc_boot_wp, "", ""),
1068 #if CONFIG_IS_ENABLED(MMC_WRITE)
1069         U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
1070         U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
1071 #endif
1072 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1073         U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
1074 #endif
1075         U_BOOT_CMD_MKENT(rescan, 2, 1, do_mmc_rescan, "", ""),
1076         U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
1077         U_BOOT_CMD_MKENT(dev, 4, 0, do_mmc_dev, "", ""),
1078         U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
1079 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1080         U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
1081 #endif
1082 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1083         U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
1084         U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
1085         U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
1086         U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
1087 #endif
1088 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1089         U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""),
1090 #endif
1091         U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
1092 #ifdef CONFIG_CMD_BKOPS_ENABLE
1093         U_BOOT_CMD_MKENT(bkops-enable, 2, 0, do_mmc_bkops_enable, "", ""),
1094 #endif
1095 };
1096
1097 static int do_mmcops(struct cmd_tbl *cmdtp, int flag, int argc,
1098                      char *const argv[])
1099 {
1100         struct cmd_tbl *cp;
1101
1102         cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc));
1103
1104         /* Drop the mmc command */
1105         argc--;
1106         argv++;
1107
1108         if (cp == NULL || argc > cp->maxargs)
1109                 return CMD_RET_USAGE;
1110         if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
1111                 return CMD_RET_SUCCESS;
1112
1113         if (curr_device < 0) {
1114                 if (get_mmc_num() > 0) {
1115                         curr_device = 0;
1116                 } else {
1117                         puts("No MMC device available\n");
1118                         return CMD_RET_FAILURE;
1119                 }
1120         }
1121         return cp->cmd(cmdtp, flag, argc, argv);
1122 }
1123
1124 U_BOOT_CMD(
1125         mmc, 29, 1, do_mmcops,
1126         "MMC sub system",
1127         "info - display info of the current MMC device\n"
1128         "mmc read addr blk# cnt\n"
1129         "mmc write addr blk# cnt\n"
1130 #if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
1131         "mmc swrite addr blk#\n"
1132 #endif
1133         "mmc erase blk# cnt\n"
1134         "mmc rescan [mode]\n"
1135         "mmc part - lists available partition on current mmc device\n"
1136         "mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode\n"
1137         "  - the required speed mode is passed as the index from the following list\n"
1138         "    [MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25,\n"
1139         "    UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES]\n"
1140         "mmc list - lists available devices\n"
1141         "mmc wp - power on write protect boot partitions\n"
1142 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
1143         "mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning\n"
1144         "  arguments (sizes in 512-byte blocks):\n"
1145         "   USER - <user> <enh> <start> <cnt> <wrrel> <{on|off}>\n"
1146         "       : sets user data area attributes\n"
1147         "   GP - <{gp1|gp2|gp3|gp4}> <cnt> <enh> <wrrel> <{on|off}>\n"
1148         "       : general purpose partition\n"
1149         "   MODE - <{check|set|complete}>\n"
1150         "       : mode, complete set partitioning completed\n"
1151         "  WARNING: Partitioning is a write-once setting once it is set to complete.\n"
1152         "  Power cycling is required to initialize partitions after set to complete.\n"
1153 #endif
1154 #ifdef CONFIG_SUPPORT_EMMC_BOOT
1155         "mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode>\n"
1156         " - Set the BOOT_BUS_WIDTH field of the specified device\n"
1157         "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
1158         " - Change sizes of boot and RPMB partitions of specified device\n"
1159         "mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]]\n"
1160         " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n"
1161         "   If showing the bits, optionally store the boot_partition field into varname\n"
1162         "mmc rst-function <dev> <value>\n"
1163         " - Change the RST_n_FUNCTION field of the specified device\n"
1164         "   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
1165 #endif
1166 #if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
1167         "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
1168         "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
1169         "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"
1170         "mmc rpmb counter - read the value of the write counter\n"
1171 #endif
1172         "mmc setdsr <value> - set DSR register value\n"
1173 #ifdef CONFIG_CMD_BKOPS_ENABLE
1174         "mmc bkops-enable <dev> - enable background operations handshake on device\n"
1175         "   WARNING: This is a write-once setting.\n"
1176 #endif
1177         );
1178
1179 /* Old command kept for compatibility. Same as 'mmc info' */
1180 U_BOOT_CMD(
1181         mmcinfo, 1, 0, do_mmcinfo,
1182         "display MMC info",
1183         "- display info of the current MMC device"
1184 );