1983e3700STom Rini /*
2983e3700STom Rini  * boot-common.c
3983e3700STom Rini  *
4983e3700STom Rini  * Common bootmode functions for omap based boards
5983e3700STom Rini  *
6983e3700STom Rini  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
7983e3700STom Rini  *
8983e3700STom Rini  * SPDX-License-Identifier:	GPL-2.0+
9983e3700STom Rini  */
10983e3700STom Rini 
11983e3700STom Rini #include <common.h>
12983e3700STom Rini #include <ahci.h>
1301510091SSimon Glass #include <environment.h>
14983e3700STom Rini #include <spl.h>
15983e3700STom Rini #include <asm/omap_common.h>
16983e3700STom Rini #include <asm/arch/omap.h>
17983e3700STom Rini #include <asm/arch/mmc_host_def.h>
18983e3700STom Rini #include <asm/arch/sys_proto.h>
19983e3700STom Rini #include <watchdog.h>
20983e3700STom Rini #include <scsi.h>
21983e3700STom Rini #include <i2c.h>
22983e3700STom Rini 
23983e3700STom Rini DECLARE_GLOBAL_DATA_PTR;
24983e3700STom Rini 
25983e3700STom Rini __weak u32 omap_sys_boot_device(void)
26983e3700STom Rini {
27983e3700STom Rini 	return BOOT_DEVICE_NONE;
28983e3700STom Rini }
29983e3700STom Rini 
30983e3700STom Rini void save_omap_boot_params(void)
31983e3700STom Rini {
32983e3700STom Rini 	u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
33983e3700STom Rini 	struct omap_boot_parameters *omap_boot_params;
34983e3700STom Rini 	int sys_boot_device = 0;
35983e3700STom Rini 	u32 boot_device;
36983e3700STom Rini 	u32 boot_mode;
37983e3700STom Rini 
38983e3700STom Rini 	if ((boot_params < NON_SECURE_SRAM_START) ||
39983e3700STom Rini 	    (boot_params > NON_SECURE_SRAM_END))
40983e3700STom Rini 		return;
41983e3700STom Rini 
42983e3700STom Rini 	omap_boot_params = (struct omap_boot_parameters *)boot_params;
43983e3700STom Rini 
44983e3700STom Rini 	boot_device = omap_boot_params->boot_device;
45983e3700STom Rini 	boot_mode = MMCSD_MODE_UNDEFINED;
46983e3700STom Rini 
47983e3700STom Rini 	/* Boot device */
48983e3700STom Rini 
49983e3700STom Rini #ifdef BOOT_DEVICE_NAND_I2C
50983e3700STom Rini 	/*
51983e3700STom Rini 	 * Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
52983e3700STom Rini 	 * Otherwise the SPL boot IF can't handle this device correctly.
53983e3700STom Rini 	 * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens
54983e3700STom Rini 	 * Draco leads to this boot-device passed to SPL from the BootROM.
55983e3700STom Rini 	 */
56983e3700STom Rini 	if (boot_device == BOOT_DEVICE_NAND_I2C)
57983e3700STom Rini 		boot_device = BOOT_DEVICE_NAND;
58983e3700STom Rini #endif
59983e3700STom Rini #ifdef BOOT_DEVICE_QSPI_4
60983e3700STom Rini 	/*
61983e3700STom Rini 	 * We get different values for QSPI_1 and QSPI_4 being used, but
62983e3700STom Rini 	 * don't actually care about this difference.  Rather than
63983e3700STom Rini 	 * mangle the later code, if we're coming in as QSPI_4 just
64983e3700STom Rini 	 * change to the QSPI_1 value.
65983e3700STom Rini 	 */
66983e3700STom Rini 	if (boot_device == BOOT_DEVICE_QSPI_4)
67983e3700STom Rini 		boot_device = BOOT_DEVICE_SPI;
68983e3700STom Rini #endif
69207f981bSTom Rini #ifdef CONFIG_TI816X
70207f981bSTom Rini 	/*
71207f981bSTom Rini 	 * On PG2.0 and later TI816x the values we get when booting are not the
72207f981bSTom Rini 	 * same as on PG1.0, which is what the defines are based on.  Update
73207f981bSTom Rini 	 * them as needed.
74207f981bSTom Rini 	 */
75207f981bSTom Rini 	if (get_cpu_rev() != 1) {
76207f981bSTom Rini 		if (boot_device == 0x05) {
77207f981bSTom Rini 			omap_boot_params->boot_device = BOOT_DEVICE_NAND;
78207f981bSTom Rini 			boot_device = BOOT_DEVICE_NAND;
79207f981bSTom Rini 		}
80207f981bSTom Rini 		if (boot_device == 0x08) {
81207f981bSTom Rini 			omap_boot_params->boot_device = BOOT_DEVICE_MMC1;
82207f981bSTom Rini 			boot_device = BOOT_DEVICE_MMC1;
83207f981bSTom Rini 		}
84207f981bSTom Rini 	}
85207f981bSTom Rini #endif
86983e3700STom Rini 	/*
87983e3700STom Rini 	 * When booting from peripheral booting, the boot device is not usable
88983e3700STom Rini 	 * as-is (unless there is support for it), so the boot device is instead
89983e3700STom Rini 	 * figured out using the SYS_BOOT pins.
90983e3700STom Rini 	 */
91983e3700STom Rini 	switch (boot_device) {
92983e3700STom Rini #if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT)
93983e3700STom Rini 		case BOOT_DEVICE_UART:
94983e3700STom Rini 			sys_boot_device = 1;
95983e3700STom Rini 			break;
96983e3700STom Rini #endif
97983e3700STom Rini #if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_SUPPORT)
98983e3700STom Rini 		case BOOT_DEVICE_USB:
99983e3700STom Rini 			sys_boot_device = 1;
100983e3700STom Rini 			break;
101983e3700STom Rini #endif
102983e3700STom Rini #if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USBETH_SUPPORT)
103983e3700STom Rini 		case BOOT_DEVICE_USBETH:
104983e3700STom Rini 			sys_boot_device = 1;
105983e3700STom Rini 			break;
106983e3700STom Rini #endif
107983e3700STom Rini #if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH_SUPPORT)
108983e3700STom Rini 		case BOOT_DEVICE_CPGMAC:
109983e3700STom Rini 			sys_boot_device = 1;
110983e3700STom Rini 			break;
111983e3700STom Rini #endif
112983e3700STom Rini #if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU_SUPPORT)
113983e3700STom Rini 		case BOOT_DEVICE_DFU:
114983e3700STom Rini 			sys_boot_device = 1;
115983e3700STom Rini 			break;
116983e3700STom Rini #endif
117983e3700STom Rini 	}
118983e3700STom Rini 
119983e3700STom Rini 	if (sys_boot_device) {
120983e3700STom Rini 		boot_device = omap_sys_boot_device();
121983e3700STom Rini 
122983e3700STom Rini 		/* MMC raw mode will fallback to FS mode. */
123983e3700STom Rini 		if ((boot_device >= MMC_BOOT_DEVICES_START) &&
124983e3700STom Rini 		    (boot_device <= MMC_BOOT_DEVICES_END))
125983e3700STom Rini 			boot_mode = MMCSD_MODE_RAW;
126983e3700STom Rini 	}
127983e3700STom Rini 
128983e3700STom Rini 	gd->arch.omap_boot_device = boot_device;
129983e3700STom Rini 
130983e3700STom Rini 	/* Boot mode */
131983e3700STom Rini 
132983e3700STom Rini #ifdef CONFIG_OMAP34XX
133983e3700STom Rini 	if ((boot_device >= MMC_BOOT_DEVICES_START) &&
134983e3700STom Rini 	    (boot_device <= MMC_BOOT_DEVICES_END)) {
135983e3700STom Rini 		switch (boot_device) {
136983e3700STom Rini 		case BOOT_DEVICE_MMC1:
137983e3700STom Rini 			boot_mode = MMCSD_MODE_FS;
138983e3700STom Rini 			break;
139983e3700STom Rini 		case BOOT_DEVICE_MMC2:
140983e3700STom Rini 			boot_mode = MMCSD_MODE_RAW;
141983e3700STom Rini 			break;
142983e3700STom Rini 		}
143983e3700STom Rini 	}
144983e3700STom Rini #else
145983e3700STom Rini 	/*
146983e3700STom Rini 	 * If the boot device was dynamically changed and doesn't match what
147983e3700STom Rini 	 * the bootrom initially booted, we cannot use the boot device
148983e3700STom Rini 	 * descriptor to figure out the boot mode.
149983e3700STom Rini 	 */
150983e3700STom Rini 	if ((boot_device == omap_boot_params->boot_device) &&
151983e3700STom Rini 	    (boot_device >= MMC_BOOT_DEVICES_START) &&
152983e3700STom Rini 	    (boot_device <= MMC_BOOT_DEVICES_END)) {
153983e3700STom Rini 		boot_params = omap_boot_params->boot_device_descriptor;
154983e3700STom Rini 		if ((boot_params < NON_SECURE_SRAM_START) ||
155983e3700STom Rini 		    (boot_params > NON_SECURE_SRAM_END))
156983e3700STom Rini 			return;
157983e3700STom Rini 
158983e3700STom Rini 		boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET));
159983e3700STom Rini 		if ((boot_params < NON_SECURE_SRAM_START) ||
160983e3700STom Rini 		    (boot_params > NON_SECURE_SRAM_END))
161983e3700STom Rini 			return;
162983e3700STom Rini 
163983e3700STom Rini 		boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET));
164983e3700STom Rini 
165983e3700STom Rini 		if (boot_mode != MMCSD_MODE_FS &&
166983e3700STom Rini 		    boot_mode != MMCSD_MODE_RAW)
167983e3700STom Rini #ifdef CONFIG_SUPPORT_EMMC_BOOT
168983e3700STom Rini 			boot_mode = MMCSD_MODE_EMMCBOOT;
169983e3700STom Rini #else
170983e3700STom Rini 			boot_mode = MMCSD_MODE_UNDEFINED;
171983e3700STom Rini #endif
172983e3700STom Rini 	}
173983e3700STom Rini #endif
174983e3700STom Rini 
175983e3700STom Rini 	gd->arch.omap_boot_mode = boot_mode;
176983e3700STom Rini 
177983e3700STom Rini #if !defined(CONFIG_TI814X) && !defined(CONFIG_TI816X) && \
178983e3700STom Rini     !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX)
179983e3700STom Rini 
180983e3700STom Rini 	/* CH flags */
181983e3700STom Rini 
182983e3700STom Rini 	gd->arch.omap_ch_flags = omap_boot_params->ch_flags;
183983e3700STom Rini #endif
184983e3700STom Rini }
185983e3700STom Rini 
186983e3700STom Rini #ifdef CONFIG_SPL_BUILD
187983e3700STom Rini u32 spl_boot_device(void)
188983e3700STom Rini {
189983e3700STom Rini 	return gd->arch.omap_boot_device;
190983e3700STom Rini }
191983e3700STom Rini 
192983e3700STom Rini u32 spl_boot_mode(const u32 boot_device)
193983e3700STom Rini {
194983e3700STom Rini 	return gd->arch.omap_boot_mode;
195983e3700STom Rini }
196983e3700STom Rini 
197983e3700STom Rini void spl_board_init(void)
198983e3700STom Rini {
199983e3700STom Rini 	/* Prepare console output */
200983e3700STom Rini 	preloader_console_init();
201983e3700STom Rini 
202983e3700STom Rini #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
203983e3700STom Rini 	gpmc_init();
204983e3700STom Rini #endif
205983e3700STom Rini #ifdef CONFIG_SPL_I2C_SUPPORT
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 
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
234983e3700STom Rini void arch_preboot_os(void)
235983e3700STom Rini {
236983e3700STom Rini 	ahci_reset((void __iomem *)DWC_AHSATA_BASE);
237983e3700STom Rini }
238983e3700STom Rini #endif
239983e3700STom Rini 
240983e3700STom Rini #if defined(CONFIG_USB_FUNCTION_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
241983e3700STom Rini int fb_set_reboot_flag(void)
242983e3700STom Rini {
243983e3700STom Rini 	printf("Setting reboot to fastboot flag ...\n");
244*382bee57SSimon Glass 	env_set("dofastboot", "1");
24501510091SSimon Glass 	env_save();
246983e3700STom Rini 	return 0;
247983e3700STom Rini }
248983e3700STom Rini #endif
249