xref: /rk3399_rockchip-uboot/test/rockchip/test-storage.c (revision 9cde1b1d0397a62bc2c5c1bbee2f9f7a41208b8f)
199d14b01SJoseph Chen /*
299d14b01SJoseph Chen  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
399d14b01SJoseph Chen  *
499d14b01SJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
599d14b01SJoseph Chen  */
699d14b01SJoseph Chen 
799d14b01SJoseph Chen #include <common.h>
8bc18ede0SKever Yang #ifdef CONFIG_DM_RAMDISK
999d14b01SJoseph Chen #include <boot_rkimg.h>
10bc18ede0SKever Yang #endif
1199d14b01SJoseph Chen #include <cli.h>
1299d14b01SJoseph Chen #include <dm.h>
1399d14b01SJoseph Chen #include <environment.h>
1499d14b01SJoseph Chen #include <malloc.h>
1599d14b01SJoseph Chen #include <misc.h>
1654108d04SKever Yang #ifdef CONFIG_RKIMG_BOOTLOADER
1799d14b01SJoseph Chen #include <sysmem.h>
1854108d04SKever Yang #endif
1999d14b01SJoseph Chen #include <linux/ctype.h>
20bc18ede0SKever Yang #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
2199d14b01SJoseph Chen #include <asm/arch/vendor.h>
22bc18ede0SKever Yang #endif
2399d14b01SJoseph Chen #include "test-rockchip.h"
2499d14b01SJoseph Chen 
2599d14b01SJoseph Chen #define DEFAULT_STORAGE_RW_PART		"userdata"
26*9cde1b1dSJon Lin static enum if_type blk_get_type_by_name_and_num(char *devtype, int devnum)
27e80ec83dSKever Yang {
28e80ec83dSKever Yang 	int type = -1;
2999d14b01SJoseph Chen 
30e80ec83dSKever Yang 	if (!strcmp(devtype, "mmc"))
31e80ec83dSKever Yang 		type = IF_TYPE_MMC;
32*9cde1b1dSJon Lin #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
33e80ec83dSKever Yang 	else if (!strcmp(devtype, "rknand"))
34e80ec83dSKever Yang 		type = IF_TYPE_RKNAND;
35bc18ede0SKever Yang #endif
36bc18ede0SKever Yang #ifdef CONFIG_RKSFC_NAND
37*9cde1b1dSJon Lin 	else if (!strcmp(devtype, "rksfc") && devnum == 0)
38e80ec83dSKever Yang 		type = IF_TYPE_SPINAND;
39bc18ede0SKever Yang #endif
40bc18ede0SKever Yang #ifdef CONFIG_RKSFC_NOR
41*9cde1b1dSJon Lin 	else if (!strcmp(devtype, "rksfc") && devnum == 1)
42e80ec83dSKever Yang 		type = IF_TYPE_SPINOR;
43bc18ede0SKever Yang #endif
44bc18ede0SKever Yang #ifdef CONFIG_DM_RAMDISK
45e80ec83dSKever Yang 	else if (!strcmp(devtype, "ramdisk"))
46e80ec83dSKever Yang 		type = IF_TYPE_RAMDISK;
47bc18ede0SKever Yang #endif
48bc18ede0SKever Yang #ifdef CONFIG_MTD_BLK
49e80ec83dSKever Yang 	else if (!strcmp(devtype, "mtd"))
50e80ec83dSKever Yang 		type = IF_TYPE_MTD;
51bc18ede0SKever Yang #endif
52e80ec83dSKever Yang 	else if (!strcmp(devtype, "usb"))
53e80ec83dSKever Yang 		type = IF_TYPE_USB;
54e80ec83dSKever Yang 
55e80ec83dSKever Yang 	return type;
56e80ec83dSKever Yang }
57e80ec83dSKever Yang 
58*9cde1b1dSJon Lin #if defined(CONFIG_MMC) ||\
59*9cde1b1dSJon Lin 	defined(CONFIG_RKNAND) ||\
60*9cde1b1dSJon Lin 	defined(CONFIG_DM_RAMDISK) ||\
61*9cde1b1dSJon Lin 	defined(CONFIG_USB_HOST) ||\
62*9cde1b1dSJon Lin 	defined(CONFIG_RKNANDC_NAND) ||\
63*9cde1b1dSJon Lin 	defined(CONFIG_RKSFC_NAND) ||\
64*9cde1b1dSJon Lin 	defined(CONFIG_RKSFC_NOR)
6599d14b01SJoseph Chen static int do_test_storage(cmd_tbl_t *cmdtp, int flag,
6699d14b01SJoseph Chen 			   int argc, char *const argv[],
6799d14b01SJoseph Chen 			   const char *devtype,
6899d14b01SJoseph Chen 			   const char *devnum,
6999d14b01SJoseph Chen 			   const char *label)
7099d14b01SJoseph Chen {
7199d14b01SJoseph Chen 	struct blk_desc *dev_desc;
72474718ffSJoseph Chen 	disk_partition_t part;
7399d14b01SJoseph Chen 	u32 blocks, round, sector;
7499d14b01SJoseph Chen 	char *w_buf, *r_buf;
7599d14b01SJoseph Chen 	char cmd[64];
7699d14b01SJoseph Chen 	int i, ret;
7799d14b01SJoseph Chen 	ulong ts;
7899d14b01SJoseph Chen 
79e80ec83dSKever Yang 	/* 1. Switch to device type/num */
80e80ec83dSKever Yang 	if (devtype && !strcmp(devtype, "usb")) {
81e80ec83dSKever Yang 		if (run_command("usb start", 0)) {
82e80ec83dSKever Yang 			printf("Switch to %s%s failed\n", devtype, devnum);
83e80ec83dSKever Yang 			ret = -ENODEV;
84e80ec83dSKever Yang 			goto err1;
85e80ec83dSKever Yang 		}
86e80ec83dSKever Yang 	} else if (devtype) {
87e80ec83dSKever Yang 		snprintf(cmd, sizeof(cmd), "%s dev %s", devtype, devnum);
88e80ec83dSKever Yang 		if (run_command(cmd, 0)) {
89e80ec83dSKever Yang 			printf("Switch to %s%s failed\n", devtype, devnum);
90e80ec83dSKever Yang 			ret = -ENODEV;
91e80ec83dSKever Yang 			goto err1;
92e80ec83dSKever Yang 		}
93e80ec83dSKever Yang 	}
94e80ec83dSKever Yang 	if (!devtype) {
95e80ec83dSKever Yang 		/* For blk test only */
96bc18ede0SKever Yang #ifdef CONFIG_DM_RAMDISK
9799d14b01SJoseph Chen 		dev_desc = rockchip_get_bootdev();
98bc18ede0SKever Yang #else
99bc18ede0SKever Yang 		printf("%s Not support devtype!\n", __func__);
100bc18ede0SKever Yang 		return -EINVAL;
101bc18ede0SKever Yang #endif
102e80ec83dSKever Yang 	} else {
103e80ec83dSKever Yang 		int if_type;
104e80ec83dSKever Yang 		int num = simple_strtoul(devnum, NULL, 10);
105*9cde1b1dSJon Lin 
106*9cde1b1dSJon Lin 		if_type = blk_get_type_by_name_and_num((char *)devtype, num);
107e80ec83dSKever Yang 		dev_desc = blk_get_devnum_by_type(if_type, num);
108e80ec83dSKever Yang 	}
10999d14b01SJoseph Chen 	if (!dev_desc) {
110443feaabSJoseph Chen 		ut_err("%s: failed to get blk desc\n", label);
11199d14b01SJoseph Chen 		return -ENODEV;
11299d14b01SJoseph Chen 	}
11399d14b01SJoseph Chen 
114e80ec83dSKever Yang 	/* 2. Get test partition */
11599d14b01SJoseph Chen 	if (part_get_info_by_name(dev_desc,
11699d14b01SJoseph Chen 				  DEFAULT_STORAGE_RW_PART, &part) < 0) {
117443feaabSJoseph Chen 		ut_err("%s: failed to find %s partition\n", label,
118443feaabSJoseph Chen 		       DEFAULT_STORAGE_RW_PART);
11999d14b01SJoseph Chen 		return -EINVAL;
12099d14b01SJoseph Chen 	}
12199d14b01SJoseph Chen 
12299d14b01SJoseph Chen 	/* 32MB */
12399d14b01SJoseph Chen 	sector = part.start;
124*9cde1b1dSJon Lin 	if (part.start + part.size > dev_desc->lba)
125*9cde1b1dSJon Lin 		part.size = dev_desc->lba - part.start;
12699d14b01SJoseph Chen 	blocks = part.size > 0x10000 ? 0x10000 : part.size;
12799d14b01SJoseph Chen 	round  = 4;
12899d14b01SJoseph Chen 
12999d14b01SJoseph Chen 	/* Round up */
13099d14b01SJoseph Chen 	if (blocks % 2)
13199d14b01SJoseph Chen 		blocks += 1;
13299d14b01SJoseph Chen 
13399d14b01SJoseph Chen 	printf("%s RW sectors on %s 0x%08x - 0x%08x(size: %ld MiB) for %d round\n\n",
134474718ffSJoseph Chen 	       label, DEFAULT_STORAGE_RW_PART,
13599d14b01SJoseph Chen 	       sector, sector + blocks,
13699d14b01SJoseph Chen 	       (blocks * dev_desc->blksz) >> 20, round);
13799d14b01SJoseph Chen 
13899d14b01SJoseph Chen 	/* 3. Prepare memory */
13954108d04SKever Yang #ifdef CONFIG_RKIMG_BOOTLOADER
14099d14b01SJoseph Chen 	w_buf = sysmem_alloc_by_name("storage_w", blocks * dev_desc->blksz);
14154108d04SKever Yang #else
14254108d04SKever Yang 	w_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, blocks * dev_desc->blksz);
14354108d04SKever Yang #endif
14499d14b01SJoseph Chen 	if (!w_buf) {
145443feaabSJoseph Chen 		ut_err("%s: no sysmem for w_buf\n", label);
14699d14b01SJoseph Chen 		ret = -ENOMEM;
14799d14b01SJoseph Chen 		goto err1;
14899d14b01SJoseph Chen 	}
14954108d04SKever Yang #ifdef CONFIG_RKIMG_BOOTLOADER
15099d14b01SJoseph Chen 	r_buf = sysmem_alloc_by_name("storage_r", blocks * dev_desc->blksz);
15154108d04SKever Yang #else
15254108d04SKever Yang 	r_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, blocks * dev_desc->blksz);
15354108d04SKever Yang #endif
15499d14b01SJoseph Chen 	if (!r_buf) {
155443feaabSJoseph Chen 		ut_err("%s: no sysmem for r_buf\n", label);
15699d14b01SJoseph Chen 		ret = -ENOMEM;
15799d14b01SJoseph Chen 		goto err2;
15899d14b01SJoseph Chen 	}
15999d14b01SJoseph Chen 
16099d14b01SJoseph Chen 	for (i = 0; i < blocks * dev_desc->blksz; i++) {
16199d14b01SJoseph Chen 		w_buf[i] = i;
16299d14b01SJoseph Chen 		r_buf[i] = 0;
16399d14b01SJoseph Chen 	}
16499d14b01SJoseph Chen 
16599d14b01SJoseph Chen 	/* 4. Write test */
16699d14b01SJoseph Chen 	ts = get_timer(0);
16799d14b01SJoseph Chen 	if (devtype) {
16899d14b01SJoseph Chen 		snprintf(cmd, sizeof(cmd), "%s write 0x%x 0x%x 0x%x",
16999d14b01SJoseph Chen 			 devtype, (u32)(ulong)w_buf, sector, blocks);
17099d14b01SJoseph Chen 		for (i = 0; i < round; i++) {
17199d14b01SJoseph Chen 			if (run_command(cmd, 0)) {
172443feaabSJoseph Chen 				ut_err("%s: failed to write @%d round\n", label, i);
17399d14b01SJoseph Chen 				ret = -EIO;
17499d14b01SJoseph Chen 				goto err3;
17599d14b01SJoseph Chen 			}
17699d14b01SJoseph Chen 		}
17799d14b01SJoseph Chen 	} else {
17899d14b01SJoseph Chen 		for (i = 0; i < round; i++) {
17999d14b01SJoseph Chen 			ret = blk_dwrite(dev_desc, sector, blocks, w_buf);
18099d14b01SJoseph Chen 			if (ret != blocks) {
181443feaabSJoseph Chen 				ut_err("%s: failed to write @%d round\n", label, i);
18299d14b01SJoseph Chen 				ret = -EIO;
18399d14b01SJoseph Chen 				goto err3;
18499d14b01SJoseph Chen 			}
18599d14b01SJoseph Chen 		}
18699d14b01SJoseph Chen 	}
18799d14b01SJoseph Chen 
18899d14b01SJoseph Chen 	ts = get_timer(0) - ts;
18999d14b01SJoseph Chen 	printf("\n%s write: size %dMB, used %ldms, speed %ldMB/s\n",
19099d14b01SJoseph Chen 	       label, blocks * round / 2048, ts, (blocks * round >> 1) / ts);
19199d14b01SJoseph Chen 
19299d14b01SJoseph Chen 	/* 5. Read test */
19399d14b01SJoseph Chen 	ts = get_timer(0);
19499d14b01SJoseph Chen 	if (devtype) {
19599d14b01SJoseph Chen 		snprintf(cmd, sizeof(cmd), "%s read 0x%x 0x%x 0x%x",
19699d14b01SJoseph Chen 			 devtype, (u32)(ulong)r_buf, sector, blocks);
19799d14b01SJoseph Chen 
19899d14b01SJoseph Chen 		for (i = 0; i < round; i++) {
19999d14b01SJoseph Chen 			if (run_command(cmd, 0)) {
200443feaabSJoseph Chen 				ut_err("%s: failed to read @%d round\n", label, i);
20199d14b01SJoseph Chen 				ret = -EIO;
20299d14b01SJoseph Chen 				goto err3;
20399d14b01SJoseph Chen 			}
20499d14b01SJoseph Chen 		}
20599d14b01SJoseph Chen 	} else {
20699d14b01SJoseph Chen 		for (i = 0; i < round; i++) {
20799d14b01SJoseph Chen 			ret = blk_dread(dev_desc, sector, blocks, r_buf);
20899d14b01SJoseph Chen 			if (ret != blocks) {
209443feaabSJoseph Chen 				ut_err("%s: failed to read @%d round\n", label, i);
21099d14b01SJoseph Chen 				ret = -EIO;
21199d14b01SJoseph Chen 				goto err3;
21299d14b01SJoseph Chen 			}
21399d14b01SJoseph Chen 		}
21499d14b01SJoseph Chen 	}
21599d14b01SJoseph Chen 
21699d14b01SJoseph Chen 	ts = get_timer(0) - ts;
21799d14b01SJoseph Chen 	printf("\n%s read: size %dMB, used %ldms, speed %ldMB/s\n",
21899d14b01SJoseph Chen 	       label, blocks * round / 2048, ts, (blocks * round >> 1) / ts);
21999d14b01SJoseph Chen 
22099d14b01SJoseph Chen 	/* 6. Verify the context */
22199d14b01SJoseph Chen 	for (i = 0; i < blocks * dev_desc->blksz; i++) {
22299d14b01SJoseph Chen 		if (w_buf[i] != r_buf[i]) {
223443feaabSJoseph Chen 			ut_err("%s: context compare error\n", label);
22499d14b01SJoseph Chen 			ret = -EINVAL;
22599d14b01SJoseph Chen 			goto err3;
22699d14b01SJoseph Chen 		}
22799d14b01SJoseph Chen 	}
22899d14b01SJoseph Chen 
22999d14b01SJoseph Chen 	/* 7. Switch back to default system devnum */
2309c7862b8SKever Yang 	if (devtype && !strcmp(devtype, "mmc") && env_get("devnum") &&
23199d14b01SJoseph Chen 	    strcmp(devnum, env_get("devnum"))) {
23299d14b01SJoseph Chen 		ret = run_command(cmd, 0);
23399d14b01SJoseph Chen 		if (ret) {
234443feaabSJoseph Chen 			ut_err("%s: failed to switch to mmc1\n", label);
23599d14b01SJoseph Chen 			ret = -ENODEV;
23699d14b01SJoseph Chen 			goto err3;
23799d14b01SJoseph Chen 		}
23899d14b01SJoseph Chen 	}
23999d14b01SJoseph Chen 
24099d14b01SJoseph Chen 	ret = 0;
24199d14b01SJoseph Chen err3:
24254108d04SKever Yang #ifdef CONFIG_RKIMG_BOOTLOADER
24399d14b01SJoseph Chen 	sysmem_free((phys_addr_t)r_buf);
24499d14b01SJoseph Chen err2:
24599d14b01SJoseph Chen 	sysmem_free((phys_addr_t)w_buf);
24654108d04SKever Yang #else
247fb09b071SKever Yang 	free(r_buf);
24854108d04SKever Yang err2:
249fb09b071SKever Yang 	free(w_buf);
25054108d04SKever Yang #endif
25199d14b01SJoseph Chen err1:
25299d14b01SJoseph Chen 
25399d14b01SJoseph Chen 	return ret;
25499d14b01SJoseph Chen }
25599d14b01SJoseph Chen 
25699d14b01SJoseph Chen #ifdef CONFIG_MMC
25799d14b01SJoseph Chen static int do_test_emmc(cmd_tbl_t *cmdtp, int flag,
25899d14b01SJoseph Chen 			int argc, char *const argv[])
25999d14b01SJoseph Chen {
26099d14b01SJoseph Chen 	return do_test_storage(cmdtp, flag, argc, argv, "mmc", "0", "MMC0");
26199d14b01SJoseph Chen }
26299d14b01SJoseph Chen 
26399d14b01SJoseph Chen static int do_test_sdmmc(cmd_tbl_t *cmdtp, int flag,
26499d14b01SJoseph Chen 			 int argc, char *const argv[])
26599d14b01SJoseph Chen {
26699d14b01SJoseph Chen 	return do_test_storage(cmdtp, flag, argc, argv, "mmc", "1", "MMC1");
26799d14b01SJoseph Chen }
26899d14b01SJoseph Chen #endif
26999d14b01SJoseph Chen 
270*9cde1b1dSJon Lin #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
27199d14b01SJoseph Chen static int do_test_rknand(cmd_tbl_t *cmdtp, int flag,
27299d14b01SJoseph Chen 			  int argc, char *const argv[])
27399d14b01SJoseph Chen {
27499d14b01SJoseph Chen 	return do_test_storage(cmdtp, flag, argc, argv, "rknand", "0", "RKNAND0");
27599d14b01SJoseph Chen }
27699d14b01SJoseph Chen #endif
27799d14b01SJoseph Chen 
278*9cde1b1dSJon Lin #ifdef CONFIG_RKSFC_NAND
279*9cde1b1dSJon Lin static int do_test_rkflash_spinand(cmd_tbl_t *cmdtp, int flag,
280*9cde1b1dSJon Lin 				   int argc, char *const argv[])
281*9cde1b1dSJon Lin {
282*9cde1b1dSJon Lin 	return do_test_storage(cmdtp, flag, argc, argv, "rksfc", "0", "RKSFC0");
283*9cde1b1dSJon Lin }
284*9cde1b1dSJon Lin #endif
285*9cde1b1dSJon Lin 
286*9cde1b1dSJon Lin #ifdef CONFIG_RKSFC_NOR
287*9cde1b1dSJon Lin static int do_test_rkflash_spinor(cmd_tbl_t *cmdtp, int flag,
288*9cde1b1dSJon Lin 				  int argc, char *const argv[])
289*9cde1b1dSJon Lin {
290*9cde1b1dSJon Lin 	return do_test_storage(cmdtp, flag, argc, argv, "rksfc", "1", "RKSFC1");
291*9cde1b1dSJon Lin }
292*9cde1b1dSJon Lin #endif
293*9cde1b1dSJon Lin 
294bc18ede0SKever Yang #ifdef CONFIG_DM_RAMDISK
29599d14b01SJoseph Chen static int do_test_blk(cmd_tbl_t *cmdtp, int flag,
29699d14b01SJoseph Chen 		       int argc, char *const argv[])
29799d14b01SJoseph Chen {
29899d14b01SJoseph Chen 	return do_test_storage(cmdtp, flag, argc, argv, NULL, NULL, "BLK");
29999d14b01SJoseph Chen }
300bc18ede0SKever Yang #endif
301*9cde1b1dSJon Lin #endif/* defined(CONFIG_MMC) ||\
302*9cde1b1dSJon Lin        * defined(CONFIG_RKNAND) ||\
303*9cde1b1dSJon Lin        * defined(CONFIG_DM_RAMDISK) ||\
304*9cde1b1dSJon Lin        * defined(CONFIG_USB_HOST) ||\
305*9cde1b1dSJon Lin        * defined(CONFIG_RKNANDC_NAND) ||\
306*9cde1b1dSJon Lin        * defined(CONFIG_RKSFC_NAND) ||\
307*9cde1b1dSJon Lin        * defined(CONFIG_RKSFC_NOR)
308*9cde1b1dSJon Lin        */
30999d14b01SJoseph Chen 
31099d14b01SJoseph Chen #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
31199d14b01SJoseph Chen static int do_test_secure_storage(cmd_tbl_t *cmdtp, int flag,
31299d14b01SJoseph Chen 				  int argc, char *const argv[])
31399d14b01SJoseph Chen {
31499d14b01SJoseph Chen 	return run_command("mmc testsecurestorage", 0);
31599d14b01SJoseph Chen }
31699d14b01SJoseph Chen #endif
31799d14b01SJoseph Chen 
31899d14b01SJoseph Chen #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
31999d14b01SJoseph Chen 	!defined(CONFIG_SPL_BUILD)
32099d14b01SJoseph Chen static int do_test_env(cmd_tbl_t *cmdtp, int flag,
32199d14b01SJoseph Chen 		       int argc, char *const argv[])
32299d14b01SJoseph Chen {
32399d14b01SJoseph Chen 	int ret;
32499d14b01SJoseph Chen 
32599d14b01SJoseph Chen 	ret = env_save();
326443feaabSJoseph Chen 	if (ret) {
327443feaabSJoseph Chen 		ut_err("env: failed to save, ret=%d\n", ret);
32899d14b01SJoseph Chen 		return ret;
329443feaabSJoseph Chen 	}
33099d14b01SJoseph Chen 
33199d14b01SJoseph Chen 	return env_load();
33299d14b01SJoseph Chen }
33399d14b01SJoseph Chen #endif
33499d14b01SJoseph Chen 
33599d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
33699d14b01SJoseph Chen static int do_test_vendor(cmd_tbl_t *cmdtp, int flag,
33799d14b01SJoseph Chen 			  int argc, char *const argv[])
33899d14b01SJoseph Chen {
33999d14b01SJoseph Chen 	return vendor_storage_test();
34099d14b01SJoseph Chen }
34199d14b01SJoseph Chen #endif
34299d14b01SJoseph Chen 
34399d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_EFUSE
34499d14b01SJoseph Chen static int do_test_efuse(cmd_tbl_t *cmdtp, int flag,
34599d14b01SJoseph Chen 			 int argc, char *const argv[])
34699d14b01SJoseph Chen {
34799d14b01SJoseph Chen 	struct udevice *dev;
34899d14b01SJoseph Chen 	u8 fuses[128] = {0};
34999d14b01SJoseph Chen 	int ret;
35099d14b01SJoseph Chen 
35199d14b01SJoseph Chen 	ret = uclass_get_device(UCLASS_MISC, 0, &dev);
35299d14b01SJoseph Chen 	if (ret) {
353443feaabSJoseph Chen 		ut_err("efuse: failed to get device, ret=%d\n", ret);
35499d14b01SJoseph Chen 		return 0;
35599d14b01SJoseph Chen 	}
35699d14b01SJoseph Chen 
35799d14b01SJoseph Chen 	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
35899d14b01SJoseph Chen 	if (ret) {
359443feaabSJoseph Chen 		ut_err("efuse: failed to read, ret=%d\n", ret);
36099d14b01SJoseph Chen 		return 0;
36199d14b01SJoseph Chen 	}
36299d14b01SJoseph Chen 
36399d14b01SJoseph Chen 	printf("Efuse-content:\n");
36499d14b01SJoseph Chen 	print_buffer(0, fuses, 1, 128, 16);
36599d14b01SJoseph Chen 
36699d14b01SJoseph Chen 	return 0;
36799d14b01SJoseph Chen }
36899d14b01SJoseph Chen #endif
36999d14b01SJoseph Chen 
37099d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_OTP
37199d14b01SJoseph Chen static int do_test_otp(cmd_tbl_t *cmdtp, int flag,
37299d14b01SJoseph Chen 		       int argc, char *const argv[])
37399d14b01SJoseph Chen {
37499d14b01SJoseph Chen 	struct udevice *dev;
37599d14b01SJoseph Chen 	u8 otps[64] = {0};
37699d14b01SJoseph Chen 	int ret;
37799d14b01SJoseph Chen 
37899d14b01SJoseph Chen 	/* retrieve the device */
37999d14b01SJoseph Chen 	ret = uclass_get_device_by_driver(UCLASS_MISC, 0, &dev);
38099d14b01SJoseph Chen 	if (ret) {
381443feaabSJoseph Chen 		ut_err("otp: failed to get device, ret=%d\n", ret);
38299d14b01SJoseph Chen 		return 0;
38399d14b01SJoseph Chen 	}
38499d14b01SJoseph Chen 
38599d14b01SJoseph Chen 	ret = misc_read(dev, 0, &otps, sizeof(otps));
38699d14b01SJoseph Chen 	if (ret) {
387443feaabSJoseph Chen 		ut_err("otp: failed to read, ret=%d\n", ret);
38899d14b01SJoseph Chen 		return 0;
38999d14b01SJoseph Chen 	}
39099d14b01SJoseph Chen 
39199d14b01SJoseph Chen 	printf("Otp-content:\n");
39299d14b01SJoseph Chen 	print_buffer(0, otps, 1, 64, 16);
39399d14b01SJoseph Chen 
39499d14b01SJoseph Chen 	return 0;
39599d14b01SJoseph Chen }
39699d14b01SJoseph Chen #endif
39799d14b01SJoseph Chen 
39899d14b01SJoseph Chen #ifdef CONFIG_PARTITIONS
39999d14b01SJoseph Chen static int do_test_part(cmd_tbl_t *cmdtp, int flag,
40099d14b01SJoseph Chen 			int argc, char *const argv[])
40199d14b01SJoseph Chen {
40299d14b01SJoseph Chen 	return run_command("part list ${devtype} ${devnum}", 0);
40399d14b01SJoseph Chen }
40499d14b01SJoseph Chen #endif
40599d14b01SJoseph Chen 
406e80ec83dSKever Yang #ifdef CONFIG_USB_HOST
407e80ec83dSKever Yang static int do_test_usb(cmd_tbl_t *cmdtp, int flag,
408e80ec83dSKever Yang 		       int argc, char *const argv[])
409e80ec83dSKever Yang {
410e80ec83dSKever Yang 	run_command("usb start", 0);
411e80ec83dSKever Yang 	return do_test_storage(cmdtp, flag, argc, argv, "usb", "0", "usb0");
412e80ec83dSKever Yang }
413e80ec83dSKever Yang #endif
414e80ec83dSKever Yang 
41599d14b01SJoseph Chen static cmd_tbl_t sub_cmd[] = {
416bc18ede0SKever Yang #ifdef CONFIG_DM_RAMDISK
41799d14b01SJoseph Chen 	UNIT_CMD_DEFINE(blk, 0),
41899d14b01SJoseph Chen #endif
41999d14b01SJoseph Chen #ifdef CONFIG_MMC
42099d14b01SJoseph Chen 	UNIT_CMD_DEFINE(emmc, 0),
42199d14b01SJoseph Chen #endif
42299d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_EFUSE
42399d14b01SJoseph Chen 	UNIT_CMD_DEFINE(efuse, 0),
42499d14b01SJoseph Chen #endif
42599d14b01SJoseph Chen #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
42699d14b01SJoseph Chen 	!defined(CONFIG_SPL_BUILD)
42799d14b01SJoseph Chen 	UNIT_CMD_DEFINE(env, 0),
42899d14b01SJoseph Chen #endif
42999d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_OTP
43099d14b01SJoseph Chen 	UNIT_CMD_DEFINE(otp, 0),
43199d14b01SJoseph Chen #endif
432*9cde1b1dSJon Lin #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
43399d14b01SJoseph Chen 	UNIT_CMD_DEFINE(rknand, 0),
43499d14b01SJoseph Chen #endif
435*9cde1b1dSJon Lin #ifdef CONFIG_RKSFC_NAND
436*9cde1b1dSJon Lin 	UNIT_CMD_DEFINE(rkflash_spinand, 0),
437*9cde1b1dSJon Lin #endif
438*9cde1b1dSJon Lin #ifdef CONFIG_RKSFC_NOR
439*9cde1b1dSJon Lin 	UNIT_CMD_DEFINE(rkflash_spinor, 0),
440*9cde1b1dSJon Lin #endif
44199d14b01SJoseph Chen #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
44299d14b01SJoseph Chen 	UNIT_CMD_DEFINE(secure_storage, 0),
44399d14b01SJoseph Chen #endif
44499d14b01SJoseph Chen #ifdef CONFIG_PARTITIONS
44599d14b01SJoseph Chen 	UNIT_CMD_DEFINE(part, 0),
44699d14b01SJoseph Chen #endif
447e80ec83dSKever Yang #ifdef CONFIG_USB_HOST
448e80ec83dSKever Yang 	UNIT_CMD_DEFINE(usb, 0),
449e80ec83dSKever Yang #endif
45099d14b01SJoseph Chen #ifdef CONFIG_MMC
45199d14b01SJoseph Chen 	UNIT_CMD_DEFINE(sdmmc, 0),
45299d14b01SJoseph Chen #endif
45399d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
45499d14b01SJoseph Chen 	UNIT_CMD_DEFINE(vendor, 0),
45599d14b01SJoseph Chen #endif
45699d14b01SJoseph Chen };
45799d14b01SJoseph Chen 
45899d14b01SJoseph Chen static char sub_cmd_help[] =
459bc18ede0SKever Yang #ifdef CONFIG_DM_RAMDISK
46099d14b01SJoseph Chen "    [.] rktest blk                         - test blk layer read/write\n"
46199d14b01SJoseph Chen #endif
46299d14b01SJoseph Chen #ifdef CONFIG_MMC
463474718ffSJoseph Chen "    [.] rktest emmc                        - test emmc read/write speed\n"
46499d14b01SJoseph Chen "    [.] rktest sdmmc                       - test sd card and fat fs read/write\n"
46599d14b01SJoseph Chen #endif
466*9cde1b1dSJon Lin #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
467474718ffSJoseph Chen "    [.] rktest rknand                      - test rknand read/write speed\n"
46899d14b01SJoseph Chen #endif
469*9cde1b1dSJon Lin #ifdef CONFIG_RKSFC_NAND
470*9cde1b1dSJon Lin "    [.] rktest rkflash_spinand             - test RKFLASH DM driver spinand read/write speed\n"
471*9cde1b1dSJon Lin #endif
472*9cde1b1dSJon Lin #ifdef CONFIG_RKSFC_NOR
473*9cde1b1dSJon Lin "    [.] rktest rkflash_spinor              - test RKFLASH DM driver read/write speed\n"
474*9cde1b1dSJon Lin #endif
47599d14b01SJoseph Chen #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
47699d14b01SJoseph Chen "    [.] rktest secure_storage              - test secure storage\n"
47799d14b01SJoseph Chen #endif
47899d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
47999d14b01SJoseph Chen "    [.] rktest vendor                      - test vendor storage read/write\n"
48099d14b01SJoseph Chen #endif
48199d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_EFUSE
48299d14b01SJoseph Chen "    [.] rktest efuse                       - test efuse, dump content\n"
48399d14b01SJoseph Chen #endif
48499d14b01SJoseph Chen #ifdef CONFIG_ROCKCHIP_OTP
48599d14b01SJoseph Chen "    [.] rktest otp                         - test otp, dump content\n"
48699d14b01SJoseph Chen #endif
48799d14b01SJoseph Chen #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
48899d14b01SJoseph Chen 	!defined(CONFIG_SPL_BUILD)
48999d14b01SJoseph Chen "    [.] rktest env                         - test save env to storage\n"
49099d14b01SJoseph Chen #endif
49199d14b01SJoseph Chen #ifdef CONFIG_PARTITIONS
49299d14b01SJoseph Chen "    [.] rktest part                        - test part list\n"
49399d14b01SJoseph Chen #endif
494e80ec83dSKever Yang #ifdef CONFIG_USB_HOST
495e80ec83dSKever Yang "    [.] rktest usb                        - test usb disk\n"
496e80ec83dSKever Yang #endif
49799d14b01SJoseph Chen ;
49899d14b01SJoseph Chen 
49999d14b01SJoseph Chen const struct cmd_group cmd_grp_storage = {
50099d14b01SJoseph Chen 	.id	= TEST_ID_STORAGE,
50199d14b01SJoseph Chen 	.help	= sub_cmd_help,
50299d14b01SJoseph Chen 	.cmd	= sub_cmd,
50399d14b01SJoseph Chen 	.cmd_n	= ARRAY_SIZE(sub_cmd),
50499d14b01SJoseph Chen };
505