]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
8a8f084e CN |
2 | /* |
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/ | |
8a8f084e CN |
8 | */ |
9 | ||
10 | #include <common.h> | |
87791adc | 11 | #include <ahci.h> |
f7ae49fc | 12 | #include <log.h> |
0197909d K |
13 | #include <dm/uclass.h> |
14 | #include <fs_loader.h> | |
47f7bcae | 15 | #include <spl.h> |
401d1c4f | 16 | #include <asm/global_data.h> |
8a8f084e CN |
17 | #include <asm/omap_common.h> |
18 | #include <asm/arch/omap.h> | |
f0881250 | 19 | #include <asm/arch/mmc_host_def.h> |
1befaffb | 20 | #include <asm/arch/sys_proto.h> |
6843918e | 21 | #include <watchdog.h> |
87791adc | 22 | #include <scsi.h> |
60c7c30a | 23 | #include <i2c.h> |
0197909d | 24 | #include <remoteproc.h> |
8a8f084e | 25 | |
4a0eb757 | 26 | DECLARE_GLOBAL_DATA_PTR; |
8a8f084e | 27 | |
0197909d K |
28 | #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 | ||
ed19bdae PK |
32 | __weak u32 omap_sys_boot_device(void) |
33 | { | |
34 | return BOOT_DEVICE_NONE; | |
35 | } | |
36 | ||
4596dcc1 TR |
37 | void save_omap_boot_params(void) |
38 | { | |
60c7c30a PK |
39 | u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS); |
40 | struct omap_boot_parameters *omap_boot_params; | |
8ceb34a1 | 41 | int sys_boot_device = 0; |
60c7c30a PK |
42 | u32 boot_device; |
43 | u32 boot_mode; | |
4596dcc1 | 44 | |
60c7c30a PK |
45 | if ((boot_params < NON_SECURE_SRAM_START) || |
46 | (boot_params > NON_SECURE_SRAM_END)) | |
4596dcc1 TR |
47 | return; |
48 | ||
60c7c30a PK |
49 | omap_boot_params = (struct omap_boot_parameters *)boot_params; |
50 | ||
60c7c30a | 51 | boot_device = omap_boot_params->boot_device; |
ed19bdae PK |
52 | boot_mode = MMCSD_MODE_UNDEFINED; |
53 | ||
54 | /* Boot device */ | |
60c7c30a PK |
55 | |
56 | #ifdef BOOT_DEVICE_NAND_I2C | |
e49631af SR |
57 | /* |
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 | |
df844772 | 66 | #ifdef BOOT_DEVICE_QSPI_4 |
79b079f3 TR |
67 | /* |
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 | */ | |
df844772 | 73 | if (boot_device == BOOT_DEVICE_QSPI_4) |
60c7c30a | 74 | boot_device = BOOT_DEVICE_SPI; |
207f981b TR |
75 | #endif |
76 | #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 | } | |
60c7c30a | 92 | #endif |
ed19bdae PK |
93 | /* |
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) { | |
8ceb34a1 PK |
99 | #if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT) |
100 | case BOOT_DEVICE_UART: | |
101 | sys_boot_device = 1; | |
102 | break; | |
ed19bdae | 103 | #endif |
79536013 | 104 | #if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_STORAGE) |
8ceb34a1 PK |
105 | case BOOT_DEVICE_USB: |
106 | sys_boot_device = 1; | |
107 | break; | |
ed19bdae | 108 | #endif |
b432b1eb | 109 | #if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USB_ETHER) |
8ceb34a1 PK |
110 | case BOOT_DEVICE_USBETH: |
111 | sys_boot_device = 1; | |
112 | break; | |
113 | #endif | |
f2d7a36e | 114 | #if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH) |
8ceb34a1 PK |
115 | case BOOT_DEVICE_CPGMAC: |
116 | sys_boot_device = 1; | |
117 | break; | |
6f8387f1 | 118 | #endif |
6536ca4d | 119 | #if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU) |
6f8387f1 R |
120 | case BOOT_DEVICE_DFU: |
121 | sys_boot_device = 1; | |
122 | break; | |
8ceb34a1 PK |
123 | #endif |
124 | } | |
125 | ||
126 | if (sys_boot_device) { | |
ed19bdae PK |
127 | 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; | |
ed19bdae | 133 | } |
60c7c30a PK |
134 | |
135 | gd->arch.omap_boot_device = boot_device; | |
136 | ||
137 | /* Boot mode */ | |
138 | ||
ed19bdae | 139 | #ifdef CONFIG_OMAP34XX |
60c7c30a PK |
140 | if ((boot_device >= MMC_BOOT_DEVICES_START) && |
141 | (boot_device <= MMC_BOOT_DEVICES_END)) { | |
60c7c30a PK |
142 | switch (boot_device) { |
143 | case BOOT_DEVICE_MMC1: | |
821c89d3 TR |
144 | boot_mode = MMCSD_MODE_FS; |
145 | break; | |
60c7c30a PK |
146 | case BOOT_DEVICE_MMC2: |
147 | boot_mode = MMCSD_MODE_RAW; | |
148 | break; | |
149 | } | |
ed19bdae | 150 | } |
60c7c30a | 151 | #else |
ed19bdae PK |
152 | /* |
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)) { | |
60c7c30a PK |
160 | 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 | |
ed19bdae | 175 | boot_mode = MMCSD_MODE_EMMCBOOT; |
60c7c30a PK |
176 | #else |
177 | boot_mode = MMCSD_MODE_UNDEFINED; | |
60c7c30a PK |
178 | #endif |
179 | } | |
ed19bdae | 180 | #endif |
60c7c30a PK |
181 | |
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; | |
79b079f3 | 190 | #endif |
4596dcc1 TR |
191 | } |
192 | ||
8a8f084e | 193 | #ifdef CONFIG_SPL_BUILD |
8e1b836e | 194 | u32 spl_boot_device(void) |
8a8f084e | 195 | { |
60c7c30a | 196 | return gd->arch.omap_boot_device; |
8a8f084e CN |
197 | } |
198 | ||
59073573 | 199 | u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) |
8a8f084e | 200 | { |
60c7c30a | 201 | return gd->arch.omap_boot_mode; |
8a8f084e | 202 | } |
f0881250 | 203 | |
0197909d K |
204 | int 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 | ||
223 | void 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 | ||
259 | skip_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 | ||
d7cb93b2 TR |
289 | void spl_board_init(void) |
290 | { | |
a6b541b0 TR |
291 | /* Prepare console output */ |
292 | preloader_console_init(); | |
3988be5f | 293 | |
60c7c30a | 294 | #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT) |
d7cb93b2 TR |
295 | gpmc_init(); |
296 | #endif | |
975e7cf3 | 297 | #if defined(CONFIG_SPL_I2C) && !CONFIG_IS_ENABLED(DM_I2C) |
14376b8e | 298 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
60c7c30a | 299 | #endif |
89ddb0bf | 300 | #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW) |
da07c21b IY |
301 | arch_misc_init(); |
302 | #endif | |
6912f2a8 | 303 | #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) |
6843918e TR |
304 | hw_watchdog_init(); |
305 | #endif | |
6a0d803c TR |
306 | #ifdef CONFIG_AM33XX |
307 | am33xx_spl_board_init(); | |
308 | #endif | |
0197909d K |
309 | if (IS_ENABLED(CONFIG_SPL_BUILD) && |
310 | IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) | |
311 | spl_boot_ipu(); | |
d7cb93b2 TR |
312 | } |
313 | ||
4a0eb757 S |
314 | void __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 | ||
60c7c30a PK |
320 | u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS); |
321 | ||
11e1479b | 322 | debug("image entry point: 0x%lX\n", spl_image->entry_point); |
4a0eb757 | 323 | /* Pass the saved boot_params from rom code */ |
60c7c30a | 324 | image_entry((u32 *)boot_params); |
4a0eb757 | 325 | } |
8a8f084e | 326 | #endif |
87791adc DL |
327 | |
328 | #ifdef CONFIG_SCSI_AHCI_PLAT | |
329 | void arch_preboot_os(void) | |
330 | { | |
9efaca3e | 331 | ahci_reset((void __iomem *)DWC_AHSATA_BASE); |
87791adc DL |
332 | } |
333 | #endif |