]>
Commit | Line | Data |
---|---|---|
4ae8bc43 SR |
1 | /* |
2 | * (C) Copyright 2000-2009 | |
3 | * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com | |
4 | * | |
5 | * Copyright (C) 2012 Stefan Roese <sr@denx.de> | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
4ae8bc43 SR |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <image.h> | |
12 | #include <linux/compiler.h> | |
13 | #include <asm/io.h> | |
14 | #include <asm/arch/spr_defs.h> | |
15 | #include <linux/mtd/st_smi.h> | |
16 | ||
17 | static const char kernel_name[] = "Linux"; | |
18 | static const char loader_name[] = "U-Boot"; | |
19 | ||
20 | int image_check_header(image_header_t *hdr, const char *name) | |
21 | { | |
22 | if (image_check_magic(hdr) && | |
23 | (!strncmp(image_get_name(hdr), name, strlen(name))) && | |
24 | image_check_hcrc(hdr)) { | |
25 | return 1; | |
26 | } | |
27 | return 0; | |
28 | } | |
29 | ||
30 | int image_check_data(image_header_t *hdr) | |
31 | { | |
32 | if (image_check_dcrc(hdr)) | |
33 | return 1; | |
34 | ||
35 | return 0; | |
36 | } | |
37 | ||
38 | /* | |
39 | * SNOR (Serial NOR flash) related functions | |
40 | */ | |
41 | void snor_init(void) | |
42 | { | |
43 | struct smi_regs *const smicntl = | |
44 | (struct smi_regs * const)CONFIG_SYS_SMI_BASE; | |
45 | ||
46 | /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */ | |
47 | writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4, | |
48 | &smicntl->smi_cr1); | |
49 | } | |
50 | ||
51 | static int snor_image_load(u8 *load_addr, void (**image_p)(void), | |
52 | const char *image_name) | |
53 | { | |
54 | image_header_t *header; | |
55 | ||
56 | /* | |
57 | * Since calculating the crc in the SNOR flash does not | |
58 | * work, we copy the image to the destination address | |
59 | * minus the header size. And point the header to this | |
60 | * new destination. This will not work for address 0 | |
61 | * of course. | |
62 | */ | |
63 | header = (image_header_t *)load_addr; | |
64 | memcpy((ulong *)(image_get_load(header) - sizeof(image_header_t)), | |
65 | (const ulong *)load_addr, | |
66 | image_get_data_size(header) + sizeof(image_header_t)); | |
67 | header = (image_header_t *)(image_get_load(header) - | |
68 | sizeof(image_header_t)); | |
69 | ||
70 | if (image_check_header(header, image_name)) { | |
71 | if (image_check_data(header)) { | |
72 | /* Jump to boot image */ | |
73 | *image_p = (void *)image_get_load(header); | |
74 | return 1; | |
75 | } | |
76 | } | |
77 | ||
78 | return 0; | |
79 | } | |
80 | ||
81 | static void boot_image(void (*image)(void)) | |
82 | { | |
83 | void (*funcp)(void) __noreturn = (void *)image; | |
84 | ||
85 | (*funcp)(); | |
86 | } | |
87 | ||
88 | /* | |
89 | * spl_boot: | |
90 | * | |
91 | * All supported booting types of all supported SoCs are listed here. | |
92 | * Generic readback APIs are provided for each supported booting type | |
93 | * eg. nand_read_skip_bad | |
94 | */ | |
95 | u32 spl_boot(void) | |
96 | { | |
97 | void (*image)(void); | |
98 | ||
99 | #ifdef CONFIG_SPEAR_USBTTY | |
100 | plat_late_init(); | |
101 | return 1; | |
102 | #endif | |
103 | ||
104 | /* | |
105 | * All the supported booting devices are listed here. Each of | |
106 | * the booting type supported by the platform would define the | |
472d5460 | 107 | * macro xxx_BOOT_SUPPORTED to true. |
4ae8bc43 SR |
108 | */ |
109 | ||
110 | if (SNOR_BOOT_SUPPORTED && snor_boot_selected()) { | |
111 | /* SNOR-SMI initialization */ | |
112 | snor_init(); | |
113 | ||
114 | serial_puts("Booting via SNOR\n"); | |
115 | /* Serial NOR booting */ | |
116 | if (1 == snor_image_load((u8 *)CONFIG_SYS_UBOOT_BASE, | |
117 | &image, loader_name)) { | |
118 | /* Platform related late initialasations */ | |
119 | plat_late_init(); | |
120 | ||
121 | /* Jump to boot image */ | |
122 | serial_puts("Jumping to U-Boot\n"); | |
123 | boot_image(image); | |
124 | return 1; | |
125 | } | |
126 | } | |
127 | ||
128 | if (NAND_BOOT_SUPPORTED && nand_boot_selected()) { | |
129 | /* NAND booting */ | |
130 | /* Not ported from XLoader to SPL yet */ | |
131 | return 0; | |
132 | } | |
133 | ||
134 | if (PNOR_BOOT_SUPPORTED && pnor_boot_selected()) { | |
135 | /* PNOR booting */ | |
136 | /* Not ported from XLoader to SPL yet */ | |
137 | return 0; | |
138 | } | |
139 | ||
140 | if (MMC_BOOT_SUPPORTED && mmc_boot_selected()) { | |
141 | /* MMC booting */ | |
142 | /* Not ported from XLoader to SPL yet */ | |
143 | return 0; | |
144 | } | |
145 | ||
146 | if (SPI_BOOT_SUPPORTED && spi_boot_selected()) { | |
147 | /* SPI booting */ | |
148 | /* Not supported for any platform as of now */ | |
149 | return 0; | |
150 | } | |
151 | ||
152 | if (I2C_BOOT_SUPPORTED && i2c_boot_selected()) { | |
153 | /* I2C booting */ | |
154 | /* Not supported for any platform as of now */ | |
155 | return 0; | |
156 | } | |
157 | ||
158 | /* | |
159 | * All booting types without memory are listed as below | |
160 | * Control has to be returned to BootROM in case of all | |
161 | * the following booting scenarios | |
162 | */ | |
163 | ||
164 | if (USB_BOOT_SUPPORTED && usb_boot_selected()) { | |
165 | plat_late_init(); | |
166 | return 1; | |
167 | } | |
168 | ||
169 | if (TFTP_BOOT_SUPPORTED && tftp_boot_selected()) { | |
170 | plat_late_init(); | |
171 | return 1; | |
172 | } | |
173 | ||
174 | if (UART_BOOT_SUPPORTED && uart_boot_selected()) { | |
175 | plat_late_init(); | |
176 | return 1; | |
177 | } | |
178 | ||
179 | /* Ideally, the control should not reach here. */ | |
180 | hang(); | |
181 | } |