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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | // SPDX-License-Identifier: GPL-2.0+ /* * boot-common.c * * Common bootmode functions for omap based boards * * Copyright (C) 2011, Texas Instruments, Incorporated - https://www.ti.com/ */ #include <ahci.h> #include <log.h> #include <dm/uclass.h> #include <fs_loader.h> #include <spl.h> #include <asm/global_data.h> #include <asm/omap_common.h> #include <asm/omap_sec_common.h> #include <asm/arch/omap.h> #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> #include <watchdog.h> #include <scsi.h> #include <i2c.h> #include <remoteproc.h> #include <image.h> DECLARE_GLOBAL_DATA_PTR; #define IPU1_LOAD_ADDR (0xa17ff000) #define MAX_REMOTECORE_BIN_SIZE (8 * 0x100000) #define IPU2_LOAD_ADDR (IPU1_LOAD_ADDR + MAX_REMOTECORE_BIN_SIZE) __weak u32 omap_sys_boot_device(void) { return BOOT_DEVICE_NONE; } void save_omap_boot_params(void) { u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS); struct omap_boot_parameters *omap_boot_params; int sys_boot_device = 0; u32 boot_device; u32 boot_mode; if ((boot_params < NON_SECURE_SRAM_START) || (boot_params > NON_SECURE_SRAM_END)) return; omap_boot_params = (struct omap_boot_parameters *)boot_params; boot_device = omap_boot_params->boot_device; boot_mode = MMCSD_MODE_UNDEFINED; /* Boot device */ #ifdef BOOT_DEVICE_NAND_I2C /* * Re-map NAND&I2C boot-device to the "normal" NAND boot-device. * Otherwise the SPL boot IF can't handle this device correctly. * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens * Draco leads to this boot-device passed to SPL from the BootROM. */ if (boot_device == BOOT_DEVICE_NAND_I2C) boot_device = BOOT_DEVICE_NAND; #endif #ifdef BOOT_DEVICE_QSPI_4 /* * We get different values for QSPI_1 and QSPI_4 being used, but * don't actually care about this difference. Rather than * mangle the later code, if we're coming in as QSPI_4 just * change to the QSPI_1 value. */ if (boot_device == BOOT_DEVICE_QSPI_4) boot_device = BOOT_DEVICE_SPI; #endif /* * When booting from peripheral booting, the boot device is not usable * as-is (unless there is support for it), so the boot device is instead * figured out using the SYS_BOOT pins. */ switch (boot_device) { #if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT) case BOOT_DEVICE_UART: sys_boot_device = 1; break; #endif #if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_STORAGE) case BOOT_DEVICE_USB: sys_boot_device = 1; break; #endif #if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USB_ETHER) case BOOT_DEVICE_USBETH: sys_boot_device = 1; break; #endif #if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH) case BOOT_DEVICE_CPGMAC: sys_boot_device = 1; break; #endif #if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU) case BOOT_DEVICE_DFU: sys_boot_device = 1; break; #endif } if (sys_boot_device) { boot_device = omap_sys_boot_device(); /* MMC raw mode will fallback to FS mode. */ if ((boot_device >= MMC_BOOT_DEVICES_START) && (boot_device <= MMC_BOOT_DEVICES_END)) boot_mode = MMCSD_MODE_RAW; } gd->arch.omap_boot_device = boot_device; /* Boot mode */ #ifdef CONFIG_OMAP34XX if ((boot_device >= MMC_BOOT_DEVICES_START) && (boot_device <= MMC_BOOT_DEVICES_END)) { switch (boot_device) { case BOOT_DEVICE_MMC1: boot_mode = MMCSD_MODE_FS; break; case BOOT_DEVICE_MMC2: boot_mode = MMCSD_MODE_RAW; break; } } #else /* * If the boot device was dynamically changed and doesn't match what * the bootrom initially booted, we cannot use the boot device * descriptor to figure out the boot mode. */ if ((boot_device == omap_boot_params->boot_device) && (boot_device >= MMC_BOOT_DEVICES_START) && (boot_device <= MMC_BOOT_DEVICES_END)) { boot_params = omap_boot_params->boot_device_descriptor; if ((boot_params < NON_SECURE_SRAM_START) || (boot_params > NON_SECURE_SRAM_END)) return; boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET)); if ((boot_params < NON_SECURE_SRAM_START) || (boot_params > NON_SECURE_SRAM_END)) return; boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET)); if (boot_mode != MMCSD_MODE_FS && boot_mode != MMCSD_MODE_RAW) #ifdef CONFIG_SUPPORT_EMMC_BOOT boot_mode = MMCSD_MODE_EMMCBOOT; #else boot_mode = MMCSD_MODE_UNDEFINED; #endif } #endif gd->arch.omap_boot_mode = boot_mode; #if !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX) /* CH flags */ gd->arch.omap_ch_flags = omap_boot_params->ch_flags; #endif } #ifdef CONFIG_XPL_BUILD u32 spl_boot_device(void) { return gd->arch.omap_boot_device; } u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) { return gd->arch.omap_boot_mode; } int load_firmware(char *name_fw, u32 *loadaddr) { struct udevice *fsdev; int size = 0; if (!CONFIG_IS_ENABLED(FS_LOADER)) return 0; if (!*loadaddr) return 0; if (!get_fs_loader(&fsdev)) { size = request_firmware_into_buf(fsdev, name_fw, (void *)*loadaddr, 0, 0); } return size; } void spl_boot_ipu(void) { int ret, size; u32 loadaddr = IPU1_LOAD_ADDR; if (!IS_ENABLED(CONFIG_XPL_BUILD) || !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) return; size = load_firmware("dra7-ipu1-fw.xem4", &loadaddr); if (size <= 0) { pr_err("Firmware loading failed\n"); goto skip_ipu1; } enable_ipu1_clocks(); ret = rproc_dev_init(0); if (ret) { debug("%s: IPU1 failed to initialize on rproc (%d)\n", __func__, ret); goto skip_ipu1; } ret = rproc_load(0, IPU1_LOAD_ADDR, 0x2000000); if (ret) { debug("%s: IPU1 failed to load on rproc (%d)\n", __func__, ret); goto skip_ipu1; } debug("Starting IPU1...\n"); ret = rproc_start(0); if (ret) debug("%s: IPU1 failed to start (%d)\n", __func__, ret); skip_ipu1: loadaddr = IPU2_LOAD_ADDR; size = load_firmware("dra7-ipu2-fw.xem4", &loadaddr); if (size <= 0) { pr_err("Firmware loading failed for ipu2\n"); return; } enable_ipu2_clocks(); ret = rproc_dev_init(1); if (ret) { debug("%s: IPU2 failed to initialize on rproc (%d)\n", __func__, ret); return; } ret = rproc_load(1, IPU2_LOAD_ADDR, 0x2000000); if (ret) { debug("%s: IPU2 failed to load on rproc (%d)\n", __func__, ret); return; } debug("Starting IPU2...\n"); ret = rproc_start(1); if (ret) debug("%s: IPU2 failed to start (%d)\n", __func__, ret); } void spl_soc_init(void) { /* Prepare console output */ preloader_console_init(); #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT) gpmc_init(); #endif #if defined(CONFIG_SPL_I2C) && !CONFIG_IS_ENABLED(DM_I2C) i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); #endif #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW) arch_misc_init(); #endif #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) hw_watchdog_init(); #endif if (IS_ENABLED(CONFIG_XPL_BUILD) && IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) spl_boot_ipu(); } void __noreturn jump_to_image(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); image_entry_noargs_t image_entry = (image_entry_noargs_t) spl_image->entry_point; u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS); debug("image entry point: 0x%lX\n", spl_image->entry_point); /* Pass the saved boot_params from rom code */ image_entry((u32 *)boot_params); } #endif #ifdef CONFIG_TI_SECURE_DEVICE void board_fit_image_post_process(const void *fit, int node, void **p_image, size_t *p_size) { secure_boot_verify_image(p_image, p_size); } static void tee_image_process(ulong tee_image, size_t tee_size) { secure_tee_install((u32)tee_image); } U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, tee_image_process); #endif #ifdef CONFIG_SPL_AM33XX_MMCSD_MULTIPLE #define AM335X_TRACE_VECTOR2 0x4030CE44 unsigned long arch_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect) { u32 bits = *(u32 *)AM335X_TRACE_VECTOR2; bits &= 0xf000; /* * The ROM code sets the "trial bit 3", bit 15, first, when * attempting offset 0, then "trial bit 2", bit 14, when * attempting offset 128K, and so on. If the tracing vector * has completely unexpected contents, fall back to the * raw_sect we were given. */ switch (bits) { case 0x8000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_0K; break; case 0xc000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_128K; break; case 0xe000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_256K; break; case 0xf000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_384K; break; default: printf("Warning: Unexpected trial bits 0x%04x in trace vector 2, falling back to 0x%lx\n", bits, raw_sect); } return raw_sect; } #endif |