xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/board.c (revision 2a3fb7bb049d69d96f3bc7dae8caa756fdc8a613)
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 <amp.h>
9 #include <android_bootloader.h>
10 #include <android_image.h>
11 #include <bidram.h>
12 #include <boot_rkimg.h>
13 #include <cli.h>
14 #include <clk.h>
15 #include <console.h>
16 #include <debug_uart.h>
17 #include <dm.h>
18 #include <dvfs.h>
19 #include <io-domain.h>
20 #include <image.h>
21 #include <key.h>
22 #include <memblk.h>
23 #include <misc.h>
24 #include <of_live.h>
25 #include <mtd_blk.h>
26 #include <ram.h>
27 #include <rockchip_debugger.h>
28 #include <syscon.h>
29 #include <sysmem.h>
30 #include <video_rockchip.h>
31 #include <asm/io.h>
32 #include <asm/gpio.h>
33 #include <dm/uclass-internal.h>
34 #include <dm/root.h>
35 #include <power/charge_display.h>
36 #include <power/regulator.h>
37 #include <optee_include/OpteeClientInterface.h>
38 #include <optee_include/OpteeClientApiLib.h>
39 #include <optee_include/tee_api_defines.h>
40 #include <asm/arch/boot_mode.h>
41 #include <asm/arch/clock.h>
42 #include <asm/arch/cpu.h>
43 #include <asm/arch/hotkey.h>
44 #include <asm/arch/param.h>
45 #include <asm/arch/periph.h>
46 #include <asm/arch/resource_img.h>
47 #include <asm/arch/rk_atags.h>
48 #include <asm/arch/vendor.h>
49 
50 DECLARE_GLOBAL_DATA_PTR;
51 
52 __weak int rk_board_late_init(void)
53 {
54 	return 0;
55 }
56 
57 __weak int rk_board_fdt_fixup(void *blob)
58 {
59 	return 0;
60 }
61 
62 __weak int soc_clk_dump(void)
63 {
64 	return 0;
65 }
66 
67 __weak int set_armclk_rate(void)
68 {
69 	return 0;
70 }
71 
72 __weak int rk_board_init(void)
73 {
74 	return 0;
75 }
76 
77 /*
78  * define serialno max length, the max length is 512 Bytes
79  * The remaining bytes are used to ensure that the first 512 bytes
80  * are valid when executing 'env_set("serial#", value)'.
81  */
82 #define VENDOR_SN_MAX	513
83 #define CPUID_LEN	0x10
84 #define CPUID_OFF	0x07
85 
86 static int rockchip_set_ethaddr(void)
87 {
88 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
89 	char buf[ARP_HLEN_ASCII + 1];
90 	u8 ethaddr[ARP_HLEN];
91 	int ret;
92 
93 	ret = vendor_storage_read(VENDOR_LAN_MAC_ID, ethaddr, sizeof(ethaddr));
94 	if (ret > 0 && is_valid_ethaddr(ethaddr)) {
95 		sprintf(buf, "%pM", ethaddr);
96 		env_set("ethaddr", buf);
97 	}
98 #endif
99 	return 0;
100 }
101 
102 static int rockchip_set_serialno(void)
103 {
104 	u8 low[CPUID_LEN / 2], high[CPUID_LEN / 2];
105 	u8 cpuid[CPUID_LEN] = {0};
106 	char serialno_str[VENDOR_SN_MAX];
107 	int ret = 0, i;
108 	u64 serialno;
109 
110 	/* Read serial number from vendor storage part */
111 	memset(serialno_str, 0, VENDOR_SN_MAX);
112 
113 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
114 	ret = vendor_storage_read(VENDOR_SN_ID, serialno_str, (VENDOR_SN_MAX-1));
115 	if (ret > 0) {
116 		i = strlen(serialno_str);
117 		for (; i > 0; i--) {
118 			if ((serialno_str[i] >= 'a' && serialno_str[i] <= 'z') ||
119 			    (serialno_str[i] >= 'A' && serialno_str[i] <= 'Z') ||
120 			    (serialno_str[i] >= '0' && serialno_str[i] <= '9'))
121 				break;
122 		}
123 
124 		serialno_str[i + 1] = 0x0;
125 		env_set("serial#", serialno_str);
126 	} else {
127 #endif
128 #ifdef CONFIG_ROCKCHIP_EFUSE
129 		struct udevice *dev;
130 
131 		/* retrieve the device */
132 		ret = uclass_get_device_by_driver(UCLASS_MISC,
133 						  DM_GET_DRIVER(rockchip_efuse),
134 						  &dev);
135 		if (ret) {
136 			printf("%s: could not find efuse device\n", __func__);
137 			return ret;
138 		}
139 
140 		/* read the cpu_id range from the efuses */
141 		ret = misc_read(dev, CPUID_OFF, &cpuid, sizeof(cpuid));
142 		if (ret) {
143 			printf("%s: read cpuid from efuses failed, ret=%d\n",
144 			       __func__, ret);
145 			return ret;
146 		}
147 #else
148 		/* generate random cpuid */
149 		for (i = 0; i < CPUID_LEN; i++)
150 			cpuid[i] = (u8)(rand());
151 #endif
152 		/* Generate the serial number based on CPU ID */
153 		for (i = 0; i < 8; i++) {
154 			low[i] = cpuid[1 + (i << 1)];
155 			high[i] = cpuid[i << 1];
156 		}
157 
158 		serialno = crc32_no_comp(0, low, 8);
159 		serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
160 		snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno);
161 
162 		env_set("serial#", serialno_str);
163 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
164 	}
165 #endif
166 
167 	return ret;
168 }
169 
170 #if defined(CONFIG_USB_FUNCTION_FASTBOOT)
171 int fb_set_reboot_flag(void)
172 {
173 	printf("Setting reboot to fastboot flag ...\n");
174 	writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG);
175 
176 	return 0;
177 }
178 #endif
179 
180 #ifdef CONFIG_ROCKCHIP_USB_BOOT
181 static int boot_from_udisk(void)
182 {
183 	struct blk_desc *desc;
184 	char *devtype;
185 	char *devnum;
186 
187 	devtype = env_get("devtype");
188 	devnum = env_get("devnum");
189 
190 	/* Booting priority: mmc1 > udisk */
191 	if (!strcmp(devtype, "mmc") && !strcmp(devnum, "1"))
192 		return 0;
193 
194 	if (!run_command("usb start", -1)) {
195 		desc = blk_get_devnum_by_type(IF_TYPE_USB, 0);
196 		if (!desc) {
197 			printf("No usb device found\n");
198 			return -ENODEV;
199 		}
200 
201 		if (!run_command("rkimgtest usb 0", -1)) {
202 			rockchip_set_bootdev(desc);
203 			env_set("devtype", "usb");
204 			env_set("devnum", "0");
205 			printf("Boot from usb 0\n");
206 		} else {
207 			printf("No usb dev 0 found\n");
208 			return -ENODEV;
209 		}
210 	}
211 
212 	return 0;
213 }
214 #endif
215 
216 static void env_fixup(void)
217 {
218 	struct memblock mem;
219 	ulong u_addr_r;
220 	phys_size_t end;
221 	char *addr_r;
222 
223 #ifdef ENV_MEM_LAYOUT_SETTINGS1
224 	const char *env_addr0[] = {
225 		"scriptaddr", "pxefile_addr_r",
226 		"fdt_addr_r", "kernel_addr_r", "ramdisk_addr_r",
227 	};
228 	const char *env_addr1[] = {
229 		"scriptaddr1", "pxefile_addr1_r",
230 		"fdt_addr1_r", "kernel_addr1_r", "ramdisk_addr1_r",
231 	};
232 	int i;
233 
234 	/* 128M is a typical ram size for most platform, so as default here */
235 	if (gd->ram_size <= SZ_128M) {
236 		/* Replace orignal xxx_addr_r */
237 		for (i = 0; i < ARRAY_SIZE(env_addr1); i++) {
238 			addr_r = env_get(env_addr1[i]);
239 			if (addr_r)
240 				env_set(env_addr0[i], addr_r);
241 		}
242 	}
243 #endif
244 	/* If BL32 is disabled, move kernel to lower address. */
245 	if (!(gd->flags & GD_FLG_BL32_ENABLED)) {
246 		addr_r = env_get("kernel_addr_no_bl32_r");
247 		if (addr_r)
248 			env_set("kernel_addr_r", addr_r);
249 
250 		/*
251 		 * 0x0a200000 and 0x08400000 are rockchip traditional address
252 		 * of BL32 and ramdisk:
253 		 *
254 		 * |------------|------------|
255 		 * |    BL32    |  ramdisk   |
256 		 * |------------|------------|
257 		 *
258 		 * Move ramdisk to BL32 address to fix sysmem alloc failed
259 		 * issue on the board with critical memory(ie. 256MB).
260 		 */
261 		if (gd->ram_size > SZ_128M && gd->ram_size <= SZ_256M) {
262 			u_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
263 			if (u_addr_r == 0x0a200000)
264 				env_set("ramdisk_addr_r", "0x08400000");
265 		}
266 
267 	/* If BL32 is enlarged, move ramdisk right behind it */
268 	} else {
269 		mem = param_parse_optee_mem();
270 		end = mem.base + mem.size;
271 		u_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
272 		if (u_addr_r >= mem.base && u_addr_r < end)
273 			env_set_hex("ramdisk_addr_r", end);
274 	}
275 }
276 
277 static void cmdline_handle(void)
278 {
279 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
280 	struct tag *t;
281 
282 	t = atags_get_tag(ATAG_PUB_KEY);
283 	if (t) {
284 		/* Pass if efuse/otp programmed */
285 		if (t->u.pub_key.flag == PUBKEY_FUSE_PROGRAMMED)
286 			env_update("bootargs", "fuse.programmed=1");
287 		else
288 			env_update("bootargs", "fuse.programmed=0");
289 	}
290 #endif
291 }
292 
293 int board_late_init(void)
294 {
295 	rockchip_set_ethaddr();
296 	rockchip_set_serialno();
297 	setup_download_mode();
298 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0)
299 	setup_boot_mode();
300 #endif
301 #ifdef CONFIG_ROCKCHIP_USB_BOOT
302 	boot_from_udisk();
303 #endif
304 #ifdef CONFIG_DM_CHARGE_DISPLAY
305 	charge_display();
306 #endif
307 #ifdef CONFIG_DRM_ROCKCHIP
308 	rockchip_show_logo();
309 #endif
310 	env_fixup();
311 	soc_clk_dump();
312 	cmdline_handle();
313 
314 	return rk_board_late_init();
315 }
316 
317 static void early_download(void)
318 {
319 #if defined(CONFIG_PWRKEY_DNL_TRIGGER_NUM) && \
320 		(CONFIG_PWRKEY_DNL_TRIGGER_NUM > 0)
321 	if (pwrkey_download_init())
322 		printf("Pwrkey download init failed\n");
323 #endif
324 
325 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0)
326 	if (is_hotkey(HK_BROM_DNL)) {
327 		printf("Enter bootrom download...");
328 		flushc();
329 		writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
330 		do_reset(NULL, 0, 0, NULL);
331 		printf("failed!\n");
332 	}
333 #endif
334 }
335 
336 static void board_debug_init(void)
337 {
338 	if (!gd->serial.using_pre_serial)
339 		board_debug_uart_init();
340 
341 	if (tstc()) {
342 		gd->console_evt = getc();
343 		if (gd->console_evt <= 0x1a) /* 'z' */
344 			printf("Hotkey: ctrl+%c\n", gd->console_evt + 'a' - 1);
345 	}
346 
347 	if (IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI))
348 		printf("Cmd interface: disabled\n");
349 }
350 
351 #ifdef CONFIG_MTD_BLK
352 static void board_mtd_blk_map_partitions(void)
353 {
354 	struct blk_desc *dev_desc;
355 
356 	dev_desc = rockchip_get_bootdev();
357 	if (dev_desc)
358 		mtd_blk_map_partitions(dev_desc);
359 }
360 #endif
361 
362 int board_init(void)
363 {
364 	board_debug_init();
365 
366 #ifdef DEBUG
367 	soc_clk_dump();
368 #endif
369 
370 #ifdef CONFIG_USING_KERNEL_DTB
371 #ifdef CONFIG_MTD_BLK
372 	board_mtd_blk_map_partitions();
373 #endif
374 	init_kernel_dtb();
375 #endif
376 	early_download();
377 
378 	/*
379 	 * pmucru isn't referenced on some platforms, so pmucru driver can't
380 	 * probe that the "assigned-clocks" is unused.
381 	 */
382 	clks_probe();
383 #ifdef CONFIG_DM_REGULATOR
384 	if (regulators_enable_boot_on(is_hotkey(HK_REGULATOR)))
385 		debug("%s: Can't enable boot on regulator\n", __func__);
386 #endif
387 
388 #ifdef CONFIG_ROCKCHIP_IO_DOMAIN
389 	io_domain_init();
390 #endif
391 
392 	set_armclk_rate();
393 
394 #ifdef CONFIG_DM_DVFS
395 	dvfs_init(true);
396 #endif
397 
398 	return rk_board_init();
399 }
400 
401 int interrupt_debugger_init(void)
402 {
403 #ifdef CONFIG_ROCKCHIP_DEBUGGER
404 	return rockchip_debugger_init();
405 #else
406 	return 0;
407 #endif
408 }
409 
410 int board_fdt_fixup(void *blob)
411 {
412 	/* Common fixup for DRM */
413 #ifdef CONFIG_DRM_ROCKCHIP
414 	rockchip_display_fixup(blob);
415 #endif
416 
417 	return rk_board_fdt_fixup(blob);
418 }
419 
420 #if defined(CONFIG_ARM64_BOOT_AARCH32) || !defined(CONFIG_ARM64)
421 /*
422  * Common for OP-TEE:
423  *	64-bit & 32-bit mode: share memory dcache is always enabled;
424  *
425  * Common for U-Boot:
426  *	64-bit mode: MMU table is static defined in rkxxx.c file, all memory
427  *		     regions are mapped. That's good to match OP-TEE MMU policy.
428  *
429  *	32-bit mode: MMU table is setup according to gd->bd->bi_dram[..] where
430  *		     the OP-TEE region has been reserved, so it can not be
431  *		     mapped(i.e. dcache is disabled). That's *NOT* good to match
432  *		     OP-TEE MMU policy.
433  *
434  * For the data coherence when communication between U-Boot and OP-TEE, U-Boot
435  * should follow OP-TEE MMU policy.
436  *
437  * So 32-bit mode U-Boot should map OP-TEE share memory as dcache enabled.
438  */
439 int board_initr_caches_fixup(void)
440 {
441 #ifdef CONFIG_OPTEE_CLIENT
442 	struct memblock mem;
443 
444 	mem.base = 0;
445 	mem.size = 0;
446 
447 	optee_get_shm_config(&mem.base, &mem.size);
448 	if (mem.size)
449 		mmu_set_region_dcache_behaviour(mem.base, mem.size,
450 						DCACHE_WRITEBACK);
451 #endif
452 	return 0;
453 }
454 #endif
455 
456 void arch_preboot_os(uint32_t bootm_state)
457 {
458 	if (bootm_state & BOOTM_STATE_OS_PREP)
459 		hotkey_run(HK_CLI_OS_PRE);
460 }
461 
462 void enable_caches(void)
463 {
464 	icache_enable();
465 	dcache_enable();
466 }
467 
468 #ifdef CONFIG_LMB
469 /*
470  * Using last bi_dram[...] to initialize "bootm_low" and "bootm_mapsize".
471  * This makes lmb_alloc_base() always alloc from tail of sdram.
472  * If we don't assign it, bi_dram[0] is used by default and it may cause
473  * lmb_alloc_base() fail when bi_dram[0] range is small.
474  */
475 void board_lmb_reserve(struct lmb *lmb)
476 {
477 	char bootm_mapsize[32];
478 	char bootm_low[32];
479 	u64 start, size;
480 	int i;
481 
482 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
483 		if (!gd->bd->bi_dram[i].size)
484 			break;
485 	}
486 
487 	start = gd->bd->bi_dram[i - 1].start;
488 	size = gd->bd->bi_dram[i - 1].size;
489 
490 	/*
491 	 * 32-bit kernel: ramdisk/fdt shouldn't be loaded to highmem area(768MB+),
492 	 * otherwise "Unable to handle kernel paging request at virtual address ...".
493 	 *
494 	 * So that we hope limit highest address at 768M, but there comes the the
495 	 * problem: ramdisk is a compressed image and it expands after descompress,
496 	 * so it accesses 768MB+ and brings the above "Unable to handle kernel ...".
497 	 *
498 	 * We make a appointment that the highest memory address is 512MB, it
499 	 * makes lmb alloc safer.
500 	 */
501 #ifndef CONFIG_ARM64
502 	if (start >= ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M)) {
503 		start = gd->bd->bi_dram[i - 2].start;
504 		size = gd->bd->bi_dram[i - 2].size;
505 	}
506 
507 	if ((start + size) > ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M))
508 		size = (u64)CONFIG_SYS_SDRAM_BASE + SZ_512M - start;
509 #endif
510 	sprintf(bootm_low, "0x%llx", start);
511 	sprintf(bootm_mapsize, "0x%llx", size);
512 	env_set("bootm_low", bootm_low);
513 	env_set("bootm_mapsize", bootm_mapsize);
514 }
515 #endif
516 
517 #ifdef CONFIG_BIDRAM
518 int board_bidram_reserve(struct bidram *bidram)
519 {
520 	struct memblock mem;
521 	int ret;
522 
523 	/* ATF */
524 	mem = param_parse_atf_mem();
525 	ret = bidram_reserve(MEM_ATF, mem.base, mem.size);
526 	if (ret)
527 		return ret;
528 
529 	/* PSTORE/ATAGS/SHM */
530 	mem = param_parse_common_resv_mem();
531 	ret = bidram_reserve(MEM_SHM, mem.base, mem.size);
532 	if (ret)
533 		return ret;
534 
535 	/* OP-TEE */
536 	mem = param_parse_optee_mem();
537 	ret = bidram_reserve(MEM_OPTEE, mem.base, mem.size);
538 	if (ret)
539 		return ret;
540 
541 	return 0;
542 }
543 
544 parse_fn_t board_bidram_parse_fn(void)
545 {
546 	return param_parse_ddr_mem;
547 }
548 #endif
549 
550 #ifdef CONFIG_ROCKCHIP_AMP
551 void cpu_secondary_init_r(void)
552 {
553 	amp_cpus_on();
554 }
555 #endif
556 
557 #if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \
558     defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS)
559 int board_init_f_init_serial(void)
560 {
561 	struct tag *t = atags_get_tag(ATAG_SERIAL);
562 
563 	if (t) {
564 		gd->serial.using_pre_serial = t->u.serial.enable;
565 		gd->serial.addr = t->u.serial.addr;
566 		gd->serial.baudrate = t->u.serial.baudrate;
567 		gd->serial.id = t->u.serial.id;
568 
569 		debug("%s: enable=%d, addr=0x%lx, baudrate=%d, id=%d\n",
570 		      __func__, gd->serial.using_pre_serial,
571 		      gd->serial.addr, gd->serial.baudrate,
572 		      gd->serial.id);
573 	}
574 
575 	return 0;
576 }
577 #endif
578 
579 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
580 #include <fdt_support.h>
581 #include <usb.h>
582 #include <usb/dwc2_udc.h>
583 
584 static struct dwc2_plat_otg_data otg_data = {
585 	.rx_fifo_sz	= 512,
586 	.np_tx_fifo_sz	= 16,
587 	.tx_fifo_sz	= 128,
588 };
589 
590 int board_usb_init(int index, enum usb_init_type init)
591 {
592 	const void *blob = gd->fdt_blob;
593 	const fdt32_t *reg;
594 	fdt_addr_t addr;
595 	int node;
596 
597 	/* find the usb_otg node */
598 	node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
599 
600 retry:
601 	if (node > 0) {
602 		reg = fdt_getprop(blob, node, "reg", NULL);
603 		if (!reg)
604 			return -EINVAL;
605 
606 		addr = fdt_translate_address(blob, node, reg);
607 		if (addr == OF_BAD_ADDR) {
608 			pr_err("Not found usb_otg address\n");
609 			return -EINVAL;
610 		}
611 
612 #if defined(CONFIG_ROCKCHIP_RK3288)
613 		if (addr != 0xff580000) {
614 			node = fdt_node_offset_by_compatible(blob, node,
615 							     "snps,dwc2");
616 			goto retry;
617 		}
618 #endif
619 	} else {
620 		/*
621 		 * With kernel dtb support, rk3288 dwc2 otg node
622 		 * use the rockchip legacy dwc2 driver "dwc_otg_310"
623 		 * with the compatible "rockchip,rk3288_usb20_otg",
624 		 * and rk3368 also use the "dwc_otg_310" driver with
625 		 * the compatible "rockchip,rk3368-usb".
626 		 */
627 #if defined(CONFIG_ROCKCHIP_RK3288)
628 		node = fdt_node_offset_by_compatible(blob, -1,
629 				"rockchip,rk3288_usb20_otg");
630 #elif defined(CONFIG_ROCKCHIP_RK3368)
631 		node = fdt_node_offset_by_compatible(blob, -1,
632 				"rockchip,rk3368-usb");
633 #endif
634 		if (node > 0) {
635 			goto retry;
636 		} else {
637 			pr_err("Not found usb_otg device\n");
638 			return -ENODEV;
639 		}
640 	}
641 
642 	otg_data.regs_otg = (uintptr_t)addr;
643 
644 	return dwc2_udc_probe(&otg_data);
645 }
646 
647 int board_usb_cleanup(int index, enum usb_init_type init)
648 {
649 	return 0;
650 }
651 #endif
652 
653 static void bootm_no_reloc(void)
654 {
655 	char *ramdisk_high;
656 	char *fdt_high;
657 
658 	if (!env_get_yesno("bootm-no-reloc"))
659 		return;
660 
661 	ramdisk_high = env_get("initrd_high");
662 	fdt_high = env_get("fdt_high");
663 
664 	if (!fdt_high) {
665 		env_set_hex("fdt_high", -1UL);
666 		printf("Fdt ");
667 	}
668 
669 	if (!ramdisk_high) {
670 		env_set_hex("initrd_high", -1UL);
671 		printf("Ramdisk ");
672 	}
673 
674 	if (!fdt_high || !ramdisk_high)
675 		printf("skip relocation\n");
676 }
677 
678 int bootm_board_start(void)
679 {
680 	/*
681 	 * print console record data
682 	 *
683 	 * On some rockchip platforms, uart debug and sdmmc pin are multiplex.
684 	 * If boot from sdmmc mode, the console data would be record in buffer,
685 	 * we switch to uart debug function in order to print it after loading
686 	 * images.
687 	 */
688 #if defined(CONFIG_CONSOLE_RECORD)
689 	if (!strcmp("mmc", env_get("devtype")) &&
690 	    !strcmp("1", env_get("devnum"))) {
691 		printf("IOMUX: sdmmc => uart debug");
692 		pinctrl_select_state(gd->cur_serial_dev, "default");
693 		console_record_print_purge();
694 	}
695 #endif
696 	/* disable bootm relcation to save boot time */
697 	bootm_no_reloc();
698 
699 	/* sysmem */
700 	hotkey_run(HK_SYSMEM);
701 	sysmem_overflow_check();
702 
703 	return 0;
704 }
705 
706 /*
707  * Implement it to support CLI command:
708  *   - Android: bootm [aosp addr]
709  *   - FIT:     bootm [fit addr]
710  *   - uImage:  bootm [uimage addr]
711  *
712  * Purpose:
713  *   - The original bootm command args require fdt addr on AOSP,
714  *     which is not flexible on rockchip boot/recovery.img.
715  *   - Take Android/FIT/uImage image into sysmem management to avoid image
716  *     memory overlap.
717  */
718 #if defined(CONFIG_ANDROID_BOOTLOADER) ||	\
719 	defined(CONFIG_ROCKCHIP_FIT_IMAGE) ||	\
720 	defined(CONFIG_ROCKCHIP_UIMAGE)
721 int board_do_bootm(int argc, char * const argv[])
722 {
723 	int format;
724 	void *img;
725 
726 	if (argc != 2)
727 		return 0;
728 
729 	img = (void *)simple_strtoul(argv[1], NULL, 16);
730 	format = (genimg_get_format(img));
731 
732 	/* Android */
733 #ifdef CONFIG_ANDROID_BOOT_IMAGE
734 	if (format == IMAGE_FORMAT_ANDROID) {
735 		struct andr_img_hdr *hdr;
736 		ulong load_addr;
737 		ulong size;
738 		int ret;
739 
740 		hdr = (struct andr_img_hdr *)img;
741 		printf("BOOTM: transferring to board Android\n");
742 
743 #ifdef CONFIG_USING_KERNEL_DTB
744 		sysmem_free((phys_addr_t)gd->fdt_blob);
745 		/* erase magic */
746 		fdt_set_magic((void *)gd->fdt_blob, ~0);
747 		gd->fdt_blob = NULL;
748 #endif
749 		load_addr = env_get_ulong("kernel_addr_r", 16, 0);
750 		load_addr -= hdr->page_size;
751 		size = android_image_get_end(hdr) - (ulong)hdr;
752 
753 		if (!sysmem_alloc_base(MEM_ANDROID, (ulong)hdr, size))
754 			return -ENOMEM;
755 
756 		ret = android_image_memcpy_separate(hdr, &load_addr);
757 		if (ret) {
758 			printf("board do bootm failed, ret=%d\n", ret);
759 			return ret;
760 		}
761 
762 		return android_bootloader_boot_kernel(load_addr);
763 	}
764 #endif
765 
766 	/* FIT */
767 #if IMAGE_ENABLE_FIT
768 	if (format == IMAGE_FORMAT_FIT) {
769 		char boot_cmd[64];
770 
771 		printf("BOOTM: transferring to board FIT\n");
772 		snprintf(boot_cmd, sizeof(boot_cmd), "boot_fit %s", argv[1]);
773 		return run_command(boot_cmd, 0);
774 	}
775 #endif
776 
777 	/* uImage */
778 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
779 	if (format == IMAGE_FORMAT_LEGACY &&
780 	    image_get_type(img) == IH_TYPE_MULTI) {
781 		char boot_cmd[64];
782 
783 		printf("BOOTM: transferring to board uImage\n");
784 		snprintf(boot_cmd, sizeof(boot_cmd), "boot_uimage %s", argv[1]);
785 		return run_command(boot_cmd, 0);
786 	}
787 #endif
788 
789 	return 0;
790 }
791 #endif
792 
793 void autoboot_command_fail_handle(void)
794 {
795 #ifdef CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE
796 #ifdef CONFIG_ANDROID_AB
797 	run_command("fastboot usb 0;", 0);  /* use fastboot to ative slot */
798 #else
799 	run_command("rockusb 0 ${devtype} ${devnum}", 0);
800 	run_command("fastboot usb 0;", 0);
801 #endif
802 #endif
803 }
804 
805 #ifdef CONFIG_FIT_ROLLBACK_PROTECT
806 
807 #define FIT_ROLLBACK_INDEX_LOCATION	0x66697472	/* "fitr" */
808 
809 int fit_read_otp_rollback_index(uint32_t fit_index, uint32_t *otp_index)
810 {
811 #ifdef CONFIG_OPTEE_CLIENT
812 	u64 index;
813 	int ret;
814 
815 	ret = trusty_read_rollback_index(FIT_ROLLBACK_INDEX_LOCATION, &index);
816 	if (ret) {
817 		if (ret != TEE_ERROR_ITEM_NOT_FOUND)
818 			return ret;
819 
820 		*otp_index = fit_index;
821 		printf("Initial otp index as %d\n", fit_index);
822 	}
823 
824 	*otp_index = index;
825 #else
826 	*otp_index = 0;
827 #endif
828 
829 	return 0;
830 }
831 
832 static int fit_write_trusty_rollback_index(u32 trusty_index)
833 {
834 	if (!trusty_index)
835 		return 0;
836 
837 	return trusty_write_rollback_index(FIT_ROLLBACK_INDEX_LOCATION,
838 					   (u64)trusty_index);
839 }
840 #endif
841 
842 void board_quiesce_devices(void *images)
843 {
844 	hotkey_run(HK_CMDLINE);
845 	hotkey_run(HK_CLI_OS_GO);
846 
847 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
848 	/* Destroy atags makes next warm boot safer */
849 	atags_destroy();
850 #endif
851 
852 #ifdef CONFIG_FIT_ROLLBACK_PROTECT
853 	int ret;
854 
855 	ret = fit_write_trusty_rollback_index(gd->rollback_index);
856 	if (ret) {
857 		panic("Failed to write fit rollback index %d, ret=%d",
858 		      gd->rollback_index, ret);
859 	}
860 #endif
861 
862 #ifdef CONFIG_ROCKCHIP_HW_DECOMPRESS
863 	misc_decompress_cleanup();
864 #endif
865 }
866