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 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 */ 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 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 79 void udelay(unsigned long usec) 80 { 81 __udelay(usec); 82 } 83 84 void hang(void) 85 { 86 bootstage_error(BOOTSTAGE_ID_NEED_RESET); 87 for (;;) 88 ; 89 } 90 #endif /* CONFIG_TPL_LIBGENERIC_SUPPORT */ 91 92 u32 spl_boot_device(void) 93 { 94 return BOOT_DEVICE_BOOTROM; 95 } 96 97 __weak void rockchip_stimer_init(void) 98 { 99 #ifndef CONFIG_ARM64 100 asm volatile("mcr p15, 0, %0, c14, c0, 0" 101 : : "r"(COUNTER_FREQUENCY)); 102 #elif CONFIG_IS_ENABLED(TINY_FRAMEWORK) 103 /* 104 * For ARM64,generally initialize CNTFRQ in start.S, 105 * but if defined CONFIG_TPL_TINY_FRAMEWORK should skip start.S. 106 * So initialize CNTFRQ to 24MHz here. 107 */ 108 asm volatile("msr CNTFRQ_EL0, %0" 109 : : "r" (COUNTER_FREQUENCY)); 110 #endif 111 writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 112 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE); 113 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4); 114 writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 115 } 116 117 __weak int arch_cpu_init(void) 118 { 119 return 0; 120 } 121 122 void board_init_f(ulong dummy) 123 { 124 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 125 struct udevice *dev; 126 int ret; 127 #endif 128 129 rockchip_stimer_init(); 130 arch_cpu_init(); 131 #define EARLY_DEBUG 132 #ifdef EARLY_DEBUG 133 /* 134 * Debug UART can be used from here if required: 135 * 136 * debug_uart_init(); 137 * printch('a'); 138 * printhex8(0x1234); 139 * printascii("string"); 140 */ 141 debug_uart_init(); 142 printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ 143 U_BOOT_TIME ")\n"); 144 #endif 145 146 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 147 ret = spl_early_init(); 148 if (ret) { 149 debug("spl_early_init() failed: %d\n", ret); 150 hang(); 151 } 152 #endif 153 154 /* Init ARM arch timer */ 155 timer_init(); 156 157 #if defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 158 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 159 if (ret) { 160 printf("DRAM init failed: %d\n", ret); 161 return; 162 } 163 #else 164 sdram_init(); 165 #endif 166 167 #if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT) 168 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 169 #endif 170 } 171 172 #if !(defined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)) 173 /* Place Holders */ 174 void board_init_r(gd_t *id, ulong dest_addr) 175 { 176 /* 177 * Function attribute is no-return 178 * This Function never executes 179 */ 180 while (1) 181 ; 182 } 183 #endif 184