blob: c463c96c74c8e18acd77a2719233b7142114d8be [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>
18#include <asm/arch/omap.h>
Tom Rinia0b9fa52012-08-14 10:25:15 -070019#include <asm/arch/mmc_host_def.h>
Ilya Yanok741c57f2012-11-06 13:06:28 +000020#include <asm/arch/sys_proto.h>
Tom Rini303bfe82013-10-01 12:32:04 -040021#include <watchdog.h>
Dmitry Lifshitz29211a02014-12-15 16:02:58 +020022#include <scsi.h>
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020023#include <i2c.h>
Keerthy0efb06d2022-01-27 13:16:52 +010024#include <remoteproc.h>
Chandan Nath77a73fe2012-01-09 20:38:59 +000025
SRICHARAN R3f30b0a2013-04-24 00:41:24 +000026DECLARE_GLOBAL_DATA_PTR;
Chandan Nath77a73fe2012-01-09 20:38:59 +000027
Keerthy0efb06d2022-01-27 13:16:52 +010028#define IPU1_LOAD_ADDR (0xa17ff000)
29#define MAX_REMOTECORE_BIN_SIZE (8 * 0x100000)
30#define IPU2_LOAD_ADDR (IPU1_LOAD_ADDR + MAX_REMOTECORE_BIN_SIZE)
31
Paul Kocialkowski062fbb62015-07-15 16:02:23 +020032__weak u32 omap_sys_boot_device(void)
33{
34 return BOOT_DEVICE_NONE;
35}
36
Tom Rini51df26c2013-05-31 12:31:59 -040037void save_omap_boot_params(void)
38{
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020039 u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
40 struct omap_boot_parameters *omap_boot_params;
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +020041 int sys_boot_device = 0;
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020042 u32 boot_device;
43 u32 boot_mode;
Tom Rini51df26c2013-05-31 12:31:59 -040044
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020045 if ((boot_params < NON_SECURE_SRAM_START) ||
46 (boot_params > NON_SECURE_SRAM_END))
Tom Rini51df26c2013-05-31 12:31:59 -040047 return;
48
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020049 omap_boot_params = (struct omap_boot_parameters *)boot_params;
Stefan Roese0f3a4802014-11-12 11:57:33 +010050
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020051 boot_device = omap_boot_params->boot_device;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +020052 boot_mode = MMCSD_MODE_UNDEFINED;
53
54 /* Boot device */
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020055
56#ifdef BOOT_DEVICE_NAND_I2C
Stefan Roese0f3a4802014-11-12 11:57:33 +010057 /*
58 * Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
59 * Otherwise the SPL boot IF can't handle this device correctly.
60 * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens
61 * Draco leads to this boot-device passed to SPL from the BootROM.
62 */
63 if (boot_device == BOOT_DEVICE_NAND_I2C)
64 boot_device = BOOT_DEVICE_NAND;
65#endif
Paul Kocialkowskib16d6d52015-07-15 16:02:21 +020066#ifdef BOOT_DEVICE_QSPI_4
Tom Rini560ef452014-04-03 07:52:56 -040067 /*
68 * We get different values for QSPI_1 and QSPI_4 being used, but
69 * don't actually care about this difference. Rather than
70 * mangle the later code, if we're coming in as QSPI_4 just
71 * change to the QSPI_1 value.
72 */
Paul Kocialkowskib16d6d52015-07-15 16:02:21 +020073 if (boot_device == BOOT_DEVICE_QSPI_4)
Paul Kocialkowskid5b76242015-07-15 16:02:19 +020074 boot_device = BOOT_DEVICE_SPI;
75#endif
Tom Rinid00abb12017-06-15 13:57:00 -040076#ifdef CONFIG_TI816X
77 /*
78 * On PG2.0 and later TI816x the values we get when booting are not the
79 * same as on PG1.0, which is what the defines are based on. Update
80 * them as needed.
81 */
82 if (get_cpu_rev() != 1) {
83 if (boot_device == 0x05) {
84 omap_boot_params->boot_device = BOOT_DEVICE_NAND;
85 boot_device = BOOT_DEVICE_NAND;
86 }
87 if (boot_device == 0x08) {
88 omap_boot_params->boot_device = BOOT_DEVICE_MMC1;
89 boot_device = BOOT_DEVICE_MMC1;
90 }
91 }
92#endif
Paul Kocialkowski062fbb62015-07-15 16:02:23 +020093 /*
94 * When booting from peripheral booting, the boot device is not usable
95 * as-is (unless there is support for it), so the boot device is instead
96 * figured out using the SYS_BOOT pins.
97 */
98 switch (boot_device) {
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +020099#if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT)
100 case BOOT_DEVICE_UART:
101 sys_boot_device = 1;
102 break;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200103#endif
Abel Vesa5ea11ba52019-02-01 16:40:07 +0000104#if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_STORAGE)
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200105 case BOOT_DEVICE_USB:
106 sys_boot_device = 1;
107 break;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200108#endif
Faiz Abbasc01553b2018-02-16 21:17:44 +0530109#if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USB_ETHER)
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200110 case BOOT_DEVICE_USBETH:
111 sys_boot_device = 1;
112 break;
113#endif
Simon Glasse5cd9a42021-07-10 21:14:26 -0600114#if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH)
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200115 case BOOT_DEVICE_CPGMAC:
116 sys_boot_device = 1;
117 break;
118#endif
Andrew F. Davis6d932e62019-01-17 13:43:02 -0600119#if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU)
B, Ravi2fb19df2016-07-28 17:39:17 +0530120 case BOOT_DEVICE_DFU:
121 sys_boot_device = 1;
122 break;
123#endif
Paul Kocialkowskidd15fab2015-08-27 10:46:09 +0200124 }
125
126 if (sys_boot_device) {
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200127 boot_device = omap_sys_boot_device();
128
129 /* MMC raw mode will fallback to FS mode. */
130 if ((boot_device >= MMC_BOOT_DEVICES_START) &&
131 (boot_device <= MMC_BOOT_DEVICES_END))
132 boot_mode = MMCSD_MODE_RAW;
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200133 }
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200134
135 gd->arch.omap_boot_device = boot_device;
136
137 /* Boot mode */
138
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200139#ifdef CONFIG_OMAP34XX
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200140 if ((boot_device >= MMC_BOOT_DEVICES_START) &&
141 (boot_device <= MMC_BOOT_DEVICES_END)) {
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200142 switch (boot_device) {
143 case BOOT_DEVICE_MMC1:
Tom Rini9266bf42016-05-02 10:52:51 -0400144 boot_mode = MMCSD_MODE_FS;
145 break;
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200146 case BOOT_DEVICE_MMC2:
147 boot_mode = MMCSD_MODE_RAW;
148 break;
149 }
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200150 }
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200151#else
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200152 /*
153 * If the boot device was dynamically changed and doesn't match what
154 * the bootrom initially booted, we cannot use the boot device
155 * descriptor to figure out the boot mode.
156 */
157 if ((boot_device == omap_boot_params->boot_device) &&
158 (boot_device >= MMC_BOOT_DEVICES_START) &&
159 (boot_device <= MMC_BOOT_DEVICES_END)) {
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200160 boot_params = omap_boot_params->boot_device_descriptor;
161 if ((boot_params < NON_SECURE_SRAM_START) ||
162 (boot_params > NON_SECURE_SRAM_END))
163 return;
164
165 boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET));
166 if ((boot_params < NON_SECURE_SRAM_START) ||
167 (boot_params > NON_SECURE_SRAM_END))
168 return;
169
170 boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET));
171
172 if (boot_mode != MMCSD_MODE_FS &&
173 boot_mode != MMCSD_MODE_RAW)
174#ifdef CONFIG_SUPPORT_EMMC_BOOT
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200175 boot_mode = MMCSD_MODE_EMMCBOOT;
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200176#else
177 boot_mode = MMCSD_MODE_UNDEFINED;
178#endif
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200179 }
Paul Kocialkowski062fbb62015-07-15 16:02:23 +0200180#endif
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200181
182 gd->arch.omap_boot_mode = boot_mode;
183
184#if !defined(CONFIG_TI814X) && !defined(CONFIG_TI816X) && \
185 !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX)
186
187 /* CH flags */
188
189 gd->arch.omap_ch_flags = omap_boot_params->ch_flags;
Tom Rini560ef452014-04-03 07:52:56 -0400190#endif
Tom Rini51df26c2013-05-31 12:31:59 -0400191}
192
Chandan Nath77a73fe2012-01-09 20:38:59 +0000193#ifdef CONFIG_SPL_BUILD
Tom Rini0be93ff2012-08-13 12:53:23 -0700194u32 spl_boot_device(void)
Chandan Nath77a73fe2012-01-09 20:38:59 +0000195{
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200196 return gd->arch.omap_boot_device;
Chandan Nath77a73fe2012-01-09 20:38:59 +0000197}
198
Andre Przywara3cb12ef2021-07-12 11:06:49 +0100199u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
Chandan Nath77a73fe2012-01-09 20:38:59 +0000200{
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200201 return gd->arch.omap_boot_mode;
Chandan Nath77a73fe2012-01-09 20:38:59 +0000202}
Tom Rinia0b9fa52012-08-14 10:25:15 -0700203
Keerthy0efb06d2022-01-27 13:16:52 +0100204int load_firmware(char *name_fw, u32 *loadaddr)
205{
206 struct udevice *fsdev;
207 int size = 0;
208
209 if (!IS_ENABLED(CONFIG_FS_LOADER))
210 return 0;
211
212 if (!*loadaddr)
213 return 0;
214
215 if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
216 size = request_firmware_into_buf(fsdev, name_fw,
217 (void *)*loadaddr, 0, 0);
218 }
219
220 return size;
221}
222
223void spl_boot_ipu(void)
224{
225 int ret, size;
226 u32 loadaddr = IPU1_LOAD_ADDR;
227
228 if (!IS_ENABLED(CONFIG_SPL_BUILD) ||
229 !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
230 return;
231
232 size = load_firmware("dra7-ipu1-fw.xem4", &loadaddr);
233 if (size <= 0) {
234 pr_err("Firmware loading failed\n");
235 goto skip_ipu1;
236 }
237
238 enable_ipu1_clocks();
239 ret = rproc_dev_init(0);
240 if (ret) {
241 debug("%s: IPU1 failed to initialize on rproc (%d)\n",
242 __func__, ret);
243 goto skip_ipu1;
244 }
245
246 ret = rproc_load(0, IPU1_LOAD_ADDR, 0x2000000);
247 if (ret) {
248 debug("%s: IPU1 failed to load on rproc (%d)\n", __func__,
249 ret);
250 goto skip_ipu1;
251 }
252
253 debug("Starting IPU1...\n");
254
255 ret = rproc_start(0);
256 if (ret)
257 debug("%s: IPU1 failed to start (%d)\n", __func__, ret);
258
259skip_ipu1:
260 loadaddr = IPU2_LOAD_ADDR;
261 size = load_firmware("dra7-ipu2-fw.xem4", &loadaddr);
262 if (size <= 0) {
263 pr_err("Firmware loading failed for ipu2\n");
264 return;
265 }
266
267 enable_ipu2_clocks();
268 ret = rproc_dev_init(1);
269 if (ret) {
270 debug("%s: IPU2 failed to initialize on rproc (%d)\n", __func__,
271 ret);
272 return;
273 }
274
275 ret = rproc_load(1, IPU2_LOAD_ADDR, 0x2000000);
276 if (ret) {
277 debug("%s: IPU2 failed to load on rproc (%d)\n", __func__,
278 ret);
279 return;
280 }
281
282 debug("Starting IPU2...\n");
283
284 ret = rproc_start(1);
285 if (ret)
286 debug("%s: IPU2 failed to start (%d)\n", __func__, ret);
287}
288
Tom Rini9e0c2602012-08-14 12:26:08 -0700289void spl_board_init(void)
290{
Tom Rinic95d6c42014-12-19 16:53:24 -0500291 /* Prepare console output */
292 preloader_console_init();
Samuel Hollandb03e6662020-05-07 18:08:10 -0500293
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200294#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
Tom Rini9e0c2602012-08-14 12:26:08 -0700295 gpmc_init();
296#endif
Simon Glassbccfc2e2021-07-10 21:14:36 -0600297#if defined(CONFIG_SPL_I2C) && !CONFIG_IS_ENABLED(DM_I2C)
Tom Rinia7a9bc02021-08-18 23:12:29 -0400298 i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200299#endif
Simon Glass762b9972021-07-10 21:14:27 -0600300#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW)
Ilya Yanok87b82cc2013-02-05 11:36:25 +0000301 arch_misc_init();
302#endif
Suniel Mahesh370d4912019-07-31 21:54:07 +0530303#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
Tom Rini303bfe82013-10-01 12:32:04 -0400304 hw_watchdog_init();
305#endif
Tom Riniac8fdf92013-08-30 16:28:44 -0400306#ifdef CONFIG_AM33XX
307 am33xx_spl_board_init();
308#endif
Keerthy0efb06d2022-01-27 13:16:52 +0100309 if (IS_ENABLED(CONFIG_SPL_BUILD) &&
310 IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
311 spl_boot_ipu();
Tom Rini9e0c2602012-08-14 12:26:08 -0700312}
313
SRICHARAN R3f30b0a2013-04-24 00:41:24 +0000314void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
315{
316 typedef void __noreturn (*image_entry_noargs_t)(u32 *);
317 image_entry_noargs_t image_entry =
318 (image_entry_noargs_t) spl_image->entry_point;
319
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200320 u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
321
Andre Przywara6c526072017-01-02 11:48:31 +0000322 debug("image entry point: 0x%lX\n", spl_image->entry_point);
SRICHARAN R3f30b0a2013-04-24 00:41:24 +0000323 /* Pass the saved boot_params from rom code */
Paul Kocialkowskid5b76242015-07-15 16:02:19 +0200324 image_entry((u32 *)boot_params);
SRICHARAN R3f30b0a2013-04-24 00:41:24 +0000325}
Chandan Nath77a73fe2012-01-09 20:38:59 +0000326#endif
Dmitry Lifshitz29211a02014-12-15 16:02:58 +0200327
328#ifdef CONFIG_SCSI_AHCI_PLAT
329void arch_preboot_os(void)
330{
Scott Wood16519a32015-04-17 09:19:01 -0500331 ahci_reset((void __iomem *)DWC_AHSATA_BASE);
Dmitry Lifshitz29211a02014-12-15 16:02:58 +0200332}
333#endif