1 /* 2 * (C) Copyright 2018 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 <ram.h> 11 #include <spl.h> 12 #include <asm/arch/bootrom.h> 13 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 14 #include <asm/arch/rk_atags.h> 15 #endif 16 #include <asm/arch/sdram.h> 17 #include <asm/arch-rockchip/sys_proto.h> 18 #include <asm/io.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 void board_return_to_bootrom(void) 23 { 24 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 25 } 26 27 __weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { 28 }; 29 30 const char *board_spl_was_booted_from(void) 31 { 32 u32 bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR); 33 const char *bootdevice_ofpath = NULL; 34 35 if (bootdevice_brom_id < ARRAY_SIZE(boot_devices)) 36 bootdevice_ofpath = boot_devices[bootdevice_brom_id]; 37 38 if (bootdevice_ofpath) 39 debug("%s: brom_bootdevice_id %x maps to '%s'\n", 40 __func__, bootdevice_brom_id, bootdevice_ofpath); 41 else 42 debug("%s: failed to resolve brom_bootdevice_id %x\n", 43 __func__, bootdevice_brom_id); 44 45 return bootdevice_ofpath; 46 } 47 48 u32 spl_boot_device(void) 49 { 50 u32 boot_device = BOOT_DEVICE_MMC1; 51 52 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ 53 defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \ 54 defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) 55 return BOOT_DEVICE_SPI; 56 #endif 57 if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) 58 return BOOT_DEVICE_BOOTROM; 59 60 return boot_device; 61 } 62 63 u32 spl_boot_mode(const u32 boot_device) 64 { 65 return MMCSD_MODE_RAW; 66 } 67 68 __weak void rockchip_stimer_init(void) 69 { 70 /* If Timer already enabled, don't re-init it */ 71 u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 72 if ( reg & 0x1 ) 73 return; 74 #ifndef CONFIG_ARM64 75 asm volatile("mcr p15, 0, %0, c14, c0, 0" 76 : : "r"(COUNTER_FREQUENCY)); 77 #endif 78 writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 79 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE); 80 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4); 81 writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 82 } 83 84 __weak int arch_cpu_init(void) 85 { 86 return 0; 87 } 88 89 __weak int rk_board_init_f(void) 90 { 91 return 0; 92 } 93 94 #ifndef CONFIG_SPL_LIBGENERIC_SUPPORT 95 void udelay(unsigned long usec) 96 { 97 __udelay(usec); 98 } 99 100 void hang(void) 101 { 102 bootstage_error(BOOTSTAGE_ID_NEED_RESET); 103 for (;;) 104 ; 105 } 106 107 /** 108 * memset - Fill a region of memory with the given value 109 * @s: Pointer to the start of the area. 110 * @c: The byte to fill the area with 111 * @count: The size of the area. 112 * 113 * Do not use memset() to access IO space, use memset_io() instead. 114 */ 115 void *memset(void *s, int c, size_t count) 116 { 117 unsigned long *sl = (unsigned long *)s; 118 char *s8; 119 120 #if !CONFIG_IS_ENABLED(TINY_MEMSET) 121 unsigned long cl = 0; 122 int i; 123 124 /* do it one word at a time (32 bits or 64 bits) while possible */ 125 if (((ulong)s & (sizeof(*sl) - 1)) == 0) { 126 for (i = 0; i < sizeof(*sl); i++) { 127 cl <<= 8; 128 cl |= c & 0xff; 129 } 130 while (count >= sizeof(*sl)) { 131 *sl++ = cl; 132 count -= sizeof(*sl); 133 } 134 } 135 #endif /* fill 8 bits at a time */ 136 s8 = (char *)sl; 137 while (count--) 138 *s8++ = c; 139 140 return s; 141 } 142 #endif 143 144 void board_init_f(ulong dummy) 145 { 146 #ifdef CONFIG_SPL_FRAMEWORK 147 int ret; 148 #if !defined(CONFIG_SUPPORT_TPL) 149 struct udevice *dev; 150 #endif 151 #endif 152 153 rockchip_stimer_init(); 154 #define EARLY_UART 155 #if defined(EARLY_UART) && defined(CONFIG_DEBUG_UART) 156 /* 157 * Debug UART can be used from here if required: 158 * 159 * debug_uart_init(); 160 * printch('a'); 161 * printhex8(0x1234); 162 * printascii("string"); 163 */ 164 debug_uart_init(); 165 printascii("U-Boot SPL board init"); 166 #endif 167 168 #ifdef CONFIG_SPL_FRAMEWORK 169 ret = spl_early_init(); 170 if (ret) { 171 printf("spl_early_init() failed: %d\n", ret); 172 hang(); 173 } 174 #if !defined(CONFIG_SUPPORT_TPL) 175 debug("\nspl:init dram\n"); 176 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 177 if (ret) { 178 printf("DRAM init failed: %d\n", ret); 179 return; 180 } 181 #endif 182 preloader_console_init(); 183 #else 184 /* Some SoCs like rk3036 does not use any frame work */ 185 sdram_init(); 186 #endif 187 188 arch_cpu_init(); 189 rk_board_init_f(); 190 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) 191 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 192 #endif 193 194 } 195 196 #ifdef CONFIG_SPL_LOAD_FIT 197 int board_fit_config_name_match(const char *name) 198 { 199 /* Just empty function now - can't decide what to choose */ 200 debug("%s: %s\n", __func__, name); 201 202 return 0; 203 } 204 #endif 205 206 #ifdef CONFIG_SPL_BOARD_INIT 207 __weak int rk_spl_board_init(void) 208 { 209 return 0; 210 } 211 212 static int setup_led(void) 213 { 214 #ifdef CONFIG_SPL_LED 215 struct udevice *dev; 216 char *led_name; 217 int ret; 218 219 led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led"); 220 if (!led_name) 221 return 0; 222 ret = led_get_by_label(led_name, &dev); 223 if (ret) { 224 debug("%s: get=%d\n", __func__, ret); 225 return ret; 226 } 227 ret = led_set_on(dev, 1); 228 if (ret) 229 return ret; 230 #endif 231 232 return 0; 233 } 234 235 void spl_board_init(void) 236 { 237 int ret; 238 239 ret = setup_led(); 240 241 if (ret) { 242 debug("LED ret=%d\n", ret); 243 hang(); 244 } 245 246 rk_spl_board_init(); 247 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) 248 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 249 #endif 250 return; 251 } 252 #endif 253 254 void spl_perform_fixups(struct spl_image_info *spl_image) 255 { 256 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 257 atags_set_bootdev_by_spl_bootdevice(spl_image->boot_device); 258 #endif 259 return; 260 } 261 262