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