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 <boot_rkimg.h> 9 #include <debug_uart.h> 10 #include <dm.h> 11 #include <key.h> 12 #include <misc.h> 13 #include <ram.h> 14 #include <spl.h> 15 #include <optee_include/OpteeClientInterface.h> 16 #include <asm/arch/bootrom.h> 17 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 18 #include <asm/arch/rk_atags.h> 19 #endif 20 #include <asm/arch/sdram.h> 21 #include <asm/arch/boot_mode.h> 22 #include <asm/arch-rockchip/sys_proto.h> 23 #include <asm/io.h> 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 void board_return_to_bootrom(void) 28 { 29 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 30 } 31 32 __weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { 33 }; 34 35 const char *board_spl_was_booted_from(void) 36 { 37 u32 bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR); 38 const char *bootdevice_ofpath = NULL; 39 40 if (bootdevice_brom_id < ARRAY_SIZE(boot_devices)) 41 bootdevice_ofpath = boot_devices[bootdevice_brom_id]; 42 43 if (bootdevice_ofpath) 44 debug("%s: brom_bootdevice_id %x maps to '%s'\n", 45 __func__, bootdevice_brom_id, bootdevice_ofpath); 46 else 47 debug("%s: failed to resolve brom_bootdevice_id %x\n", 48 __func__, bootdevice_brom_id); 49 50 return bootdevice_ofpath; 51 } 52 53 u32 spl_boot_device(void) 54 { 55 u32 boot_device = BOOT_DEVICE_MMC1; 56 57 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ 58 defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \ 59 defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) 60 return BOOT_DEVICE_SPI; 61 #endif 62 if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) 63 return BOOT_DEVICE_BOOTROM; 64 65 return boot_device; 66 } 67 68 u32 spl_boot_mode(const u32 boot_device) 69 { 70 return MMCSD_MODE_RAW; 71 } 72 73 __weak void rockchip_stimer_init(void) 74 { 75 /* If Timer already enabled, don't re-init it */ 76 u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 77 if ( reg & 0x1 ) 78 return; 79 #ifndef CONFIG_ARM64 80 asm volatile("mcr p15, 0, %0, c14, c0, 0" 81 : : "r"(COUNTER_FREQUENCY)); 82 #endif 83 writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 84 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE); 85 writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4); 86 writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10); 87 } 88 89 __weak int arch_cpu_init(void) 90 { 91 return 0; 92 } 93 94 __weak int rk_board_init_f(void) 95 { 96 return 0; 97 } 98 99 #ifndef CONFIG_SPL_LIBGENERIC_SUPPORT 100 void udelay(unsigned long usec) 101 { 102 __udelay(usec); 103 } 104 105 void hang(void) 106 { 107 bootstage_error(BOOTSTAGE_ID_NEED_RESET); 108 for (;;) 109 ; 110 } 111 112 /** 113 * memset - Fill a region of memory with the given value 114 * @s: Pointer to the start of the area. 115 * @c: The byte to fill the area with 116 * @count: The size of the area. 117 * 118 * Do not use memset() to access IO space, use memset_io() instead. 119 */ 120 void *memset(void *s, int c, size_t count) 121 { 122 unsigned long *sl = (unsigned long *)s; 123 char *s8; 124 125 #if !CONFIG_IS_ENABLED(TINY_MEMSET) 126 unsigned long cl = 0; 127 int i; 128 129 /* do it one word at a time (32 bits or 64 bits) while possible */ 130 if (((ulong)s & (sizeof(*sl) - 1)) == 0) { 131 for (i = 0; i < sizeof(*sl); i++) { 132 cl <<= 8; 133 cl |= c & 0xff; 134 } 135 while (count >= sizeof(*sl)) { 136 *sl++ = cl; 137 count -= sizeof(*sl); 138 } 139 } 140 #endif /* fill 8 bits at a time */ 141 s8 = (char *)sl; 142 while (count--) 143 *s8++ = c; 144 145 return s; 146 } 147 #endif 148 149 void board_init_f(ulong dummy) 150 { 151 #ifdef CONFIG_SPL_FRAMEWORK 152 int ret; 153 #if !defined(CONFIG_SUPPORT_TPL) 154 struct udevice *dev; 155 #endif 156 #endif 157 158 rockchip_stimer_init(); 159 #define EARLY_UART 160 #if defined(EARLY_UART) && defined(CONFIG_DEBUG_UART) 161 /* 162 * Debug UART can be used from here if required: 163 * 164 * debug_uart_init(); 165 * printch('a'); 166 * printhex8(0x1234); 167 * printascii("string"); 168 */ 169 debug_uart_init(); 170 printascii("U-Boot SPL board init"); 171 #endif 172 173 #ifdef CONFIG_SPL_FRAMEWORK 174 ret = spl_early_init(); 175 if (ret) { 176 printf("spl_early_init() failed: %d\n", ret); 177 hang(); 178 } 179 #if !defined(CONFIG_SUPPORT_TPL) 180 debug("\nspl:init dram\n"); 181 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 182 if (ret) { 183 printf("DRAM init failed: %d\n", ret); 184 return; 185 } 186 #endif 187 preloader_console_init(); 188 #else 189 /* Some SoCs like rk3036 does not use any frame work */ 190 sdram_init(); 191 #endif 192 193 arch_cpu_init(); 194 rk_board_init_f(); 195 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) 196 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 197 #endif 198 199 } 200 201 #ifdef CONFIG_SPL_LOAD_FIT 202 int board_fit_config_name_match(const char *name) 203 { 204 /* Just empty function now - can't decide what to choose */ 205 debug("%s: %s\n", __func__, name); 206 207 return 0; 208 } 209 #endif 210 211 #ifdef CONFIG_SPL_BOARD_INIT 212 __weak int rk_spl_board_init(void) 213 { 214 return 0; 215 } 216 217 static int setup_led(void) 218 { 219 #ifdef CONFIG_SPL_LED 220 struct udevice *dev; 221 char *led_name; 222 int ret; 223 224 led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led"); 225 if (!led_name) 226 return 0; 227 ret = led_get_by_label(led_name, &dev); 228 if (ret) { 229 debug("%s: get=%d\n", __func__, ret); 230 return ret; 231 } 232 ret = led_set_on(dev, 1); 233 if (ret) 234 return ret; 235 #endif 236 237 return 0; 238 } 239 240 void spl_board_init(void) 241 { 242 int ret; 243 244 ret = setup_led(); 245 246 if (ret) { 247 debug("LED ret=%d\n", ret); 248 hang(); 249 } 250 251 rk_spl_board_init(); 252 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) 253 back_to_bootrom(BROM_BOOT_NEXTSTAGE); 254 #endif 255 return; 256 } 257 #endif 258 259 void spl_perform_fixups(struct spl_image_info *spl_image) 260 { 261 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 262 atags_set_bootdev_by_spl_bootdevice(spl_image->boot_device); 263 #endif 264 return; 265 } 266 267 #ifdef CONFIG_SPL_KERNEL_BOOT 268 static int spl_rockchip_dnl_key_pressed(void) 269 { 270 #if defined(CONFIG_SPL_INPUT) 271 return key_read(KEY_VOLUMEUP); 272 #else 273 return 0; 274 #endif 275 } 276 277 void spl_next_stage(struct spl_image_info *spl) 278 { 279 uint32_t reg_boot_mode; 280 281 if (spl_rockchip_dnl_key_pressed()) { 282 spl->next_stage = SPL_NEXT_STAGE_UBOOT; 283 return; 284 } 285 286 reg_boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG); 287 switch (reg_boot_mode) { 288 case BOOT_COLD: 289 case BOOT_PANIC: 290 case BOOT_WATCHDOG: 291 case BOOT_NORMAL: 292 case BOOT_RECOVERY: 293 spl->next_stage = SPL_NEXT_STAGE_KERNEL; 294 break; 295 default: 296 spl->next_stage = SPL_NEXT_STAGE_UBOOT; 297 } 298 } 299 #endif 300 301 #ifdef CONFIG_SPL_FIT_LOAD_KERNEL 302 const char *spl_kernel_partition(struct spl_image_info *spl, 303 struct spl_load_info *info) 304 { 305 struct bootloader_message *bmsg = NULL; 306 u32 boot_mode; 307 int ret, cnt; 308 u32 sector = 0; 309 310 #ifdef CONFIG_SPL_LIBDISK_SUPPORT 311 disk_partition_t part_info; 312 313 ret = part_get_info_by_name(info->dev, PART_MISC, &part_info); 314 if (ret >= 0) 315 sector = part_info.start; 316 #else 317 sector = CONFIG_SPL_MISC_SECTOR; 318 #endif 319 if (sector) { 320 cnt = DIV_ROUND_UP(sizeof(*bmsg), info->bl_len); 321 bmsg = memalign(ARCH_DMA_MINALIGN, cnt * info->bl_len); 322 ret = info->read(info, sector + BCB_MESSAGE_BLK_OFFSET, 323 cnt, bmsg); 324 if (ret == cnt && !strcmp(bmsg->command, "boot-recovery")) { 325 free(bmsg); 326 return PART_RECOVERY; 327 } else { 328 free(bmsg); 329 } 330 } 331 332 boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG); 333 334 return (boot_mode == BOOT_RECOVERY) ? PART_RECOVERY : PART_BOOT; 335 } 336 #endif 337 338 void spl_hang_reset(void) 339 { 340 printf("# Reset the board to bootrom #\n"); 341 #if defined(CONFIG_SPL_SYSRESET) && defined(CONFIG_SPL_DRIVERS_MISC_SUPPORT) 342 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); 343 do_reset(NULL, 0, 0, NULL); 344 #endif 345 } 346 347 #ifdef CONFIG_SPL_FIT_ROLLBACK_PROTECT 348 int fit_read_otp_rollback_index(uint32_t fit_index, uint32_t *otp_index) 349 { 350 int ret = 0; 351 352 *otp_index = 0; 353 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2) 354 struct udevice *dev; 355 u32 index, i, otp_version; 356 u32 bit_count; 357 358 dev = misc_otp_get_device(OTP_S); 359 if (!dev) 360 return -ENODEV; 361 362 otp_version = 0; 363 for (i = 0; i < OTP_UBOOT_ROLLBACK_WORDS; i++) { 364 if (misc_otp_read(dev, 4 * 365 (OTP_UBOOT_ROLLBACK_OFFSET + i), 366 &index, 367 4)) { 368 printf("Can't read rollback index\n"); 369 return -EIO; 370 } 371 bit_count = fls(index); 372 otp_version += bit_count; 373 } 374 *otp_index = otp_version; 375 #endif 376 377 return ret; 378 } 379 380 static int fit_write_otp_rollback_index(u32 fit_index) 381 { 382 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2) 383 struct udevice *dev; 384 u32 index, i, otp_index; 385 386 if (!fit_index) 387 return 0; 388 389 if (fit_index > OTP_UBOOT_ROLLBACK_WORDS * 32) 390 return -EINVAL; 391 392 dev = misc_otp_get_device(OTP_S); 393 if (!dev) 394 return -ENODEV; 395 396 if (fit_read_otp_rollback_index(fit_index, &otp_index)) 397 return -EIO; 398 399 if (otp_index < fit_index) { 400 /* Write new SW version to otp */ 401 for (i = 0; i < OTP_UBOOT_ROLLBACK_WORDS; i++) { 402 /* convert to base-1 representation */ 403 index = 0xffffffff >> (OTP_ALL_ONES_NUM_BITS - 404 min(fit_index, (u32)OTP_ALL_ONES_NUM_BITS)); 405 fit_index -= min(fit_index, 406 (u32)OTP_ALL_ONES_NUM_BITS); 407 if (index) { 408 if (misc_otp_write(dev, 4 * 409 (OTP_UBOOT_ROLLBACK_OFFSET + i), 410 &index, 411 4)) { 412 printf("Can't write rollback index\n"); 413 return -EIO; 414 } 415 } 416 } 417 } 418 #endif 419 420 return 0; 421 } 422 #endif 423 424 int spl_board_prepare_for_jump(struct spl_image_info *spl_image) 425 { 426 #ifdef CONFIG_SPL_FIT_ROLLBACK_PROTECT 427 int ret; 428 429 ret = fit_write_otp_rollback_index(gd->rollback_index); 430 if (ret) { 431 panic("Failed to write fit rollback index %d, ret=%d", 432 gd->rollback_index, ret); 433 } 434 #endif 435 436 #ifdef CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS 437 misc_decompress_cleanup(); 438 #endif 439 return 0; 440 } 441