]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
b0f80b91 | 2 | /* |
a5f88877 | 3 | * Copyright (C) 2014-2016 Stefan Roese <[email protected]> |
b0f80b91 SR |
4 | */ |
5 | ||
6 | #include <common.h> | |
871ee663 | 7 | #include <cpu_func.h> |
6451223a | 8 | #include <dm.h> |
6451223a | 9 | #include <fdtdec.h> |
db41d65a | 10 | #include <hang.h> |
2226ca17 | 11 | #include <image.h> |
691d719d | 12 | #include <init.h> |
f7ae49fc | 13 | #include <log.h> |
b0f80b91 | 14 | #include <spl.h> |
401d1c4f | 15 | #include <asm/global_data.h> |
b0f80b91 SR |
16 | #include <asm/io.h> |
17 | #include <asm/arch/cpu.h> | |
18 | #include <asm/arch/soc.h> | |
19 | ||
103c5f18 | 20 | #if defined(CONFIG_SPL_SPI_FLASH_SUPPORT) || defined(CONFIG_SPL_MMC) || \ |
f7560376 | 21 | defined(CONFIG_SPL_SATA) |
2226ca17 T |
22 | |
23 | /* | |
24 | * When loading U-Boot via SPL from SPI NOR, CONFIG_SYS_SPI_U_BOOT_OFFS must | |
25 | * point to the offset of kwbimage main header which is always at offset zero | |
26 | * (defined by BootROM). Therefore other values of CONFIG_SYS_SPI_U_BOOT_OFFS | |
27 | * makes U-Boot non-bootable. | |
28 | */ | |
29 | #ifdef CONFIG_SPL_SPI_FLASH_SUPPORT | |
30 | #if defined(CONFIG_SYS_SPI_U_BOOT_OFFS) && CONFIG_SYS_SPI_U_BOOT_OFFS != 0 | |
31 | #error CONFIG_SYS_SPI_U_BOOT_OFFS must be set to 0 | |
32 | #endif | |
33 | #endif | |
34 | ||
35 | /* | |
36 | * When loading U-Boot via SPL from eMMC (in Marvell terminology SDIO), the | |
37 | * kwbimage main header is stored at sector 0. U-Boot SPL needs to parse this | |
38 | * header and figure out at which sector the U-Boot proper binary is stored. | |
39 | * Partition booting is therefore not supported and CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR | |
40 | * and CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET need to point to the | |
41 | * kwbimage main header. | |
42 | */ | |
103c5f18 | 43 | #ifdef CONFIG_SPL_MMC |
2226ca17 T |
44 | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION |
45 | #error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION is unsupported | |
46 | #endif | |
47 | #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) && CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR != 0 | |
48 | #error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR must be set to 0 | |
49 | #endif | |
0d582a46 MB |
50 | #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET) && \ |
51 | CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET != 0 | |
2226ca17 T |
52 | #error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET must be set to 0 |
53 | #endif | |
54 | #endif | |
55 | ||
56 | /* | |
57 | * When loading U-Boot via SPL from SATA disk, the kwbimage main header is | |
58 | * stored at sector 1. Therefore CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR must be | |
59 | * set to 1. Otherwise U-Boot SPL would not be able to load U-Boot proper. | |
60 | */ | |
f7560376 | 61 | #ifdef CONFIG_SPL_SATA |
0d582a46 MB |
62 | #if !defined(CONFIG_SPL_SATA_RAW_U_BOOT_USE_SECTOR) || \ |
63 | !defined(CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR) || CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR != 1 | |
2226ca17 T |
64 | #error CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR must be set to 1 |
65 | #endif | |
66 | #endif | |
67 | ||
68 | /* Boot Type - block ID */ | |
69 | #define IBR_HDR_I2C_ID 0x4D | |
70 | #define IBR_HDR_SPI_ID 0x5A | |
71 | #define IBR_HDR_NAND_ID 0x8B | |
72 | #define IBR_HDR_SATA_ID 0x78 | |
73 | #define IBR_HDR_PEX_ID 0x9C | |
74 | #define IBR_HDR_UART_ID 0x69 | |
75 | #define IBR_HDR_SDIO_ID 0xAE | |
76 | ||
7af368f4 | 77 | /* Structure of the main header, version 1 (Armada 370/XP/375/38x/39x) */ |
2226ca17 | 78 | struct kwbimage_main_hdr_v1 { |
c894566c MB |
79 | u8 blockid; /* 0x0 */ |
80 | u8 flags; /* 0x1 */ | |
81 | u16 nandpagesize; /* 0x2-0x3 */ | |
82 | u32 blocksize; /* 0x4-0x7 */ | |
83 | u8 version; /* 0x8 */ | |
84 | u8 headersz_msb; /* 0x9 */ | |
85 | u16 headersz_lsb; /* 0xA-0xB */ | |
86 | u32 srcaddr; /* 0xC-0xF */ | |
87 | u32 destaddr; /* 0x10-0x13 */ | |
88 | u32 execaddr; /* 0x14-0x17 */ | |
89 | u8 options; /* 0x18 */ | |
90 | u8 nandblocksize; /* 0x19 */ | |
91 | u8 nandbadblklocation; /* 0x1A */ | |
92 | u8 reserved4; /* 0x1B */ | |
93 | u16 reserved5; /* 0x1C-0x1D */ | |
94 | u8 ext; /* 0x1E */ | |
95 | u8 checksum; /* 0x1F */ | |
2226ca17 T |
96 | } __packed; |
97 | ||
103c5f18 | 98 | #ifdef CONFIG_SPL_MMC |
59073573 | 99 | u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) |
2226ca17 T |
100 | { |
101 | return MMCSD_MODE_RAW; | |
102 | } | |
103 | #endif | |
104 | ||
402e84ee T |
105 | static u32 checksum32(void *start, u32 len) |
106 | { | |
107 | u32 csum = 0; | |
108 | u32 *p = start; | |
109 | ||
110 | while (len > 0) { | |
111 | csum += *p++; | |
112 | len -= sizeof(u32); | |
113 | }; | |
114 | ||
115 | return csum; | |
116 | } | |
117 | ||
118 | int spl_check_board_image(struct spl_image_info *spl_image, | |
119 | const struct spl_boot_device *bootdev) | |
120 | { | |
121 | u32 csum = *(u32 *)(spl_image->load_addr + spl_image->size - 4); | |
122 | ||
123 | if (checksum32((void *)spl_image->load_addr, | |
124 | spl_image->size - 4) != csum) { | |
125 | printf("ERROR: Invalid data checksum in kwbimage\n"); | |
126 | return -EINVAL; | |
127 | } | |
128 | ||
129 | return 0; | |
130 | } | |
131 | ||
2226ca17 | 132 | int spl_parse_board_header(struct spl_image_info *spl_image, |
2e0429bc | 133 | const struct spl_boot_device *bootdev, |
2226ca17 T |
134 | const void *image_header, size_t size) |
135 | { | |
136 | const struct kwbimage_main_hdr_v1 *mhdr = image_header; | |
137 | ||
138 | if (size < sizeof(*mhdr)) { | |
139 | /* This should be compile time assert */ | |
140 | printf("FATAL ERROR: Image header size is too small\n"); | |
141 | hang(); | |
142 | } | |
143 | ||
144 | /* | |
145 | * Very basic check for image validity. We cannot check mhdr->checksum | |
146 | * as it is calculated also from variable length extended headers | |
147 | * (including SPL content) which is not included in U-Boot image_header. | |
148 | */ | |
149 | if (mhdr->version != 1 || | |
f830703f T |
150 | ((mhdr->headersz_msb << 16) | mhdr->headersz_lsb) < sizeof(*mhdr)) { |
151 | printf("ERROR: Invalid kwbimage v1\n"); | |
152 | return -EINVAL; | |
153 | } | |
154 | ||
37241ce1 MB |
155 | if (IS_ENABLED(CONFIG_SPL_SPI_FLASH_SUPPORT) && |
156 | bootdev->boot_device == BOOT_DEVICE_SPI && | |
f830703f T |
157 | mhdr->blockid != IBR_HDR_SPI_ID) { |
158 | printf("ERROR: Wrong blockid (0x%x) in SPI kwbimage\n", | |
159 | mhdr->blockid); | |
160 | return -EINVAL; | |
161 | } | |
f830703f | 162 | |
37241ce1 MB |
163 | if (IS_ENABLED(CONFIG_SPL_SATA) && |
164 | bootdev->boot_device == BOOT_DEVICE_SATA && | |
f830703f T |
165 | mhdr->blockid != IBR_HDR_SATA_ID) { |
166 | printf("ERROR: Wrong blockid (0x%x) in SATA kwbimage\n", | |
167 | mhdr->blockid); | |
168 | return -EINVAL; | |
169 | } | |
f830703f | 170 | |
37241ce1 MB |
171 | if (IS_ENABLED(CONFIG_SPL_MMC) && |
172 | (bootdev->boot_device == BOOT_DEVICE_MMC1 || | |
f830703f T |
173 | bootdev->boot_device == BOOT_DEVICE_MMC2 || |
174 | bootdev->boot_device == BOOT_DEVICE_MMC2_2) && | |
175 | mhdr->blockid != IBR_HDR_SDIO_ID) { | |
176 | printf("ERROR: Wrong blockid (0x%x) in SDIO kwbimage\n", | |
177 | mhdr->blockid); | |
2226ca17 T |
178 | return -EINVAL; |
179 | } | |
180 | ||
181 | spl_image->offset = mhdr->srcaddr; | |
182 | ||
2226ca17 T |
183 | /* |
184 | * For SATA srcaddr is specified in number of sectors. | |
185 | * The main header is must be stored at sector number 1. | |
186 | * This expects that sector size is 512 bytes and recalculates | |
187 | * data offset to bytes relative to the main header. | |
188 | */ | |
37241ce1 | 189 | if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID) { |
2226ca17 | 190 | if (spl_image->offset < 1) { |
62ee75a3 MB |
191 | printf("ERROR: Wrong srcaddr (0x%08x) in SATA kwbimage\n", |
192 | spl_image->offset); | |
2226ca17 T |
193 | return -EINVAL; |
194 | } | |
195 | spl_image->offset -= 1; | |
196 | spl_image->offset *= 512; | |
197 | } | |
2226ca17 | 198 | |
2226ca17 T |
199 | /* |
200 | * For SDIO (eMMC) srcaddr is specified in number of sectors. | |
201 | * This expects that sector size is 512 bytes and recalculates | |
202 | * data offset to bytes. | |
203 | */ | |
37241ce1 | 204 | if (IS_ENABLED(CONFIG_SPL_MMC) && mhdr->blockid == IBR_HDR_SDIO_ID) |
2226ca17 | 205 | spl_image->offset *= 512; |
2226ca17 | 206 | |
66f87485 T |
207 | if (spl_image->offset % 4 != 0) { |
208 | printf("ERROR: Wrong srcaddr (0x%08x) in kwbimage\n", | |
209 | spl_image->offset); | |
210 | return -EINVAL; | |
211 | } | |
212 | ||
213 | if (mhdr->blocksize <= 4 || mhdr->blocksize % 4 != 0) { | |
214 | printf("ERROR: Wrong blocksize (0x%08x) in kwbimage\n", | |
215 | mhdr->blocksize); | |
216 | return -EINVAL; | |
217 | } | |
218 | ||
2226ca17 T |
219 | spl_image->size = mhdr->blocksize; |
220 | spl_image->entry_point = mhdr->execaddr; | |
221 | spl_image->load_addr = mhdr->destaddr; | |
222 | spl_image->os = IH_OS_U_BOOT; | |
223 | spl_image->name = "U-Boot"; | |
224 | ||
225 | return 0; | |
226 | } | |
227 | ||
a5f88877 SR |
228 | u32 spl_boot_device(void) |
229 | { | |
abbf2179 T |
230 | u32 boot_device = get_boot_device(); |
231 | ||
2226ca17 | 232 | switch (boot_device) { |
abbf2179 T |
233 | /* |
234 | * Return to the BootROM to continue the Marvell xmodem | |
235 | * UART boot protocol. As initiated by the kwboot tool. | |
236 | * | |
237 | * This can only be done by the BootROM since the beginning | |
238 | * of the image is already read and interpreted by the BootROM. | |
239 | * SPL has no chance to receive this information. So we | |
240 | * need to return to the BootROM to enable this xmodem | |
241 | * UART download. Use SPL infrastructure to return to BootROM. | |
abbf2179 | 242 | */ |
abbf2179 | 243 | case BOOT_DEVICE_UART: |
abbf2179 | 244 | return BOOT_DEVICE_BOOTROM; |
2226ca17 T |
245 | |
246 | /* | |
247 | * If SPL is compiled with chosen boot_device support | |
248 | * then use SPL driver for loading U-Boot proper. | |
249 | */ | |
103c5f18 | 250 | #ifdef CONFIG_SPL_MMC |
2226ca17 T |
251 | case BOOT_DEVICE_MMC1: |
252 | return BOOT_DEVICE_MMC1; | |
253 | #endif | |
f7560376 | 254 | #ifdef CONFIG_SPL_SATA |
d73db304 T |
255 | case BOOT_DEVICE_SATA: |
256 | return BOOT_DEVICE_SATA; | |
2226ca17 T |
257 | #endif |
258 | #ifdef CONFIG_SPL_SPI_FLASH_SUPPORT | |
259 | case BOOT_DEVICE_SPI: | |
260 | return BOOT_DEVICE_SPI; | |
261 | #endif | |
262 | ||
263 | /* | |
264 | * If SPL is not compiled with chosen boot_device support | |
265 | * then return to the BootROM. BootROM supports loading | |
266 | * U-Boot proper from any valid boot_device present in SAR | |
267 | * register. | |
268 | */ | |
abbf2179 | 269 | default: |
2226ca17 | 270 | return BOOT_DEVICE_BOOTROM; |
abbf2179 | 271 | } |
b0f80b91 SR |
272 | } |
273 | ||
dc595e3e MB |
274 | #else |
275 | ||
276 | u32 spl_boot_device(void) | |
277 | { | |
278 | return BOOT_DEVICE_BOOTROM; | |
279 | } | |
280 | ||
281 | #endif | |
282 | ||
9d0225b7 T |
283 | int board_return_to_bootrom(struct spl_image_info *spl_image, |
284 | struct spl_boot_device *bootdev) | |
285 | { | |
286 | u32 *regs = *(u32 **)CONFIG_SPL_BOOTROM_SAVE; | |
287 | ||
288 | printf("Returning to BootROM (return address 0x%08x)...\n", regs[13]); | |
289 | return_to_bootrom(); | |
290 | ||
291 | /* NOTREACHED - return_to_bootrom() does not return */ | |
292 | hang(); | |
293 | } | |
294 | ||
b0f80b91 SR |
295 | void board_init_f(ulong dummy) |
296 | { | |
6451223a SR |
297 | int ret; |
298 | ||
e3cccf9e SR |
299 | /* |
300 | * Pin muxing needs to be done before UART output, since | |
301 | * on A38x the UART pins need some re-muxing for output | |
302 | * to work. | |
303 | */ | |
304 | board_early_init_f(); | |
305 | ||
f2100f6f SR |
306 | /* |
307 | * Use special translation offset for SPL. This needs to be | |
308 | * configured *before* spl_init() is called as this function | |
309 | * calls dm_init() which calls the bind functions of the | |
310 | * device drivers. Here the base address needs to be configured | |
311 | * (translated) correctly. | |
312 | */ | |
313 | gd->translation_offset = 0xd0000000 - 0xf1000000; | |
314 | ||
6451223a SR |
315 | ret = spl_init(); |
316 | if (ret) { | |
2e5d0aa3 | 317 | printf("spl_init() failed: %d\n", ret); |
6451223a SR |
318 | hang(); |
319 | } | |
320 | ||
b0f80b91 SR |
321 | preloader_console_init(); |
322 | ||
ade741b3 SR |
323 | timer_init(); |
324 | ||
09e89ab4 SR |
325 | /* Armada 375 does not support SerDes and DDR3 init yet */ |
326 | #if !defined(CONFIG_ARMADA_375) | |
b0f80b91 SR |
327 | /* First init the serdes PHY's */ |
328 | serdes_phy_config(); | |
329 | ||
330 | /* Setup DDR */ | |
7e1c0d0d T |
331 | ret = ddr3_init(); |
332 | if (ret) { | |
2e5d0aa3 | 333 | printf("ddr3_init() failed: %d\n", ret); |
871ee663 MB |
334 | if (IS_ENABLED(CONFIG_DDR_RESET_ON_TRAINING_FAILURE) && |
335 | get_boot_device() != BOOT_DEVICE_UART) | |
336 | reset_cpu(); | |
337 | else | |
338 | hang(); | |
7e1c0d0d | 339 | } |
09e89ab4 | 340 | #endif |
b0f80b91 | 341 | |
cc66ebde BS |
342 | /* Initialize Auto Voltage Scaling */ |
343 | mv_avs_init(); | |
344 | ||
ad91fdff CP |
345 | /* Update read timing control for PCIe */ |
346 | mv_rtc_config(); | |
b0f80b91 | 347 | } |