xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/resource_img.c (revision e8c34540a61ba8ec3ef255e3e8a72e7d3409f5f5)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 #include <common.h>
7 #include <adc.h>
8 #include <asm/io.h>
9 #include <fs.h>
10 #include <malloc.h>
11 #include <sysmem.h>
12 #include <linux/list.h>
13 #include <asm/arch/resource_img.h>
14 #include <boot_rkimg.h>
15 #include <dm/ofnode.h>
16 #ifdef CONFIG_ANDROID_AB
17 #include <android_avb/libavb_ab.h>
18 #include <android_avb/rk_avb_ops_user.h>
19 #endif
20 #ifdef CONFIG_ANDROID_BOOT_IMAGE
21 #include <android_bootloader.h>
22 #include <android_image.h>
23 #endif
24 
25 DECLARE_GLOBAL_DATA_PTR;
26 
27 #define PART_RESOURCE			"resource"
28 #define RESOURCE_MAGIC			"RSCE"
29 #define RESOURCE_MAGIC_SIZE		4
30 #define RESOURCE_VERSION		0
31 #define CONTENT_VERSION			0
32 #define ENTRY_TAG			"ENTR"
33 #define ENTRY_TAG_SIZE			4
34 #define MAX_FILE_NAME_LEN		256
35 
36 /*
37  *         resource image structure
38  * ----------------------------------------------
39  * |                                            |
40  * |    header  (1 block)                       |
41  * |                                            |
42  * ---------------------------------------------|
43  * |                      |                     |
44  * |    entry0  (1 block) |                     |
45  * |                      |                     |
46  * ------------------------                     |
47  * |                      |                     |
48  * |    entry1  (1 block) | contents (n blocks) |
49  * |                      |                     |
50  * ------------------------                     |
51  * |    ......            |                     |
52  * ------------------------                     |
53  * |                      |                     |
54  * |    entryn  (1 block) |                     |
55  * |                      |                     |
56  * ----------------------------------------------
57  * |                                            |
58  * |    file0  (x blocks)                       |
59  * |                                            |
60  * ----------------------------------------------
61  * |                                            |
62  * |    file1  (y blocks)                       |
63  * |                                            |
64  * ----------------------------------------------
65  * |                   ......                   |
66  * |---------------------------------------------
67  * |                                            |
68  * |    filen  (z blocks)                       |
69  * |                                            |
70  * ----------------------------------------------
71  */
72 
73 /**
74  * struct resource_image_header
75  *
76  * @magic: should be "RSCE"
77  * @version: resource image version, current is 0
78  * @c_version: content version, current is 0
79  * @blks: the size of the header ( 1 block = 512 bytes)
80  * @c_offset: contents offset(by block) in the image
81  * @e_blks: the size(by block) of the entry in the contents
82  * @e_num: numbers of the entrys.
83  */
84 
85 struct resource_img_hdr {
86 	char		magic[4];
87 	uint16_t	version;
88 	uint16_t	c_version;
89 	uint8_t		blks;
90 	uint8_t		c_offset;
91 	uint8_t		e_blks;
92 	uint32_t	e_nums;
93 };
94 
95 struct resource_entry {
96 	char		tag[4];
97 	char		name[MAX_FILE_NAME_LEN];
98 	uint32_t	f_offset;
99 	uint32_t	f_size;
100 };
101 
102 struct resource_file {
103 	char		name[MAX_FILE_NAME_LEN];
104 	uint32_t	f_offset;
105 	uint32_t	f_size;
106 	struct list_head link;
107 	uint32_t 	rsce_base;	/* Base addr of resource */
108 };
109 
110 static LIST_HEAD(entrys_head);
111 
112 static int resource_image_check_header(const struct resource_img_hdr *hdr)
113 {
114 	int ret;
115 
116 	ret = memcmp(RESOURCE_MAGIC, hdr->magic, RESOURCE_MAGIC_SIZE);
117 	if (ret) {
118 		printf("bad resource image magic: %s\n",
119 		       hdr->magic ? hdr->magic : "none");
120 		ret = -EINVAL;
121 	}
122 	debug("resource image header:\n");
123 	debug("magic:%s\n", hdr->magic);
124 	debug("version:%d\n", hdr->version);
125 	debug("c_version:%d\n", hdr->c_version);
126 	debug("blks:%d\n", hdr->blks);
127 	debug("c_offset:%d\n", hdr->c_offset);
128 	debug("e_blks:%d\n", hdr->e_blks);
129 	debug("e_num:%d\n", hdr->e_nums);
130 
131 	return ret;
132 }
133 
134 static int add_file_to_list(struct resource_entry *entry, int rsce_base)
135 {
136 	struct resource_file *file;
137 
138 	if (memcmp(entry->tag, ENTRY_TAG, ENTRY_TAG_SIZE)) {
139 		printf("invalid entry tag\n");
140 		return -ENOENT;
141 	}
142 	file = malloc(sizeof(*file));
143 	if (!file) {
144 		printf("out of memory\n");
145 		return -ENOMEM;
146 	}
147 	strcpy(file->name, entry->name);
148 	file->rsce_base = rsce_base;
149 	file->f_offset = entry->f_offset;
150 	file->f_size = entry->f_size;
151 	list_add_tail(&file->link, &entrys_head);
152 	debug("entry:%p  %s offset:%d size:%d\n",
153 	      entry, file->name, file->f_offset, file->f_size);
154 
155 	return 0;
156 }
157 
158 static int init_resource_list(struct resource_img_hdr *hdr)
159 {
160 	struct resource_entry *entry;
161 	void *content;
162 	int size;
163 	int ret;
164 	int e_num;
165 	int offset = 0;
166 	int resource_found = 0;
167 	struct blk_desc *dev_desc;
168 	disk_partition_t part_info;
169 	char *boot_partname = PART_BOOT;
170 
171 /*
172  * Primary detect AOSP format image, try to get resource image from
173  * boot/recovery partition. If not, it's an RK format image and try
174  * to get from resource partition.
175  */
176 #ifdef CONFIG_ANDROID_BOOT_IMAGE
177 	struct andr_img_hdr *andr_hdr;
178 #endif
179 
180 	if (hdr) {
181 		if (resource_image_check_header(hdr))
182 			return -EEXIST;
183 
184 		content = (void *)((char *)hdr
185 				   + (hdr->c_offset) * RK_BLK_SIZE);
186 		for (e_num = 0; e_num < hdr->e_nums; e_num++) {
187 			size = e_num * hdr->e_blks * RK_BLK_SIZE;
188 			entry = (struct resource_entry *)(content + size);
189 			add_file_to_list(entry, offset);
190 		}
191 		return 0;
192 	}
193 
194 	dev_desc = rockchip_get_bootdev();
195 	if (!dev_desc) {
196 		printf("%s: dev_desc is NULL!\n", __func__);
197 		return -ENODEV;
198 	}
199 	hdr = memalign(ARCH_DMA_MINALIGN, RK_BLK_SIZE);
200 	if (!hdr) {
201 		printf("%s: out of memory!\n", __func__);
202 		return -ENOMEM;
203 	}
204 
205 #ifdef CONFIG_ANDROID_BOOT_IMAGE
206 	/* Get boot mode from misc */
207 #ifndef CONFIG_ANDROID_AB
208 	if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY)
209 		boot_partname = PART_RECOVERY;
210 #endif
211 
212 	/* Read boot/recovery and chenc if this is an AOSP img */
213 #ifdef CONFIG_ANDROID_AB
214 	char slot_suffix[3] = {0};
215 
216 	if (rk_avb_get_current_slot(slot_suffix)) {
217 		ret = -ENODEV;
218 		goto out;
219 	}
220 
221 	boot_partname = android_str_append(boot_partname, slot_suffix);
222 	if (!boot_partname) {
223 		ret = -EINVAL;
224 		goto out;
225 	}
226 #endif
227 	ret = part_get_info_by_name(dev_desc, boot_partname, &part_info);
228 	if (ret < 0) {
229 		printf("%s: failed to get %s part, ret=%d\n",
230 		       __func__, boot_partname, ret);
231 		/* RKIMG can support part table without 'boot' */
232 		goto next;
233 	}
234 
235 	/*
236 	 * Only read header and check magic, is a AOSP format image?
237 	 * If so, get resource image from second part.
238 	 */
239 	andr_hdr = (void *)hdr;
240 	ret = blk_dread(dev_desc, part_info.start, 1, andr_hdr);
241 	if (ret != 1) {
242 		printf("%s: failed to read %s hdr, ret=%d\n",
243 		       __func__, part_info.name, ret);
244 		ret = -EIO;
245 		goto out;
246 	}
247 	ret = android_image_check_header(andr_hdr);
248 	if (!ret) {
249 		debug("%s: Load resource from %s second pos\n",
250 		      __func__, part_info.name);
251 		/* Read resource from second offset */
252 		offset = part_info.start * RK_BLK_SIZE;
253 		offset += andr_hdr->page_size;
254 		offset += ALIGN(andr_hdr->kernel_size, andr_hdr->page_size);
255 		offset += ALIGN(andr_hdr->ramdisk_size, andr_hdr->page_size);
256 		offset = offset / RK_BLK_SIZE;
257 
258 		resource_found = 1;
259 	}
260 next:
261 #endif
262 	/*
263 	 * If not found resource image in AOSP format images(boot/recovery part),
264 	 * try to read RK format images(resource part).
265 	 */
266 	if (!resource_found) {
267 		debug("%s: Load resource from resource part\n", __func__);
268 		/* Read resource from Rockchip Resource partition */
269 		boot_partname = PART_RESOURCE;
270 		ret = part_get_info_by_name(dev_desc, boot_partname, &part_info);
271 		if (ret < 0) {
272 			printf("%s: failed to get resource part, ret=%d\n",
273 			       __func__, ret);
274 			goto out;
275 		}
276 		offset = part_info.start;
277 	}
278 
279 	/* Only read header and check magic */
280 	ret = blk_dread(dev_desc, offset, 1, hdr);
281 	if (ret != 1) {
282 		printf("%s: failed to read resource hdr, ret=%d\n",
283 		       __func__, ret);
284 		ret = -EIO;
285 		goto out;
286 	}
287 
288 	ret = resource_image_check_header(hdr);
289 	if (ret < 0) {
290 		ret = -EINVAL;
291 		goto out;
292 	}
293 
294 	content = memalign(ARCH_DMA_MINALIGN,
295 			   hdr->e_blks * hdr->e_nums * RK_BLK_SIZE);
296 	if (!content) {
297 		printf("%s: failed to alloc memory for content\n", __func__);
298 		ret = -ENOMEM;
299 		goto out;
300 	}
301 
302 	/* Read all entries from resource image */
303 	ret = blk_dread(dev_desc, offset + hdr->c_offset,
304 			hdr->e_blks * hdr->e_nums, content);
305 	if (ret != (hdr->e_blks * hdr->e_nums)) {
306 		printf("%s: failed to read resource entries, ret=%d\n",
307 		       __func__, ret);
308 		ret = -EIO;
309 		goto err;
310 	}
311 
312 	for (e_num = 0; e_num < hdr->e_nums; e_num++) {
313 		size = e_num * hdr->e_blks * RK_BLK_SIZE;
314 		entry = (struct resource_entry *)(content + size);
315 		add_file_to_list(entry, offset);
316 	}
317 
318 	ret = 0;
319 	printf("Load FDT from %s part\n", boot_partname);
320 err:
321 	free(content);
322 out:
323 	free(hdr);
324 
325 	return ret;
326 }
327 
328 static struct resource_file *get_file_info(struct resource_img_hdr *hdr,
329 					   const char *name)
330 {
331 	struct resource_file *file;
332 	struct list_head *node;
333 
334 	if (list_empty(&entrys_head)) {
335 		if (init_resource_list(hdr))
336 			return NULL;
337 	}
338 
339 	list_for_each(node, &entrys_head) {
340 		file = list_entry(node, struct resource_file, link);
341 		if (!strcmp(file->name, name))
342 			return file;
343 	}
344 
345 	return NULL;
346 }
347 
348 int rockchip_get_resource_file_offset(void *resc_hdr, const char *name)
349 {
350 	struct resource_file *file;
351 
352 	file = get_file_info(resc_hdr, name);
353 	if (!file)
354 		return -ENFILE;
355 
356 	return file->f_offset;
357 }
358 
359 int rockchip_get_resource_file_size(void *resc_hdr, const char *name)
360 {
361 	struct resource_file *file;
362 
363 	file = get_file_info(resc_hdr, name);
364 	if (!file)
365 		return -ENFILE;
366 
367 	return file->f_size;
368 }
369 
370 /*
371  * read file from resource partition
372  * @buf: destination buf to store file data;
373  * @name: file name
374  * @offset: blocks offset in the file, 1 block = 512 bytes
375  * @len: the size(by bytes) of file to read.
376  */
377 int rockchip_read_resource_file(void *buf, const char *name,
378 				int offset, int len)
379 {
380 	struct resource_file *file;
381 	int ret = 0;
382 	int blks;
383 	struct blk_desc *dev_desc;
384 
385 	file = get_file_info(NULL, name);
386 	if (!file) {
387 		printf("Can't find file:%s\n", name);
388 		return -ENOENT;
389 	}
390 
391 	if (len <= 0 || len > file->f_size)
392 		len = file->f_size;
393 	blks = DIV_ROUND_UP(len, RK_BLK_SIZE);
394 	dev_desc = rockchip_get_bootdev();
395 	if (!dev_desc) {
396 		printf("%s: dev_desc is NULL!\n", __func__);
397 		return -ENODEV;
398 	}
399 	ret = blk_dread(dev_desc, file->rsce_base + file->f_offset + offset,
400 			blks, buf);
401 	if (ret != blks)
402 		ret = -EIO;
403 	else
404 		ret = len;
405 
406 	return ret;
407 }
408 
409 #define is_digit(c)		((c) >= '0' && (c) <= '9')
410 #define is_abcd(c)		((c) >= 'a' && (c) <= 'd')
411 #define is_equal(c)		((c) == '=')
412 
413 #define DTB_FILE		"rk-kernel.dtb"
414 #define KEY_WORDS_ADC_CTRL	"#_"
415 #define KEY_WORDS_ADC_CH	"_ch"
416 #define KEY_WORDS_GPIO		"#gpio"
417 #define GPIO_SWPORT_DDR		0x04
418 #define GPIO_EXT_PORT		0x50
419 #define MAX_ADC_CH_NR		10
420 #define MAX_GPIO_NR		10
421 
422 #ifdef CONFIG_ADC
423 /*
424  * How to make it works ?
425  *
426  * 1. pack dtb into rockchip resource.img, require:
427  *    (1) file name end with ".dtb";
428  *    (2) file name contains key words, like: ...#_[controller]_ch[channel]=[value]...dtb
429  *	  @controller: adc controller name in dts, eg. "saradc", ...;
430  *	  @channel: adc channel;
431  *	  @value: adc value;
432  *    eg: ...#_saradc_ch1=223#_saradc_ch2=650....dtb
433  *
434  * 2. U-Boot dtsi about adc controller node:
435  *    (1) enable "u-boot,dm-pre-reloc;";
436  *    (2) must set status "okay";
437  */
438 static int rockchip_read_dtb_by_adc(const char *file_name)
439 {
440 	static int cached_v[MAX_ADC_CH_NR];
441 	int offset_ctrl = strlen(KEY_WORDS_ADC_CTRL);
442 	int offset_ch = strlen(KEY_WORDS_ADC_CH);
443 	int ret, channel, len = 0, found = 0, margin = 30;
444 	uint32_t raw_adc;
445 	unsigned long dtb_adc;
446 	char *stradc, *strch, *p;
447 	char adc_v_string[10];
448 	char dev_name[32];
449 
450 	debug("%s: %s\n", __func__, file_name);
451 
452 	/* Invalid format ? */
453 	stradc = strstr(file_name, KEY_WORDS_ADC_CTRL);
454 	while (stradc) {
455 		debug("   - substr: %s\n", stradc);
456 
457 		/* Parse controller name */
458 		strch = strstr(stradc, KEY_WORDS_ADC_CH);
459 		len = strch - (stradc + offset_ctrl);
460 		strlcpy(dev_name, stradc + offset_ctrl, len + 1);
461 
462 		/* Parse adc channel */
463 		p = strch + offset_ch;
464 		if (is_digit(*p) && is_equal(*(p + 1))) {
465 			channel = *p - '0';
466 		} else {
467 			debug("   - invalid format: %s\n", stradc);
468 			return -EINVAL;
469 		}
470 
471 		/*
472 		 * Read raw adc value
473 		 *
474 		 * It doesn't need to read adc value every loop, reading once
475 		 * is enough. We use cached_v[] to save what we have read, zero
476 		 * means not read before.
477 		 */
478 		if (cached_v[channel] == 0) {
479 			ret = adc_channel_single_shot(dev_name,
480 						      channel, &raw_adc);
481 			if (ret) {
482 				debug("   - failed to read adc, ret=%d\n", ret);
483 				return ret;
484 			}
485 			cached_v[channel] = raw_adc;
486 		}
487 
488 		/* Parse dtb adc value */
489 		p = strch + offset_ch + 2;	/* 2: channel and '=' */
490 		while (*p && is_digit(*p)) {
491 			len++;
492 			p++;
493 		}
494 		strlcpy(adc_v_string, strch + offset_ch + 2, len + 1);
495 		dtb_adc = simple_strtoul(adc_v_string, NULL, 10);
496 
497 		if (abs(dtb_adc - cached_v[channel]) <= margin) {
498 			found = 1;
499 			stradc = strstr(p, KEY_WORDS_ADC_CTRL);
500 		} else {
501 			found = 0;
502 			break;
503 		}
504 
505 		debug("   - parse: controller=%s, channel=%d, dtb_adc=%ld, read=%d %s\n",
506 		      dev_name, channel, dtb_adc, cached_v[channel], found ? "(Y)" : "");
507 	}
508 
509 	return found ? 0 : -ENOENT;
510 }
511 #else
512 static int rockchip_read_dtb_by_adc(const char *file_name)
513 {
514 	return  -ENOENT;
515 }
516 #endif
517 
518 static int gpio_parse_base_address(fdt_addr_t *gpio_base_addr)
519 {
520 	static int initial;
521 	ofnode parent, node;
522 	const char *name;
523 	int idx, nr = 0;
524 
525 	if (initial)
526 		return 0;
527 
528 	parent = ofnode_path("/pinctrl");
529 	if (!ofnode_valid(parent)) {
530 		debug("   - Can't find pinctrl node\n");
531 		return -EINVAL;
532 	}
533 
534 	ofnode_for_each_subnode(node, parent) {
535 		if (!ofnode_get_property(node, "gpio-controller", NULL)) {
536 			debug("   - Can't find gpio-controller\n");
537 			continue;
538 		}
539 
540 		name = ofnode_get_name(node);
541 		if (!is_digit((char)*(name + 4))) {
542 			debug("   - bad gpio node name: %s\n", name);
543 			continue;
544 		}
545 
546 		nr++;
547 		idx = *(name + 4) - '0';
548 		gpio_base_addr[idx] = ofnode_get_addr(node);
549 		debug("   - gpio%d: 0x%x\n", idx, (uint32_t)gpio_base_addr[idx]);
550 	}
551 
552 	if (nr == 0) {
553 		debug("   - parse gpio address failed\n");
554 		return -EINVAL;
555 	}
556 
557 	initial = 1;
558 
559 	return 0;
560 }
561 
562 /*
563  * How to make it works ?
564  *
565  * 1. pack dtb into rockchip resource.img, require:
566  *    (1) file name end with ".dtb";
567  *    (2) file name contains key words, like: ...#gpio[pin]=[value]...dtb
568  *	  @pin: gpio name, eg. 0a2 means GPIO0A2;
569  *	  @value: gpio level, 0 or 1;
570  *    eg: ...#gpio0a6=1#gpio1c2=0....dtb
571  *
572  * 2. U-Boot dtsi about gpio node:
573  *    (1) enable "u-boot,dm-pre-reloc;" for all gpio node;
574  *    (2) set all gpio status "disabled"(Because we just want their property);
575  */
576 static int rockchip_read_dtb_by_gpio(const char *file_name)
577 {
578 	static uint32_t cached_v[MAX_GPIO_NR];
579 	fdt_addr_t gpio_base_addr[MAX_GPIO_NR];
580 	int ret, found = 0, offset = strlen(KEY_WORDS_GPIO);
581 	uint8_t port, pin, bank, lvl, val;
582 	char *strgpio, *p;
583 	uint32_t bit;
584 
585 	debug("%s\n", file_name);
586 
587 	/* Parse gpio address */
588 	memset(gpio_base_addr, 0, sizeof(gpio_base_addr));
589 	ret = gpio_parse_base_address(gpio_base_addr);
590 	if (ret) {
591 		debug("   - Can't parse gpio base address: %d\n", ret);
592 		return ret;
593 	}
594 
595 	strgpio = strstr(file_name, KEY_WORDS_GPIO);
596 	while (strgpio) {
597 		debug("   - substr: %s\n", strgpio);
598 
599 		p = strgpio + offset;
600 
601 		/* Invalid format ? */
602 		if (!(is_digit(*(p + 0)) && is_abcd(*(p + 1)) &&
603 		      is_digit(*(p + 2)) && is_equal(*(p + 3)) &&
604 		      is_digit(*(p + 4)))) {
605 			debug("   - invalid format: %s\n", strgpio);
606 			return -EINVAL;
607 		}
608 
609 		/* Read gpio value */
610 		port = *(p + 0) - '0';
611 		bank = *(p + 1) - 'a';
612 		pin  = *(p + 2) - '0';
613 		lvl  = *(p + 4) - '0';
614 
615 		/*
616 		 * It doesn't need to read gpio value every loop, reading once
617 		 * is enough. We use cached_v[] to save what we have read, zero
618 		 * means not read before.
619 		 */
620 		if (cached_v[port] == 0) {
621 			if (!gpio_base_addr[port]) {
622 				debug("   - can't find gpio%d base address\n", port);
623 				return 0;
624 			}
625 
626 			/* Input mode */
627 			val = readl(gpio_base_addr[port] + GPIO_SWPORT_DDR);
628 			val &= ~(1 << (bank * 8 + pin));
629 			writel(val, gpio_base_addr[port] + GPIO_SWPORT_DDR);
630 
631 			cached_v[port] =
632 				readl(gpio_base_addr[port] + GPIO_EXT_PORT);
633 		}
634 
635 		/* Verify result */
636 		bit = bank * 8 + pin;
637 		val = cached_v[port] & (1 << bit) ? 1 : 0;
638 
639 		if (val == !!lvl) {
640 			found = 1;
641 			strgpio = strstr(p, KEY_WORDS_GPIO);
642 		} else {
643 			found = 0;
644 			break;
645 		}
646 
647 		debug("   - parse: gpio%d%c%d=%d, read=%d %s\n",
648 		      port, bank + 'a', pin, lvl, val, found ? "(Y)" : "(N)");
649 	}
650 
651 	return found ? 0 : -ENOENT;
652 }
653 
654 #ifdef CONFIG_ROCKCHIP_EARLY_DISTRO_DTB
655 static int rockchip_read_distro_dtb_file(char *fdt_addr)
656 {
657 	const char *cmd = "part list ${devtype} ${devnum} -bootable devplist";
658 	char *devnum, *devtype, *devplist;
659 	char devnum_part[12];
660 	char fdt_hex_str[19];
661 	char *fs_argv[5];
662 	int ret;
663 
664 	if (!rockchip_get_bootdev() || !fdt_addr)
665 		return -ENODEV;
666 
667 	ret = run_command_list(cmd, -1, 0);
668 	if (ret)
669 		return ret;
670 
671 	devplist = env_get("devplist");
672 	if (!devplist)
673 		return -ENODEV;
674 
675 	devtype = env_get("devtype");
676 	devnum = env_get("devnum");
677 	sprintf(devnum_part, "%s:%s", devnum, devplist);
678 	sprintf(fdt_hex_str, "0x%lx", (ulong)fdt_addr);
679 
680 #ifdef CONFIG_CMD_FS_GENERIC
681 	fs_argv[0] = "load";
682 	fs_argv[1] = devtype,
683 	fs_argv[2] = devnum_part;
684 	fs_argv[3] = fdt_hex_str;
685 	fs_argv[4] = CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH;
686 
687 	if (do_load(NULL, 0, 5, fs_argv, FS_TYPE_ANY))
688 		return -EIO;
689 #endif
690 	if (fdt_check_header(fdt_addr))
691 		return -EIO;
692 
693 	return fdt_totalsize(fdt_addr);
694 }
695 #endif
696 
697 int rockchip_read_dtb_file(void *fdt_addr)
698 {
699 	struct resource_file *file;
700 	struct list_head *node;
701 	char *dtb_name = DTB_FILE;
702 	int size = -ENODEV;
703 
704 	if (list_empty(&entrys_head)) {
705 		if (init_resource_list(NULL)) {
706 #ifdef CONFIG_ROCKCHIP_EARLY_DISTRO_DTB
707 			/* Maybe a distro boot.img with dtb ? */
708 			printf("Distro DTB: %s\n",
709 			       CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH);
710 			size = rockchip_read_distro_dtb_file(fdt_addr);
711 			if (size < 0)
712 				return size;
713 			if (!sysmem_alloc_base(MEMBLK_ID_FDT,
714 				(phys_addr_t)fdt_addr,
715 				ALIGN(size, RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD))
716 				return -ENOMEM;
717 #endif
718 			return size;
719 		}
720 	}
721 
722 	list_for_each(node, &entrys_head) {
723 		file = list_entry(node, struct resource_file, link);
724 		if (!strstr(file->name, ".dtb"))
725 			continue;
726 
727 		if (strstr(file->name, KEY_WORDS_ADC_CTRL) &&
728 		    strstr(file->name, KEY_WORDS_ADC_CH) &&
729 		    !rockchip_read_dtb_by_adc(file->name)) {
730 			dtb_name = file->name;
731 			break;
732 		} else if (strstr(file->name, KEY_WORDS_GPIO) &&
733 			   !rockchip_read_dtb_by_gpio(file->name)) {
734 			dtb_name = file->name;
735 			break;
736 		}
737 	}
738 
739 	printf("DTB: %s\n", dtb_name);
740 
741 	size = rockchip_get_resource_file_size((void *)fdt_addr, dtb_name);
742 	if (size < 0)
743 		return size;
744 
745 	if (!sysmem_alloc_base(MEMBLK_ID_FDT, (phys_addr_t)fdt_addr,
746 			       ALIGN(size, RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD))
747 		return -ENOMEM;
748 
749 	size = rockchip_read_resource_file((void *)fdt_addr, dtb_name, 0, 0);
750 	if (size < 0)
751 		return size;
752 
753 #if defined(CONFIG_CMD_DTIMG) && defined(CONFIG_OF_LIBFDT_OVERLAY)
754 	android_fdt_overlay_apply((void *)fdt_addr);
755 #endif
756 
757 	return size;
758 }
759