xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/boot_rkimg.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <adc.h>
9 #include <android_bootloader.h>
10 #include <android_image.h>
11 #include <bidram.h>
12 #include <bootm.h>
13 #include <boot_rkimg.h>
14 #include <cli.h>
15 #include <crypto.h>
16 #include <dm.h>
17 #include <fs.h>
18 #include <image.h>
19 #include <key.h>
20 #include <mmc.h>
21 #include <malloc.h>
22 #include <mp_boot.h>
23 #include <mtd_blk.h>
24 #include <nvme.h>
25 #include <scsi.h>
26 #include <stdlib.h>
27 #include <sysmem.h>
28 #include <asm/io.h>
29 #include <asm/arch/boot_mode.h>
30 #include <asm/arch/fit.h>
31 #include <asm/arch/hotkey.h>
32 #include <asm/arch/param.h>
33 #include <asm/arch/resource_img.h>
34 #include <asm/arch/uimage.h>
35 #include <dm/ofnode.h>
36 #include <linux/list.h>
37 #include <u-boot/sha1.h>
38 #include <u-boot/sha256.h>
39 #include <linux/usb/phy-rockchip-usb2.h>
40 
41 DECLARE_GLOBAL_DATA_PTR;
42 
rk_board_early_fdt_fixup(void * blob)43 __weak int rk_board_early_fdt_fixup(void *blob)
44 {
45 	return 0;
46 }
47 
rk_board_scan_bootdev(void)48 __weak int rk_board_scan_bootdev(void)
49 {
50 	const char *devtype_num_set = "run rkimg_bootdev";
51 
52 	return run_command_list(devtype_num_set, -1, 0);
53 }
54 
bootdev_init(const char * devtype,const char * devnum)55 static int bootdev_init(const char *devtype, const char *devnum)
56 {
57 #ifdef CONFIG_MMC
58 	if (!strcmp("mmc", devtype))
59 		mmc_initialize(gd->bd);
60 #endif
61 #ifdef CONFIG_NVME
62 	if (!strcmp("nvme", devtype)) {
63 		pci_init();
64 		if (nvme_scan_namespace())
65 			return -ENODEV;
66 	}
67 #endif
68 #if defined(CONFIG_SCSI) && defined(CONFIG_CMD_SCSI) && defined(CONFIG_AHCI)
69 	if (!strcmp("scsi", devtype)) {
70 		if (scsi_scan(true))
71 			return -ENODEV;
72 	}
73 #endif
74 	/* Ok, let's test whether we can get the expected boot device or not */
75 	if (!blk_get_devnum_by_typename(devtype, atoi(devnum)))
76 		return -ENODEV;
77 
78 	env_set("devtype", devtype);
79 	env_set("devnum", devnum);
80 
81 	return 0;
82 }
83 
84 /*
85  * Priority: configuration > atags > scan list.
86  */
boot_devtype_init(void)87 static void boot_devtype_init(void)
88 {
89 	char *devtype = NULL, *devnum = NULL;
90 	char *src = "scan";
91 	static int done;	/* static */
92 	int ret;
93 
94 	if (done)
95 		return;
96 
97 #ifdef CONFIG_MP_BOOT
98 	mpb_post(0);
99 #endif
100 
101 	/* configuration */
102 	if (!param_parse_assign_bootdev(&devtype, &devnum)) {
103 		if (!bootdev_init(devtype, devnum)) {
104 			src = "assign";
105 			goto finish;
106 		}
107 	}
108 
109 	/* atags */
110 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
111 	if (!param_parse_atags_bootdev(&devtype, &devnum)) {
112 		if (!bootdev_init(devtype, devnum)) {
113 			src = "atags";
114 			goto finish;
115 		}
116 	}
117 #endif
118 
119 	/* scan list */
120 #ifdef CONFIG_MMC
121 	mmc_initialize(gd->bd);
122 #endif
123 	ret = rk_board_scan_bootdev();
124 	if (ret) {
125 		/* Set default if all failed */
126 		devtype = "mmc";
127 		devnum = "0";
128 		env_set("devtype", devtype);
129 		env_set("devnum", devnum);
130 	}
131 finish:
132 	done = 1;
133 	printf("Bootdev(%s): %s %s\n", src,
134 	       env_get("devtype"), env_get("devnum"));
135 }
136 
get_bootdev_type(void)137 static int get_bootdev_type(void)
138 {
139 	char *boot_media = NULL, *devtype = NULL;
140 	char boot_options[128] = {0};
141 	static int appended;
142 	ulong devnum = 0;
143 	int type = 0;
144 
145 	devtype = env_get("devtype");
146 	devnum = env_get_ulong("devnum", 10, 0);
147 
148 	/* For current use(Only EMMC support!) */
149 	if (!devtype) {
150 		devtype = "mmc";
151 		printf("Use emmc as default boot media\n");
152 	}
153 
154 	if (!strcmp(devtype, "mmc")) {
155 		type = IF_TYPE_MMC;
156 		if (devnum == 1)
157 			boot_media = "sd";
158 		else
159 			boot_media = "emmc";
160 	} else if (!strcmp(devtype, "rknand")) {
161 		type = IF_TYPE_RKNAND;
162 		boot_media = "nand";
163 	} else if (!strcmp(devtype, "spinand")) {
164 		type = IF_TYPE_SPINAND;
165 		boot_media = "nand"; /* kernel treat sfc nand as nand device */
166 	} else if (!strcmp(devtype, "spinor")) {
167 		type = IF_TYPE_SPINOR;
168 		boot_media = "nor";
169 	} else if (!strcmp(devtype, "ramdisk")) {
170 		type = IF_TYPE_RAMDISK;
171 		boot_media = "ramdisk";
172 	} else if (!strcmp(devtype, "mtd")) {
173 		type = IF_TYPE_MTD;
174 		boot_media = "mtd";
175 	} else if (!strcmp(devtype, "scsi")) {
176 		type = IF_TYPE_SCSI;
177 		boot_media = "scsi";
178 	} else if (!strcmp(devtype, "nvme")) {
179 		type = IF_TYPE_NVME;
180 		boot_media = "nvme";
181 	} else {
182 		/* Add new to support */
183 	}
184 
185 	if (!appended && boot_media) {
186 		appended = 1;
187 
188 	/*
189 	 * The legacy rockchip Android (SDK < 8.1) requires "androidboot.mode="
190 	 * to be "charger" or boot media which is a rockchip private solution.
191 	 *
192 	 * The official Android rule (SDK >= 8.1) is:
193 	 * "androidboot.mode=normal" or "androidboot.mode=charger".
194 	 *
195 	 * Now that this U-Boot is usually working with higher version
196 	 * Android (SDK >= 8.1), we follow the official rules.
197 	 *
198 	 * Common: androidboot.mode=charger has higher priority, don't override;
199 	 */
200 #ifdef CONFIG_RKIMG_ANDROID_BOOTMODE_LEGACY
201 		/* rknand doesn't need "androidboot.mode="; */
202 		if (env_exist("bootargs", "androidboot.mode=charger") ||
203 		    (type == IF_TYPE_RKNAND) ||
204 		    (type == IF_TYPE_SPINAND) ||
205 		    (type == IF_TYPE_SPINOR))
206 			snprintf(boot_options, sizeof(boot_options),
207 				 "storagemedia=%s", boot_media);
208 		else
209 			snprintf(boot_options, sizeof(boot_options),
210 				 "storagemedia=%s androidboot.mode=%s",
211 				 boot_media, boot_media);
212 #else
213 		/*
214 		 * 1. "storagemedia": This is a legacy variable to indicate board
215 		 *    storage media for kernel and android.
216 		 *
217 		 * 2. "androidboot.storagemedia": The same purpose as "storagemedia",
218 		 *    but the android framework will auto create property by
219 		 *    variable with format "androidboot.xxx", eg:
220 		 *
221 		 *    "androidboot.storagemedia" => "ro.boot.storagemedia".
222 		 *
223 		 *    So, U-Boot pass this new variable is only for the convenience
224 		 *    to Android.
225 		 */
226 		if (env_exist("bootargs", "androidboot.mode=charger"))
227 			snprintf(boot_options, sizeof(boot_options),
228 				 "storagemedia=%s androidboot.storagemedia=%s",
229 				 boot_media, boot_media);
230 		else
231 			snprintf(boot_options, sizeof(boot_options),
232 				 "storagemedia=%s androidboot.storagemedia=%s "
233 				 "androidboot.mode=normal ",
234 				 boot_media, boot_media);
235 #endif
236 		env_update("bootargs", boot_options);
237 	}
238 
239 	return type;
240 }
241 
242 static struct blk_desc *dev_desc;
243 
rockchip_get_bootdev(void)244 struct blk_desc *rockchip_get_bootdev(void)
245 {
246 	int dev_type;
247 	int devnum;
248 
249 	if (dev_desc)
250 		return dev_desc;
251 
252 	boot_devtype_init();
253 	dev_type = get_bootdev_type();
254 	devnum = env_get_ulong("devnum", 10, 0);
255 
256 	dev_desc = blk_get_devnum_by_type(dev_type, devnum);
257 	if (!dev_desc) {
258 		printf("%s: Can't find dev_desc!\n", __func__);
259 		return NULL;
260 	}
261 
262 #ifdef CONFIG_MMC
263 	if (dev_type == IF_TYPE_MMC) {
264 		struct mmc *mmc;
265 		const char *timing[] = {
266 			"Legacy", "High Speed", "High Speed", "SDR12",
267 			"SDR25", "SDR50", "SDR104", "DDR50",
268 			"DDR52", "HS200", "HS400", "HS400 Enhanced Strobe"};
269 
270 		mmc = find_mmc_device(devnum);
271 		printf("MMC%d: %s, %dMhz\n", devnum,
272 		       timing[mmc->timing], mmc->clock / 1000000);
273 	}
274 #endif
275 
276 	printf("PartType: %s\n", part_get_type(dev_desc));
277 
278 #ifdef CONFIG_MTD_BLK
279 	mtd_blk_map_partitions(dev_desc);
280 #endif
281 	return dev_desc;
282 }
283 
rockchip_set_bootdev(struct blk_desc * desc)284 void rockchip_set_bootdev(struct blk_desc *desc)
285 {
286 	dev_desc = desc;
287 }
288 
289 /*
290  * detect download key status by adc, most rockchip
291  * based boards use adc sample the download key status,
292  * but there are also some use gpio. So it's better to
293  * make this a weak function that can be override by
294  * some special boards.
295  */
296 #define KEY_DOWN_MIN_VAL	0
297 #define KEY_DOWN_MAX_VAL	30
298 
rockchip_dnl_key_pressed(void)299 __weak int rockchip_dnl_key_pressed(void)
300 {
301 #if defined(CONFIG_DM_KEY)
302 	return key_is_pressed(key_read(KEY_VOLUMEUP));
303 
304 #elif defined(CONFIG_ADC)
305 	const void *blob = gd->fdt_blob;
306 	int node, ret, channel = 1;
307 	u32 val, chns[2];
308 
309 	node = fdt_node_offset_by_compatible(blob, 0, "adc-keys");
310 	if (node >= 0) {
311 		if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2))
312 			channel = chns[1];
313 	}
314 
315 	ret = adc_channel_single_shot("saradc", channel, &val);
316 	if (ret) {
317 		printf("%s: Failed to read saradc, ret=%d\n", __func__, ret);
318 		return 0;
319 	}
320 
321 	return ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL));
322 #endif
323 
324 	return 0;
325 }
326 
setup_download_mode(void)327 void setup_download_mode(void)
328 {
329 	int vbus = 1; /* Assumed 1 in case of no rockusb */
330 
331 	boot_devtype_init();
332 
333 	if (rockchip_dnl_key_pressed() || is_hotkey(HK_ROCKUSB_DNL)) {
334 		printf("download %skey pressed... ",
335 		       is_hotkey(HK_ROCKUSB_DNL) ? "hot" : "");
336 #ifdef CONFIG_CMD_ROCKUSB
337 		vbus = rockchip_u2phy_vbus_detect();
338 #endif
339 		if (vbus > 0) {
340 			printf("%sentering download mode...\n",
341 			       IS_ENABLED(CONFIG_CMD_ROCKUSB) ?
342 			       "" : "no rockusb, ");
343 
344 			/* try rockusb download and brom download */
345 			run_command("download", 0);
346 		} else {
347 			printf("entering recovery mode!\n");
348 			env_set("reboot_mode", "recovery-key");
349 		}
350 	} else if (is_hotkey(HK_FASTBOOT)) {
351 		env_set("reboot_mode", "fastboot");
352 	}
353 }
354 
board_run_recovery_wipe_data(void)355 void board_run_recovery_wipe_data(void)
356 {
357 	struct bootloader_message bmsg;
358 	struct blk_desc *dev_desc;
359 	disk_partition_t part_info;
360 #ifdef CONFIG_ANDROID_BOOT_IMAGE
361 	u32 bcb_offset = android_bcb_msg_sector_offset();
362 #else
363 	u32 bcb_offset = BCB_MESSAGE_BLK_OFFSET;
364 #endif
365 	int cnt, ret;
366 
367 	printf("Rebooting into recovery to do wipe_data\n");
368 	dev_desc = rockchip_get_bootdev();
369 	if (!dev_desc) {
370 		printf("%s: dev_desc is NULL!\n", __func__);
371 		return;
372 	}
373 
374 	ret = part_get_info_by_name(dev_desc, PART_MISC, &part_info);
375 	if (ret < 0) {
376 		printf("%s: Could not found misc partition, just run recovery\n",
377 		       __func__);
378 		goto out;
379 	}
380 
381 	memset((char *)&bmsg, 0, sizeof(struct bootloader_message));
382 	strcpy(bmsg.command, "boot-recovery");
383 	strcpy(bmsg.recovery, "recovery\n--wipe_data");
384 	bmsg.status[0] = 0;
385 	cnt = DIV_ROUND_UP(sizeof(struct bootloader_message), dev_desc->blksz);
386 	ret = blk_dwrite(dev_desc, part_info.start + bcb_offset, cnt, &bmsg);
387 	if (ret != cnt)
388 		printf("Wipe data failed, ret=%d\n", ret);
389 out:
390 	/* now reboot to recovery */
391 	env_set("reboot_mode", "recovery");
392 	run_command("run bootcmd", 0);
393 }
394 
395 #if defined(CONFIG_USING_KERNEL_DTB) || defined(CONFIG_CMD_BOOTM) || \
396     defined(CONFIG_CMD_BOOTZ) || defined(CONFIG_CMD_BOOTI)
397 #ifdef CONFIG_ROCKCHIP_DTB_VERIFY
398 #ifdef CONFIG_DM_CRYPTO
crypto_csum(u32 cap,char * input,u32 input_len,u8 * output)399 static int crypto_csum(u32 cap, char *input, u32 input_len, u8 *output)
400 {
401 	sha_context csha_ctx;
402 	struct udevice *dev;
403 
404 	dev = crypto_get_device(cap);
405 	if (!dev) {
406 		printf("Can't find expected crypto device\n");
407 		return -ENODEV;
408 	}
409 
410 	csha_ctx.algo = cap;
411 	csha_ctx.length = input_len;
412 	crypto_sha_csum(dev, &csha_ctx, (char *)input,
413 			input_len, output);
414 
415 	return 0;
416 }
417 
fdt_check_hash(void * fdt_addr,u32 fdt_size,char * hash_cmp,u32 hash_size)418 static int fdt_check_hash(void *fdt_addr, u32 fdt_size,
419 			  char *hash_cmp, u32 hash_size)
420 {
421 	uchar hash[32];
422 
423 	if (!hash_size)
424 		return 0;
425 
426 	if (hash_size == 20)
427 		crypto_csum(CRYPTO_SHA1, fdt_addr, fdt_size, hash);
428 	else if (hash_size == 32)
429 		crypto_csum(CRYPTO_SHA256, fdt_addr, fdt_size, hash);
430 	else
431 		return -EINVAL;
432 
433 	printf("HASH(c): ");
434 	if (memcmp(hash, hash_cmp, hash_size)) {
435 		printf("error\n");
436 		return -EBADF;
437 	}
438 
439 	printf("OK\n");
440 
441 	return 0;
442 }
443 
444 #else
fdt_check_hash(void * fdt_addr,u32 fdt_size,char * hash_cmp,u32 hash_size)445 static int fdt_check_hash(void *fdt_addr, u32 fdt_size,
446 			  char *hash_cmp, u32 hash_size)
447 {
448 	uchar hash[32];
449 
450 	if (!hash_size)
451 		return 0;
452 
453 	if (hash_size == 20)
454 		sha1_csum((const uchar *)fdt_addr, fdt_size, hash);
455 	else if (hash_size == 32)
456 		sha256_csum((const uchar *)fdt_addr, fdt_size, hash);
457 	else
458 		return -EINVAL;
459 
460 	printf("HASH(s): ");
461 	if (memcmp(hash, hash_cmp, hash_size)) {
462 		printf("error\n");
463 		return -EBADF;
464 	}
465 
466 	printf("OK\n");
467 
468 	return 0;
469 }
470 #endif
471 #endif	/* CONFIG_ROCKCHIP_DTB_VERIFY */
472 
473 #if defined(CONFIG_ROCKCHIP_EARLY_DISTRO_DTB)
rockchip_read_distro_dtb(void * fdt_addr)474 static int rockchip_read_distro_dtb(void *fdt_addr)
475 {
476 	const char *cmd = "part list ${devtype} ${devnum} -bootable devplist";
477 	char *devnum, *devtype, *devplist;
478 	char devnum_part[12];
479 	char fdt_hex_str[19];
480 	char *fs_argv[5];
481 
482 	if (!rockchip_get_bootdev() || !fdt_addr)
483 		return -ENODEV;
484 
485 	if (run_command_list(cmd, -1, 0)) {
486 		printf("Failed to find -bootable\n");
487 		return -EINVAL;
488 	}
489 
490 	devplist = env_get("devplist");
491 	if (!devplist)
492 		devplist = "1";
493 
494 	devtype = env_get("devtype");
495 	devnum = env_get("devnum");
496 	sprintf(devnum_part, "%s:%s", devnum, devplist);
497 	sprintf(fdt_hex_str, "0x%lx", (ulong)fdt_addr);
498 
499 	fs_argv[0] = "load";
500 	fs_argv[1] = devtype,
501 	fs_argv[2] = devnum_part;
502 	fs_argv[3] = fdt_hex_str;
503 	fs_argv[4] = CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH;
504 
505 	if (do_load(NULL, 0, 5, fs_argv, FS_TYPE_ANY))
506 		return -EIO;
507 
508 	if (fdt_check_header(fdt_addr))
509 		return -EBADF;
510 
511 	printf("DTB(Distro): %s\n", CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH);
512 
513 	return 0;
514 }
515 #endif
516 
517 enum {
518 	LOCATE_DISTRO,
519 	LOCATE_RESOURCE,
520 	LOCATE_FIT,
521 	LOCATE_END,
522 };
523 
dtb_scan(void * fdt,int where)524 static int dtb_scan(void *fdt, int where)
525 {
526 	if (where == LOCATE_DISTRO) {
527 #ifdef CONFIG_ROCKCHIP_EARLY_DISTRO_DTB
528 		return rockchip_read_distro_dtb(fdt);
529 #endif
530 	} else if (where == LOCATE_RESOURCE) {
531 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
532 		int hash_size = 0;
533 		char *hash;
534 		u32 ret;
535 
536 		ret = rockchip_read_resource_dtb(fdt, &hash, &hash_size);
537 		if (ret) {
538 			printf("Failed to load DTB, ret=%d\n", ret);
539 			return ret;
540 		}
541 
542 		if (fdt_check_header(fdt)) {
543 			printf("Invalid DTB magic !\n");
544 			return -EBADF;
545 		}
546 #ifdef CONFIG_ROCKCHIP_DTB_VERIFY
547 		if (hash_size && fdt_check_hash(fdt,
548 			fdt_totalsize(fdt), hash, hash_size)) {
549 			printf("Invalid DTB hash !\n");
550 			return -EBADF;
551 		}
552 #endif
553 		return 0;
554 #endif
555 	} else if (where == LOCATE_FIT) {
556 #if defined(CONFIG_ROCKCHIP_FIT_IMAGE) && !defined(CONFIG_ROCKCHIP_RESOURCE_IMAGE)
557 		return fit_image_read_dtb(fdt);
558 #endif
559 	}
560 
561 	return -EINVAL;
562 }
563 
rockchip_read_dtb_file(void * fdt)564 int rockchip_read_dtb_file(void *fdt)
565 {
566 	int locate, ret;
567 	int size;
568 
569 	for (locate = 0; locate < LOCATE_END; locate++) {
570 		ret = dtb_scan(fdt, locate);
571 		if (!ret)
572 			break;
573 	}
574 	if (ret) {
575 		printf("No valid DTB, ret=%d\n", ret);
576 		return ret;
577 	}
578 
579 	/* reserved memory */
580 	size = fdt_totalsize(fdt);
581 	if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)fdt,
582 		ALIGN(size, RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD))
583 		return -ENOMEM;
584 
585 	/* fixup/overlay */
586 	rk_board_early_fdt_fixup(fdt);
587 #if defined(CONFIG_ANDROID_BOOT_IMAGE) && defined(CONFIG_OF_LIBFDT_OVERLAY)
588 	android_fdt_overlay_apply((void *)fdt);
589 #endif
590 
591 	return 0;
592 }
593 #endif
594 
rockchip_ram_read_dtb_file(void * img,void * fdt)595 int rockchip_ram_read_dtb_file(void *img, void *fdt)
596 {
597 	int format;
598 	int ret;
599 
600 	format = (genimg_get_format(img));
601 #ifdef CONFIG_ANDROID_BOOT_IMAGE
602 	if (format == IMAGE_FORMAT_ANDROID) {
603 		struct andr_img_hdr *hdr = img;
604 		struct blk_desc *dev_desc;
605 		ulong offset;
606 
607 		dev_desc = rockchip_get_bootdev();
608 		if (!dev_desc)
609 			return -ENODEV;
610 
611 		offset = hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size) +
612 			ALIGN(hdr->ramdisk_size, hdr->page_size);
613 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
614 		ret = resource_setup_ram_list(dev_desc, (void *)hdr + offset);
615 		if (ret)
616 			return ret;
617 
618 		return rockchip_read_dtb_file((void *)fdt);
619 #else
620 		if (fdt_check_header((void *)offset))
621 			return -EINVAL;
622 
623 		memcpy(fdt, (char *)offset, fdt_totalsize(offset));
624 		if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)fdt,
625 			ALIGN(fdt_totalsize(fdt), RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD))
626 			return -ENOMEM;
627 
628 		return 0;
629 #endif
630 	}
631 #endif
632 #if IMAGE_ENABLE_FIT
633 	if (format == IMAGE_FORMAT_FIT) {
634 		const void *data;
635 		size_t size;
636 		int noffset;
637 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
638 		const char *path = "/images/resource";
639 #else
640 		const char *path = "/images/fdt";
641 #endif
642 
643 		noffset = fdt_path_offset(img, path);
644 		if (noffset < 0)
645 			return noffset;
646 
647 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
648 		ret = fit_image_get_data(img, noffset, &data, &size);
649 		if (ret < 0)
650 			return ret;
651 
652 		dev_desc = rockchip_get_bootdev();
653 		if (!dev_desc)
654 			return -ENODEV;
655 
656 		ret = resource_setup_ram_list(dev_desc, (void *)data);
657 		if (ret) {
658 			printf("resource_setup_ram_list fail, ret=%d\n", ret);
659 			return ret;
660 		}
661 
662 		return rockchip_read_dtb_file((void *)fdt);
663 #else
664 
665 		ret = fit_image_get_data(img, noffset, &data, &size);
666 		if (ret)
667 			return ret;
668 
669 		if (fdt_check_header(data))
670 			return -EINVAL;
671 
672 		memcpy(fdt, data, size);
673 		if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)fdt,
674 			ALIGN(fdt_totalsize(fdt), RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD))
675 			return -ENOMEM;
676 
677 		printf("Load DTB from 'images/fdt'\n");
678 
679 		return 0;
680 #endif
681 	}
682 #endif
683 
684 	return -EINVAL;
685 }
686