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