xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/board.c (revision fc5f56b20bd67fdd4bd9fa913b96bd3f3f2a0e99)
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 <version.h>
9 #include <abuf.h>
10 #include <amp.h>
11 #include <android_ab.h>
12 #include <android_bootloader.h>
13 #include <android_image.h>
14 #include <bidram.h>
15 #include <boot_rkimg.h>
16 #include <cli.h>
17 #include <clk.h>
18 #include <console.h>
19 #include <debug_uart.h>
20 #include <dm.h>
21 #include <dvfs.h>
22 #include <fdt_support.h>
23 #include <io-domain.h>
24 #include <image.h>
25 #include <key.h>
26 #include <memblk.h>
27 #include <misc.h>
28 #include <of_live.h>
29 #include <mtd_blk.h>
30 #include <ram.h>
31 #include <rng.h>
32 #include <rockchip_debugger.h>
33 #include <syscon.h>
34 #include <sysmem.h>
35 #include <video_rockchip.h>
36 #include <xbc.h>
37 #include <asm/io.h>
38 #include <asm/gpio.h>
39 #include <android_avb/rk_avb_ops_user.h>
40 #include <dm/uclass-internal.h>
41 #include <dm/root.h>
42 #include <power/charge_display.h>
43 #include <power/regulator.h>
44 #include <optee_include/OpteeClientInterface.h>
45 #include <optee_include/OpteeClientApiLib.h>
46 #include <optee_include/tee_api_defines.h>
47 #include <asm/arch/boot_mode.h>
48 #include <asm/arch/clock.h>
49 #include <asm/arch/cpu.h>
50 #include <asm/arch/hotkey.h>
51 #include <asm/arch/param.h>
52 #include <asm/arch/periph.h>
53 #include <asm/arch/resource_img.h>
54 #include <asm/arch/rk_atags.h>
55 #include <asm/arch/vendor.h>
56 #ifdef CONFIG_ROCKCHIP_EINK_DISPLAY
57 #include <rk_eink.h>
58 #endif
59 #ifdef CONFIG_SERDES_DISPLAY
60 #include <serdes-display-core.h>
61 #include <serdes-display-gpio.h>
62 #endif
63 DECLARE_GLOBAL_DATA_PTR;
64 
65 #ifdef CONFIG_ARM64
66 static ulong orig_images_ep;
67 #endif
68 
69 __weak int rk_board_late_init(void)
70 {
71 	return 0;
72 }
73 
74 __weak int rk_board_fdt_fixup(void *blob)
75 {
76 	return 0;
77 }
78 
79 __weak int rk_board_dm_fdt_fixup(void *blob)
80 {
81 	return 0;
82 }
83 
84 __weak int soc_clk_dump(void)
85 {
86 	return 0;
87 }
88 
89 __weak int set_armclk_rate(void)
90 {
91 	return 0;
92 }
93 
94 __weak int rk_board_init(void)
95 {
96 	return 0;
97 }
98 
99 #ifdef CONFIG_ROCKCHIP_SET_ETHADDR
100 /*
101  * define serialno max length, the max length is 512 Bytes
102  * The remaining bytes are used to ensure that the first 512 bytes
103  * are valid when executing 'env_set("serial#", value)'.
104  */
105 #define VENDOR_SN_MAX	513
106 #define CPUID_LEN	0x10
107 #define CPUID_OFF	0x07
108 
109 #define MAX_ETHERNET	0x2
110 
111 static int rockchip_set_ethaddr(void)
112 {
113 	__maybe_unused bool need_write = false;
114 	bool randomed = false;
115 	char buf[ARP_HLEN_ASCII + 1], mac[16];
116 	u8 ethaddr[ARP_HLEN * MAX_ETHERNET] = {0};
117 	int i, ret = -EINVAL;
118 
119 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
120 	ret = vendor_storage_read(LAN_MAC_ID, ethaddr, sizeof(ethaddr));
121 #endif
122 	for (i = 0; i < MAX_ETHERNET; i++) {
123 		if (ret <= 0 || !is_valid_ethaddr(&ethaddr[i * ARP_HLEN])) {
124 			if (!randomed) {
125 				net_random_ethaddr(&ethaddr[i * ARP_HLEN]);
126 				randomed = true;
127 			} else {
128 				if (i > 0) {
129 					memcpy(&ethaddr[i * ARP_HLEN],
130 					       &ethaddr[(i - 1) * ARP_HLEN],
131 					       ARP_HLEN);
132 					ethaddr[i * ARP_HLEN] |= 0x02;
133 					ethaddr[i * ARP_HLEN] += (i << 2);
134 				}
135 			}
136 
137 			need_write = true;
138 		}
139 
140 		if (is_valid_ethaddr(&ethaddr[i * ARP_HLEN])) {
141 			snprintf(buf, ARP_HLEN_ASCII + 1, "%pM", &ethaddr[i * ARP_HLEN]);
142 			if (i == 0)
143 				memcpy(mac, "ethaddr", sizeof("ethaddr"));
144 			else
145 				sprintf(mac, "eth%daddr", i);
146 			env_set(mac, buf);
147 		}
148 	}
149 
150 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
151 	if (need_write) {
152 		ret = vendor_storage_write(LAN_MAC_ID,
153 					   ethaddr, sizeof(ethaddr));
154 		if (ret < 0)
155 			printf("%s: vendor_storage_write failed %d\n",
156 			       __func__, ret);
157 	}
158 #endif
159 	return 0;
160 }
161 #endif
162 
163 #ifdef CONFIG_ROCKCHIP_SET_SN
164 static int rockchip_set_serialno(void)
165 {
166 	u8 low[CPUID_LEN / 2], high[CPUID_LEN / 2];
167 	u8 cpuid[CPUID_LEN] = {0};
168 	char serialno_str[VENDOR_SN_MAX];
169 	int ret = 0, i;
170 	u64 serialno;
171 
172 	/* Read serial number from vendor storage part */
173 	memset(serialno_str, 0, VENDOR_SN_MAX);
174 
175 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
176 	int j;
177 
178 	ret = vendor_storage_read(SN_ID, serialno_str, (VENDOR_SN_MAX-1));
179 	if (ret > 0) {
180 		j = strlen(serialno_str);
181 		for (i = 0; i < j; i++) {
182 			if ((serialno_str[i] >= 'a' && serialno_str[i] <= 'z') ||
183 			    (serialno_str[i] >= 'A' && serialno_str[i] <= 'Z') ||
184 			    (serialno_str[i] >= '0' && serialno_str[i] <= '9'))
185 				continue;
186 			else
187 				break;
188 		}
189 
190 		/* valid character count > 0 */
191 		if (i > 0) {
192 			serialno_str[i + 1] = 0x0;
193 			env_set("serial#", serialno_str);
194 		}
195 	}
196 #endif
197 	if (!env_get("serial#")) {
198 #if defined(CONFIG_ROCKCHIP_EFUSE) || defined(CONFIG_ROCKCHIP_OTP)
199 		struct udevice *dev;
200 
201 		/* retrieve the device */
202 		if (IS_ENABLED(CONFIG_ROCKCHIP_EFUSE))
203 			ret = uclass_get_device_by_driver(UCLASS_MISC,
204 							  DM_GET_DRIVER(rockchip_efuse),
205 							  &dev);
206 		else
207 			ret = uclass_get_device_by_driver(UCLASS_MISC,
208 							  DM_GET_DRIVER(rockchip_otp),
209 							  &dev);
210 
211 		if (ret) {
212 			printf("%s: could not find efuse/otp device\n", __func__);
213 			return ret;
214 		}
215 
216 		/* read the cpu_id range from the efuses */
217 		ret = misc_read(dev, CPUID_OFF, &cpuid, sizeof(cpuid));
218 		if (ret) {
219 			printf("%s: read cpuid from efuse/otp failed, ret=%d\n",
220 			       __func__, ret);
221 			return ret;
222 		}
223 #else
224 		/* generate random cpuid */
225 		for (i = 0; i < CPUID_LEN; i++)
226 			cpuid[i] = (u8)(rand());
227 #endif
228 		/* Generate the serial number based on CPU ID */
229 		for (i = 0; i < 8; i++) {
230 			low[i] = cpuid[1 + (i << 1)];
231 			high[i] = cpuid[i << 1];
232 		}
233 
234 		serialno = crc32_no_comp(0, low, 8);
235 		serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
236 		snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno);
237 
238 		env_set("serial#", serialno_str);
239 	}
240 
241 	return ret;
242 }
243 #endif
244 
245 #if defined(CONFIG_USB_FUNCTION_FASTBOOT)
246 int fb_set_reboot_flag(void)
247 {
248 	printf("Setting reboot to fastboot flag ...\n");
249 	writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG);
250 
251 	return 0;
252 }
253 #endif
254 
255 #ifdef CONFIG_ROCKCHIP_USB_BOOT
256 static int boot_from_udisk(void)
257 {
258 	struct blk_desc *desc;
259 	struct udevice *dev;
260 	int devnum = -1;
261 	char buf[32];
262 
263 	/* Booting priority: mmc1 > udisk */
264 	if (!strcmp(env_get("devtype"), "mmc") && !strcmp(env_get("devnum"), "1"))
265 		return 0;
266 
267 	if (!run_command("usb start", -1)) {
268 		for (blk_first_device(IF_TYPE_USB, &dev);
269 		     dev;
270 		     blk_next_device(&dev)) {
271 			desc = dev_get_uclass_platdata(dev);
272 			printf("Scanning usb %d ...\n", desc->devnum);
273 			if (desc->type == DEV_TYPE_UNKNOWN)
274 				continue;
275 
276 			if (desc->lba > 0L && desc->blksz > 0L) {
277 				devnum = desc->devnum;
278 				break;
279 			}
280 		}
281 		if (devnum < 0) {
282 			printf("No usb mass storage found\n");
283 			return -ENODEV;
284 		}
285 
286 		desc = blk_get_devnum_by_type(IF_TYPE_USB, devnum);
287 		if (!desc) {
288 			printf("No usb %d found\n", devnum);
289 			return -ENODEV;
290 		}
291 
292 		snprintf(buf, 32, "rkimgtest usb %d", devnum);
293 		if (!run_command(buf, -1)) {
294 			snprintf(buf, 32, "%d", devnum);
295 			rockchip_set_bootdev(desc);
296 			env_set("devtype", "usb");
297 			env_set("devnum", buf);
298 			printf("=== Booting from usb %d ===\n", devnum);
299 		} else {
300 			printf("No available udisk image on usb %d\n", devnum);
301 			return -ENODEV;
302 		}
303 	}
304 
305 	return 0;
306 }
307 #endif
308 
309 static void env_fixup(void)
310 {
311 	struct memblock mem;
312 	ulong u_addr_r;
313 	phys_size_t end;
314 	char *addr_r;
315 
316 #ifdef ENV_MEM_LAYOUT_SETTINGS1
317 	const char *env_addr0[] = {
318 		"scriptaddr", "pxefile_addr_r",
319 		"fdt_addr_r", "kernel_addr_r", "ramdisk_addr_r",
320 	};
321 	const char *env_addr1[] = {
322 		"scriptaddr1", "pxefile_addr1_r",
323 		"fdt_addr1_r", "kernel_addr1_r", "ramdisk_addr1_r",
324 	};
325 	int i;
326 
327 	/* 128M is a typical ram size for most platform, so as default here */
328 	if (gd->ram_size <= SZ_128M) {
329 		/* Replace orignal xxx_addr_r */
330 		for (i = 0; i < ARRAY_SIZE(env_addr1); i++) {
331 			addr_r = env_get(env_addr1[i]);
332 			if (addr_r)
333 				env_set(env_addr0[i], addr_r);
334 		}
335 	}
336 #endif
337 	/* No BL32 ? */
338 	if (!(gd->flags & GD_FLG_BL32_ENABLED)) {
339 		/*
340 		 * [1] Move kernel to lower address if possible.
341 		 */
342 		addr_r = env_get("kernel_addr_no_low_bl32_r");
343 		if (addr_r)
344 			env_set("kernel_addr_r", addr_r);
345 
346 		/*
347 		 * [2] Move ramdisk at BL32 position if need.
348 		 *
349 		 * 0x0a200000 and 0x08400000 are rockchip traditional address
350 		 * of BL32 and ramdisk:
351 		 *
352 		 * |------------|------------|
353 		 * |    BL32    |  ramdisk   |
354 		 * |------------|------------|
355 		 *
356 		 * Move ramdisk to BL32 address to fix sysmem alloc failed
357 		 * issue on the board with critical memory(ie. 256MB).
358 		 */
359 		if (gd->ram_size > SZ_128M && gd->ram_size <= SZ_256M) {
360 			u_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
361 			if (u_addr_r == 0x0a200000)
362 				env_set("ramdisk_addr_r", "0x08400000");
363 		}
364 	} else {
365 		mem = param_parse_optee_mem();
366 
367 		/*
368 		 * [1] Move kernel forward if possible.
369 		 */
370 		if (mem.base > SZ_128M) {
371 			addr_r = env_get("kernel_addr_no_low_bl32_r");
372 			if (addr_r)
373 				env_set("kernel_addr_r", addr_r);
374 		}
375 
376 		/*
377 		 * [2] Move ramdisk backward if optee enlarge.
378 		 */
379 		end = mem.base + mem.size;
380 		u_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
381 		if (u_addr_r >= mem.base && u_addr_r < end)
382 			env_set_hex("ramdisk_addr_r", end);
383 	}
384 }
385 
386 static void cmdline_handle(void)
387 {
388 	struct blk_desc *dev_desc;
389 	int if_type;
390 	int devnum;
391 
392 	param_parse_pubkey_fuse_programmed();
393 
394 	dev_desc = rockchip_get_bootdev();
395 	if (!dev_desc)
396 		return;
397 
398 	/*
399 	 * 1. From rk356x, the sd/udisk recovery update flag was moved from
400 	 *    IDB to Android BCB.
401 	 *
402 	 * 2. Udisk is init at the late boot_from_udisk(), but
403 	 *    rockchip_get_boot_mode() actually only read once,
404 	 *    we need to update boot mode according to udisk BCB.
405 	 */
406 	if_type = dev_desc->if_type;
407 	devnum = dev_desc->devnum;
408 	if ((if_type == IF_TYPE_MMC && devnum == 1) || (if_type == IF_TYPE_USB)) {
409 		if (get_bcb_recovery_msg() == BCB_MSG_RECOVERY_RK_FWUPDATE) {
410 			if (if_type == IF_TYPE_MMC && devnum == 1) {
411 				env_update("bootargs", "sdfwupdate");
412 			} else if (if_type == IF_TYPE_USB) {
413 				env_update("bootargs", "usbfwupdate");
414 				env_set("reboot_mode", "recovery-usb");
415 			}
416 		} else {
417 			if (if_type == IF_TYPE_USB)
418 				env_set("reboot_mode", "normal");
419 		}
420 	}
421 
422 	if (rockchip_get_boot_mode() == BOOT_MODE_QUIESCENT)
423 		env_update("bootargs", "androidboot.quiescent=1 pwm_bl.quiescent=1");
424 }
425 
426 static void scan_run_cmd(void)
427 {
428 	char *config = CONFIG_ROCKCHIP_CMD;
429 	char *cmd, *key;
430 
431 	key = strchr(config, ' ');
432 	if (!key)
433 		return;
434 
435 	cmd = strdup(config);
436 	cmd[key - config] = 0;
437 	key++;
438 
439 	if (!strcmp(key, "-")) {
440 		run_command(cmd, 0);
441 	} else {
442 #ifdef CONFIG_DM_KEY
443 		ulong map;
444 
445 		map = simple_strtoul(key, NULL, 10);
446 		if (key_is_pressed(key_read(map))) {
447 			printf("## Key<%ld> pressed... run cmd '%s'\n", map, cmd);
448 			run_command(cmd, 0);
449 		}
450 #endif
451 	}
452 }
453 
454 int board_late_init(void)
455 {
456 #ifdef CONFIG_ROCKCHIP_SET_ETHADDR
457 	rockchip_set_ethaddr();
458 #endif
459 #ifdef CONFIG_ROCKCHIP_SET_SN
460 	rockchip_set_serialno();
461 #endif
462 	setup_download_mode();
463 	scan_run_cmd();
464 #ifdef CONFIG_ROCKCHIP_USB_BOOT
465 	boot_from_udisk();
466 #endif
467 #ifdef CONFIG_DM_CHARGE_DISPLAY
468 	charge_display();
469 #endif
470 #ifdef CONFIG_DRM_ROCKCHIP
471 	if (rockchip_get_boot_mode() != BOOT_MODE_QUIESCENT)
472 		rockchip_show_logo();
473 #endif
474 #ifdef CONFIG_ROCKCHIP_EINK_DISPLAY
475 	rockchip_eink_show_uboot_logo();
476 #endif
477 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0)
478 	setup_boot_mode();
479 #endif
480 	env_fixup();
481 	soc_clk_dump();
482 	cmdline_handle();
483 #ifdef CONFIG_AMP
484 	amp_cpus_on();
485 #endif
486 	return rk_board_late_init();
487 }
488 
489 static void early_download(void)
490 {
491 #if defined(CONFIG_PWRKEY_DNL_TRIGGER_NUM) && \
492 		(CONFIG_PWRKEY_DNL_TRIGGER_NUM > 0)
493 	if (pwrkey_download_init())
494 		printf("Pwrkey download init failed\n");
495 #endif
496 
497 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0)
498 	if (is_hotkey(HK_BROM_DNL)) {
499 		printf("Enter bootrom download...");
500 		flushc();
501 		writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
502 		do_reset(NULL, 0, 0, NULL);
503 		printf("failed!\n");
504 	}
505 #endif
506 }
507 
508 static void board_debug_init(void)
509 {
510 	if (!gd->serial.using_pre_serial &&
511 	    !(gd->flags & GD_FLG_DISABLE_CONSOLE))
512 		debug_uart_init();
513 
514 	if (tstc()) {
515 		gd->console_evt = getc();
516 		if (gd->console_evt <= 0x1a) /* 'z' */
517 			printf("Hotkey: ctrl+%c\n", gd->console_evt + 'a' - 1);
518 	}
519 
520 	if (IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI))
521 		printf("Cmd interface: disabled\n");
522 }
523 
524 int board_init(void)
525 {
526 	board_debug_init();
527 #ifdef DEBUG
528 	soc_clk_dump();
529 #endif
530 #ifdef CONFIG_OPTEE_CLIENT
531 	optee_client_init();
532 #endif
533 #ifdef CONFIG_USING_KERNEL_DTB
534 	init_kernel_dtb();
535 #endif
536 	early_download();
537 
538 	clks_probe();
539 #ifdef CONFIG_DM_REGULATOR
540 	regulators_enable_boot_on(is_hotkey(HK_REGULATOR));
541 #endif
542 #ifdef CONFIG_ROCKCHIP_IO_DOMAIN
543 	io_domain_init();
544 #endif
545 	set_armclk_rate();
546 #ifdef CONFIG_DM_DVFS
547 	dvfs_init(true);
548 #endif
549 #ifdef CONFIG_ANDROID_AB
550 	if (ab_decrease_tries())
551 		printf("Decrease ab tries count fail!\n");
552 #endif
553 #ifdef CONFIG_SERDES_DISPLAY
554 	serdes_power_init();
555 #endif
556 	return rk_board_init();
557 }
558 
559 int interrupt_debugger_init(void)
560 {
561 #ifdef CONFIG_ROCKCHIP_DEBUGGER
562 	return rockchip_debugger_init();
563 #else
564 	return 0;
565 #endif
566 }
567 
568 int board_fdt_fixup(void *blob)
569 {
570 	/*
571 	 * Device's platdata points to orignal fdt blob property,
572 	 * access DM device before any fdt fixup.
573 	 */
574 	rk_board_dm_fdt_fixup(blob);
575 
576 	/* Common fixup for DRM */
577 #ifdef CONFIG_DRM_ROCKCHIP
578 	rockchip_display_fixup(blob);
579 #endif
580 
581 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
582 	vendor_storage_fixup(blob);
583 #endif
584 
585 	return rk_board_fdt_fixup(blob);
586 }
587 
588 #if defined(CONFIG_ARM64_BOOT_AARCH32) || !defined(CONFIG_ARM64)
589 /*
590  * Common for OP-TEE:
591  *	64-bit & 32-bit mode: share memory dcache is always enabled;
592  *
593  * Common for U-Boot:
594  *	64-bit mode: MMU table is static defined in rkxxx.c file, all memory
595  *		     regions are mapped. That's good to match OP-TEE MMU policy.
596  *
597  *	32-bit mode: MMU table is setup according to gd->bd->bi_dram[..] where
598  *		     the OP-TEE region has been reserved, so it can not be
599  *		     mapped(i.e. dcache is disabled). That's *NOT* good to match
600  *		     OP-TEE MMU policy.
601  *
602  * For the data coherence when communication between U-Boot and OP-TEE, U-Boot
603  * should follow OP-TEE MMU policy.
604  *
605  * So 32-bit mode U-Boot should map OP-TEE share memory as dcache enabled.
606  */
607 int board_initr_caches_fixup(void)
608 {
609 #ifdef CONFIG_OPTEE_CLIENT
610 	struct memblock mem;
611 
612 	mem.base = 0;
613 	mem.size = 0;
614 
615 	optee_get_shm_config(&mem.base, &mem.size);
616 	if (mem.size)
617 		mmu_set_region_dcache_behaviour(mem.base, mem.size,
618 						DCACHE_WRITEBACK);
619 #endif
620 	return 0;
621 }
622 #endif
623 
624 void arch_preboot_os(uint32_t bootm_state, bootm_headers_t *images)
625 {
626 	if (!(bootm_state & BOOTM_STATE_OS_PREP))
627 		return;
628 
629 #ifdef CONFIG_ARM64
630 	u8 *data = (void *)images->ep;
631 
632 	/*
633 	 * Fix kernel 5.10 arm64 boot warning:
634 	 * "[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!"
635 	 *
636 	 * kernel: 5.10 commit 120dc60d0bdb ("arm64: get rid of TEXT_OFFSET")
637 	 * arm64 kernel version:
638 	 *	data[10] == 0x00 if kernel version >= 5.10: N*2MB align
639 	 *	data[10] == 0x08 if kernel version <  5.10: N*2MB + 0x80000(TEXT_OFFSET)
640 	 *
641 	 * Why fix here?
642 	 *   1. this is the common and final path for any boot command.
643 	 *   2. don't influence original boot flow, just fix it exactly before
644 	 *	jumping kernel.
645 	 *
646 	 * But relocation is in board_quiesce_devices() until all decompress
647 	 * done, mainly for saving boot time.
648 	 */
649 
650 	orig_images_ep = images->ep;
651 
652 	if (data[10] == 0x00) {
653 		if (round_down(images->ep, SZ_2M) != images->ep)
654 			images->ep = round_down(images->ep, SZ_2M);
655 	} else {
656 		if (IS_ALIGNED(images->ep, SZ_2M))
657 			images->ep += 0x80000;
658 	}
659 #endif
660 	hotkey_run(HK_CLI_OS_PRE);
661 }
662 
663 void enable_caches(void)
664 {
665 	icache_enable();
666 	dcache_enable();
667 }
668 
669 #ifdef CONFIG_LMB
670 /*
671  * Using last bi_dram[...] to initialize "bootm_low" and "bootm_mapsize".
672  * This makes lmb_alloc_base() always alloc from tail of sdram.
673  * If we don't assign it, bi_dram[0] is used by default and it may cause
674  * lmb_alloc_base() fail when bi_dram[0] range is small.
675  */
676 void board_lmb_reserve(struct lmb *lmb)
677 {
678 	char bootm_mapsize[32];
679 	char bootm_low[32];
680 	u64 start, size;
681 	int i;
682 
683 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
684 		if (!gd->bd->bi_dram[i].size)
685 			break;
686 	}
687 
688 	start = gd->bd->bi_dram[i - 1].start;
689 	size = gd->bd->bi_dram[i - 1].size;
690 
691 	/*
692 	 * 32-bit kernel: ramdisk/fdt shouldn't be loaded to highmem area(768MB+),
693 	 * otherwise "Unable to handle kernel paging request at virtual address ...".
694 	 *
695 	 * So that we hope limit highest address at 768M, but there comes the the
696 	 * problem: ramdisk is a compressed image and it expands after descompress,
697 	 * so it accesses 768MB+ and brings the above "Unable to handle kernel ...".
698 	 *
699 	 * We make a appointment that the highest memory address is 512MB, it
700 	 * makes lmb alloc safer.
701 	 */
702 #ifndef CONFIG_ARM64
703 	if (start >= ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M)) {
704 		start = gd->bd->bi_dram[i - 2].start;
705 		size = gd->bd->bi_dram[i - 2].size;
706 	}
707 
708 	if ((start + size) > ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M))
709 		size = (u64)CONFIG_SYS_SDRAM_BASE + SZ_512M - start;
710 #endif
711 	sprintf(bootm_low, "0x%llx", start);
712 	sprintf(bootm_mapsize, "0x%llx", size);
713 	env_set("bootm_low", bootm_low);
714 	env_set("bootm_mapsize", bootm_mapsize);
715 }
716 #endif
717 
718 #ifdef CONFIG_BIDRAM
719 int board_bidram_reserve(struct bidram *bidram)
720 {
721 	struct memblock mem;
722 	int ret;
723 
724 	/* ATF */
725 	mem = param_parse_atf_mem();
726 	ret = bidram_reserve(MEM_ATF, mem.base, mem.size);
727 	if (ret)
728 		return ret;
729 
730 	/* PSTORE/ATAGS/SHM */
731 	mem = param_parse_common_resv_mem();
732 	ret = bidram_reserve(MEM_SHM, mem.base, mem.size);
733 	if (ret)
734 		return ret;
735 
736 	/* OP-TEE */
737 	mem = param_parse_optee_mem();
738 	ret = bidram_reserve(MEM_OPTEE, mem.base, mem.size);
739 	if (ret)
740 		return ret;
741 
742 	return 0;
743 }
744 
745 #ifdef CONFIG_SYSMEM
746 int board_sysmem_reserve(struct sysmem *sysmem)
747 {
748 #ifdef CONFIG_SKIP_RELOCATE_UBOOT
749 	if (!sysmem_alloc_base_by_name("NO-RELOC-CODE",
750 	    CONFIG_SYS_TEXT_BASE, SZ_2M)) {
751 		printf("Failed to reserve sysmem for U-Boot code\n");
752 		return -ENOMEM;
753 	}
754 #endif
755 	return 0;
756 }
757 #endif
758 
759 parse_fn_t board_bidram_parse_fn(void)
760 {
761 	return param_parse_ddr_mem;
762 }
763 #endif
764 
765 int board_init_f_boot_flags(void)
766 {
767 	int boot_flags = 0;
768 
769 #ifdef CONFIG_FPGA_ROCKCHIP
770 	arch_fpga_init();
771 #endif
772 #ifdef CONFIG_PSTORE
773 	param_parse_pstore();
774 #endif
775 	param_parse_pre_serial(&boot_flags);
776 
777 	/* The highest priority to turn off (override) console */
778 #if defined(CONFIG_DISABLE_CONSOLE)
779 	boot_flags |= GD_FLG_DISABLE_CONSOLE;
780 #endif
781 
782 	return boot_flags;
783 }
784 
785 #if defined(CONFIG_USB_GADGET)
786 #include <usb.h>
787 #if defined(CONFIG_USB_GADGET_DWC2_OTG)
788 #include <fdt_support.h>
789 #include <usb/dwc2_udc.h>
790 
791 static struct dwc2_plat_otg_data otg_data = {
792 	.rx_fifo_sz	= 512,
793 	.np_tx_fifo_sz	= 16,
794 	.tx_fifo_sz	= 128,
795 };
796 
797 int board_usb_init(int index, enum usb_init_type init)
798 {
799 	const void *blob = gd->fdt_blob;
800 	const fdt32_t *reg;
801 	fdt_addr_t addr;
802 	int node;
803 
804 	/* find the usb_otg node */
805 	node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
806 
807 retry:
808 	if (node > 0) {
809 		reg = fdt_getprop(blob, node, "reg", NULL);
810 		if (!reg)
811 			return -EINVAL;
812 
813 		addr = fdt_translate_address(blob, node, reg);
814 		if (addr == OF_BAD_ADDR) {
815 			pr_err("Not found usb_otg address\n");
816 			return -EINVAL;
817 		}
818 
819 #if defined(CONFIG_ROCKCHIP_RK3288)
820 		if (addr != 0xff580000) {
821 			node = fdt_node_offset_by_compatible(blob, node,
822 							     "snps,dwc2");
823 			goto retry;
824 		}
825 #endif
826 	} else {
827 		/*
828 		 * With kernel dtb support, rk3288 dwc2 otg node
829 		 * use the rockchip legacy dwc2 driver "dwc_otg_310"
830 		 * with the compatible "rockchip,rk3288_usb20_otg",
831 		 * and rk3368 also use the "dwc_otg_310" driver with
832 		 * the compatible "rockchip,rk3368-usb".
833 		 */
834 #if defined(CONFIG_ROCKCHIP_RK3288)
835 		node = fdt_node_offset_by_compatible(blob, -1,
836 				"rockchip,rk3288_usb20_otg");
837 #elif defined(CONFIG_ROCKCHIP_RK3368)
838 		node = fdt_node_offset_by_compatible(blob, -1,
839 				"rockchip,rk3368-usb");
840 #endif
841 		if (node > 0) {
842 			goto retry;
843 		} else {
844 			pr_err("Not found usb_otg device\n");
845 			return -ENODEV;
846 		}
847 	}
848 
849 	otg_data.regs_otg = (uintptr_t)addr;
850 
851 	return dwc2_udc_probe(&otg_data);
852 }
853 
854 int board_usb_cleanup(int index, enum usb_init_type init)
855 {
856 	return 0;
857 }
858 #elif defined(CONFIG_USB_DWC3_GADGET) /* CONFIG_USB_GADGET_DWC2_OTG */
859 #include <dwc3-uboot.h>
860 
861 int board_usb_cleanup(int index, enum usb_init_type init)
862 {
863 	dwc3_uboot_exit(index);
864 	return 0;
865 }
866 
867 #endif /* CONFIG_USB_DWC3_GADGET */
868 #endif /* CONFIG_USB_GADGET */
869 
870 static void bootm_no_reloc(void)
871 {
872 	char *ramdisk_high;
873 	char *fdt_high;
874 
875 	if (!env_get_yesno("bootm-no-reloc"))
876 		return;
877 
878 	ramdisk_high = env_get("initrd_high");
879 	fdt_high = env_get("fdt_high");
880 
881 	if (!fdt_high) {
882 		env_set_hex("fdt_high", -1UL);
883 		printf("Fdt ");
884 	}
885 
886 	if (!ramdisk_high) {
887 		env_set_hex("initrd_high", -1UL);
888 		printf("Ramdisk ");
889 	}
890 
891 	if (!fdt_high || !ramdisk_high)
892 		printf("skip relocation\n");
893 }
894 
895 int bootm_board_start(void)
896 {
897 	/*
898 	 * print console record data
899 	 *
900 	 * On some rockchip platforms, uart debug and sdmmc pin are multiplex.
901 	 * If boot from sdmmc mode, the console data would be record in buffer,
902 	 * we switch to uart debug function in order to print it after loading
903 	 * images.
904 	 */
905 #if 0
906 	if (!strcmp("mmc", env_get("devtype")) &&
907 	    !strcmp("1", env_get("devnum"))) {
908 		printf("IOMUX: sdmmc => uart debug");
909 		pinctrl_select_state(gd->cur_serial_dev, "default");
910 		console_record_print_purge();
911 	}
912 #endif
913 	/* disable bootm relcation to save boot time */
914 	bootm_no_reloc();
915 
916 	/* PCBA test needs more permission */
917 	if (get_bcb_recovery_msg() == BCB_MSG_RECOVERY_PCBA)
918 		env_update("bootargs", "androidboot.selinux=permissive");
919 
920 	/* sysmem */
921 	hotkey_run(HK_SYSMEM);
922 	sysmem_overflow_check();
923 
924 	return 0;
925 }
926 
927 int bootm_image_populate_dtb(void *img)
928 {
929 	if ((gd->flags & GD_FLG_KDTB_READY) && !gd->fdt_blob_kern)
930 		sysmem_free((phys_addr_t)gd->fdt_blob);
931 	else
932 		gd->fdt_blob = (void *)env_get_ulong("fdt_addr_r", 16, 0);
933 
934 	return rockchip_ram_read_dtb_file(img, (void *)gd->fdt_blob);
935 }
936 
937 /*
938  * Implement it to support CLI command:
939  *   - Android: bootm [aosp addr]
940  *   - FIT:     bootm [fit addr]
941  *   - uImage:  bootm [uimage addr]
942  *
943  * Purpose:
944  *   - The original bootm command args require fdt addr on AOSP,
945  *     which is not flexible on rockchip boot/recovery.img.
946  *   - Take Android/FIT/uImage image into sysmem management to avoid image
947  *     memory overlap.
948  */
949 #if defined(CONFIG_ANDROID_BOOTLOADER) ||	\
950 	defined(CONFIG_ROCKCHIP_FIT_IMAGE) ||	\
951 	defined(CONFIG_ROCKCHIP_UIMAGE)
952 int board_do_bootm(int argc, char * const argv[])
953 {
954 	int format;
955 	void *img;
956 
957 	/* only 'bootm' full image goes further */
958 	if (argc != 2)
959 		return 0;
960 
961 	img = (void *)simple_strtoul(argv[1], NULL, 16);
962 	format = (genimg_get_format(img));
963 
964 	/* Android */
965 #ifdef CONFIG_ANDROID_BOOT_IMAGE
966 	if (format == IMAGE_FORMAT_ANDROID) {
967 		struct andr_img_hdr *hdr;
968 		ulong load_addr;
969 		ulong size;
970 		int ret;
971 
972 		hdr = (struct andr_img_hdr *)img;
973 		printf("BOOTM: transferring to board Android\n");
974 
975 		load_addr = env_get_ulong("kernel_addr_r", 16, 0);
976 		load_addr -= hdr->page_size;
977 		size = android_image_get_end(hdr) - (ulong)hdr;
978 
979 		if (!sysmem_alloc_base(MEM_ANDROID, (ulong)hdr, size))
980 			return -ENOMEM;
981 
982 		ret = bootm_image_populate_dtb(img);
983 		if (ret) {
984 			printf("bootm can't read dtb, ret=%d\n", ret);
985 			return ret;
986 		}
987 
988 		ret = android_image_memcpy_separate(hdr, &load_addr);
989 		if (ret) {
990 			printf("board do bootm failed, ret=%d\n", ret);
991 			return ret;
992 		}
993 
994 		return android_bootloader_boot_kernel(load_addr);
995 	}
996 #endif
997 
998 	/* FIT */
999 #if IMAGE_ENABLE_FIT
1000 	if (format == IMAGE_FORMAT_FIT) {
1001 		char boot_cmd[64];
1002 		int ret;
1003 
1004 		printf("BOOTM: transferring to board FIT\n");
1005 
1006 		ret = bootm_image_populate_dtb(img);
1007 		if (ret) {
1008 			printf("bootm can't read dtb, ret=%d\n", ret);
1009 			return ret;
1010 		}
1011 		snprintf(boot_cmd, sizeof(boot_cmd), "boot_fit %s", argv[1]);
1012 		return run_command(boot_cmd, 0);
1013 	}
1014 #endif
1015 
1016 	/* uImage */
1017 #if 0
1018 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
1019 	if (format == IMAGE_FORMAT_LEGACY &&
1020 	    image_get_type(img) == IH_TYPE_MULTI) {
1021 		char boot_cmd[64];
1022 
1023 		printf("BOOTM: transferring to board uImage\n");
1024 		snprintf(boot_cmd, sizeof(boot_cmd), "boot_uimage %s", argv[1]);
1025 		return run_command(boot_cmd, 0);
1026 	}
1027 #endif
1028 #endif
1029 	return 0;
1030 }
1031 #endif
1032 
1033 void autoboot_command_fail_handle(void)
1034 {
1035 #ifdef CONFIG_ANDROID_AB
1036 	if (rk_avb_ab_have_bootable_slot() == true)
1037 		run_command("reset;", 0);
1038 	else
1039 		run_command("fastboot usb 0;", 0);
1040 #endif
1041 
1042 #ifdef CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE
1043 	run_command("download", 0);
1044 	run_command("fastboot usb 0;", 0);
1045 #endif
1046 
1047 }
1048 
1049 #ifdef CONFIG_FIT_ROLLBACK_PROTECT
1050 
1051 #define FIT_ROLLBACK_INDEX_LOCATION	0x66697472	/* "fitr" */
1052 
1053 int fit_read_otp_rollback_index(uint32_t fit_index, uint32_t *otp_index)
1054 {
1055 #ifdef CONFIG_OPTEE_CLIENT
1056 	u64 index;
1057 	int ret;
1058 
1059 	ret = trusty_read_rollback_index(FIT_ROLLBACK_INDEX_LOCATION, &index);
1060 	if (ret) {
1061 		if (ret != TEE_ERROR_ITEM_NOT_FOUND)
1062 			return ret;
1063 
1064 		index = 0;
1065 		printf("Initial otp index as %d\n", fit_index);
1066 	}
1067 
1068 	*otp_index = (uint32_t)index;
1069 #else
1070 	*otp_index = 0;
1071 #endif
1072 
1073 	return 0;
1074 }
1075 
1076 int fit_write_trusty_rollback_index(u32 trusty_index)
1077 {
1078 	if (!trusty_index)
1079 		return 0;
1080 #ifdef CONFIG_OPTEE_CLIENT
1081 	return trusty_write_rollback_index(FIT_ROLLBACK_INDEX_LOCATION,
1082 					   (u64)trusty_index);
1083 #else
1084 	return 0;
1085 #endif
1086 }
1087 #endif
1088 
1089 void board_quiesce_devices(void *images)
1090 {
1091 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
1092 	/* Destroy atags makes next warm boot safer */
1093 	atags_destroy();
1094 #endif
1095 #ifdef CONFIG_FIT_ROLLBACK_PROTECT
1096 	int ret;
1097 
1098 	ret = fit_write_trusty_rollback_index(gd->rollback_index);
1099 	if (ret) {
1100 		panic("Failed to write fit rollback index %d, ret=%d",
1101 		      gd->rollback_index, ret);
1102 	}
1103 #endif
1104 #ifdef CONFIG_ROCKCHIP_HW_DECOMPRESS
1105 	misc_decompress_cleanup();
1106 #endif
1107 #ifdef CONFIG_ARM64
1108 	bootm_headers_t *bootm_images = (bootm_headers_t *)images;
1109 
1110 	/* relocate kernel after decompress cleanup */
1111 	if (orig_images_ep && orig_images_ep != bootm_images->ep) {
1112 		memmove((char *)bootm_images->ep, (const char *)orig_images_ep,
1113 			bootm_images->os.image_len);
1114 		printf("== DO RELOCATE == Kernel from 0x%08lx to 0x%08lx\n",
1115 		       orig_images_ep, bootm_images->ep);
1116 	}
1117 #endif
1118 
1119 	hotkey_run(HK_CMDLINE);
1120 	hotkey_run(HK_CLI_OS_GO);
1121 #ifdef CONFIG_ROCKCHIP_REBOOT_TEST
1122 	do_reset(NULL, 0, 0, NULL);
1123 #endif
1124 }
1125 
1126 /*
1127  * Use hardware rng to seed Linux random
1128  *
1129  * 'Android_14 + GKI' requires this information.
1130  */
1131 int board_rng_seed(struct abuf *buf)
1132 {
1133 	struct udevice *dev;
1134 	size_t len = 32;
1135 	u64 *data;
1136 
1137 	data = malloc(len);
1138 	if (!data) {
1139 	        printf("Out of memory\n");
1140 	        return -ENOMEM;
1141 	}
1142 
1143 	if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
1144 	        printf("No RNG device\n");
1145 	        return -ENODEV;
1146 	}
1147 
1148 	if (dm_rng_read(dev, data, len)) {
1149 	        printf("Reading RNG failed\n");
1150 	        return -EIO;
1151 	}
1152 
1153 	abuf_init_set(buf, data, len);
1154 
1155 	return 0;
1156 }
1157 
1158 /*
1159  * Pass fwver when any available.
1160  */
1161 static void bootargs_add_fwver(bool verbose)
1162 {
1163 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
1164 	struct tag *t;
1165 	char *list1 = NULL;
1166 	char *list2 = NULL;
1167 	char *fwver = NULL;
1168 	char *p = PLAIN_VERSION;
1169 	int i, end;
1170 
1171 	t = atags_get_tag(ATAG_FWVER);
1172 	if (t) {
1173 		list1 = calloc(1, sizeof(struct tag_fwver));
1174 		if (!list1)
1175 			return;
1176 		for (i = 0; i < FW_MAX; i++) {
1177 			if (t->u.fwver.ver[i][0] != '\0') {
1178 				strcat(list1, t->u.fwver.ver[i]);
1179 				strcat(list1, ",");
1180 			}
1181 		}
1182 	}
1183 
1184 	list2 = calloc(1, FWVER_LEN);
1185 	if (!list2)
1186 		goto out;
1187 	strcat(list2, "uboot-");
1188 	/* optional */
1189 #ifdef BUILD_TAG
1190 	strcat(list2, BUILD_TAG);
1191 	strcat(list2, "-");
1192 #endif
1193 	/* optional */
1194 	if (strcmp(PLAIN_VERSION, "2017.09")) {
1195 		strncat(list2, p + strlen("2017.09-g"), 10);
1196 		strcat(list2, "-");
1197 	}
1198 	strcat(list2, U_BOOT_DMI_DATE);
1199 
1200 	/* merge ! */
1201 	if (list1 || list2) {
1202 		fwver = calloc(1, sizeof(struct tag_fwver));
1203 		if (!fwver)
1204 			goto out;
1205 
1206 		strcat(fwver, "androidboot.fwver=");
1207 		if (list1)
1208 			strcat(fwver, list1);
1209 		if (list2) {
1210 			strcat(fwver, list2);
1211 		} else {
1212 			end = strlen(fwver) - 1;
1213 			fwver[end] = '\0'; /* omit last ',' */
1214 		}
1215 		if (verbose)
1216 			printf("## fwver: %s\n\n", fwver);
1217 		env_update("bootargs", fwver);
1218 		env_set("fwver", fwver + strlen("androidboot."));
1219 	}
1220 out:
1221 	if (list1)
1222 		free(list1);
1223 	if (list2)
1224 		free(list2);
1225 	if (fwver)
1226 		free(fwver);
1227 #endif
1228 }
1229 
1230 static void bootargs_add_android(bool verbose)
1231 {
1232 #ifdef CONFIG_ANDROID_AB
1233 	ab_update_root_partition();
1234 #endif
1235 
1236 	/* Android header v4+ need this handle */
1237 #ifdef CONFIG_ANDROID_BOOT_IMAGE
1238 	struct andr_img_hdr *hdr;
1239 	char *fwver;
1240 
1241 	hdr = (void *)env_get_ulong("android_addr_r", 16, 0);
1242 	if (hdr && !android_image_check_header(hdr) && hdr->header_version >= 4) {
1243 		if (env_update_extract_subset("bootargs", "andr_bootargs", "androidboot."))
1244 			printf("extract androidboot.xxx error\n");
1245 		if (verbose)
1246 			printf("## bootargs(android): %s\n\n", env_get("andr_bootargs"));
1247 
1248 		/* for kernel cmdline can be read */
1249 		fwver = env_get("fwver");
1250 		if (fwver) {
1251 			env_update("bootargs", fwver);
1252 			env_set("fwver", NULL);
1253 		}
1254 	}
1255 #endif
1256 }
1257 
1258 static void bootargs_add_partition(bool verbose)
1259 {
1260 #if defined(CONFIG_ENVF) || defined(CONFIG_ENV_PARTITION)
1261 	char *part_type[] = { "mtdparts", "blkdevparts" };
1262 	char *part_list;
1263 	char *env;
1264 	int id = 0;
1265 
1266 	env = env_get(part_type[id]);
1267 	if (!env)
1268 		env = env_get(part_type[++id]);
1269 	if (env) {
1270 		if (!strstr(env, part_type[id])) {
1271 			part_list = calloc(1, strlen(env) + strlen(part_type[id]) + 2);
1272 			if (part_list) {
1273 				strcat(part_list, part_type[id]);
1274 				strcat(part_list, "=");
1275 				strcat(part_list, env);
1276 			}
1277 		} else {
1278 			part_list = env;
1279 		}
1280 		env_update("bootargs", part_list);
1281 		if (verbose)
1282 			printf("## parts: %s\n\n", part_list);
1283 	}
1284 
1285 	env = env_get("sys_bootargs");
1286 	if (env) {
1287 		env_update("bootargs", env);
1288 		if (verbose)
1289 			printf("## sys_bootargs: %s\n\n", env);
1290 	}
1291 #endif
1292 
1293 #ifdef CONFIG_MTD_BLK
1294 	if (!env_get("mtdparts")) {
1295 		char *mtd_par_info = mtd_part_parse(NULL);
1296 
1297 		if (mtd_par_info) {
1298 			if (memcmp(env_get("devtype"), "mtd", 3) == 0)
1299 				env_update("bootargs", mtd_par_info);
1300 		}
1301 	}
1302 #endif
1303 }
1304 
1305 static void bootargs_add_dtb_dtbo(void *fdt, bool verbose)
1306 {
1307 	/* bootargs_ext is used when dtbo is applied. */
1308 	const char *arr_bootargs[] = { "bootargs", "bootargs_ext" };
1309 	const char *bootargs;
1310 	char *msg = "kernel";
1311 	int i, noffset;
1312 
1313 	/* find or create "/chosen" node. */
1314 	noffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
1315 	if (noffset < 0)
1316 		return;
1317 
1318 	for (i = 0; i < ARRAY_SIZE(arr_bootargs); i++) {
1319 		bootargs = fdt_getprop(fdt, noffset, arr_bootargs[i], NULL);
1320 		if (!bootargs)
1321 			continue;
1322 		if (verbose)
1323 			printf("## bootargs(%s-%s): %s\n\n",
1324 			       msg, arr_bootargs[i], bootargs);
1325 		/*
1326 		 * Append kernel bootargs
1327 		 * If use AB system, delete default "root=" which route
1328 		 * to rootfs. Then the ab bootctl will choose the
1329 		 * high priority system to boot and add its UUID
1330 		 * to cmdline. The format is "roo=PARTUUID=xxxx...".
1331 		 */
1332 #ifdef CONFIG_ANDROID_AB
1333 		env_update_filter("bootargs", bootargs, "root=");
1334 #else
1335 		env_update("bootargs", bootargs);
1336 #endif
1337 	}
1338 }
1339 
1340 char *board_fdt_chosen_bootargs(void *fdt)
1341 {
1342 	int verbose = is_hotkey(HK_CMDLINE);
1343 	const char *bootargs;
1344 
1345 	/* debug */
1346 	hotkey_run(HK_INITCALL);
1347 	if (verbose)
1348 		printf("## bootargs(u-boot): %s\n\n", env_get("bootargs"));
1349 
1350 	bootargs_add_dtb_dtbo(fdt, verbose);
1351 	bootargs_add_partition(verbose);
1352 	bootargs_add_android(verbose);
1353 	bootargs_add_fwver(verbose);
1354 
1355 	/*
1356 	 * Initrd fixup: remove unused "initrd=0x...,0x...",
1357 	 * this for compatible with legacy parameter.txt
1358 	 */
1359 	env_delete("bootargs", "initrd=", 0);
1360 
1361 	/*
1362 	 * If uart is required to be disabled during
1363 	 * power on, it would be not initialized by
1364 	 * any pre-loader and U-Boot.
1365 	 *
1366 	 * If we don't remove earlycon from commandline,
1367 	 * kernel hangs while using earlycon to putc/getc
1368 	 * which may dead loop for waiting uart status.
1369 	 * (It seems the root cause is baundrate is not
1370 	 * initilalized)
1371 	 *
1372 	 * So let's remove earlycon from commandline.
1373 	 */
1374 	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
1375 		env_delete("bootargs", "earlycon=", 0);
1376 
1377 	bootargs = env_get("bootargs");
1378 	if (verbose)
1379 		printf("## bootargs(merged): %s\n\n", bootargs);
1380 
1381 	return (char *)bootargs;
1382 }
1383 
1384 int ft_verify_fdt(void *fdt)
1385 {
1386 	/* for android header v4+, we load bootparams and fixup initrd */
1387 #if defined(CONFIG_ANDROID_BOOT_IMAGE) && defined(CONFIG_XBC)
1388 	struct andr_img_hdr *hdr;
1389 	uint64_t initrd_start, initrd_end;
1390 	char *bootargs, *p;
1391 	int nodeoffset;
1392 	int is_u64, err;
1393 	u32 len;
1394 
1395 	hdr = (void *)env_get_ulong("android_addr_r", 16, 0);
1396 	if (!hdr || android_image_check_header(hdr) ||
1397 	    hdr->header_version < 4)
1398 		return 1;
1399 
1400 	bootargs = env_get("andr_bootargs");
1401 	if (!bootargs)
1402 		return 1;
1403 
1404 	/* trans character: space to new line */
1405 	p = bootargs;
1406 	while (*p++) {
1407 		if (*p == ' ')
1408 			*p = '\n';
1409 	}
1410 
1411 	debug("## andr_bootargs: %s\n", bootargs);
1412 
1413 	/*
1414 	 * add boot params right after bootconfig
1415 	 *
1416 	 * because we can get final full bootargs in board_fdt_chosen_bootargs(),
1417 	 * android_image_get_ramdisk() is early than that.
1418 	 *
1419 	 * we have to add boot params by now.
1420 	 */
1421 	len = addBootConfigParameters((char *)bootargs, strlen(bootargs),
1422 		(u64)hdr->ramdisk_addr + hdr->ramdisk_size +
1423 		hdr->vendor_ramdisk_size, hdr->vendor_bootconfig_size);
1424 	if (len < 0) {
1425 		printf("error: addBootConfigParameters\n");
1426 		return 0;
1427 	}
1428 
1429 	nodeoffset = fdt_subnode_offset(fdt, 0, "chosen");
1430 	if (nodeoffset < 0) {
1431 		printf("error: No /chosen node\n");
1432 		return 0;
1433 	}
1434 
1435 	/* fixup initrd with real value */
1436 	fdt_delprop(fdt, nodeoffset, "linux,initrd-start");
1437 	fdt_delprop(fdt, nodeoffset, "linux,initrd-end");
1438 
1439 	is_u64 = (fdt_address_cells(fdt, 0) == 2);
1440 	initrd_start = hdr->ramdisk_addr;
1441 	initrd_end = initrd_start + hdr->ramdisk_size +
1442 			hdr->vendor_ramdisk_size +
1443 			hdr->vendor_bootconfig_size + len;
1444 	err = fdt_setprop_uxx(fdt, nodeoffset, "linux,initrd-start",
1445 			      initrd_start, is_u64);
1446 	if (err < 0) {
1447 		printf("WARNING: could not set linux,initrd-start %s.\n",
1448 		       fdt_strerror(err));
1449 		return 0;
1450 	}
1451 	err = fdt_setprop_uxx(fdt, nodeoffset, "linux,initrd-end",
1452 			      initrd_end, is_u64);
1453 	if (err < 0) {
1454 		printf("WARNING: could not set linux,initrd-end %s.\n",
1455 		       fdt_strerror(err));
1456 		return 0;
1457 	}
1458 #endif
1459 	return 1;
1460 }
1461 
1462