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