]>
Commit | Line | Data |
---|---|---|
828d9af5 BM |
1 | /* |
2 | * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
6df7ffea | 8 | #include <mmc.h> |
828d9af5 | 9 | #include <asm/io.h> |
911d6f69 | 10 | #include <asm/ioapic.h> |
2fc2b83a | 11 | #include <asm/mrccache.h> |
c6d4705f | 12 | #include <asm/mtrr.h> |
828d9af5 BM |
13 | #include <asm/pci.h> |
14 | #include <asm/post.h> | |
b162257d BM |
15 | #include <asm/arch/device.h> |
16 | #include <asm/arch/msg_port.h> | |
17 | #include <asm/arch/quark.h> | |
18 | ||
6df7ffea BM |
19 | static struct pci_device_id mmc_supported[] = { |
20 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO }, | |
4abe8e40 | 21 | {}, |
6df7ffea BM |
22 | }; |
23 | ||
c6d4705f BM |
24 | static void quark_setup_mtrr(void) |
25 | { | |
26 | u32 base, mask; | |
27 | int i; | |
28 | ||
29 | disable_caches(); | |
30 | ||
31 | /* mark the VGA RAM area as uncacheable */ | |
32 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_A0000, | |
33 | MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE)); | |
34 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_B0000, | |
35 | MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE)); | |
36 | ||
37 | /* mark other fixed range areas as cacheable */ | |
38 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_64K_00000, | |
39 | MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); | |
40 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_64K_40000, | |
41 | MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); | |
42 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_80000, | |
43 | MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); | |
44 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_90000, | |
45 | MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); | |
46 | for (i = MTRR_FIX_4K_C0000; i <= MTRR_FIX_4K_FC000; i++) | |
47 | msg_port_write(MSG_PORT_HOST_BRIDGE, i, | |
48 | MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); | |
49 | ||
50 | /* variable range MTRR#0: ROM area */ | |
51 | mask = ~(CONFIG_SYS_MONITOR_LEN - 1); | |
52 | base = CONFIG_SYS_TEXT_BASE & mask; | |
53 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_ROM), | |
54 | base | MTRR_TYPE_WRBACK); | |
55 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_ROM), | |
56 | mask | MTRR_PHYS_MASK_VALID); | |
57 | ||
58 | /* variable range MTRR#1: eSRAM area */ | |
59 | mask = ~(ESRAM_SIZE - 1); | |
60 | base = CONFIG_ESRAM_BASE & mask; | |
61 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_ESRAM), | |
62 | base | MTRR_TYPE_WRBACK); | |
63 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_ESRAM), | |
64 | mask | MTRR_PHYS_MASK_VALID); | |
65 | ||
66 | /* enable both variable and fixed range MTRRs */ | |
67 | msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_DEF_TYPE, | |
68 | MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN); | |
69 | ||
70 | enable_caches(); | |
71 | } | |
72 | ||
b162257d BM |
73 | static void quark_setup_bars(void) |
74 | { | |
75 | /* GPIO - D31:F0:R44h */ | |
aa09505b BM |
76 | qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GBA, |
77 | CONFIG_GPIO_BASE | IO_BAR_EN); | |
b162257d BM |
78 | |
79 | /* ACPI PM1 Block - D31:F0:R48h */ | |
aa09505b BM |
80 | qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_PM1BLK, |
81 | CONFIG_ACPI_PM1_BASE | IO_BAR_EN); | |
b162257d BM |
82 | |
83 | /* GPE0 - D31:F0:R4Ch */ | |
aa09505b BM |
84 | qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GPE0BLK, |
85 | CONFIG_ACPI_GPE0_BASE | IO_BAR_EN); | |
b162257d BM |
86 | |
87 | /* WDT - D31:F0:R84h */ | |
aa09505b BM |
88 | qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_WDTBA, |
89 | CONFIG_WDT_BASE | IO_BAR_EN); | |
b162257d BM |
90 | |
91 | /* RCBA - D31:F0:RF0h */ | |
aa09505b BM |
92 | qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, |
93 | CONFIG_RCBA_BASE | MEM_BAR_EN); | |
b162257d BM |
94 | |
95 | /* ACPI P Block - Msg Port 04:R70h */ | |
96 | msg_port_write(MSG_PORT_RMU, PBLK_BA, | |
97 | CONFIG_ACPI_PBLK_BASE | IO_BAR_EN); | |
98 | ||
99 | /* SPI DMA - Msg Port 04:R7Ah */ | |
100 | msg_port_write(MSG_PORT_RMU, SPI_DMA_BA, | |
101 | CONFIG_SPI_DMA_BASE | IO_BAR_EN); | |
102 | ||
103 | /* PCIe ECAM */ | |
104 | msg_port_write(MSG_PORT_MEM_ARBITER, AEC_CTRL, | |
105 | CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN); | |
106 | msg_port_write(MSG_PORT_HOST_BRIDGE, HEC_REG, | |
107 | CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN); | |
108 | } | |
828d9af5 | 109 | |
316fd392 BM |
110 | static void quark_pcie_early_init(void) |
111 | { | |
316fd392 BM |
112 | /* |
113 | * Step1: Assert PCIe signal PERST# | |
114 | * | |
115 | * The CPU interface to the PERST# signal is platform dependent. | |
116 | * Call the board-specific codes to perform this task. | |
117 | */ | |
118 | board_assert_perst(); | |
119 | ||
120 | /* Step2: PHY common lane reset */ | |
8e368302 | 121 | msg_port_alt_setbits(MSG_PORT_SOC_UNIT, PCIE_CFG, PCIE_PHY_LANE_RST); |
316fd392 BM |
122 | /* wait 1 ms for PHY common lane reset */ |
123 | mdelay(1); | |
124 | ||
125 | /* Step3: PHY sideband interface reset and controller main reset */ | |
8e368302 BM |
126 | msg_port_alt_setbits(MSG_PORT_SOC_UNIT, PCIE_CFG, |
127 | PCIE_PHY_SB_RST | PCIE_CTLR_MAIN_RST); | |
316fd392 BM |
128 | /* wait 80ms for PLL to lock */ |
129 | mdelay(80); | |
130 | ||
131 | /* Step4: Controller sideband interface reset */ | |
8e368302 | 132 | msg_port_alt_setbits(MSG_PORT_SOC_UNIT, PCIE_CFG, PCIE_CTLR_SB_RST); |
316fd392 BM |
133 | /* wait 20ms for controller sideband interface reset */ |
134 | mdelay(20); | |
135 | ||
136 | /* Step5: De-assert PERST# */ | |
137 | board_deassert_perst(); | |
138 | ||
139 | /* Step6: Controller primary interface reset */ | |
8e368302 | 140 | msg_port_alt_setbits(MSG_PORT_SOC_UNIT, PCIE_CFG, PCIE_CTLR_PRI_RST); |
316fd392 BM |
141 | |
142 | /* Mixer Load Lane 0 */ | |
8e368302 BM |
143 | msg_port_io_clrbits(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L0, |
144 | (1 << 6) | (1 << 7)); | |
316fd392 BM |
145 | |
146 | /* Mixer Load Lane 1 */ | |
8e368302 BM |
147 | msg_port_io_clrbits(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L1, |
148 | (1 << 6) | (1 << 7)); | |
316fd392 BM |
149 | } |
150 | ||
b06862b9 BM |
151 | static void quark_usb_early_init(void) |
152 | { | |
b06862b9 BM |
153 | /* The sequence below comes from Quark firmware writer guide */ |
154 | ||
8e368302 BM |
155 | msg_port_alt_clrsetbits(MSG_PORT_USB_AFE, USB2_GLOBAL_PORT, |
156 | 1 << 1, (1 << 6) | (1 << 7)); | |
b06862b9 | 157 | |
8e368302 BM |
158 | msg_port_alt_clrsetbits(MSG_PORT_USB_AFE, USB2_COMPBG, |
159 | (1 << 8) | (1 << 9), (1 << 7) | (1 << 10)); | |
b06862b9 | 160 | |
8e368302 | 161 | msg_port_alt_setbits(MSG_PORT_USB_AFE, USB2_PLL2, 1 << 29); |
b06862b9 | 162 | |
8e368302 | 163 | msg_port_alt_setbits(MSG_PORT_USB_AFE, USB2_PLL1, 1 << 1); |
b06862b9 | 164 | |
8e368302 BM |
165 | msg_port_alt_clrsetbits(MSG_PORT_USB_AFE, USB2_PLL1, |
166 | (1 << 3) | (1 << 4) | (1 << 5), 1 << 6); | |
b06862b9 | 167 | |
8e368302 | 168 | msg_port_alt_clrbits(MSG_PORT_USB_AFE, USB2_PLL2, 1 << 29); |
b06862b9 | 169 | |
8e368302 | 170 | msg_port_alt_setbits(MSG_PORT_USB_AFE, USB2_PLL2, 1 << 24); |
b06862b9 BM |
171 | } |
172 | ||
554778c2 BM |
173 | static void quark_thermal_early_init(void) |
174 | { | |
175 | /* The sequence below comes from Quark firmware writer guide */ | |
176 | ||
177 | /* thermal sensor mode config */ | |
178 | msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG1, | |
179 | (1 << 3) | (1 << 4) | (1 << 5), 1 << 5); | |
180 | msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG1, | |
181 | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | | |
182 | (1 << 12), 1 << 9); | |
183 | msg_port_alt_setbits(MSG_PORT_SOC_UNIT, TS_CFG1, 1 << 14); | |
184 | msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG1, 1 << 17); | |
185 | msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG1, 1 << 18); | |
186 | msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG2, 0xffff, 0x011f); | |
187 | msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG3, 0xff, 0x17); | |
188 | msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG3, | |
189 | (1 << 8) | (1 << 9), 1 << 8); | |
190 | msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG3, 0xff000000); | |
191 | msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG4, | |
192 | 0x7ff800, 0xc8 << 11); | |
193 | ||
194 | /* thermal monitor catastrophic trip set point (105 celsius) */ | |
195 | msg_port_clrsetbits(MSG_PORT_RMU, TS_TRIP, 0xff, 155); | |
196 | ||
197 | /* thermal monitor catastrophic trip clear point (0 celsius) */ | |
198 | msg_port_clrsetbits(MSG_PORT_RMU, TS_TRIP, 0xff0000, 50 << 16); | |
199 | ||
200 | /* take thermal sensor out of reset */ | |
201 | msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG4, 1 << 0); | |
202 | ||
203 | /* enable thermal monitor */ | |
204 | msg_port_setbits(MSG_PORT_RMU, TS_MODE, 1 << 15); | |
205 | ||
206 | /* lock all thermal configuration */ | |
207 | msg_port_setbits(MSG_PORT_RMU, RMU_CTRL, (1 << 5) | (1 << 6)); | |
208 | } | |
209 | ||
f82a7840 BM |
210 | static void quark_enable_legacy_seg(void) |
211 | { | |
8e368302 BM |
212 | msg_port_setbits(MSG_PORT_HOST_BRIDGE, HMISC2, |
213 | HMISC2_SEGE | HMISC2_SEGF | HMISC2_SEGAB); | |
f82a7840 BM |
214 | } |
215 | ||
828d9af5 BM |
216 | int arch_cpu_init(void) |
217 | { | |
828d9af5 BM |
218 | int ret; |
219 | ||
220 | post_code(POST_CPU_INIT); | |
828d9af5 BM |
221 | |
222 | ret = x86_cpu_init_f(); | |
223 | if (ret) | |
224 | return ret; | |
225 | ||
c6d4705f BM |
226 | /* |
227 | * Quark SoC does not support MSR MTRRs. Fixed and variable range MTRRs | |
228 | * are accessed indirectly via the message port and not the traditional | |
229 | * MSR mechanism. Only UC, WT and WB cache types are supported. | |
230 | */ | |
231 | quark_setup_mtrr(); | |
232 | ||
b162257d BM |
233 | /* |
234 | * Quark SoC has some non-standard BARs (excluding PCI standard BARs) | |
235 | * which need be initialized with suggested values | |
236 | */ | |
237 | quark_setup_bars(); | |
238 | ||
b06862b9 BM |
239 | /* Initialize USB2 PHY */ |
240 | quark_usb_early_init(); | |
241 | ||
554778c2 BM |
242 | /* Initialize thermal sensor */ |
243 | quark_thermal_early_init(); | |
244 | ||
f82a7840 BM |
245 | /* Turn on legacy segments (A/B/E/F) decode to system RAM */ |
246 | quark_enable_legacy_seg(); | |
247 | ||
828d9af5 BM |
248 | return 0; |
249 | } | |
250 | ||
6071cd62 BM |
251 | int arch_cpu_init_dm(void) |
252 | { | |
253 | /* | |
254 | * Initialize PCIe controller | |
255 | * | |
256 | * Quark SoC holds the PCIe controller in reset following a power on. | |
257 | * U-Boot needs to release the PCIe controller from reset. The PCIe | |
258 | * controller (D23:F0/F1) will not be visible in PCI configuration | |
259 | * space and any access to its PCI configuration registers will cause | |
260 | * system hang while it is held in reset. | |
261 | */ | |
262 | quark_pcie_early_init(); | |
263 | ||
264 | return 0; | |
265 | } | |
266 | ||
76d1d02f SG |
267 | int checkcpu(void) |
268 | { | |
269 | return 0; | |
270 | } | |
271 | ||
828d9af5 BM |
272 | int print_cpuinfo(void) |
273 | { | |
274 | post_code(POST_CPU_INFO); | |
275 | return default_print_cpuinfo(); | |
276 | } | |
277 | ||
278 | void reset_cpu(ulong addr) | |
279 | { | |
280 | /* cold reset */ | |
ebebf059 | 281 | x86_full_reset(); |
828d9af5 | 282 | } |
6df7ffea | 283 | |
2afb6230 BM |
284 | static void quark_pcie_init(void) |
285 | { | |
286 | u32 val; | |
287 | ||
288 | /* PCIe upstream non-posted & posted request size */ | |
289 | qrk_pci_write_config_dword(QUARK_PCIE0, PCIE_RP_CCFG, | |
290 | CCFG_UPRS | CCFG_UNRS); | |
291 | qrk_pci_write_config_dword(QUARK_PCIE1, PCIE_RP_CCFG, | |
292 | CCFG_UPRS | CCFG_UNRS); | |
293 | ||
294 | /* PCIe packet fast transmit mode (IPF) */ | |
295 | qrk_pci_write_config_dword(QUARK_PCIE0, PCIE_RP_MPC2, MPC2_IPF); | |
296 | qrk_pci_write_config_dword(QUARK_PCIE1, PCIE_RP_MPC2, MPC2_IPF); | |
297 | ||
298 | /* PCIe message bus idle counter (SBIC) */ | |
299 | qrk_pci_read_config_dword(QUARK_PCIE0, PCIE_RP_MBC, &val); | |
300 | val |= MBC_SBIC; | |
301 | qrk_pci_write_config_dword(QUARK_PCIE0, PCIE_RP_MBC, val); | |
302 | qrk_pci_read_config_dword(QUARK_PCIE1, PCIE_RP_MBC, &val); | |
303 | val |= MBC_SBIC; | |
304 | qrk_pci_write_config_dword(QUARK_PCIE1, PCIE_RP_MBC, val); | |
305 | } | |
306 | ||
307 | static void quark_usb_init(void) | |
308 | { | |
309 | u32 bar; | |
310 | ||
311 | /* Change USB EHCI packet buffer OUT/IN threshold */ | |
312 | qrk_pci_read_config_dword(QUARK_USB_EHCI, PCI_BASE_ADDRESS_0, &bar); | |
313 | writel((0x7f << 16) | 0x7f, bar + EHCI_INSNREG01); | |
314 | ||
315 | /* Disable USB device interrupts */ | |
316 | qrk_pci_read_config_dword(QUARK_USB_DEVICE, PCI_BASE_ADDRESS_0, &bar); | |
317 | writel(0x7f, bar + USBD_INT_MASK); | |
318 | writel((0xf << 16) | 0xf, bar + USBD_EP_INT_MASK); | |
319 | writel((0xf << 16) | 0xf, bar + USBD_EP_INT_STS); | |
320 | } | |
321 | ||
322 | int arch_early_init_r(void) | |
323 | { | |
324 | quark_pcie_init(); | |
325 | ||
326 | quark_usb_init(); | |
327 | ||
328 | return 0; | |
329 | } | |
330 | ||
6df7ffea BM |
331 | int cpu_mmc_init(bd_t *bis) |
332 | { | |
4abe8e40 | 333 | return pci_mmc_init("Quark SDHCI", mmc_supported); |
6df7ffea | 334 | } |
e4ad6031 | 335 | |
05b98ec3 BM |
336 | int arch_misc_init(void) |
337 | { | |
2fc2b83a BM |
338 | #ifdef CONFIG_ENABLE_MRC_CACHE |
339 | /* | |
340 | * We intend not to check any return value here, as even MRC cache | |
341 | * is not saved successfully, it is not a severe error that will | |
342 | * prevent system from continuing to boot. | |
343 | */ | |
344 | mrccache_save(); | |
345 | #endif | |
346 | ||
911d6f69 BM |
347 | /* Assign a unique I/O APIC ID */ |
348 | io_apic_set_id(1); | |
349 | ||
12d6929e | 350 | return 0; |
05b98ec3 | 351 | } |
2afb6230 BM |
352 | |
353 | void board_final_cleanup(void) | |
354 | { | |
355 | struct quark_rcba *rcba; | |
356 | u32 base, val; | |
357 | ||
358 | qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, &base); | |
359 | base &= ~MEM_BAR_EN; | |
360 | rcba = (struct quark_rcba *)base; | |
361 | ||
362 | /* Initialize 'Component ID' to zero */ | |
363 | val = readl(&rcba->esd); | |
364 | val &= ~0xff0000; | |
365 | writel(val, &rcba->esd); | |
366 | ||
693b5f6c BM |
367 | /* Lock HMBOUND for security */ |
368 | msg_port_setbits(MSG_PORT_HOST_BRIDGE, HM_BOUND, HM_BOUND_LOCK); | |
369 | ||
2afb6230 BM |
370 | return; |
371 | } |