xref: /rk3399_rockchip-uboot/drivers/mtd/mtd_uboot.c (revision f18d11163e4ea523aff489721db5de752fe062bf)
109c32807SHeiko Schocher /*
209c32807SHeiko Schocher  * (C) Copyright 2014
309c32807SHeiko Schocher  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
409c32807SHeiko Schocher  *
509c32807SHeiko Schocher  * SPDX-License-Identifier:	GPL-2.0+
609c32807SHeiko Schocher  */
709c32807SHeiko Schocher #include <common.h>
809c32807SHeiko Schocher #include <linux/mtd/mtd.h>
909c32807SHeiko Schocher #include <jffs2/jffs2.h>
1009c32807SHeiko Schocher 
1109c32807SHeiko Schocher static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size,
1209c32807SHeiko Schocher 		loff_t *maxsize, int devtype)
1309c32807SHeiko Schocher {
1409c32807SHeiko Schocher #ifdef CONFIG_CMD_MTDPARTS
1509c32807SHeiko Schocher 	struct mtd_device *dev;
1609c32807SHeiko Schocher 	struct part_info *part;
1709c32807SHeiko Schocher 	u8 pnum;
1809c32807SHeiko Schocher 	int ret;
1909c32807SHeiko Schocher 
2009c32807SHeiko Schocher 	ret = mtdparts_init();
2109c32807SHeiko Schocher 	if (ret)
2209c32807SHeiko Schocher 		return ret;
2309c32807SHeiko Schocher 
2409c32807SHeiko Schocher 	ret = find_dev_and_part(partname, &dev, &pnum, &part);
2509c32807SHeiko Schocher 	if (ret)
2609c32807SHeiko Schocher 		return ret;
2709c32807SHeiko Schocher 
2809c32807SHeiko Schocher 	if (dev->id->type != devtype) {
2909c32807SHeiko Schocher 		printf("not same typ %d != %d\n", dev->id->type, devtype);
3009c32807SHeiko Schocher 		return -1;
3109c32807SHeiko Schocher 	}
3209c32807SHeiko Schocher 
3309c32807SHeiko Schocher 	*off = part->offset;
3409c32807SHeiko Schocher 	*size = part->size;
3509c32807SHeiko Schocher 	*maxsize = part->size;
3609c32807SHeiko Schocher 	*idx = dev->id->num;
3709c32807SHeiko Schocher 
3809c32807SHeiko Schocher 	return 0;
3909c32807SHeiko Schocher #else
4009c32807SHeiko Schocher 	puts("offset is not a number\n");
4109c32807SHeiko Schocher 	return -1;
4209c32807SHeiko Schocher #endif
4309c32807SHeiko Schocher }
4409c32807SHeiko Schocher 
4509c32807SHeiko Schocher int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
46*f18d1116SMasahiro Yamada 		loff_t *maxsize, int devtype, uint64_t chipsize)
4709c32807SHeiko Schocher {
4809c32807SHeiko Schocher 	if (!str2off(arg, off))
4909c32807SHeiko Schocher 		return get_part(arg, idx, off, size, maxsize, devtype);
5009c32807SHeiko Schocher 
5109c32807SHeiko Schocher 	if (*off >= chipsize) {
5209c32807SHeiko Schocher 		puts("Offset exceeds device limit\n");
5309c32807SHeiko Schocher 		return -1;
5409c32807SHeiko Schocher 	}
5509c32807SHeiko Schocher 
5609c32807SHeiko Schocher 	*maxsize = chipsize - *off;
5709c32807SHeiko Schocher 	*size = *maxsize;
5809c32807SHeiko Schocher 	return 0;
5909c32807SHeiko Schocher }
6009c32807SHeiko Schocher 
6109c32807SHeiko Schocher int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
62*f18d1116SMasahiro Yamada 		     loff_t *size, loff_t *maxsize, int devtype,
63*f18d1116SMasahiro Yamada 		     uint64_t chipsize)
6409c32807SHeiko Schocher {
6509c32807SHeiko Schocher 	int ret;
6609c32807SHeiko Schocher 
6709c32807SHeiko Schocher 	if (argc == 0) {
6809c32807SHeiko Schocher 		*off = 0;
6909c32807SHeiko Schocher 		*size = chipsize;
7009c32807SHeiko Schocher 		*maxsize = *size;
7109c32807SHeiko Schocher 		goto print;
7209c32807SHeiko Schocher 	}
7309c32807SHeiko Schocher 
7409c32807SHeiko Schocher 	ret = mtd_arg_off(argv[0], idx, off, size, maxsize, devtype,
7509c32807SHeiko Schocher 			  chipsize);
7609c32807SHeiko Schocher 	if (ret)
7709c32807SHeiko Schocher 		return ret;
7809c32807SHeiko Schocher 
7909c32807SHeiko Schocher 	if (argc == 1)
8009c32807SHeiko Schocher 		goto print;
8109c32807SHeiko Schocher 
8209c32807SHeiko Schocher 	if (!str2off(argv[1], size)) {
8309c32807SHeiko Schocher 		printf("'%s' is not a number\n", argv[1]);
8409c32807SHeiko Schocher 		return -1;
8509c32807SHeiko Schocher 	}
8609c32807SHeiko Schocher 
8709c32807SHeiko Schocher 	if (*size > *maxsize) {
8809c32807SHeiko Schocher 		puts("Size exceeds partition or device limit\n");
8909c32807SHeiko Schocher 		return -1;
9009c32807SHeiko Schocher 	}
9109c32807SHeiko Schocher 
9209c32807SHeiko Schocher print:
9309c32807SHeiko Schocher 	printf("device %d ", *idx);
9409c32807SHeiko Schocher 	if (*size == chipsize)
9509c32807SHeiko Schocher 		puts("whole chip\n");
9609c32807SHeiko Schocher 	else
9709c32807SHeiko Schocher 		printf("offset 0x%llx, size 0x%llx\n",
9809c32807SHeiko Schocher 		       (unsigned long long)*off, (unsigned long long)*size);
9909c32807SHeiko Schocher 	return 0;
10009c32807SHeiko Schocher }
101