]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
887717db TH |
2 | /* |
3 | * Copyright (C) 2014 Gateworks Corporation | |
4 | * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. | |
5 | * | |
6 | * Author: Tim Harvey <tharvey@gateworks.com> | |
887717db TH |
7 | */ |
8 | ||
d678a59d | 9 | #include <common.h> |
db41d65a | 10 | #include <hang.h> |
691d719d | 11 | #include <init.h> |
f7ae49fc | 12 | #include <log.h> |
401d1c4f | 13 | #include <asm/global_data.h> |
887717db TH |
14 | #include <asm/io.h> |
15 | #include <asm/arch/imx-regs.h> | |
cba586b4 | 16 | #include <asm/arch/sys_proto.h> |
887717db TH |
17 | #include <asm/spl.h> |
18 | #include <spl.h> | |
552a848e | 19 | #include <asm/mach-imx/hab.h> |
c5c6f37a | 20 | #include <asm/mach-imx/boot_mode.h> |
511db3bf | 21 | #include <g_dnl.h> |
efc4ad0b | 22 | #include <linux/libfdt.h> |
6039e0ed | 23 | #include <memalign.h> |
887717db | 24 | |
46668df5 JT |
25 | DECLARE_GLOBAL_DATA_PTR; |
26 | ||
6c646b3d PF |
27 | __weak int spl_board_boot_device(enum boot_device boot_dev_spl) |
28 | { | |
bf43907f YL |
29 | switch (boot_dev_spl) { |
30 | #if defined(CONFIG_MX7) | |
31 | case SD1_BOOT: | |
32 | case MMC1_BOOT: | |
33 | case SD2_BOOT: | |
34 | case MMC2_BOOT: | |
35 | case SD3_BOOT: | |
36 | case MMC3_BOOT: | |
37 | return BOOT_DEVICE_MMC1; | |
38 | #elif defined(CONFIG_IMX8) | |
39 | case MMC1_BOOT: | |
40 | return BOOT_DEVICE_MMC1; | |
41 | case SD2_BOOT: | |
42 | return BOOT_DEVICE_MMC2_2; | |
43 | case SD3_BOOT: | |
44 | return BOOT_DEVICE_MMC1; | |
45 | case FLEXSPI_BOOT: | |
46 | return BOOT_DEVICE_SPI; | |
47 | #elif defined(CONFIG_IMX8M) | |
48 | case SD1_BOOT: | |
49 | case MMC1_BOOT: | |
50 | return BOOT_DEVICE_MMC1; | |
51 | case SD2_BOOT: | |
52 | case MMC2_BOOT: | |
53 | return BOOT_DEVICE_MMC2; | |
54 | #endif | |
55 | case NAND_BOOT: | |
56 | return BOOT_DEVICE_NAND; | |
57 | case SPI_NOR_BOOT: | |
58 | return BOOT_DEVICE_SPI; | |
59 | case QSPI_BOOT: | |
60 | return BOOT_DEVICE_NOR; | |
61 | case USB_BOOT: | |
62 | return BOOT_DEVICE_BOARD; | |
63 | default: | |
64 | return BOOT_DEVICE_NONE; | |
65 | } | |
6c646b3d PF |
66 | } |
67 | ||
887717db | 68 | #if defined(CONFIG_MX6) |
f2863ff3 | 69 | /* determine boot device from SRC_SBMR1 (BOOT_CFG[4:1]) or SRC_GPR9 register */ |
887717db TH |
70 | u32 spl_boot_device(void) |
71 | { | |
7b54f5a8 | 72 | unsigned int bmode = readl(&src_base->sbmr2); |
cba586b4 | 73 | u32 reg = imx6_src_get_boot_mode(); |
887717db | 74 | |
40f4839c SB |
75 | /* |
76 | * Check for BMODE if serial downloader is enabled | |
77 | * BOOT_MODE - see IMX6DQRM Table 8-1 | |
78 | */ | |
ac0a93fd | 79 | if (((bmode >> 24) & 0x03) == 0x01) /* Serial Downloader */ |
962c78b1 | 80 | return BOOT_DEVICE_BOARD; |
96aac843 | 81 | |
e203dcf2 SA |
82 | /* |
83 | * The above method does not detect that the boot ROM used | |
84 | * serial downloader in case the boot ROM decided to use the | |
85 | * serial downloader as a fall back (primary boot source failed). | |
86 | * | |
87 | * Infer that the boot ROM used the USB serial downloader by | |
88 | * checking whether the USB PHY is currently active... This | |
89 | * assumes that SPL did not (yet) initialize the USB PHY... | |
90 | */ | |
91 | if (is_usbotg_phy_active()) | |
92 | return BOOT_DEVICE_BOARD; | |
93 | ||
887717db | 94 | /* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */ |
96aac843 | 95 | switch ((reg & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT) { |
887717db | 96 | /* EIM: See 8.5.1, Table 8-9 */ |
f62611a9 | 97 | case IMX6_BMODE_EIM: |
887717db | 98 | /* BOOT_CFG1[3]: NOR/OneNAND Selection */ |
f62611a9 | 99 | switch ((reg & IMX6_BMODE_EIM_MASK) >> IMX6_BMODE_EIM_SHIFT) { |
96aac843 | 100 | case IMX6_BMODE_ONENAND: |
887717db | 101 | return BOOT_DEVICE_ONENAND; |
96aac843 | 102 | case IMX6_BMODE_NOR: |
887717db TH |
103 | return BOOT_DEVICE_NOR; |
104 | break; | |
96aac843 | 105 | } |
ac0a93fd | 106 | /* Reserved: Used to force Serial Downloader */ |
3bd1642d | 107 | case IMX6_BMODE_RESERVED: |
962c78b1 | 108 | return BOOT_DEVICE_BOARD; |
887717db | 109 | /* SATA: See 8.5.4, Table 8-20 */ |
624da53c | 110 | #if !defined(CONFIG_MX6UL) && !defined(CONFIG_MX6ULL) |
96aac843 | 111 | case IMX6_BMODE_SATA: |
887717db | 112 | return BOOT_DEVICE_SATA; |
624da53c | 113 | #endif |
887717db | 114 | /* Serial ROM: See 8.5.5.1, Table 8-22 */ |
96aac843 | 115 | case IMX6_BMODE_SERIAL_ROM: |
887717db | 116 | /* BOOT_CFG4[2:0] */ |
96aac843 JT |
117 | switch ((reg & IMX6_BMODE_SERIAL_ROM_MASK) >> |
118 | IMX6_BMODE_SERIAL_ROM_SHIFT) { | |
119 | case IMX6_BMODE_ECSPI1: | |
120 | case IMX6_BMODE_ECSPI2: | |
121 | case IMX6_BMODE_ECSPI3: | |
122 | case IMX6_BMODE_ECSPI4: | |
123 | case IMX6_BMODE_ECSPI5: | |
887717db | 124 | return BOOT_DEVICE_SPI; |
96aac843 JT |
125 | case IMX6_BMODE_I2C1: |
126 | case IMX6_BMODE_I2C2: | |
127 | case IMX6_BMODE_I2C3: | |
887717db TH |
128 | return BOOT_DEVICE_I2C; |
129 | } | |
130 | break; | |
131 | /* SD/eSD: 8.5.3, Table 8-15 */ | |
96aac843 JT |
132 | case IMX6_BMODE_SD: |
133 | case IMX6_BMODE_ESD: | |
63ce94b1 AF |
134 | return BOOT_DEVICE_MMC1; |
135 | /* MMC/eMMC: 8.5.3 */ | |
96aac843 JT |
136 | case IMX6_BMODE_MMC: |
137 | case IMX6_BMODE_EMMC: | |
63ce94b1 | 138 | return BOOT_DEVICE_MMC1; |
20f14714 | 139 | /* NAND Flash: 8.5.2, Table 8-10 */ |
af104ae5 | 140 | case IMX6_BMODE_NAND_MIN ... IMX6_BMODE_NAND_MAX: |
887717db | 141 | return BOOT_DEVICE_NAND; |
d10d1386 SR |
142 | #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) |
143 | /* QSPI boot */ | |
144 | case IMX6_BMODE_QSPI: | |
145 | return BOOT_DEVICE_SPI; | |
146 | #endif | |
887717db TH |
147 | } |
148 | return BOOT_DEVICE_NONE; | |
149 | } | |
511db3bf | 150 | |
881df6ed | 151 | #elif defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) || defined(CONFIG_IMX9) |
cd357ad1 | 152 | /* Translate iMX7/i.MX8M boot device to the SPL boot device enumeration */ |
c5c6f37a UM |
153 | u32 spl_boot_device(void) |
154 | { | |
0fe69adc EM |
155 | #if defined(CONFIG_MX7) |
156 | unsigned int bmode = readl(&src_base->sbmr2); | |
157 | ||
158 | /* | |
159 | * Check for BMODE if serial downloader is enabled | |
160 | * BOOT_MODE - see IMX7DRM Table 6-24 | |
161 | */ | |
162 | if (((bmode >> 24) & 0x03) == 0x01) /* Serial Downloader */ | |
163 | return BOOT_DEVICE_BOARD; | |
164 | ||
165 | /* | |
166 | * The above method does not detect that the boot ROM used | |
167 | * serial downloader in case the boot ROM decided to use the | |
168 | * serial downloader as a fall back (primary boot source failed). | |
169 | * | |
170 | * Infer that the boot ROM used the USB serial downloader by | |
171 | * checking whether the USB PHY is currently active... This | |
172 | * assumes that SPL did not (yet) initialize the USB PHY... | |
173 | */ | |
174 | if (is_boot_from_usb()) | |
175 | return BOOT_DEVICE_BOARD; | |
176 | #endif | |
177 | ||
c5c6f37a UM |
178 | enum boot_device boot_device_spl = get_boot_device(); |
179 | ||
bf43907f | 180 | return spl_board_boot_device(boot_device_spl); |
c5c6f37a | 181 | } |
f541796a | 182 | #endif /* CONFIG_MX7 || CONFIG_IMX8M || CONFIG_IMX8 */ |
c5c6f37a | 183 | |
f811e976 | 184 | #ifdef CONFIG_SPL_USB_GADGET |
511db3bf FE |
185 | int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) |
186 | { | |
a95aee6a | 187 | put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM + 0xfff, &dev->idProduct); |
511db3bf FE |
188 | |
189 | return 0; | |
190 | } | |
27c80384 PF |
191 | |
192 | #define SDPV_BCD_DEVICE 0x500 | |
193 | int g_dnl_get_board_bcd_device_number(int gcnum) | |
194 | { | |
195 | return SDPV_BCD_DEVICE; | |
196 | } | |
511db3bf | 197 | #endif |
887717db | 198 | |
103c5f18 | 199 | #if defined(CONFIG_SPL_MMC) |
0339086b | 200 | /* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */ |
59073573 | 201 | u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) |
0339086b | 202 | { |
9d86dbd9 PF |
203 | #if defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) |
204 | switch (get_boot_device()) { | |
205 | /* for MMC return either RAW or FAT mode */ | |
206 | case SD1_BOOT: | |
207 | case SD2_BOOT: | |
208 | case SD3_BOOT: | |
d81a6895 | 209 | if (IS_ENABLED(CONFIG_SPL_FS_FAT)) |
5fc5bac6 HS |
210 | return MMCSD_MODE_FS; |
211 | else | |
212 | return MMCSD_MODE_RAW; | |
9d86dbd9 PF |
213 | case MMC1_BOOT: |
214 | case MMC2_BOOT: | |
215 | case MMC3_BOOT: | |
d81a6895 | 216 | if (IS_ENABLED(CONFIG_SPL_FS_FAT)) |
5fc5bac6 HS |
217 | return MMCSD_MODE_FS; |
218 | else if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) | |
219 | return MMCSD_MODE_EMMCBOOT; | |
220 | else | |
221 | return MMCSD_MODE_RAW; | |
9d86dbd9 PF |
222 | default: |
223 | puts("spl: ERROR: unsupported device\n"); | |
224 | hang(); | |
225 | } | |
226 | #else | |
772b5572 | 227 | switch (boot_device) { |
0339086b FE |
228 | /* for MMC return either RAW or FAT mode */ |
229 | case BOOT_DEVICE_MMC1: | |
230 | case BOOT_DEVICE_MMC2: | |
f541796a | 231 | case BOOT_DEVICE_MMC2_2: |
5fc5bac6 HS |
232 | if (IS_ENABLED(CONFIG_SPL_FS_FAT)) |
233 | return MMCSD_MODE_FS; | |
234 | else if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) | |
235 | return MMCSD_MODE_EMMCBOOT; | |
236 | else | |
237 | return MMCSD_MODE_RAW; | |
0339086b FE |
238 | default: |
239 | puts("spl: ERROR: unsupported device\n"); | |
240 | hang(); | |
241 | } | |
9d86dbd9 | 242 | #endif |
0339086b FE |
243 | } |
244 | #endif | |
245 | ||
d714a75f | 246 | #if defined(CONFIG_IMX_HAB) |
15b505b0 | 247 | |
c5800b25 BD |
248 | /* |
249 | * +------------+ 0x0 (DDR_UIMAGE_START) - | |
250 | * | Header | | | |
251 | * +------------+ 0x40 | | |
252 | * | | | | |
253 | * | | | | |
254 | * | | | | |
255 | * | | | | |
256 | * | Image Data | | | |
257 | * . | | | |
258 | * . | > Stuff to be authenticated ----+ | |
259 | * . | | | | |
260 | * | | | | | |
261 | * | | | | | |
262 | * +------------+ | | | |
263 | * | | | | | |
264 | * | Fill Data | | | | |
265 | * | | | | | |
266 | * +------------+ Align to ALIGN_SIZE | | | |
267 | * | IVT | | | | |
268 | * +------------+ + IVT_SIZE - | | |
269 | * | | | | |
270 | * | CSF DATA | <---------------------------------------------------------+ | |
271 | * | | | |
272 | * +------------+ | |
273 | * | | | |
274 | * | Fill Data | | |
275 | * | | | |
276 | * +------------+ + CSF_PAD_SIZE | |
277 | */ | |
278 | ||
15b505b0 SE |
279 | __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) |
280 | { | |
281 | typedef void __noreturn (*image_entry_noargs_t)(void); | |
c5800b25 | 282 | uint32_t offset; |
15b505b0 SE |
283 | |
284 | image_entry_noargs_t image_entry = | |
285 | (image_entry_noargs_t)(unsigned long)spl_image->entry_point; | |
286 | ||
4386feb7 | 287 | debug("image entry point: 0x%lX\n", spl_image->entry_point); |
15b505b0 | 288 | |
e246bfcf | 289 | if (spl_image->flags & SPL_FIT_FOUND) { |
15b505b0 SE |
290 | image_entry(); |
291 | } else { | |
e246bfcf YL |
292 | /* |
293 | * HAB looks for the CSF at the end of the authenticated | |
294 | * data therefore, we need to subtract the size of the | |
295 | * CSF from the actual filesize | |
296 | */ | |
297 | offset = spl_image->size - CONFIG_CSF_SIZE; | |
298 | if (!imx_hab_authenticate_image(spl_image->load_addr, | |
299 | offset + IVT_SIZE + | |
300 | CSF_PAD_SIZE, offset)) { | |
301 | image_entry(); | |
302 | } else { | |
1e7a69f6 | 303 | panic("spl: ERROR: image authentication fail\n"); |
e246bfcf YL |
304 | } |
305 | } | |
306 | } | |
307 | ||
01fc7e7b | 308 | #if !defined(CONFIG_SPL_FIT_SIGNATURE) |
e246bfcf YL |
309 | ulong board_spl_fit_size_align(ulong size) |
310 | { | |
311 | /* | |
312 | * HAB authenticate_image requests the IVT offset is | |
313 | * aligned to 0x1000 | |
314 | */ | |
315 | ||
316 | size = ALIGN(size, 0x1000); | |
317 | size += CONFIG_CSF_SIZE; | |
318 | ||
6039e0ed MV |
319 | if (size > CONFIG_SYS_BOOTM_LEN) |
320 | panic("spl: ERROR: image too big\n"); | |
e246bfcf | 321 | |
6039e0ed | 322 | return size; |
15b505b0 | 323 | } |
01fc7e7b | 324 | #endif |
15b505b0 | 325 | |
deb80ec0 HS |
326 | void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len) |
327 | { | |
6039e0ed MV |
328 | #if defined(CONFIG_SPL_LOAD_FIT_ADDRESS) |
329 | return (void *)CONFIG_SPL_LOAD_FIT_ADDRESS; | |
330 | #else | |
331 | return (void *)(CONFIG_TEXT_BASE + CONFIG_SYS_BOOTM_LEN); | |
15b505b0 | 332 | #endif |
46668df5 | 333 | } |
9de35448 HS |
334 | /* |
335 | * read the address where the IVT header must sit | |
336 | * from IVT image header, loaded from SPL into | |
337 | * an malloced buffer and copy the IVT header | |
338 | * to this address | |
339 | */ | |
340 | void *spl_load_simple_fit_fix_load(const void *fit) | |
341 | { | |
342 | struct ivt *ivt; | |
9de35448 HS |
343 | unsigned long offset; |
344 | unsigned long size; | |
345 | u8 *tmp = (u8 *)fit; | |
346 | ||
347 | offset = ALIGN(fdt_totalsize(fit), 0x1000); | |
348 | size = ALIGN(fdt_totalsize(fit), 4); | |
349 | size = board_spl_fit_size_align(size); | |
350 | tmp += offset; | |
351 | ivt = (struct ivt *)tmp; | |
6039e0ed | 352 | |
9de35448 HS |
353 | debug("%s: ivt: %p offset: %lx size: %lx\n", __func__, ivt, offset, size); |
354 | debug("%s: ivt self: %x\n", __func__, ivt->self); | |
9de35448 | 355 | |
b0296e22 | 356 | if (imx_hab_authenticate_image((uintptr_t)fit, (uintptr_t)size, offset)) |
6039e0ed MV |
357 | panic("spl: ERROR: image authentication unsuccessful\n"); |
358 | ||
359 | return (void *)fit; | |
9de35448 | 360 | } |
6039e0ed MV |
361 | #endif /* CONFIG_IMX_HAB */ |
362 | ||
363 | #if defined(CONFIG_MX6) && defined(CONFIG_SPL_OS_BOOT) | |
364 | int dram_init_banksize(void) | |
365 | { | |
366 | gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE; | |
367 | gd->bd->bi_dram[0].size = imx_ddr_size(); | |
368 | ||
369 | return 0; | |
370 | } | |
371 | #endif |