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 21 void puts(const char *str) 22 { 23 while (*str) 24 putc(*str++); 25 } 26 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 37 #ifdef CONFIG_ARM64 38 /* for ARM64,it don't have define timer_init and __udelay except lib/timer.c */ 39 int __weak timer_init(void) 40 { 41 return 0; 42 } 43 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 #endif /* CONFIG_ARM64 */ 60 61 void udelay(unsigned long usec) 62 { 63 __udelay(usec); 64 } 65 66 void hang(void) 67 { 68 bootstage_error(BOOTSTAGE_ID_NEED_RESET); 69 for (;;) 70 ; 71 } 72 #endif /* CONFIG_TPL_LIBGENERIC_SUPPORT */ 73 74 u32 spl_boot_device(void) 75 { 76 return BOOT_DEVICE_BOOTROM; 77 } 78 79 __weak void rockchip_stimer_init(void) 80 { 81 #ifndef CONFIG_ARM64 82 asm volatile("mcr p15, 0, %0, c14, c0, 0" 83 : : "r"(COUNTER_FREQUENCY)); 84 #elif CONFIG_IS_ENABLED(TINY_FRAMEWORK) 85 /* 86 * For ARM64,generally initialize CNTFRQ in start.S, 87 * but if defined CONFIG_TPL_TINY_FRAMEWORK should skip start.S. 88 * So initialize CNTFRQ to 24MHz here. 89 */ 90 asm volatile("msr CNTFRQ_EL0, %0" 91 : : "r" (COUNTER_FREQUENCY)); 92 #endif 93 writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 94 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE); 95 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4); 96 writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 97 } 98 99 __weak int arch_cpu_init(void) 100 { 101 return 0; 102 } 103 104 void board_init_f(ulong dummy) 105 { 106 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 107 struct udevice *dev; 108 int ret; 109 #endif 110 111 rockchip_stimer_init(); 112 arch_cpu_init(); 113 #define EARLY_DEBUG 114 #ifdef EARLY_DEBUG 115 /* 116 * Debug UART can be used from here if required: 117 * 118 * debug_uart_init(); 119 * printch('a'); 120 * printhex8(0x1234); 121 * printascii("string"); 122 */ 123 debug_uart_init(); 124 printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ 125 U_BOOT_TIME ")\n"); 126 #endif 127 128 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 129 ret = spl_early_init(); 130 if (ret) { 131 debug("spl_early_init() failed: %d\n", ret); 132 hang(); 133 } 134 #endif 135 136 /* Init ARM arch timer */ 137 timer_init(); 138 139 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 140 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 141 if (ret) { 142 printf("DRAM init failed: %d\n", ret); 143 return; 144 } 145 #else 146 sdram_init(); 147 #endif 148 149 #if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT) 150 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 151 #endif 152 } 153 154 #if !(defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)) 155 /* Place Holders */ 156 void board_init_r(gd_t *id, ulong dest_addr) 157 { 158 /* 159 * Function attribute is no-return 160 * This Function never executes 161 */ 162 while (1) 163 ; 164 } 165 #endif 166