]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0 |
4bbc0245 SG |
2 | /* |
3 | * Copyright (c) 2016 Google, Inc | |
4bbc0245 SG |
4 | */ |
5 | ||
6 | #include <common.h> | |
9edefc27 | 7 | #include <cpu_func.h> |
4bbc0245 | 8 | #include <debug_uart.h> |
c0e2c81d | 9 | #include <dm.h> |
7c03caf6 | 10 | #include <malloc.h> |
4bbc0245 | 11 | #include <spl.h> |
c0e2c81d | 12 | #include <syscon.h> |
4bbc0245 | 13 | #include <asm/cpu.h> |
c0e2c81d | 14 | #include <asm/cpu_common.h> |
7c03caf6 | 15 | #include <asm/mrccache.h> |
4bbc0245 | 16 | #include <asm/mtrr.h> |
c0e2c81d | 17 | #include <asm/pci.h> |
4bbc0245 | 18 | #include <asm/processor.h> |
daade119 | 19 | #include <asm/spl.h> |
4bbc0245 SG |
20 | #include <asm-generic/sections.h> |
21 | ||
22 | DECLARE_GLOBAL_DATA_PTR; | |
23 | ||
8f60ea00 BM |
24 | __weak int arch_cpu_init_dm(void) |
25 | { | |
26 | return 0; | |
27 | } | |
28 | ||
c0e2c81d SG |
29 | #ifdef CONFIG_TPL |
30 | ||
31 | static int set_max_freq(void) | |
32 | { | |
33 | if (cpu_get_burst_mode_state() == BURST_MODE_UNAVAILABLE) { | |
34 | /* | |
35 | * Burst Mode has been factory-configured as disabled and is not | |
36 | * available in this physical processor package | |
37 | */ | |
38 | debug("Burst Mode is factory-disabled\n"); | |
39 | return -ENOENT; | |
40 | } | |
41 | ||
42 | /* Enable burst mode */ | |
43 | cpu_set_burst_mode(true); | |
44 | ||
45 | /* Enable speed step */ | |
46 | cpu_set_eist(true); | |
47 | ||
48 | /* Set P-State ratio */ | |
49 | cpu_set_p_state_to_turbo_ratio(); | |
50 | ||
51 | return 0; | |
52 | } | |
53 | #endif | |
54 | ||
4bbc0245 SG |
55 | static int x86_spl_init(void) |
56 | { | |
7c03caf6 | 57 | #ifndef CONFIG_TPL |
4bbc0245 SG |
58 | /* |
59 | * TODO([email protected]): We use this area of RAM for the stack | |
60 | * and global_data in SPL. Once U-Boot starts up and releocates it | |
61 | * is not needed. We could make this a CONFIG option or perhaps | |
62 | * place it immediately below CONFIG_SYS_TEXT_BASE. | |
63 | */ | |
64 | char *ptr = (char *)0x110000; | |
c0e2c81d SG |
65 | #else |
66 | struct udevice *punit; | |
7c03caf6 | 67 | #endif |
4bbc0245 SG |
68 | int ret; |
69 | ||
70 | debug("%s starting\n", __func__); | |
0e72ac71 SG |
71 | if (IS_ENABLED(TPL)) |
72 | ret = x86_cpu_reinit_f(); | |
73 | else | |
74 | ret = x86_cpu_init_f(); | |
4bbc0245 SG |
75 | ret = spl_init(); |
76 | if (ret) { | |
77 | debug("%s: spl_init() failed\n", __func__); | |
78 | return ret; | |
79 | } | |
4bbc0245 SG |
80 | ret = arch_cpu_init(); |
81 | if (ret) { | |
82 | debug("%s: arch_cpu_init() failed\n", __func__); | |
83 | return ret; | |
84 | } | |
7c03caf6 | 85 | #ifndef CONFIG_TPL |
4bbc0245 SG |
86 | ret = arch_cpu_init_dm(); |
87 | if (ret) { | |
88 | debug("%s: arch_cpu_init_dm() failed\n", __func__); | |
89 | return ret; | |
90 | } | |
7c03caf6 | 91 | #endif |
3ff0900a | 92 | preloader_console_init(); |
7c03caf6 | 93 | #ifndef CONFIG_TPL |
4bbc0245 SG |
94 | ret = print_cpuinfo(); |
95 | if (ret) { | |
96 | debug("%s: print_cpuinfo() failed\n", __func__); | |
97 | return ret; | |
98 | } | |
7c03caf6 | 99 | #endif |
4bbc0245 SG |
100 | ret = dram_init(); |
101 | if (ret) { | |
102 | debug("%s: dram_init() failed\n", __func__); | |
103 | return ret; | |
104 | } | |
7c03caf6 SG |
105 | if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) { |
106 | ret = mrccache_spl_save(); | |
107 | if (ret) | |
108 | debug("%s: Failed to write to mrccache (err=%d)\n", | |
109 | __func__, ret); | |
110 | } | |
111 | ||
112 | #ifndef CONFIG_TPL | |
4bbc0245 SG |
113 | memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start); |
114 | ||
115 | /* TODO([email protected]): Consider calling cpu_init_r() here */ | |
116 | ret = interrupt_init(); | |
117 | if (ret) { | |
118 | debug("%s: interrupt_init() failed\n", __func__); | |
119 | return ret; | |
120 | } | |
121 | ||
122 | /* | |
123 | * The stack grows down from ptr. Put the global data at ptr. This | |
124 | * will only be used for SPL. Once SPL loads U-Boot proper it will | |
125 | * set up its own stack. | |
126 | */ | |
127 | gd->new_gd = (struct global_data *)ptr; | |
128 | memcpy(gd->new_gd, gd, sizeof(*gd)); | |
129 | arch_setup_gd(gd->new_gd); | |
130 | gd->start_addr_sp = (ulong)ptr; | |
131 | ||
132 | /* Cache the SPI flash. Otherwise copying the code to RAM takes ages */ | |
133 | ret = mtrr_add_request(MTRR_TYPE_WRBACK, | |
134 | (1ULL << 32) - CONFIG_XIP_ROM_SIZE, | |
135 | CONFIG_XIP_ROM_SIZE); | |
136 | if (ret) { | |
7c03caf6 | 137 | debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret); |
4bbc0245 SG |
138 | return ret; |
139 | } | |
7c03caf6 | 140 | mtrr_commit(true); |
c0e2c81d SG |
141 | #else |
142 | ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit); | |
143 | if (ret) | |
144 | debug("Could not find PUNIT (err=%d)\n", ret); | |
145 | ||
146 | ret = set_max_freq(); | |
147 | if (ret) | |
148 | debug("Failed to set CPU frequency (err=%d)\n", ret); | |
7c03caf6 | 149 | #endif |
4bbc0245 SG |
150 | |
151 | return 0; | |
152 | } | |
153 | ||
154 | void board_init_f(ulong flags) | |
155 | { | |
156 | int ret; | |
157 | ||
158 | ret = x86_spl_init(); | |
159 | if (ret) { | |
160 | debug("Error %d\n", ret); | |
3d95688c | 161 | panic("x86_spl_init fail"); |
4bbc0245 | 162 | } |
7c03caf6 SG |
163 | #ifdef CONFIG_TPL |
164 | gd->bd = malloc(sizeof(*gd->bd)); | |
165 | if (!gd->bd) { | |
166 | printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd)); | |
167 | hang(); | |
168 | } | |
169 | board_init_r(gd, 0); | |
170 | #else | |
4bbc0245 SG |
171 | /* Uninit CAR and jump to board_init_f_r() */ |
172 | board_init_f_r_trampoline(gd->start_addr_sp); | |
7c03caf6 | 173 | #endif |
4bbc0245 SG |
174 | } |
175 | ||
176 | void board_init_f_r(void) | |
177 | { | |
178 | init_cache_f_r(); | |
179 | gd->flags &= ~GD_FLG_SERIAL_READY; | |
180 | debug("cache status %d\n", dcache_status()); | |
181 | board_init_r(gd, 0); | |
182 | } | |
183 | ||
184 | u32 spl_boot_device(void) | |
185 | { | |
daade119 | 186 | return BOOT_DEVICE_SPI_MMAP; |
4bbc0245 SG |
187 | } |
188 | ||
189 | int spl_start_uboot(void) | |
190 | { | |
191 | return 0; | |
192 | } | |
193 | ||
194 | void spl_board_announce_boot_device(void) | |
195 | { | |
196 | printf("SPI flash"); | |
197 | } | |
198 | ||
199 | static int spl_board_load_image(struct spl_image_info *spl_image, | |
200 | struct spl_boot_device *bootdev) | |
201 | { | |
202 | spl_image->size = CONFIG_SYS_MONITOR_LEN; | |
203 | spl_image->entry_point = CONFIG_SYS_TEXT_BASE; | |
204 | spl_image->load_addr = CONFIG_SYS_TEXT_BASE; | |
205 | spl_image->os = IH_OS_U_BOOT; | |
206 | spl_image->name = "U-Boot"; | |
207 | ||
208 | debug("Loading to %lx\n", spl_image->load_addr); | |
209 | ||
210 | return 0; | |
211 | } | |
daade119 | 212 | SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image); |
4bbc0245 SG |
213 | |
214 | int spl_spi_load_image(void) | |
215 | { | |
216 | return -EPERM; | |
217 | } | |
218 | ||
7c03caf6 | 219 | #ifdef CONFIG_X86_RUN_64BIT |
4bbc0245 SG |
220 | void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) |
221 | { | |
222 | int ret; | |
223 | ||
224 | printf("Jumping to 64-bit U-Boot: Note many features are missing\n"); | |
225 | ret = cpu_jump_to_64bit_uboot(spl_image->entry_point); | |
226 | debug("ret=%d\n", ret); | |
14dd93be | 227 | hang(); |
4bbc0245 | 228 | } |
7c03caf6 SG |
229 | #endif |
230 | ||
231 | void spl_board_init(void) | |
232 | { | |
233 | #ifndef CONFIG_TPL | |
234 | preloader_console_init(); | |
235 | #endif | |
236 | } |