Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | // SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2019 Rockchip Electronics Co., Ltd */ #include <binman_sym.h> #include <cpu_func.h> #include <debug_uart.h> #include <dm.h> #include <hang.h> #include <image.h> #include <init.h> #include <log.h> #include <mapmem.h> #include <ram.h> #include <spl.h> #include <asm/arch-rockchip/bootrom.h> #include <asm/arch-rockchip/timer.h> #include <asm/global_data.h> #include <asm/io.h> #include <linux/bitops.h> DECLARE_GLOBAL_DATA_PTR; int board_return_to_bootrom(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { back_to_bootrom(BROM_BOOT_NEXTSTAGE); return 0; } __weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { }; __weak u32 read_brom_bootsource_id(void) { u32 bootsource_id = readl(BROM_BOOTSOURCE_ID_ADDR); /* Re-map the raw value read from reg to an existing BROM_BOOTSOURCE * enum value to avoid having to create a larger boot_devices table. */ if (bootsource_id == 0x81) return BROM_BOOTSOURCE_USB; else if (bootsource_id > BROM_LAST_BOOTSOURCE) log_debug("Unknown bootsource %x\n", bootsource_id); return bootsource_id; } const char *board_spl_was_booted_from(void) { static u32 brom_bootsource_id_cache = BROM_BOOTSOURCE_UNKNOWN; u32 bootdevice_brom_id; const char *bootdevice_ofpath = NULL; if (brom_bootsource_id_cache != BROM_BOOTSOURCE_UNKNOWN) bootdevice_brom_id = brom_bootsource_id_cache; else bootdevice_brom_id = read_brom_bootsource_id(); if (bootdevice_brom_id < ARRAY_SIZE(boot_devices)) bootdevice_ofpath = boot_devices[bootdevice_brom_id]; if (bootdevice_ofpath) { brom_bootsource_id_cache = bootdevice_brom_id; debug("%s: brom_bootdevice_id %x maps to '%s'\n", __func__, bootdevice_brom_id, bootdevice_ofpath); } else { debug("%s: failed to resolve brom_bootdevice_id %x\n", __func__, bootdevice_brom_id); } return bootdevice_ofpath; } u32 spl_boot_device(void) { u32 boot_device = BOOT_DEVICE_MMC1; #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \ defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) || \ defined(CONFIG_TARGET_CHROMEBOOK_SPEEDY) || \ defined(CONFIG_TARGET_CHROMEBOOK_BOB) || \ defined(CONFIG_TARGET_CHROMEBOOK_KEVIN) return BOOT_DEVICE_SPI; #endif if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) return BOOT_DEVICE_BOOTROM; return boot_device; } u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) { return MMCSD_MODE_RAW; } __weak int board_early_init_f(void) { return 0; } __weak int arch_cpu_init(void) { return 0; } void board_init_f(ulong dummy) { int ret; board_early_init_f(); ret = spl_early_init(); if (ret) { printf("spl_early_init() failed: %d\n", ret); hang(); } arch_cpu_init(); rockchip_stimer_init(); #ifdef CONFIG_SYS_ARCH_TIMER /* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */ timer_init(); #endif #if !defined(CONFIG_TPL) || defined(CONFIG_SPL_RAM) debug("\nspl:init dram\n"); ret = dram_init(); if (ret) { printf("DRAM init failed: %d\n", ret); return; } gd->ram_top = gd->ram_base + get_effective_memsize(); gd->ram_top = board_get_usable_ram_top(gd->ram_size); if (IS_ENABLED(CONFIG_ARM64) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) { gd->relocaddr = gd->ram_top; arch_reserve_mmu(); enable_caches(); } #endif preloader_console_init(); } void spl_board_prepare_for_boot(void) { if (!IS_ENABLED(CONFIG_ARM64) || CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) return; cleanup_before_linux(); } #if CONFIG_IS_ENABLED(RAM_DEVICE) && IS_ENABLED(CONFIG_SPL_LOAD_FIT) binman_sym_declare_optional(ulong, payload, image_pos); binman_sym_declare_optional(ulong, payload, size); static ulong ramboot_load_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) { ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT, CONFIG_SPL_LOAD_FIT_ADDRESS); memcpy(buf, map_sysmem(addr + sector, 0), count); return count; } static int ramboot_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { struct legacy_img_hdr *header; ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT, CONFIG_SPL_LOAD_FIT_ADDRESS); ulong image_pos = binman_sym(ulong, payload, image_pos); ulong size = binman_sym(ulong, payload, size); if (addr == CFG_SYS_SDRAM_BASE || addr == CONFIG_SPL_TEXT_BASE) return -ENODEV; if (image_pos != BINMAN_SYM_MISSING && size != BINMAN_SYM_MISSING) { header = map_sysmem(image_pos, 0); if (image_get_magic(header) == FDT_MAGIC) { memmove(map_sysmem(addr, 0), header, size); memset(header, 0, sizeof(*header)); } } header = map_sysmem(addr, 0); if (image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; spl_load_init(&load, ramboot_load_read, NULL, 1); return spl_load_simple_fit(spl_image, &load, 0, header); } return -ENODEV; } /* Use priority and method name that sort before default spl_ram_load_image */ SPL_LOAD_IMAGE_METHOD("RAM", 0, BOOT_DEVICE_RAM, ramboot_load_image); #endif |