blob: d104f23b3e23e9348af032b286c856079d9cc77a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Chandan Nath77a73fe2012-01-09 20:38:59 +00002/*
3 * boot-common.c
4 *
5 * Common bootmode functions for omap based boards
6 *
7 * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
Chandan Nath77a73fe2012-01-09 20:38:59 +00008 */
9
10#include <common.h>
Dmitry Lifshitz29211a02014-12-15 16:02:58 +020011#include <ahci.h>
Simon Glass0f2af882020-05-10 11:40:05 -060012#include <log.h>
Keerthy0efb06d2022-01-27 13:16:52 +010013#include <dm/uclass.h>
14#include <fs_loader.h>
Tom Rini28591df2012-08-13 12:03:19 -070015#include <spl.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060016#include <asm/global_data.h>
Chandan Nath77a73fe2012-01-09 20:38:59 +000017#include <asm/omap_common.h>
Andrew Davisb3f0f832022-10-20 12:12:19 -050018#include <asm/omap_sec_common.h>
Chandan Nath77a73fe2012-01-09 20:38:59 +000019#include <asm/arch/omap.h>
Tom Rinia0b9fa52012-08-14 10:25:15 -070020#include <asm/arch/mmc_host_def.h>
Ilya Yanok741c57f2012-11-06 13:06:28 +000021#include <asm/arch/sys_proto.h>
Tom Rini303bfe82013-10-01 12:32:04 -040022#include <watchdog.h>
Dmitry Lifshitz29211a02014-12-15 16:02:58 +020023#include <scsi.h>
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020024#include <i2c.h>
Keerthy0efb06d2022-01-27 13:16:52 +010025#include <remoteproc.h>
Andrew Davisb3f0f832022-10-20 12:12:19 -050026#include <image.h>
Chandan Nath77a73fe2012-01-09 20:38:59 +000027
SRICHARAN R3f30b0a2013-04-24 00:41:24 +000028DECLARE_GLOBAL_DATA_PTR;
Chandan Nath77a73fe2012-01-09 20:38:59 +000029
Keerthy0efb06d2022-01-27 13:16:52 +010030#define IPU1_LOAD_ADDR (0xa17ff000)
31#define MAX_REMOTECORE_BIN_SIZE (8 * 0x100000)
32#define IPU2_LOAD_ADDR (IPU1_LOAD_ADDR + MAX_REMOTECORE_BIN_SIZE)
33
Paul Kocialkowski062fbb62015-07-15 16:02:23 +020034__weak u32 omap_sys_boot_device(void)
35{
36 return BOOT_DEVICE_NONE;
37}
38
Tom Rini51df26c2013-05-31 12:31:59 -040039void save_omap_boot_params(void)
40{
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020041 u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
42 struct omap_boot_parameters *omap_boot_params;
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +020043 int sys_boot_device = 0;
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020044 u32 boot_device;
45 u32 boot_mode;
Tom Rini51df26c2013-05-31 12:31:59 -040046
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020047 if ((boot_params < NON_SECURE_SRAM_START) ||
48 (boot_params > NON_SECURE_SRAM_END))
Tom Rini51df26c2013-05-31 12:31:59 -040049 return;
50
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020051 omap_boot_params = (struct omap_boot_parameters *)boot_params;
Stefan Roese0f3a4802014-11-12 11:57:33 +010052
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020053 boot_device = omap_boot_params->boot_device;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +020054 boot_mode = MMCSD_MODE_UNDEFINED;
55
56 /* Boot device */
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020057
58#ifdef BOOT_DEVICE_NAND_I2C
Stefan Roese0f3a4802014-11-12 11:57:33 +010059 /*
60 * Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
61 * Otherwise the SPL boot IF can't handle this device correctly.
62 * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens
63 * Draco leads to this boot-device passed to SPL from the BootROM.
64 */
65 if (boot_device == BOOT_DEVICE_NAND_I2C)
66 boot_device = BOOT_DEVICE_NAND;
67#endif
Paul Kocialkowskib16d6d52015-07-15 16:02:21 +020068#ifdef BOOT_DEVICE_QSPI_4
Tom Rini560ef452014-04-03 07:52:56 -040069 /*
70 * We get different values for QSPI_1 and QSPI_4 being used, but
71 * don't actually care about this difference. Rather than
72 * mangle the later code, if we're coming in as QSPI_4 just
73 * change to the QSPI_1 value.
74 */
Paul Kocialkowskib16d6d52015-07-15 16:02:21 +020075 if (boot_device == BOOT_DEVICE_QSPI_4)
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020076 boot_device = BOOT_DEVICE_SPI;
77#endif
Tom Rinid00abb12017-06-15 13:57:00 -040078#ifdef CONFIG_TI816X
79 /*
80 * On PG2.0 and later TI816x the values we get when booting are not the
81 * same as on PG1.0, which is what the defines are based on. Update
82 * them as needed.
83 */
84 if (get_cpu_rev() != 1) {
85 if (boot_device == 0x05) {
86 omap_boot_params->boot_device = BOOT_DEVICE_NAND;
87 boot_device = BOOT_DEVICE_NAND;
88 }
89 if (boot_device == 0x08) {
90 omap_boot_params->boot_device = BOOT_DEVICE_MMC1;
91 boot_device = BOOT_DEVICE_MMC1;
92 }
93 }
94#endif
Paul Kocialkowski062fbb62015-07-15 16:02:23 +020095 /*
96 * When booting from peripheral booting, the boot device is not usable
97 * as-is (unless there is support for it), so the boot device is instead
98 * figured out using the SYS_BOOT pins.
99 */
100 switch (boot_device) {
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200101#if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT)
102 case BOOT_DEVICE_UART:
103 sys_boot_device = 1;
104 break;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200105#endif
Abel Vesa5ea11ba52019-02-01 16:40:07 +0000106#if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_STORAGE)
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200107 case BOOT_DEVICE_USB:
108 sys_boot_device = 1;
109 break;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200110#endif
Faiz Abbasc01553b2018-02-16 21:17:44 +0530111#if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USB_ETHER)
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200112 case BOOT_DEVICE_USBETH:
113 sys_boot_device = 1;
114 break;
115#endif
Simon Glasse5cd9a42021-07-10 21:14:26 -0600116#if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH)
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200117 case BOOT_DEVICE_CPGMAC:
118 sys_boot_device = 1;
119 break;
120#endif
Andrew F. Davis6d932e62019-01-17 13:43:02 -0600121#if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU)
B, Ravi2fb19df2016-07-28 17:39:17 +0530122 case BOOT_DEVICE_DFU:
123 sys_boot_device = 1;
124 break;
125#endif
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200126 }
127
128 if (sys_boot_device) {
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200129 boot_device = omap_sys_boot_device();
130
131 /* MMC raw mode will fallback to FS mode. */
132 if ((boot_device >= MMC_BOOT_DEVICES_START) &&
133 (boot_device <= MMC_BOOT_DEVICES_END))
134 boot_mode = MMCSD_MODE_RAW;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200135 }
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200136
137 gd->arch.omap_boot_device = boot_device;
138
139 /* Boot mode */
140
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200141#ifdef CONFIG_OMAP34XX
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200142 if ((boot_device >= MMC_BOOT_DEVICES_START) &&
143 (boot_device <= MMC_BOOT_DEVICES_END)) {
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200144 switch (boot_device) {
145 case BOOT_DEVICE_MMC1:
Tom Rini9266bf42016-05-02 10:52:51 -0400146 boot_mode = MMCSD_MODE_FS;
147 break;
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200148 case BOOT_DEVICE_MMC2:
149 boot_mode = MMCSD_MODE_RAW;
150 break;
151 }
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200152 }
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200153#else
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200154 /*
155 * If the boot device was dynamically changed and doesn't match what
156 * the bootrom initially booted, we cannot use the boot device
157 * descriptor to figure out the boot mode.
158 */
159 if ((boot_device == omap_boot_params->boot_device) &&
160 (boot_device >= MMC_BOOT_DEVICES_START) &&
161 (boot_device <= MMC_BOOT_DEVICES_END)) {
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200162 boot_params = omap_boot_params->boot_device_descriptor;
163 if ((boot_params < NON_SECURE_SRAM_START) ||
164 (boot_params > NON_SECURE_SRAM_END))
165 return;
166
167 boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET));
168 if ((boot_params < NON_SECURE_SRAM_START) ||
169 (boot_params > NON_SECURE_SRAM_END))
170 return;
171
172 boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET));
173
174 if (boot_mode != MMCSD_MODE_FS &&
175 boot_mode != MMCSD_MODE_RAW)
176#ifdef CONFIG_SUPPORT_EMMC_BOOT
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200177 boot_mode = MMCSD_MODE_EMMCBOOT;
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200178#else
179 boot_mode = MMCSD_MODE_UNDEFINED;
180#endif
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200181 }
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200182#endif
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200183
184 gd->arch.omap_boot_mode = boot_mode;
185
Tom Rini428deb32022-12-02 16:42:41 -0500186#if !defined(CONFIG_TI816X) && \
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200187 !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX)
188
189 /* CH flags */
190
191 gd->arch.omap_ch_flags = omap_boot_params->ch_flags;
Tom Rini560ef452014-04-03 07:52:56 -0400192#endif
Tom Rini51df26c2013-05-31 12:31:59 -0400193}
194
Chandan Nath77a73fe2012-01-09 20:38:59 +0000195#ifdef CONFIG_SPL_BUILD
Tom Rini0be93ff2012-08-13 12:53:23 -0700196u32 spl_boot_device(void)
Chandan Nath77a73fe2012-01-09 20:38:59 +0000197{
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200198 return gd->arch.omap_boot_device;
Chandan Nath77a73fe2012-01-09 20:38:59 +0000199}
200
Andre Przywara3cb12ef2021-07-12 11:06:49 +0100201u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
Chandan Nath77a73fe2012-01-09 20:38:59 +0000202{
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200203 return gd->arch.omap_boot_mode;
Chandan Nath77a73fe2012-01-09 20:38:59 +0000204}
Tom Rinia0b9fa52012-08-14 10:25:15 -0700205
Keerthy0efb06d2022-01-27 13:16:52 +0100206int load_firmware(char *name_fw, u32 *loadaddr)
207{
208 struct udevice *fsdev;
209 int size = 0;
210
211 if (!IS_ENABLED(CONFIG_FS_LOADER))
212 return 0;
213
214 if (!*loadaddr)
215 return 0;
216
217 if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
218 size = request_firmware_into_buf(fsdev, name_fw,
219 (void *)*loadaddr, 0, 0);
220 }
221
222 return size;
223}
224
225void spl_boot_ipu(void)
226{
227 int ret, size;
228 u32 loadaddr = IPU1_LOAD_ADDR;
229
230 if (!IS_ENABLED(CONFIG_SPL_BUILD) ||
231 !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
232 return;
233
234 size = load_firmware("dra7-ipu1-fw.xem4", &loadaddr);
235 if (size <= 0) {
236 pr_err("Firmware loading failed\n");
237 goto skip_ipu1;
238 }
239
240 enable_ipu1_clocks();
241 ret = rproc_dev_init(0);
242 if (ret) {
243 debug("%s: IPU1 failed to initialize on rproc (%d)\n",
244 __func__, ret);
245 goto skip_ipu1;
246 }
247
248 ret = rproc_load(0, IPU1_LOAD_ADDR, 0x2000000);
249 if (ret) {
250 debug("%s: IPU1 failed to load on rproc (%d)\n", __func__,
251 ret);
252 goto skip_ipu1;
253 }
254
255 debug("Starting IPU1...\n");
256
257 ret = rproc_start(0);
258 if (ret)
259 debug("%s: IPU1 failed to start (%d)\n", __func__, ret);
260
261skip_ipu1:
262 loadaddr = IPU2_LOAD_ADDR;
263 size = load_firmware("dra7-ipu2-fw.xem4", &loadaddr);
264 if (size <= 0) {
265 pr_err("Firmware loading failed for ipu2\n");
266 return;
267 }
268
269 enable_ipu2_clocks();
270 ret = rproc_dev_init(1);
271 if (ret) {
272 debug("%s: IPU2 failed to initialize on rproc (%d)\n", __func__,
273 ret);
274 return;
275 }
276
277 ret = rproc_load(1, IPU2_LOAD_ADDR, 0x2000000);
278 if (ret) {
279 debug("%s: IPU2 failed to load on rproc (%d)\n", __func__,
280 ret);
281 return;
282 }
283
284 debug("Starting IPU2...\n");
285
286 ret = rproc_start(1);
287 if (ret)
288 debug("%s: IPU2 failed to start (%d)\n", __func__, ret);
289}
290
Tom Rini9e0c2602012-08-14 12:26:08 -0700291void spl_board_init(void)
292{
Tom Rinic95d6c42014-12-19 16:53:24 -0500293 /* Prepare console output */
294 preloader_console_init();
Samuel Hollandb03e6662020-05-07 18:08:10 -0500295
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200296#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
Tom Rini9e0c2602012-08-14 12:26:08 -0700297 gpmc_init();
298#endif
Simon Glassbccfc2e2021-07-10 21:14:36 -0600299#if defined(CONFIG_SPL_I2C) && !CONFIG_IS_ENABLED(DM_I2C)
Tom Rinia7a9bc02021-08-18 23:12:29 -0400300 i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200301#endif
Simon Glass762b9972021-07-10 21:14:27 -0600302#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW)
Ilya Yanok87b82cc2013-02-05 11:36:25 +0000303 arch_misc_init();
304#endif
Suniel Mahesh370d4912019-07-31 21:54:07 +0530305#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
Tom Rini303bfe82013-10-01 12:32:04 -0400306 hw_watchdog_init();
307#endif
Tom Riniac8fdf92013-08-30 16:28:44 -0400308#ifdef CONFIG_AM33XX
309 am33xx_spl_board_init();
310#endif
Keerthy0efb06d2022-01-27 13:16:52 +0100311 if (IS_ENABLED(CONFIG_SPL_BUILD) &&
312 IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
313 spl_boot_ipu();
Tom Rini9e0c2602012-08-14 12:26:08 -0700314}
315
SRICHARAN R3f30b0a2013-04-24 00:41:24 +0000316void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
317{
318 typedef void __noreturn (*image_entry_noargs_t)(u32 *);
319 image_entry_noargs_t image_entry =
320 (image_entry_noargs_t) spl_image->entry_point;
321
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200322 u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
323
Andre Przywara6c526072017-01-02 11:48:31 +0000324 debug("image entry point: 0x%lX\n", spl_image->entry_point);
SRICHARAN R3f30b0a2013-04-24 00:41:24 +0000325 /* Pass the saved boot_params from rom code */
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200326 image_entry((u32 *)boot_params);
SRICHARAN R3f30b0a2013-04-24 00:41:24 +0000327}
Chandan Nath77a73fe2012-01-09 20:38:59 +0000328#endif
Dmitry Lifshitz29211a02014-12-15 16:02:58 +0200329
330#ifdef CONFIG_SCSI_AHCI_PLAT
331void arch_preboot_os(void)
332{
Scott Wood16519a32015-04-17 09:19:01 -0500333 ahci_reset((void __iomem *)DWC_AHSATA_BASE);
Dmitry Lifshitz29211a02014-12-15 16:02:58 +0200334}
335#endif
Andrew Davisb3f0f832022-10-20 12:12:19 -0500336
337#ifdef CONFIG_TI_SECURE_DEVICE
338void board_fit_image_post_process(const void *fit, int node, void **p_image,
339 size_t *p_size)
340{
341 secure_boot_verify_image(p_image, p_size);
342}
343
344static void tee_image_process(ulong tee_image, size_t tee_size)
345{
346 secure_tee_install((u32)tee_image);
347}
348U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, tee_image_process);
349#endif