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