xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/tpl.c (revision 13ceb2afdcb6f5114908e39f0d2453728eb24e0f)
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 <debug_uart.h>
9 #include <dm.h>
10 #include <ns16550.h>
11 #include <ram.h>
12 #include <spl.h>
13 #include <version.h>
14 #include <asm/io.h>
15 #include <asm/arch/bootrom.h>
16 #include <asm/arch/uart.h>
17 #include <asm/arch-rockchip/sys_proto.h>
18 
19 #ifndef CONFIG_TPL_LIBCOMMON_SUPPORT
20 #define CONFIG_SYS_NS16550_COM1 CONFIG_DEBUG_UART_BASE
puts(const char * str)21 void puts(const char *str)
22 {
23 	while (*str)
24 		putc(*str++);
25 }
26 
putc(char c)27 void putc(char c)
28 {
29 	if (c == '\n')
30 		NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), '\r');
31 
32 	NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c);
33 }
34 #endif /* CONFIG_TPL_LIBCOMMON_SUPPORT */
35 
36 #ifndef CONFIG_TPL_LIBGENERIC_SUPPORT
timer_init(void)37 int __weak timer_init(void)
38 {
39 	return 0;
40 }
41 
42 #ifdef CONFIG_ARM64
43 /* for ARM64,it don't have define timer_init and __udelay except lib/timer.c */
__udelay(unsigned long usec)44 void __weak __udelay(unsigned long usec)
45 {
46 	u64 i, j, count;
47 
48 	asm volatile ("MRS %0, CNTPCT_EL0" : "=r"(count));
49 	i = count;
50 	/* usec to count,24MHz */
51 	j = usec * 24;
52 	i += j;
53 	while (1) {
54 		asm volatile ("MRS %0, CNTPCT_EL0" : "=r"(count));
55 		if (count > i)
56 			break;
57 	}
58 }
59 #else
__udelay(unsigned long usec)60 void __weak __udelay(unsigned long usec)
61 {
62 	u32 nowl, nowu;
63 	u64 cur_count, end_count;
64 
65 	asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
66 	cur_count = (u64)nowu << 32 | nowl;
67 	/* usec to count,24MHz */
68 	end_count = usec * 24 + cur_count;
69 	while (1) {
70 		asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl),
71 			     "=r" (nowu));
72 		cur_count = (u64)nowu << 32 | nowl;
73 		if (cur_count > end_count)
74 			break;
75 	}
76 }
77 #endif /* CONFIG_ARM64 */
78 
udelay(unsigned long usec)79 void udelay(unsigned long usec)
80 {
81 	__udelay(usec);
82 }
83 
hang(void)84 void hang(void)
85 {
86         bootstage_error(BOOTSTAGE_ID_NEED_RESET);
87         for (;;)
88                 ;
89 }
90 #endif /* CONFIG_TPL_LIBGENERIC_SUPPORT */
91 
spl_boot_device(void)92 u32 spl_boot_device(void)
93 {
94 	return BOOT_DEVICE_BOOTROM;
95 }
96 
rockchip_stimer_init(void)97 __weak void rockchip_stimer_init(void)
98 {
99 #ifdef COUNTER_FREQUENCY
100 #ifndef CONFIG_ARM64
101 	asm volatile("mcr p15, 0, %0, c14, c0, 0"
102 		     : : "r"(COUNTER_FREQUENCY));
103 #elif CONFIG_IS_ENABLED(TINY_FRAMEWORK)
104 	/*
105 	 * For ARM64,generally initialize CNTFRQ in start.S,
106 	 * but if defined CONFIG_TPL_TINY_FRAMEWORK should skip start.S.
107 	 * So initialize CNTFRQ to 24MHz here.
108 	 */
109 	asm volatile("msr CNTFRQ_EL0, %0"
110 		     : : "r" (COUNTER_FREQUENCY));
111 #endif
112 #endif
113 	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
114 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
115 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
116 	writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
117 }
118 
arch_cpu_init(void)119 __weak int arch_cpu_init(void)
120 {
121 	return 0;
122 }
123 
board_init_f(ulong dummy)124 void board_init_f(ulong dummy)
125 {
126 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
127 	struct udevice *dev;
128 	int ret;
129 #endif
130 
131 	rockchip_stimer_init();
132 	arch_cpu_init();
133 #define EARLY_DEBUG
134 #ifdef EARLY_DEBUG
135 	/*
136 	 * Debug UART can be used from here if required:
137 	 *
138 	 * debug_uart_init();
139 	 * printch('a');
140 	 * printhex8(0x1234);
141 	 * printascii("string");
142 	 */
143 	debug_uart_init();
144 	printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
145 				U_BOOT_TIME ")\n");
146 #endif
147 
148 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
149 	ret = spl_early_init();
150 	if (ret) {
151 		debug("spl_early_init() failed: %d\n", ret);
152 		hang();
153 	}
154 #endif
155 
156 	/* Init ARM arch timer */
157 	timer_init();
158 
159 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
160 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
161 	if (ret) {
162 		printf("DRAM init failed: %d\n", ret);
163 		return;
164 	}
165 #else
166 	sdram_init();
167 #endif
168 
169 #if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT)
170 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
171 #endif
172 }
173 
174 #if !(defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK))
175 /* Place Holders */
board_init_r(gd_t * id,ulong dest_addr)176 void board_init_r(gd_t *id, ulong dest_addr)
177 {
178 	/*
179 	 * Function attribute is no-return
180 	 * This Function never executes
181 	 */
182 	while (1)
183 		;
184 }
185 #endif
186