xref: /OK3568_Linux_fs/u-boot/test/rockchip/test-storage.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #ifdef CONFIG_DM_RAMDISK
9 #include <boot_rkimg.h>
10 #endif
11 #include <cli.h>
12 #include <dm.h>
13 #include <environment.h>
14 #include <malloc.h>
15 #include <misc.h>
16 #ifdef CONFIG_RKIMG_BOOTLOADER
17 #include <sysmem.h>
18 #endif
19 #include <linux/ctype.h>
20 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
21 #include <asm/arch/vendor.h>
22 #endif
23 #include "test-rockchip.h"
24 
25 #define DEFAULT_STORAGE_RW_PART		"userdata"
blk_get_type_by_name_and_num(char * devtype,int devnum)26 static enum if_type blk_get_type_by_name_and_num(char *devtype, int devnum)
27 {
28 	int type = -1;
29 
30 	if (!strcmp(devtype, "mmc"))
31 		type = IF_TYPE_MMC;
32 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
33 	else if (!strcmp(devtype, "rknand"))
34 		type = IF_TYPE_RKNAND;
35 #endif
36 #ifdef CONFIG_RKSFC_NAND
37 	else if (!strcmp(devtype, "rksfc") && devnum == 0)
38 		type = IF_TYPE_SPINAND;
39 #endif
40 #ifdef CONFIG_RKSFC_NOR
41 	else if (!strcmp(devtype, "rksfc") && devnum == 1)
42 		type = IF_TYPE_SPINOR;
43 #endif
44 #ifdef CONFIG_DM_RAMDISK
45 	else if (!strcmp(devtype, "ramdisk"))
46 		type = IF_TYPE_RAMDISK;
47 #endif
48 #ifdef CONFIG_MTD_BLK
49 	else if (!strcmp(devtype, "mtd"))
50 		type = IF_TYPE_MTD;
51 #endif
52 #ifdef CONFIG_SCSI
53 	else if (!strcmp(devtype, "scsi"))
54 		type = IF_TYPE_SCSI;
55 #endif
56 	else if (!strcmp(devtype, "usb"))
57 		type = IF_TYPE_USB;
58 
59 	return type;
60 }
61 
62 #if defined(CONFIG_MMC) ||\
63 	defined(CONFIG_RKNAND) ||\
64 	defined(CONFIG_DM_RAMDISK) ||\
65 	defined(CONFIG_USB_HOST) ||\
66 	defined(CONFIG_RKNANDC_NAND) ||\
67 	defined(CONFIG_RKSFC_NAND) ||\
68 	defined(CONFIG_RKSFC_NOR)
do_test_storage(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],const char * devtype,const char * devnum,const char * label)69 static int do_test_storage(cmd_tbl_t *cmdtp, int flag,
70 			   int argc, char *const argv[],
71 			   const char *devtype,
72 			   const char *devnum,
73 			   const char *label)
74 {
75 	struct blk_desc *dev_desc;
76 	disk_partition_t part;
77 	u32 blocks, round, sector;
78 	char *w_buf, *r_buf;
79 	char cmd[64];
80 	int i, ret;
81 	ulong ts;
82 
83 	/* 1. Switch to device type/num */
84 	if (devtype && !strcmp(devtype, "usb")) {
85 		if (run_command("usb start", 0)) {
86 			printf("Switch to %s%s failed\n", devtype, devnum);
87 			ret = -ENODEV;
88 			goto err1;
89 		}
90 	} else if (devtype) {
91 		snprintf(cmd, sizeof(cmd), "%s dev %s", devtype, devnum);
92 		if (run_command(cmd, 0)) {
93 			printf("Switch to %s%s failed\n", devtype, devnum);
94 			ret = -ENODEV;
95 			goto err1;
96 		}
97 	}
98 	if (!devtype) {
99 		/* For blk test only */
100 #ifdef CONFIG_DM_RAMDISK
101 		dev_desc = rockchip_get_bootdev();
102 #else
103 		printf("%s Not support devtype!\n", __func__);
104 		return -EINVAL;
105 #endif
106 	} else {
107 		int if_type;
108 		int num = simple_strtoul(devnum, NULL, 10);
109 
110 		if_type = blk_get_type_by_name_and_num((char *)devtype, num);
111 		dev_desc = blk_get_devnum_by_type(if_type, num);
112 	}
113 	if (!dev_desc) {
114 		ut_err("%s: failed to get blk desc\n", label);
115 		return -ENODEV;
116 	}
117 
118 	/* 2. Get test partition */
119 	if (part_get_info_by_name(dev_desc,
120 				  DEFAULT_STORAGE_RW_PART, &part) < 0) {
121 		ut_err("%s: failed to find %s partition\n", label,
122 		       DEFAULT_STORAGE_RW_PART);
123 		return -EINVAL;
124 	}
125 
126 	/* 32MB */
127 	sector = part.start;
128 	if (part.start + part.size > dev_desc->lba)
129 		part.size = dev_desc->lba - part.start;
130 	blocks = part.size > 0x10000 ? 0x10000 : part.size;
131 	round  = 4;
132 
133 	/* Round up */
134 	if (blocks % 2)
135 		blocks += 1;
136 
137 	printf("%s RW sectors on %s 0x%08x - 0x%08x(size: %ld MiB) for %d round\n\n",
138 	       label, DEFAULT_STORAGE_RW_PART,
139 	       sector, sector + blocks,
140 	       (blocks * dev_desc->blksz) >> 20, round);
141 
142 	/* 3. Prepare memory */
143 #ifdef CONFIG_RKIMG_BOOTLOADER
144 	w_buf = sysmem_alloc_by_name("storage_w", blocks * dev_desc->blksz);
145 #else
146 	w_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, blocks * dev_desc->blksz);
147 #endif
148 	if (!w_buf) {
149 		ut_err("%s: no sysmem for w_buf\n", label);
150 		ret = -ENOMEM;
151 		goto err1;
152 	}
153 #ifdef CONFIG_RKIMG_BOOTLOADER
154 	r_buf = sysmem_alloc_by_name("storage_r", blocks * dev_desc->blksz);
155 #else
156 	r_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, blocks * dev_desc->blksz);
157 #endif
158 	if (!r_buf) {
159 		ut_err("%s: no sysmem for r_buf\n", label);
160 		ret = -ENOMEM;
161 		goto err2;
162 	}
163 
164 	for (i = 0; i < blocks * dev_desc->blksz; i++) {
165 		w_buf[i] = i;
166 		r_buf[i] = 0;
167 	}
168 
169 	/* 4. Write test */
170 	ts = get_timer(0);
171 	if (devtype) {
172 		snprintf(cmd, sizeof(cmd), "%s write 0x%x 0x%x 0x%x",
173 			 devtype, (u32)(ulong)w_buf, sector, blocks);
174 		for (i = 0; i < round; i++) {
175 			if (run_command(cmd, 0)) {
176 				ut_err("%s: failed to write @%d round\n", label, i);
177 				ret = -EIO;
178 				goto err3;
179 			}
180 		}
181 	} else {
182 		for (i = 0; i < round; i++) {
183 			ret = blk_dwrite(dev_desc, sector, blocks, w_buf);
184 			if (ret != blocks) {
185 				ut_err("%s: failed to write @%d round\n", label, i);
186 				ret = -EIO;
187 				goto err3;
188 			}
189 		}
190 	}
191 
192 	ts = get_timer(0) - ts;
193 	printf("\n%s write: size %dMB, used %ldms, speed %ldMB/s\n",
194 	       label, blocks * round / 2048, ts, (blocks * round >> 1) / ts);
195 
196 	/* 5. Read test */
197 	ts = get_timer(0);
198 	if (devtype) {
199 		snprintf(cmd, sizeof(cmd), "%s read 0x%x 0x%x 0x%x",
200 			 devtype, (u32)(ulong)r_buf, sector, blocks);
201 
202 		for (i = 0; i < round; i++) {
203 			if (run_command(cmd, 0)) {
204 				ut_err("%s: failed to read @%d round\n", label, i);
205 				ret = -EIO;
206 				goto err3;
207 			}
208 		}
209 	} else {
210 		for (i = 0; i < round; i++) {
211 			ret = blk_dread(dev_desc, sector, blocks, r_buf);
212 			if (ret != blocks) {
213 				ut_err("%s: failed to read @%d round\n", label, i);
214 				ret = -EIO;
215 				goto err3;
216 			}
217 		}
218 	}
219 
220 	ts = get_timer(0) - ts;
221 	printf("\n%s read: size %dMB, used %ldms, speed %ldMB/s\n",
222 	       label, blocks * round / 2048, ts, (blocks * round >> 1) / ts);
223 
224 	/* 6. Verify the context */
225 	for (i = 0; i < blocks * dev_desc->blksz; i++) {
226 		if (w_buf[i] != r_buf[i]) {
227 			ut_err("%s: context compare error\n", label);
228 			ret = -EINVAL;
229 			goto err3;
230 		}
231 	}
232 
233 	/* 7. Switch back to default system devnum */
234 	if (devtype && !strcmp(devtype, "mmc") && env_get("devnum") &&
235 	    strcmp(devnum, env_get("devnum"))) {
236 		ret = run_command(cmd, 0);
237 		if (ret) {
238 			ut_err("%s: failed to switch to mmc1\n", label);
239 			ret = -ENODEV;
240 			goto err3;
241 		}
242 	}
243 
244 	ret = 0;
245 err3:
246 #ifdef CONFIG_RKIMG_BOOTLOADER
247 	sysmem_free((phys_addr_t)r_buf);
248 err2:
249 	sysmem_free((phys_addr_t)w_buf);
250 #else
251 	free(r_buf);
252 err2:
253 	free(w_buf);
254 #endif
255 err1:
256 
257 	return ret;
258 }
259 
260 #ifdef CONFIG_MMC
do_test_emmc(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])261 static int do_test_emmc(cmd_tbl_t *cmdtp, int flag,
262 			int argc, char *const argv[])
263 {
264 	return do_test_storage(cmdtp, flag, argc, argv, "mmc", "0", "MMC0");
265 }
266 
do_test_sdmmc(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])267 static int do_test_sdmmc(cmd_tbl_t *cmdtp, int flag,
268 			 int argc, char *const argv[])
269 {
270 	return do_test_storage(cmdtp, flag, argc, argv, "mmc", "1", "MMC1");
271 }
272 #endif
273 
274 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
do_test_rknand(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])275 static int do_test_rknand(cmd_tbl_t *cmdtp, int flag,
276 			  int argc, char *const argv[])
277 {
278 	return do_test_storage(cmdtp, flag, argc, argv, "rknand", "0", "RKNAND0");
279 }
280 #endif
281 
282 #ifdef CONFIG_RKSFC_NAND
do_test_rkflash_spinand(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])283 static int do_test_rkflash_spinand(cmd_tbl_t *cmdtp, int flag,
284 				   int argc, char *const argv[])
285 {
286 	return do_test_storage(cmdtp, flag, argc, argv, "rksfc", "0", "RKSFC0");
287 }
288 #endif
289 
290 #ifdef CONFIG_RKSFC_NOR
do_test_rkflash_spinor(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])291 static int do_test_rkflash_spinor(cmd_tbl_t *cmdtp, int flag,
292 				  int argc, char *const argv[])
293 {
294 	return do_test_storage(cmdtp, flag, argc, argv, "rksfc", "1", "RKSFC1");
295 }
296 #endif
297 
298 #ifdef CONFIG_DM_RAMDISK
do_test_blk(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])299 static int do_test_blk(cmd_tbl_t *cmdtp, int flag,
300 		       int argc, char *const argv[])
301 {
302 	return do_test_storage(cmdtp, flag, argc, argv, NULL, NULL, "BLK");
303 }
304 #endif
305 
306 #ifdef CONFIG_SCSI
do_test_scsi(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])307 static int do_test_scsi(cmd_tbl_t *cmdtp, int flag,
308 			int argc, char *const argv[])
309 {
310 	return do_test_storage(cmdtp, flag, argc, argv, "scsi", "0", "BLK");
311 }
312 #endif
313 
314 #endif/* defined(CONFIG_MMC) ||\
315        * defined(CONFIG_RKNAND) ||\
316        * defined(CONFIG_DM_RAMDISK) ||\
317        * defined(CONFIG_USB_HOST) ||\
318        * defined(CONFIG_RKNANDC_NAND) ||\
319        * defined(CONFIG_RKSFC_NAND) ||\
320        * defined(CONFIG_RKSFC_NOR)
321        */
322 
323 #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
do_test_secure_storage(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])324 static int do_test_secure_storage(cmd_tbl_t *cmdtp, int flag,
325 				  int argc, char *const argv[])
326 {
327 	return run_command("mmc testsecurestorage", 0);
328 }
329 #endif
330 
331 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
332 	!defined(CONFIG_SPL_BUILD)
do_test_env(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])333 static int do_test_env(cmd_tbl_t *cmdtp, int flag,
334 		       int argc, char *const argv[])
335 {
336 	int ret;
337 
338 	ret = env_save();
339 	if (ret) {
340 		ut_err("env: failed to save, ret=%d\n", ret);
341 		return ret;
342 	}
343 
344 	return env_load();
345 }
346 #endif
347 
348 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
do_test_vendor(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])349 static int do_test_vendor(cmd_tbl_t *cmdtp, int flag,
350 			  int argc, char *const argv[])
351 {
352 	return vendor_storage_test();
353 }
354 #endif
355 
356 #ifdef CONFIG_ROCKCHIP_EFUSE
do_test_efuse(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])357 static int do_test_efuse(cmd_tbl_t *cmdtp, int flag,
358 			 int argc, char *const argv[])
359 {
360 	struct udevice *dev;
361 	u8 fuses[128] = {0};
362 	int ret;
363 
364 	ret = uclass_get_device(UCLASS_MISC, 0, &dev);
365 	if (ret) {
366 		ut_err("efuse: failed to get device, ret=%d\n", ret);
367 		return 0;
368 	}
369 
370 	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
371 	if (ret) {
372 		ut_err("efuse: failed to read, ret=%d\n", ret);
373 		return 0;
374 	}
375 
376 	printf("Efuse-content:\n");
377 	print_buffer(0, fuses, 1, 128, 16);
378 
379 	return 0;
380 }
381 #endif
382 
383 #ifdef CONFIG_ROCKCHIP_OTP
do_test_otp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])384 static int do_test_otp(cmd_tbl_t *cmdtp, int flag,
385 		       int argc, char *const argv[])
386 {
387 	struct udevice *dev;
388 	u8 otps[64] = {0};
389 	int ret;
390 
391 	/* retrieve the device */
392 	ret = uclass_get_device_by_driver(UCLASS_MISC, 0, &dev);
393 	if (ret) {
394 		ut_err("otp: failed to get device, ret=%d\n", ret);
395 		return 0;
396 	}
397 
398 	ret = misc_read(dev, 0, &otps, sizeof(otps));
399 	if (ret) {
400 		ut_err("otp: failed to read, ret=%d\n", ret);
401 		return 0;
402 	}
403 
404 	printf("Otp-content:\n");
405 	print_buffer(0, otps, 1, 64, 16);
406 
407 	return 0;
408 }
409 #endif
410 
411 #ifdef CONFIG_PARTITIONS
do_test_part(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])412 static int do_test_part(cmd_tbl_t *cmdtp, int flag,
413 			int argc, char *const argv[])
414 {
415 	return run_command("part list ${devtype} ${devnum}", 0);
416 }
417 #endif
418 
419 #ifdef CONFIG_USB_HOST
do_test_usb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])420 static int do_test_usb(cmd_tbl_t *cmdtp, int flag,
421 		       int argc, char *const argv[])
422 {
423 	run_command("usb start", 0);
424 	return do_test_storage(cmdtp, flag, argc, argv, "usb", "0", "usb0");
425 }
426 #endif
427 
428 static cmd_tbl_t sub_cmd[] = {
429 #ifdef CONFIG_DM_RAMDISK
430 	UNIT_CMD_DEFINE(blk, 0),
431 #endif
432 #ifdef CONFIG_MMC
433 	UNIT_CMD_DEFINE(emmc, 0),
434 #endif
435 #ifdef CONFIG_ROCKCHIP_EFUSE
436 	UNIT_CMD_DEFINE(efuse, 0),
437 #endif
438 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
439 	!defined(CONFIG_SPL_BUILD)
440 	UNIT_CMD_DEFINE(env, 0),
441 #endif
442 #ifdef CONFIG_ROCKCHIP_OTP
443 	UNIT_CMD_DEFINE(otp, 0),
444 #endif
445 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
446 	UNIT_CMD_DEFINE(rknand, 0),
447 #endif
448 #ifdef CONFIG_RKSFC_NAND
449 	UNIT_CMD_DEFINE(rkflash_spinand, 0),
450 #endif
451 #ifdef CONFIG_RKSFC_NOR
452 	UNIT_CMD_DEFINE(rkflash_spinor, 0),
453 #endif
454 #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
455 	UNIT_CMD_DEFINE(secure_storage, 0),
456 #endif
457 #ifdef CONFIG_PARTITIONS
458 	UNIT_CMD_DEFINE(part, 0),
459 #endif
460 #ifdef CONFIG_USB_HOST
461 	UNIT_CMD_DEFINE(usb, 0),
462 #endif
463 #ifdef CONFIG_MMC
464 	UNIT_CMD_DEFINE(sdmmc, 0),
465 #endif
466 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
467 	UNIT_CMD_DEFINE(vendor, 0),
468 #endif
469 #ifdef CONFIG_SCSI
470 	UNIT_CMD_DEFINE(scsi, 0),
471 #endif
472 };
473 
474 static char sub_cmd_help[] =
475 #ifdef CONFIG_DM_RAMDISK
476 "    [.] rktest blk                         - test blk layer read/write\n"
477 #endif
478 #ifdef CONFIG_MMC
479 "    [.] rktest emmc                        - test emmc read/write speed\n"
480 "    [.] rktest sdmmc                       - test sd card and fat fs read/write\n"
481 #endif
482 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
483 "    [.] rktest rknand                      - test rknand read/write speed\n"
484 #endif
485 #ifdef CONFIG_RKSFC_NAND
486 "    [.] rktest rkflash_spinand             - test RKFLASH DM driver spinand read/write speed\n"
487 #endif
488 #ifdef CONFIG_RKSFC_NOR
489 "    [.] rktest rkflash_spinor              - test RKFLASH DM driver read/write speed\n"
490 #endif
491 #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
492 "    [.] rktest secure_storage              - test secure storage\n"
493 #endif
494 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
495 "    [.] rktest vendor                      - test vendor storage read/write\n"
496 #endif
497 #ifdef CONFIG_ROCKCHIP_EFUSE
498 "    [.] rktest efuse                       - test efuse, dump content\n"
499 #endif
500 #ifdef CONFIG_ROCKCHIP_OTP
501 "    [.] rktest otp                         - test otp, dump content\n"
502 #endif
503 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
504 	!defined(CONFIG_SPL_BUILD)
505 "    [.] rktest env                         - test save env to storage\n"
506 #endif
507 #ifdef CONFIG_PARTITIONS
508 "    [.] rktest part                        - test part list\n"
509 #endif
510 #ifdef CONFIG_USB_HOST
511 "    [.] rktest usb                         - test usb disk\n"
512 #endif
513 #ifdef CONFIG_SCSI
514 "    [.] rktest scsi                        - test sata disk\n"
515 #endif
516 ;
517 
518 const struct cmd_group cmd_grp_storage = {
519 	.id	= TEST_ID_STORAGE,
520 	.help	= sub_cmd_help,
521 	.cmd	= sub_cmd,
522 	.cmd_n	= ARRAY_SIZE(sub_cmd),
523 };
524