1c859f2a7SLey Foon Tan // SPDX-License-Identifier: GPL-2.0+
2c859f2a7SLey Foon Tan /*
3c859f2a7SLey Foon Tan * Copyright (C) 2012 Altera Corporation <www.altera.com>
4c859f2a7SLey Foon Tan */
5c859f2a7SLey Foon Tan
6c859f2a7SLey Foon Tan #include <common.h>
7c859f2a7SLey Foon Tan #include <asm/io.h>
8*4a9743f7SMarek Vasut #include <asm/pl310.h>
9c859f2a7SLey Foon Tan #include <asm/u-boot.h>
10c859f2a7SLey Foon Tan #include <asm/utils.h>
11c859f2a7SLey Foon Tan #include <image.h>
12c859f2a7SLey Foon Tan #include <asm/arch/reset_manager.h>
13c859f2a7SLey Foon Tan #include <spl.h>
14c859f2a7SLey Foon Tan #include <asm/arch/system_manager.h>
15c859f2a7SLey Foon Tan #include <asm/arch/freeze_controller.h>
16c859f2a7SLey Foon Tan #include <asm/arch/clock_manager.h>
17c859f2a7SLey Foon Tan #include <asm/arch/misc.h>
18c859f2a7SLey Foon Tan #include <asm/arch/scan_manager.h>
19c859f2a7SLey Foon Tan #include <asm/arch/sdram.h>
20c859f2a7SLey Foon Tan #include <asm/sections.h>
21c0b4fc1aSSimon Goldschmidt #include <debug_uart.h>
22c859f2a7SLey Foon Tan #include <fdtdec.h>
23c859f2a7SLey Foon Tan #include <watchdog.h>
24c859f2a7SLey Foon Tan
25c859f2a7SLey Foon Tan DECLARE_GLOBAL_DATA_PTR;
26c859f2a7SLey Foon Tan
27*4a9743f7SMarek Vasut static struct pl310_regs *const pl310 =
28*4a9743f7SMarek Vasut (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
29c859f2a7SLey Foon Tan static const struct socfpga_system_manager *sysmgr_regs =
30c859f2a7SLey Foon Tan (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
31c859f2a7SLey Foon Tan
spl_boot_device(void)32c859f2a7SLey Foon Tan u32 spl_boot_device(void)
33c859f2a7SLey Foon Tan {
34c859f2a7SLey Foon Tan const u32 bsel = readl(&sysmgr_regs->bootinfo);
35c859f2a7SLey Foon Tan
36c859f2a7SLey Foon Tan switch (SYSMGR_GET_BOOTINFO_BSEL(bsel)) {
37c859f2a7SLey Foon Tan case 0x1: /* FPGA (HPS2FPGA Bridge) */
38c859f2a7SLey Foon Tan return BOOT_DEVICE_RAM;
39c859f2a7SLey Foon Tan case 0x2: /* NAND Flash (1.8V) */
40c859f2a7SLey Foon Tan case 0x3: /* NAND Flash (3.0V) */
41c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
42c859f2a7SLey Foon Tan return BOOT_DEVICE_NAND;
43c859f2a7SLey Foon Tan case 0x4: /* SD/MMC External Transceiver (1.8V) */
44c859f2a7SLey Foon Tan case 0x5: /* SD/MMC Internal Transceiver (3.0V) */
45c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0);
46c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(DMA), 0);
47c859f2a7SLey Foon Tan return BOOT_DEVICE_MMC1;
48c859f2a7SLey Foon Tan case 0x6: /* QSPI Flash (1.8V) */
49c859f2a7SLey Foon Tan case 0x7: /* QSPI Flash (3.0V) */
50c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(QSPI), 0);
51c859f2a7SLey Foon Tan return BOOT_DEVICE_SPI;
52c859f2a7SLey Foon Tan default:
53c859f2a7SLey Foon Tan printf("Invalid boot device (bsel=%08x)!\n", bsel);
54c859f2a7SLey Foon Tan hang();
55c859f2a7SLey Foon Tan }
56c859f2a7SLey Foon Tan }
57c859f2a7SLey Foon Tan
58c859f2a7SLey Foon Tan #ifdef CONFIG_SPL_MMC_SUPPORT
spl_boot_mode(const u32 boot_device)59c859f2a7SLey Foon Tan u32 spl_boot_mode(const u32 boot_device)
60c859f2a7SLey Foon Tan {
61f4b40924STien Fong Chee #if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
62c859f2a7SLey Foon Tan return MMCSD_MODE_FS;
63c859f2a7SLey Foon Tan #else
64c859f2a7SLey Foon Tan return MMCSD_MODE_RAW;
65c859f2a7SLey Foon Tan #endif
66c859f2a7SLey Foon Tan }
67c859f2a7SLey Foon Tan #endif
68c859f2a7SLey Foon Tan
socfpga_pl310_clear(void)69*4a9743f7SMarek Vasut static void socfpga_pl310_clear(void)
70*4a9743f7SMarek Vasut {
71*4a9743f7SMarek Vasut u32 mask = 0xff, ena = 0;
72*4a9743f7SMarek Vasut
73*4a9743f7SMarek Vasut icache_enable();
74*4a9743f7SMarek Vasut
75*4a9743f7SMarek Vasut /* Disable the L2 cache */
76*4a9743f7SMarek Vasut clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
77*4a9743f7SMarek Vasut
78*4a9743f7SMarek Vasut writel(0x111, &pl310->pl310_tag_latency_ctrl);
79*4a9743f7SMarek Vasut writel(0x121, &pl310->pl310_data_latency_ctrl);
80*4a9743f7SMarek Vasut
81*4a9743f7SMarek Vasut /* enable BRESP, instruction and data prefetch, full line of zeroes */
82*4a9743f7SMarek Vasut setbits_le32(&pl310->pl310_aux_ctrl,
83*4a9743f7SMarek Vasut L310_AUX_CTRL_DATA_PREFETCH_MASK |
84*4a9743f7SMarek Vasut L310_AUX_CTRL_INST_PREFETCH_MASK |
85*4a9743f7SMarek Vasut L310_SHARED_ATT_OVERRIDE_ENABLE);
86*4a9743f7SMarek Vasut
87*4a9743f7SMarek Vasut /* Enable the L2 cache */
88*4a9743f7SMarek Vasut ena = readl(&pl310->pl310_ctrl);
89*4a9743f7SMarek Vasut ena |= L2X0_CTRL_EN;
90*4a9743f7SMarek Vasut
91*4a9743f7SMarek Vasut /*
92*4a9743f7SMarek Vasut * Invalidate the PL310 L2 cache. Keep the invalidation code
93*4a9743f7SMarek Vasut * entirely in L1 I-cache to avoid any bus traffic through
94*4a9743f7SMarek Vasut * the L2.
95*4a9743f7SMarek Vasut */
96*4a9743f7SMarek Vasut asm volatile(
97*4a9743f7SMarek Vasut ".align 5 \n"
98*4a9743f7SMarek Vasut " b 3f \n"
99*4a9743f7SMarek Vasut "1: str %1, [%4] \n"
100*4a9743f7SMarek Vasut " dsb \n"
101*4a9743f7SMarek Vasut " isb \n"
102*4a9743f7SMarek Vasut " str %0, [%2] \n"
103*4a9743f7SMarek Vasut " dsb \n"
104*4a9743f7SMarek Vasut " isb \n"
105*4a9743f7SMarek Vasut "2: ldr %0, [%2] \n"
106*4a9743f7SMarek Vasut " cmp %0, #0 \n"
107*4a9743f7SMarek Vasut " bne 2b \n"
108*4a9743f7SMarek Vasut " str %0, [%3] \n"
109*4a9743f7SMarek Vasut " dsb \n"
110*4a9743f7SMarek Vasut " isb \n"
111*4a9743f7SMarek Vasut " b 4f \n"
112*4a9743f7SMarek Vasut "3: b 1b \n"
113*4a9743f7SMarek Vasut "4: nop \n"
114*4a9743f7SMarek Vasut : "+r"(mask), "+r"(ena)
115*4a9743f7SMarek Vasut : "r"(&pl310->pl310_inv_way),
116*4a9743f7SMarek Vasut "r"(&pl310->pl310_cache_sync), "r"(&pl310->pl310_ctrl)
117*4a9743f7SMarek Vasut : "memory", "cc");
118*4a9743f7SMarek Vasut
119*4a9743f7SMarek Vasut /* Disable the L2 cache */
120*4a9743f7SMarek Vasut clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
121*4a9743f7SMarek Vasut }
122*4a9743f7SMarek Vasut
board_init_f(ulong dummy)123c859f2a7SLey Foon Tan void board_init_f(ulong dummy)
124c859f2a7SLey Foon Tan {
125c859f2a7SLey Foon Tan const struct cm_config *cm_default_cfg = cm_get_default_config();
126c859f2a7SLey Foon Tan unsigned long sdram_size;
127c859f2a7SLey Foon Tan unsigned long reg;
12840c36f8dSSimon Goldschmidt int ret;
129c859f2a7SLey Foon Tan
130c859f2a7SLey Foon Tan /*
131c859f2a7SLey Foon Tan * First C code to run. Clear fake OCRAM ECC first as SBE
132c859f2a7SLey Foon Tan * and DBE might triggered during power on
133c859f2a7SLey Foon Tan */
134c859f2a7SLey Foon Tan reg = readl(&sysmgr_regs->eccgrp_ocram);
135c859f2a7SLey Foon Tan if (reg & SYSMGR_ECC_OCRAM_SERR)
136c859f2a7SLey Foon Tan writel(SYSMGR_ECC_OCRAM_SERR | SYSMGR_ECC_OCRAM_EN,
137c859f2a7SLey Foon Tan &sysmgr_regs->eccgrp_ocram);
138c859f2a7SLey Foon Tan if (reg & SYSMGR_ECC_OCRAM_DERR)
139c859f2a7SLey Foon Tan writel(SYSMGR_ECC_OCRAM_DERR | SYSMGR_ECC_OCRAM_EN,
140c859f2a7SLey Foon Tan &sysmgr_regs->eccgrp_ocram);
141c859f2a7SLey Foon Tan
142c859f2a7SLey Foon Tan memset(__bss_start, 0, __bss_end - __bss_start);
143c859f2a7SLey Foon Tan
144e4ff8420SSimon Goldschmidt socfpga_sdram_remap_zero();
145*4a9743f7SMarek Vasut socfpga_pl310_clear();
146c859f2a7SLey Foon Tan
147c859f2a7SLey Foon Tan debug("Freezing all I/O banks\n");
148c859f2a7SLey Foon Tan /* freeze all IO banks */
149c859f2a7SLey Foon Tan sys_mgr_frzctrl_freeze_req();
150c859f2a7SLey Foon Tan
151c859f2a7SLey Foon Tan /* Put everything into reset but L4WD0. */
152c859f2a7SLey Foon Tan socfpga_per_reset_all();
15330bade20SSimon Goldschmidt
15430bade20SSimon Goldschmidt if (!socfpga_is_booting_from_fpga()) {
155c859f2a7SLey Foon Tan /* Put FPGA bridges into reset too. */
156c859f2a7SLey Foon Tan socfpga_bridges_reset(1);
15730bade20SSimon Goldschmidt }
158c859f2a7SLey Foon Tan
159c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(SDR), 0);
160c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
161c859f2a7SLey Foon Tan socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
162c859f2a7SLey Foon Tan
163c859f2a7SLey Foon Tan timer_init();
164c859f2a7SLey Foon Tan
165c859f2a7SLey Foon Tan debug("Reconfigure Clock Manager\n");
166c859f2a7SLey Foon Tan /* reconfigure the PLLs */
167c859f2a7SLey Foon Tan if (cm_basic_init(cm_default_cfg))
168c859f2a7SLey Foon Tan hang();
169c859f2a7SLey Foon Tan
170c859f2a7SLey Foon Tan /* Enable bootrom to configure IOs. */
171c859f2a7SLey Foon Tan sysmgr_config_warmrstcfgio(1);
172c859f2a7SLey Foon Tan
173c859f2a7SLey Foon Tan /* configure the IOCSR / IO buffer settings */
174c859f2a7SLey Foon Tan if (scan_mgr_configure_iocsr())
175c859f2a7SLey Foon Tan hang();
176c859f2a7SLey Foon Tan
177c859f2a7SLey Foon Tan sysmgr_config_warmrstcfgio(0);
178c859f2a7SLey Foon Tan
179c859f2a7SLey Foon Tan /* configure the pin muxing through system manager */
180c859f2a7SLey Foon Tan sysmgr_config_warmrstcfgio(1);
181c859f2a7SLey Foon Tan sysmgr_pinmux_init();
182c859f2a7SLey Foon Tan sysmgr_config_warmrstcfgio(0);
183c859f2a7SLey Foon Tan
184c859f2a7SLey Foon Tan /* De-assert reset for peripherals and bridges based on handoff */
185c859f2a7SLey Foon Tan reset_deassert_peripherals_handoff();
186c859f2a7SLey Foon Tan socfpga_bridges_reset(0);
187c859f2a7SLey Foon Tan
188c859f2a7SLey Foon Tan debug("Unfreezing/Thaw all I/O banks\n");
189c859f2a7SLey Foon Tan /* unfreeze / thaw all IO banks */
190c859f2a7SLey Foon Tan sys_mgr_frzctrl_thaw_req();
191c859f2a7SLey Foon Tan
192c0b4fc1aSSimon Goldschmidt #ifdef CONFIG_DEBUG_UART
193c0b4fc1aSSimon Goldschmidt socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
194c0b4fc1aSSimon Goldschmidt debug_uart_init();
195c0b4fc1aSSimon Goldschmidt #endif
196c0b4fc1aSSimon Goldschmidt
19740c36f8dSSimon Goldschmidt ret = spl_early_init();
19840c36f8dSSimon Goldschmidt if (ret) {
19940c36f8dSSimon Goldschmidt debug("spl_early_init() failed: %d\n", ret);
20040c36f8dSSimon Goldschmidt hang();
20140c36f8dSSimon Goldschmidt }
20240c36f8dSSimon Goldschmidt
203c859f2a7SLey Foon Tan /* enable console uart printing */
204c859f2a7SLey Foon Tan preloader_console_init();
205c859f2a7SLey Foon Tan
206c859f2a7SLey Foon Tan if (sdram_mmr_init_full(0xffffffff) != 0) {
207c859f2a7SLey Foon Tan puts("SDRAM init failed.\n");
208c859f2a7SLey Foon Tan hang();
209c859f2a7SLey Foon Tan }
210c859f2a7SLey Foon Tan
211c859f2a7SLey Foon Tan debug("SDRAM: Calibrating PHY\n");
212c859f2a7SLey Foon Tan /* SDRAM calibration */
213c859f2a7SLey Foon Tan if (sdram_calibration_full() == 0) {
214c859f2a7SLey Foon Tan puts("SDRAM calibration failed.\n");
215c859f2a7SLey Foon Tan hang();
216c859f2a7SLey Foon Tan }
217c859f2a7SLey Foon Tan
218c859f2a7SLey Foon Tan sdram_size = sdram_calculate_size();
219c859f2a7SLey Foon Tan debug("SDRAM: %ld MiB\n", sdram_size >> 20);
220c859f2a7SLey Foon Tan
221c859f2a7SLey Foon Tan /* Sanity check ensure correct SDRAM size specified */
222c859f2a7SLey Foon Tan if (get_ram_size(0, sdram_size) != sdram_size) {
223c859f2a7SLey Foon Tan puts("SDRAM size check failed!\n");
224c859f2a7SLey Foon Tan hang();
225c859f2a7SLey Foon Tan }
226c859f2a7SLey Foon Tan
22730bade20SSimon Goldschmidt if (!socfpga_is_booting_from_fpga())
228c859f2a7SLey Foon Tan socfpga_bridges_reset(1);
229c859f2a7SLey Foon Tan }
230