xref: /rk3399_rockchip-uboot/drivers/mtd/mtd_uboot.c (revision 09c3280754f8f68a4d7fc0ee397a92b38c4f59e4)
1*09c32807SHeiko Schocher /*
2*09c32807SHeiko Schocher  * (C) Copyright 2014
3*09c32807SHeiko Schocher  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4*09c32807SHeiko Schocher  *
5*09c32807SHeiko Schocher  * SPDX-License-Identifier:	GPL-2.0+
6*09c32807SHeiko Schocher  */
7*09c32807SHeiko Schocher #include <common.h>
8*09c32807SHeiko Schocher #include <linux/mtd/mtd.h>
9*09c32807SHeiko Schocher #include <jffs2/jffs2.h>
10*09c32807SHeiko Schocher 
11*09c32807SHeiko Schocher static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size,
12*09c32807SHeiko Schocher 		loff_t *maxsize, int devtype)
13*09c32807SHeiko Schocher {
14*09c32807SHeiko Schocher #ifdef CONFIG_CMD_MTDPARTS
15*09c32807SHeiko Schocher 	struct mtd_device *dev;
16*09c32807SHeiko Schocher 	struct part_info *part;
17*09c32807SHeiko Schocher 	u8 pnum;
18*09c32807SHeiko Schocher 	int ret;
19*09c32807SHeiko Schocher 
20*09c32807SHeiko Schocher 	ret = mtdparts_init();
21*09c32807SHeiko Schocher 	if (ret)
22*09c32807SHeiko Schocher 		return ret;
23*09c32807SHeiko Schocher 
24*09c32807SHeiko Schocher 	ret = find_dev_and_part(partname, &dev, &pnum, &part);
25*09c32807SHeiko Schocher 	if (ret)
26*09c32807SHeiko Schocher 		return ret;
27*09c32807SHeiko Schocher 
28*09c32807SHeiko Schocher 	if (dev->id->type != devtype) {
29*09c32807SHeiko Schocher 		printf("not same typ %d != %d\n", dev->id->type, devtype);
30*09c32807SHeiko Schocher 		return -1;
31*09c32807SHeiko Schocher 	}
32*09c32807SHeiko Schocher 
33*09c32807SHeiko Schocher 	*off = part->offset;
34*09c32807SHeiko Schocher 	*size = part->size;
35*09c32807SHeiko Schocher 	*maxsize = part->size;
36*09c32807SHeiko Schocher 	*idx = dev->id->num;
37*09c32807SHeiko Schocher 
38*09c32807SHeiko Schocher 	return 0;
39*09c32807SHeiko Schocher #else
40*09c32807SHeiko Schocher 	puts("offset is not a number\n");
41*09c32807SHeiko Schocher 	return -1;
42*09c32807SHeiko Schocher #endif
43*09c32807SHeiko Schocher }
44*09c32807SHeiko Schocher 
45*09c32807SHeiko Schocher int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
46*09c32807SHeiko Schocher 		loff_t *maxsize, int devtype, int chipsize)
47*09c32807SHeiko Schocher {
48*09c32807SHeiko Schocher 	if (!str2off(arg, off))
49*09c32807SHeiko Schocher 		return get_part(arg, idx, off, size, maxsize, devtype);
50*09c32807SHeiko Schocher 
51*09c32807SHeiko Schocher 	if (*off >= chipsize) {
52*09c32807SHeiko Schocher 		puts("Offset exceeds device limit\n");
53*09c32807SHeiko Schocher 		return -1;
54*09c32807SHeiko Schocher 	}
55*09c32807SHeiko Schocher 
56*09c32807SHeiko Schocher 	*maxsize = chipsize - *off;
57*09c32807SHeiko Schocher 	*size = *maxsize;
58*09c32807SHeiko Schocher 	return 0;
59*09c32807SHeiko Schocher }
60*09c32807SHeiko Schocher 
61*09c32807SHeiko Schocher int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
62*09c32807SHeiko Schocher 		 loff_t *size, loff_t *maxsize, int devtype, int chipsize)
63*09c32807SHeiko Schocher {
64*09c32807SHeiko Schocher 	int ret;
65*09c32807SHeiko Schocher 
66*09c32807SHeiko Schocher 	if (argc == 0) {
67*09c32807SHeiko Schocher 		*off = 0;
68*09c32807SHeiko Schocher 		*size = chipsize;
69*09c32807SHeiko Schocher 		*maxsize = *size;
70*09c32807SHeiko Schocher 		goto print;
71*09c32807SHeiko Schocher 	}
72*09c32807SHeiko Schocher 
73*09c32807SHeiko Schocher 	ret = mtd_arg_off(argv[0], idx, off, size, maxsize, devtype,
74*09c32807SHeiko Schocher 			  chipsize);
75*09c32807SHeiko Schocher 	if (ret)
76*09c32807SHeiko Schocher 		return ret;
77*09c32807SHeiko Schocher 
78*09c32807SHeiko Schocher 	if (argc == 1)
79*09c32807SHeiko Schocher 		goto print;
80*09c32807SHeiko Schocher 
81*09c32807SHeiko Schocher 	if (!str2off(argv[1], size)) {
82*09c32807SHeiko Schocher 		printf("'%s' is not a number\n", argv[1]);
83*09c32807SHeiko Schocher 		return -1;
84*09c32807SHeiko Schocher 	}
85*09c32807SHeiko Schocher 
86*09c32807SHeiko Schocher 	if (*size > *maxsize) {
87*09c32807SHeiko Schocher 		puts("Size exceeds partition or device limit\n");
88*09c32807SHeiko Schocher 		return -1;
89*09c32807SHeiko Schocher 	}
90*09c32807SHeiko Schocher 
91*09c32807SHeiko Schocher print:
92*09c32807SHeiko Schocher 	printf("device %d ", *idx);
93*09c32807SHeiko Schocher 	if (*size == chipsize)
94*09c32807SHeiko Schocher 		puts("whole chip\n");
95*09c32807SHeiko Schocher 	else
96*09c32807SHeiko Schocher 		printf("offset 0x%llx, size 0x%llx\n",
97*09c32807SHeiko Schocher 		       (unsigned long long)*off, (unsigned long long)*size);
98*09c32807SHeiko Schocher 	return 0;
99*09c32807SHeiko Schocher }
100