xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/tpl.c (revision 13ceb2afdcb6f5114908e39f0d2453728eb24e0f)
138771996SKever Yang /*
238771996SKever Yang  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
338771996SKever Yang  *
438771996SKever Yang  * SPDX-License-Identifier:     GPL-2.0+
538771996SKever Yang  */
638771996SKever Yang 
738771996SKever Yang #include <common.h>
838771996SKever Yang #include <debug_uart.h>
938771996SKever Yang #include <dm.h>
1038771996SKever Yang #include <ns16550.h>
1138771996SKever Yang #include <ram.h>
1238771996SKever Yang #include <spl.h>
1338771996SKever Yang #include <version.h>
1438771996SKever Yang #include <asm/io.h>
1538771996SKever Yang #include <asm/arch/bootrom.h>
1638771996SKever Yang #include <asm/arch/uart.h>
1730129f2fSDavid Wu #include <asm/arch-rockchip/sys_proto.h>
1838771996SKever Yang 
1951b91a97SDavid Wu #ifndef CONFIG_TPL_LIBCOMMON_SUPPORT
2051b91a97SDavid Wu #define CONFIG_SYS_NS16550_COM1 CONFIG_DEBUG_UART_BASE
puts(const char * str)2138771996SKever Yang void puts(const char *str)
2238771996SKever Yang {
2338771996SKever Yang 	while (*str)
2438771996SKever Yang 		putc(*str++);
2538771996SKever Yang }
2638771996SKever Yang 
putc(char c)2738771996SKever Yang void putc(char c)
2838771996SKever Yang {
2938771996SKever Yang 	if (c == '\n')
3038771996SKever Yang 		NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), '\r');
3138771996SKever Yang 
3238771996SKever Yang 	NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c);
3338771996SKever Yang }
3451b91a97SDavid Wu #endif /* CONFIG_TPL_LIBCOMMON_SUPPORT */
3538771996SKever Yang 
3656af0010SDavid Wu #ifndef CONFIG_TPL_LIBGENERIC_SUPPORT
timer_init(void)375dd9d28aSYouMin Chen int __weak timer_init(void)
385dd9d28aSYouMin Chen {
395dd9d28aSYouMin Chen 	return 0;
405dd9d28aSYouMin Chen }
415dd9d28aSYouMin Chen 
42a3f8c59fSZhihuan He #ifdef CONFIG_ARM64
43a3f8c59fSZhihuan He /* for ARM64,it don't have define timer_init and __udelay except lib/timer.c */
__udelay(unsigned long usec)445dd9d28aSYouMin Chen void __weak __udelay(unsigned long usec)
455dd9d28aSYouMin Chen {
465dd9d28aSYouMin Chen 	u64 i, j, count;
475dd9d28aSYouMin Chen 
485dd9d28aSYouMin Chen 	asm volatile ("MRS %0, CNTPCT_EL0" : "=r"(count));
495dd9d28aSYouMin Chen 	i = count;
505dd9d28aSYouMin Chen 	/* usec to count,24MHz */
515dd9d28aSYouMin Chen 	j = usec * 24;
525dd9d28aSYouMin Chen 	i += j;
535dd9d28aSYouMin Chen 	while (1) {
545dd9d28aSYouMin Chen 		asm volatile ("MRS %0, CNTPCT_EL0" : "=r"(count));
555dd9d28aSYouMin Chen 		if (count > i)
565dd9d28aSYouMin Chen 			break;
575dd9d28aSYouMin Chen 	}
585dd9d28aSYouMin Chen }
59a3f8c59fSZhihuan He #else
__udelay(unsigned long usec)60a3f8c59fSZhihuan He void __weak __udelay(unsigned long usec)
61a3f8c59fSZhihuan He {
62a3f8c59fSZhihuan He 	u32 nowl, nowu;
63a3f8c59fSZhihuan He 	u64 cur_count, end_count;
64a3f8c59fSZhihuan He 
65a3f8c59fSZhihuan He 	asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
66a3f8c59fSZhihuan He 	cur_count = (u64)nowu << 32 | nowl;
67a3f8c59fSZhihuan He 	/* usec to count,24MHz */
68a3f8c59fSZhihuan He 	end_count = usec * 24 + cur_count;
69a3f8c59fSZhihuan He 	while (1) {
70a3f8c59fSZhihuan He 		asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl),
71a3f8c59fSZhihuan He 			     "=r" (nowu));
72a3f8c59fSZhihuan He 		cur_count = (u64)nowu << 32 | nowl;
73a3f8c59fSZhihuan He 		if (cur_count > end_count)
74a3f8c59fSZhihuan He 			break;
75a3f8c59fSZhihuan He 	}
76a3f8c59fSZhihuan He }
775dd9d28aSYouMin Chen #endif /* CONFIG_ARM64 */
785dd9d28aSYouMin Chen 
udelay(unsigned long usec)7956af0010SDavid Wu void udelay(unsigned long usec)
8056af0010SDavid Wu {
8156af0010SDavid Wu 	__udelay(usec);
8256af0010SDavid Wu }
8356af0010SDavid Wu 
hang(void)8456af0010SDavid Wu void hang(void)
8556af0010SDavid Wu {
8656af0010SDavid Wu         bootstage_error(BOOTSTAGE_ID_NEED_RESET);
8756af0010SDavid Wu         for (;;)
8856af0010SDavid Wu                 ;
8956af0010SDavid Wu }
905dd9d28aSYouMin Chen #endif /* CONFIG_TPL_LIBGENERIC_SUPPORT */
9156af0010SDavid Wu 
spl_boot_device(void)9238771996SKever Yang u32 spl_boot_device(void)
9338771996SKever Yang {
9438771996SKever Yang 	return BOOT_DEVICE_BOOTROM;
9538771996SKever Yang }
9638771996SKever Yang 
rockchip_stimer_init(void)9738771996SKever Yang __weak void rockchip_stimer_init(void)
9838771996SKever Yang {
99*13ceb2afSXuhui Lin #ifdef COUNTER_FREQUENCY
10038771996SKever Yang #ifndef CONFIG_ARM64
10138771996SKever Yang 	asm volatile("mcr p15, 0, %0, c14, c0, 0"
10238771996SKever Yang 		     : : "r"(COUNTER_FREQUENCY));
10337e5dcc8SYouMin Chen #elif CONFIG_IS_ENABLED(TINY_FRAMEWORK)
10437e5dcc8SYouMin Chen 	/*
10537e5dcc8SYouMin Chen 	 * For ARM64,generally initialize CNTFRQ in start.S,
10637e5dcc8SYouMin Chen 	 * but if defined CONFIG_TPL_TINY_FRAMEWORK should skip start.S.
10737e5dcc8SYouMin Chen 	 * So initialize CNTFRQ to 24MHz here.
10837e5dcc8SYouMin Chen 	 */
10937e5dcc8SYouMin Chen 	asm volatile("msr CNTFRQ_EL0, %0"
11037e5dcc8SYouMin Chen 		     : : "r" (COUNTER_FREQUENCY));
11138771996SKever Yang #endif
112*13ceb2afSXuhui Lin #endif
11338771996SKever Yang 	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
11438771996SKever Yang 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
11538771996SKever Yang 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
11638771996SKever Yang 	writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
11738771996SKever Yang }
11838771996SKever Yang 
arch_cpu_init(void)119ad119319SZhihuan He __weak int arch_cpu_init(void)
120ad119319SZhihuan He {
121ad119319SZhihuan He 	return 0;
122ad119319SZhihuan He }
123ad119319SZhihuan He 
board_init_f(ulong dummy)12438771996SKever Yang void board_init_f(ulong dummy)
12538771996SKever Yang {
126ba5fd738SYouMin Chen #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
12738771996SKever Yang 	struct udevice *dev;
12838771996SKever Yang 	int ret;
12930129f2fSDavid Wu #endif
13038771996SKever Yang 
131a09afa08SKever Yang 	rockchip_stimer_init();
132ad119319SZhihuan He 	arch_cpu_init();
13338771996SKever Yang #define EARLY_DEBUG
13438771996SKever Yang #ifdef EARLY_DEBUG
13538771996SKever Yang 	/*
13638771996SKever Yang 	 * Debug UART can be used from here if required:
13738771996SKever Yang 	 *
13838771996SKever Yang 	 * debug_uart_init();
13938771996SKever Yang 	 * printch('a');
14038771996SKever Yang 	 * printhex8(0x1234);
14138771996SKever Yang 	 * printascii("string");
14238771996SKever Yang 	 */
14338771996SKever Yang 	debug_uart_init();
14438771996SKever Yang 	printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
14538771996SKever Yang 				U_BOOT_TIME ")\n");
14638771996SKever Yang #endif
14730129f2fSDavid Wu 
148ba5fd738SYouMin Chen #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
14938771996SKever Yang 	ret = spl_early_init();
15038771996SKever Yang 	if (ret) {
15138771996SKever Yang 		debug("spl_early_init() failed: %d\n", ret);
15238771996SKever Yang 		hang();
15338771996SKever Yang 	}
15430129f2fSDavid Wu #endif
15538771996SKever Yang 
15638771996SKever Yang 	/* Init ARM arch timer */
15738771996SKever Yang 	timer_init();
15830129f2fSDavid Wu 
159ba5fd738SYouMin Chen #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
16038771996SKever Yang 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
16138771996SKever Yang 	if (ret) {
16238771996SKever Yang 		printf("DRAM init failed: %d\n", ret);
16338771996SKever Yang 		return;
16438771996SKever Yang 	}
16530129f2fSDavid Wu #else
16630129f2fSDavid Wu 	sdram_init();
16730129f2fSDavid Wu #endif
16838771996SKever Yang 
16938771996SKever Yang #if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT)
17038771996SKever Yang 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
17138771996SKever Yang #endif
17238771996SKever Yang }
17338771996SKever Yang 
174ba5fd738SYouMin Chen #if !(defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK))
17538771996SKever Yang /* Place Holders */
board_init_r(gd_t * id,ulong dest_addr)17638771996SKever Yang void board_init_r(gd_t *id, ulong dest_addr)
17738771996SKever Yang {
17838771996SKever Yang 	/*
17938771996SKever Yang 	 * Function attribute is no-return
18038771996SKever Yang 	 * This Function never executes
18138771996SKever Yang 	 */
18238771996SKever Yang 	while (1)
18338771996SKever Yang 		;
18438771996SKever Yang }
18538771996SKever Yang #endif
186