183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2983e3700STom Rini /*
3983e3700STom Rini  * boot-common.c
4983e3700STom Rini  *
5983e3700STom Rini  * Common bootmode functions for omap based boards
6983e3700STom Rini  *
7983e3700STom Rini  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
8983e3700STom Rini  */
9983e3700STom Rini 
10983e3700STom Rini #include <common.h>
11983e3700STom Rini #include <ahci.h>
1201510091SSimon Glass #include <environment.h>
13983e3700STom Rini #include <spl.h>
14983e3700STom Rini #include <asm/omap_common.h>
15983e3700STom Rini #include <asm/arch/omap.h>
16983e3700STom Rini #include <asm/arch/mmc_host_def.h>
17983e3700STom Rini #include <asm/arch/sys_proto.h>
18983e3700STom Rini #include <watchdog.h>
19983e3700STom Rini #include <scsi.h>
20983e3700STom Rini #include <i2c.h>
21983e3700STom Rini 
22983e3700STom Rini DECLARE_GLOBAL_DATA_PTR;
23983e3700STom Rini 
omap_sys_boot_device(void)24983e3700STom Rini __weak u32 omap_sys_boot_device(void)
25983e3700STom Rini {
26983e3700STom Rini 	return BOOT_DEVICE_NONE;
27983e3700STom Rini }
28983e3700STom Rini 
save_omap_boot_params(void)29983e3700STom Rini void save_omap_boot_params(void)
30983e3700STom Rini {
31983e3700STom Rini 	u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
32983e3700STom Rini 	struct omap_boot_parameters *omap_boot_params;
33983e3700STom Rini 	int sys_boot_device = 0;
34983e3700STom Rini 	u32 boot_device;
35983e3700STom Rini 	u32 boot_mode;
36983e3700STom Rini 
37983e3700STom Rini 	if ((boot_params < NON_SECURE_SRAM_START) ||
38983e3700STom Rini 	    (boot_params > NON_SECURE_SRAM_END))
39983e3700STom Rini 		return;
40983e3700STom Rini 
41983e3700STom Rini 	omap_boot_params = (struct omap_boot_parameters *)boot_params;
42983e3700STom Rini 
43983e3700STom Rini 	boot_device = omap_boot_params->boot_device;
44983e3700STom Rini 	boot_mode = MMCSD_MODE_UNDEFINED;
45983e3700STom Rini 
46983e3700STom Rini 	/* Boot device */
47983e3700STom Rini 
48983e3700STom Rini #ifdef BOOT_DEVICE_NAND_I2C
49983e3700STom Rini 	/*
50983e3700STom Rini 	 * Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
51983e3700STom Rini 	 * Otherwise the SPL boot IF can't handle this device correctly.
52983e3700STom Rini 	 * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens
53983e3700STom Rini 	 * Draco leads to this boot-device passed to SPL from the BootROM.
54983e3700STom Rini 	 */
55983e3700STom Rini 	if (boot_device == BOOT_DEVICE_NAND_I2C)
56983e3700STom Rini 		boot_device = BOOT_DEVICE_NAND;
57983e3700STom Rini #endif
58983e3700STom Rini #ifdef BOOT_DEVICE_QSPI_4
59983e3700STom Rini 	/*
60983e3700STom Rini 	 * We get different values for QSPI_1 and QSPI_4 being used, but
61983e3700STom Rini 	 * don't actually care about this difference.  Rather than
62983e3700STom Rini 	 * mangle the later code, if we're coming in as QSPI_4 just
63983e3700STom Rini 	 * change to the QSPI_1 value.
64983e3700STom Rini 	 */
65983e3700STom Rini 	if (boot_device == BOOT_DEVICE_QSPI_4)
66983e3700STom Rini 		boot_device = BOOT_DEVICE_SPI;
67983e3700STom Rini #endif
68207f981bSTom Rini #ifdef CONFIG_TI816X
69207f981bSTom Rini 	/*
70207f981bSTom Rini 	 * On PG2.0 and later TI816x the values we get when booting are not the
71207f981bSTom Rini 	 * same as on PG1.0, which is what the defines are based on.  Update
72207f981bSTom Rini 	 * them as needed.
73207f981bSTom Rini 	 */
74207f981bSTom Rini 	if (get_cpu_rev() != 1) {
75207f981bSTom Rini 		if (boot_device == 0x05) {
76207f981bSTom Rini 			omap_boot_params->boot_device = BOOT_DEVICE_NAND;
77207f981bSTom Rini 			boot_device = BOOT_DEVICE_NAND;
78207f981bSTom Rini 		}
79207f981bSTom Rini 		if (boot_device == 0x08) {
80207f981bSTom Rini 			omap_boot_params->boot_device = BOOT_DEVICE_MMC1;
81207f981bSTom Rini 			boot_device = BOOT_DEVICE_MMC1;
82207f981bSTom Rini 		}
83207f981bSTom Rini 	}
84207f981bSTom Rini #endif
85983e3700STom Rini 	/*
86983e3700STom Rini 	 * When booting from peripheral booting, the boot device is not usable
87983e3700STom Rini 	 * as-is (unless there is support for it), so the boot device is instead
88983e3700STom Rini 	 * figured out using the SYS_BOOT pins.
89983e3700STom Rini 	 */
90983e3700STom Rini 	switch (boot_device) {
91983e3700STom Rini #if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT)
92983e3700STom Rini 		case BOOT_DEVICE_UART:
93983e3700STom Rini 			sys_boot_device = 1;
94983e3700STom Rini 			break;
95983e3700STom Rini #endif
96*79536013SAbel Vesa #if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_STORAGE)
97983e3700STom Rini 		case BOOT_DEVICE_USB:
98983e3700STom Rini 			sys_boot_device = 1;
99983e3700STom Rini 			break;
100983e3700STom Rini #endif
101b432b1ebSFaiz Abbas #if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USB_ETHER)
102983e3700STom Rini 		case BOOT_DEVICE_USBETH:
103983e3700STom Rini 			sys_boot_device = 1;
104983e3700STom Rini 			break;
105983e3700STom Rini #endif
106983e3700STom Rini #if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH_SUPPORT)
107983e3700STom Rini 		case BOOT_DEVICE_CPGMAC:
108983e3700STom Rini 			sys_boot_device = 1;
109983e3700STom Rini 			break;
110983e3700STom Rini #endif
1116536ca4dSAndrew F. Davis #if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU)
112983e3700STom Rini 		case BOOT_DEVICE_DFU:
113983e3700STom Rini 			sys_boot_device = 1;
114983e3700STom Rini 			break;
115983e3700STom Rini #endif
116983e3700STom Rini 	}
117983e3700STom Rini 
118983e3700STom Rini 	if (sys_boot_device) {
119983e3700STom Rini 		boot_device = omap_sys_boot_device();
120983e3700STom Rini 
121983e3700STom Rini 		/* MMC raw mode will fallback to FS mode. */
122983e3700STom Rini 		if ((boot_device >= MMC_BOOT_DEVICES_START) &&
123983e3700STom Rini 		    (boot_device <= MMC_BOOT_DEVICES_END))
124983e3700STom Rini 			boot_mode = MMCSD_MODE_RAW;
125983e3700STom Rini 	}
126983e3700STom Rini 
127983e3700STom Rini 	gd->arch.omap_boot_device = boot_device;
128983e3700STom Rini 
129983e3700STom Rini 	/* Boot mode */
130983e3700STom Rini 
131983e3700STom Rini #ifdef CONFIG_OMAP34XX
132983e3700STom Rini 	if ((boot_device >= MMC_BOOT_DEVICES_START) &&
133983e3700STom Rini 	    (boot_device <= MMC_BOOT_DEVICES_END)) {
134983e3700STom Rini 		switch (boot_device) {
135983e3700STom Rini 		case BOOT_DEVICE_MMC1:
136983e3700STom Rini 			boot_mode = MMCSD_MODE_FS;
137983e3700STom Rini 			break;
138983e3700STom Rini 		case BOOT_DEVICE_MMC2:
139983e3700STom Rini 			boot_mode = MMCSD_MODE_RAW;
140983e3700STom Rini 			break;
141983e3700STom Rini 		}
142983e3700STom Rini 	}
143983e3700STom Rini #else
144983e3700STom Rini 	/*
145983e3700STom Rini 	 * If the boot device was dynamically changed and doesn't match what
146983e3700STom Rini 	 * the bootrom initially booted, we cannot use the boot device
147983e3700STom Rini 	 * descriptor to figure out the boot mode.
148983e3700STom Rini 	 */
149983e3700STom Rini 	if ((boot_device == omap_boot_params->boot_device) &&
150983e3700STom Rini 	    (boot_device >= MMC_BOOT_DEVICES_START) &&
151983e3700STom Rini 	    (boot_device <= MMC_BOOT_DEVICES_END)) {
152983e3700STom Rini 		boot_params = omap_boot_params->boot_device_descriptor;
153983e3700STom Rini 		if ((boot_params < NON_SECURE_SRAM_START) ||
154983e3700STom Rini 		    (boot_params > NON_SECURE_SRAM_END))
155983e3700STom Rini 			return;
156983e3700STom Rini 
157983e3700STom Rini 		boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET));
158983e3700STom Rini 		if ((boot_params < NON_SECURE_SRAM_START) ||
159983e3700STom Rini 		    (boot_params > NON_SECURE_SRAM_END))
160983e3700STom Rini 			return;
161983e3700STom Rini 
162983e3700STom Rini 		boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET));
163983e3700STom Rini 
164983e3700STom Rini 		if (boot_mode != MMCSD_MODE_FS &&
165983e3700STom Rini 		    boot_mode != MMCSD_MODE_RAW)
166983e3700STom Rini #ifdef CONFIG_SUPPORT_EMMC_BOOT
167983e3700STom Rini 			boot_mode = MMCSD_MODE_EMMCBOOT;
168983e3700STom Rini #else
169983e3700STom Rini 			boot_mode = MMCSD_MODE_UNDEFINED;
170983e3700STom Rini #endif
171983e3700STom Rini 	}
172983e3700STom Rini #endif
173983e3700STom Rini 
174983e3700STom Rini 	gd->arch.omap_boot_mode = boot_mode;
175983e3700STom Rini 
176983e3700STom Rini #if !defined(CONFIG_TI814X) && !defined(CONFIG_TI816X) && \
177983e3700STom Rini     !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX)
178983e3700STom Rini 
179983e3700STom Rini 	/* CH flags */
180983e3700STom Rini 
181983e3700STom Rini 	gd->arch.omap_ch_flags = omap_boot_params->ch_flags;
182983e3700STom Rini #endif
183983e3700STom Rini }
184983e3700STom Rini 
185983e3700STom Rini #ifdef CONFIG_SPL_BUILD
spl_boot_device(void)186983e3700STom Rini u32 spl_boot_device(void)
187983e3700STom Rini {
188983e3700STom Rini 	return gd->arch.omap_boot_device;
189983e3700STom Rini }
190983e3700STom Rini 
spl_boot_mode(const u32 boot_device)191983e3700STom Rini u32 spl_boot_mode(const u32 boot_device)
192983e3700STom Rini {
193983e3700STom Rini 	return gd->arch.omap_boot_mode;
194983e3700STom Rini }
195983e3700STom Rini 
spl_board_init(void)196983e3700STom Rini void spl_board_init(void)
197983e3700STom Rini {
198117a0e02SAlex Kiernan #ifdef CONFIG_SPL_SERIAL_SUPPORT
199983e3700STom Rini 	/* Prepare console output */
200983e3700STom Rini 	preloader_console_init();
201117a0e02SAlex Kiernan #endif
202983e3700STom Rini #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
203983e3700STom Rini 	gpmc_init();
204983e3700STom Rini #endif
20566814612SAdam Ford #if defined(CONFIG_SPL_I2C_SUPPORT) && !defined(CONFIG_DM_I2C)
206983e3700STom Rini 	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
207983e3700STom Rini #endif
208983e3700STom Rini #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
209983e3700STom Rini 	arch_misc_init();
210983e3700STom Rini #endif
211983e3700STom Rini #if defined(CONFIG_HW_WATCHDOG)
212983e3700STom Rini 	hw_watchdog_init();
213983e3700STom Rini #endif
214983e3700STom Rini #ifdef CONFIG_AM33XX
215983e3700STom Rini 	am33xx_spl_board_init();
216983e3700STom Rini #endif
217983e3700STom Rini }
218983e3700STom Rini 
jump_to_image_no_args(struct spl_image_info * spl_image)219983e3700STom Rini void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
220983e3700STom Rini {
221983e3700STom Rini 	typedef void __noreturn (*image_entry_noargs_t)(u32 *);
222983e3700STom Rini 	image_entry_noargs_t image_entry =
223983e3700STom Rini 			(image_entry_noargs_t) spl_image->entry_point;
224983e3700STom Rini 
225983e3700STom Rini 	u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
226983e3700STom Rini 
22711e1479bSAndre Przywara 	debug("image entry point: 0x%lX\n", spl_image->entry_point);
228983e3700STom Rini 	/* Pass the saved boot_params from rom code */
229983e3700STom Rini 	image_entry((u32 *)boot_params);
230983e3700STom Rini }
231983e3700STom Rini #endif
232983e3700STom Rini 
233983e3700STom Rini #ifdef CONFIG_SCSI_AHCI_PLAT
arch_preboot_os(void)234983e3700STom Rini void arch_preboot_os(void)
235983e3700STom Rini {
236983e3700STom Rini 	ahci_reset((void __iomem *)DWC_AHSATA_BASE);
237983e3700STom Rini }
238983e3700STom Rini #endif
239