Prepare v2024.10
[platform/kernel/u-boot.git] / arch / arm / mach-socfpga / spl_a10.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Copyright (C) 2012-2021 Altera Corporation <www.altera.com>
4  */
5
6 #include <config.h>
7 #include <cpu_func.h>
8 #include <hang.h>
9 #include <init.h>
10 #include <asm/global_data.h>
11 #include <asm/io.h>
12 #include <asm/pl310.h>
13 #include <asm/utils.h>
14 #include <image.h>
15 #include <asm/arch/reset_manager.h>
16 #include <spl.h>
17 #include <asm/arch/system_manager.h>
18 #include <asm/arch/freeze_controller.h>
19 #include <asm/arch/clock_manager.h>
20 #include <asm/arch/scan_manager.h>
21 #include <asm/arch/sdram.h>
22 #include <asm/arch/scu.h>
23 #include <asm/arch/misc.h>
24 #include <asm/arch/nic301.h>
25 #include <asm/sections.h>
26 #include <fdtdec.h>
27 #include <watchdog.h>
28 #include <asm/arch/pinmux.h>
29 #include <asm/arch/fpga_manager.h>
30 #include <mmc.h>
31 #include <memalign.h>
32 #include <linux/delay.h>
33
34 #define FPGA_BUFSIZ     16 * 1024
35 #define FSBL_IMAGE_IS_VALID     0x49535756
36
37 #define FSBL_IMAGE_IS_INVALID   0x0
38 #define BOOTROM_CONFIGURES_IO_PINMUX    0x3
39
40 DECLARE_GLOBAL_DATA_PTR;
41
42 #define BOOTROM_SHARED_MEM_SIZE         0x800   /* 2KB */
43 #define BOOTROM_SHARED_MEM_ADDR         (CFG_SYS_INIT_RAM_ADDR + \
44                                          SOCFPGA_PHYS_OCRAM_SIZE - \
45                                          BOOTROM_SHARED_MEM_SIZE)
46 #define RST_STATUS_SHARED_ADDR          (BOOTROM_SHARED_MEM_ADDR + 0x438)
47 static u32 rst_mgr_status __section(".data");
48
49 /*
50  * Bootrom will clear the status register in reset manager and stores the
51  * reset status value in shared memory. Bootrom stores shared data at last
52  * 2KB of onchip RAM.
53  * This function save reset status provided by BootROM to rst_mgr_status.
54  * More information about reset status register value can be found in reset
55  * manager register description.
56  * When running in debugger without Bootrom, r0 to r3 are random values.
57  * So, skip save the value when r0 is not BootROM shared data address.
58  *
59  * r0 - Contains the pointer to the shared memory block. The shared
60  *      memory block is located in the top 2 KB of on-chip RAM.
61  * r1 - contains the length of the shared memory.
62  * r2 - unused and set to 0x0.
63  * r3 - points to the version block.
64  */
65 void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
66                       unsigned long r3)
67 {
68         if (r0 == BOOTROM_SHARED_MEM_ADDR)
69                 rst_mgr_status = readl(RST_STATUS_SHARED_ADDR);
70
71         save_boot_params_ret();
72 }
73
74 u32 spl_boot_device(void)
75 {
76         const u32 bsel = readl(socfpga_get_sysmgr_addr() + SYSMGR_A10_BOOTINFO);
77
78         switch (SYSMGR_GET_BOOTINFO_BSEL(bsel)) {
79         case 0x1:       /* FPGA (HPS2FPGA Bridge) */
80                 return BOOT_DEVICE_RAM;
81         case 0x2:       /* NAND Flash (1.8V) */
82         case 0x3:       /* NAND Flash (3.0V) */
83                 socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
84                 return BOOT_DEVICE_NAND;
85         case 0x4:       /* SD/MMC External Transceiver (1.8V) */
86         case 0x5:       /* SD/MMC Internal Transceiver (3.0V) */
87                 socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0);
88                 socfpga_per_reset(SOCFPGA_RESET(DMA), 0);
89                 return BOOT_DEVICE_MMC1;
90         case 0x6:       /* QSPI Flash (1.8V) */
91         case 0x7:       /* QSPI Flash (3.0V) */
92                 socfpga_per_reset(SOCFPGA_RESET(QSPI), 0);
93                 return BOOT_DEVICE_SPI;
94         default:
95                 printf("Invalid boot device (bsel=%08x)!\n", bsel);
96                 hang();
97         }
98 }
99
100 #ifdef CONFIG_SPL_MMC
101 u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
102 {
103 #if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
104         return MMCSD_MODE_FS;
105 #else
106         return MMCSD_MODE_RAW;
107 #endif
108 }
109 #endif
110
111 void spl_board_init(void)
112 {
113         int ret;
114
115         ALLOC_CACHE_ALIGN_BUFFER(char, buf, FPGA_BUFSIZ);
116
117         /* enable console uart printing */
118         preloader_console_init();
119         schedule();
120
121         arch_early_init_r();
122
123         /* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */
124         if ((IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) &&
125              is_regular_boot_valid()) ||
126             (!IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) &&
127              is_fpgamgr_user_mode())) {
128                 ret = config_pins(gd->fdt_blob, "shared");
129                 if (ret)
130                         return;
131
132                 ret = config_pins(gd->fdt_blob, "fpga");
133                 if (ret)
134                         return;
135         } else if (IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) ||
136                    !is_fpgamgr_early_user_mode()) {
137                 /* Program IOSSM(early IO release) or full FPGA */
138                 fpgamgr_program(buf, FPGA_BUFSIZ, 0);
139
140                 /* Skipping double program for combined RBF */
141                 if (!is_fpgamgr_user_mode()) {
142                         /*
143                          * Expect FPGA entered early user mode, so
144                          * the flag is set to re-program IOSSM
145                          */
146                         force_periph_program(true);
147
148                         /* Re-program IOSSM to stabilize IO system */
149                         fpgamgr_program(buf, FPGA_BUFSIZ, 0);
150
151                         force_periph_program(false);
152                 }
153         }
154
155         /* If the IOSSM/full FPGA is already loaded, start DDR */
156         if (is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode()) {
157                 if (!is_regular_boot_valid()) {
158                         /*
159                          * Ensure all signals in stable state before triggering
160                          * warm reset. This value is recommended from stress
161                          * test.
162                          */
163                         mdelay(10);
164
165 #if IS_ENABLED(CONFIG_CADENCE_QSPI)
166                         /*
167                          * Trigger software reset to QSPI flash.
168                          * On some boards, the QSPI flash reset may not be
169                          * connected to the HPS warm reset.
170                          */
171                         qspi_flash_software_reset();
172 #endif
173
174                         ret = readl(socfpga_get_rstmgr_addr() +
175                                     RSTMGR_A10_SYSWARMMASK);
176                         /*
177                          * Masking s2f & FPGA manager module reset from warm
178                          * reset
179                          */
180                         writel(ret & (~(ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK |
181                                ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK)),
182                                socfpga_get_rstmgr_addr() +
183                                RSTMGR_A10_SYSWARMMASK);
184
185                         /*
186                          * BootROM will configure both IO and pin mux after a
187                          * warm reset
188                          */
189                         ret = readl(socfpga_get_sysmgr_addr() +
190                                     SYSMGR_A10_ROMCODE_CTRL);
191                         writel(ret | BOOTROM_CONFIGURES_IO_PINMUX,
192                                socfpga_get_sysmgr_addr() +
193                                SYSMGR_A10_ROMCODE_CTRL);
194
195                         /*
196                          * Up to here, image is considered valid and should be
197                          * set as valid before warm reset is triggered
198                          */
199                         writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() +
200                                SYSMGR_A10_ROMCODE_INITSWSTATE);
201
202                         /*
203                          * Set this flag to scratch register, so that a proper
204                          * boot progress before / after warm reset can be
205                          * tracked by FSBL
206                          */
207                         set_regular_boot(true);
208
209                         schedule();
210
211                         reset_cpu();
212                 }
213
214                 /*
215                  * Reset this flag to scratch register, so that a proper
216                  * boot progress before / after warm reset can be
217                  * tracked by FSBL
218                  */
219                 set_regular_boot(false);
220
221                 ret = readl(socfpga_get_rstmgr_addr() +
222                             RSTMGR_A10_SYSWARMMASK);
223
224                 /*
225                  * Unmasking s2f & FPGA manager module reset from warm
226                  * reset
227                  */
228                 writel(ret | ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK |
229                         ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK,
230                         socfpga_get_rstmgr_addr() + RSTMGR_A10_SYSWARMMASK);
231
232                 /*
233                  * Up to here, MPFE hang workaround is considered done and
234                  * should be reset as invalid until FSBL successfully loading
235                  * SSBL, and prepare jumping to SSBL, then only setting as
236                  * valid
237                  */
238                 writel(FSBL_IMAGE_IS_INVALID, socfpga_get_sysmgr_addr() +
239                        SYSMGR_A10_ROMCODE_INITSWSTATE);
240
241                 ddr_calibration_sequence();
242         }
243
244         if (!is_fpgamgr_user_mode())
245                 fpgamgr_program(buf, FPGA_BUFSIZ, 0);
246 }
247
248 void board_init_f(ulong dummy)
249 {
250         if (spl_early_init())
251                 hang();
252
253         socfpga_get_managers_addr();
254
255         dcache_disable();
256
257         socfpga_init_security_policies();
258         socfpga_sdram_remap_zero();
259         socfpga_pl310_clear();
260
261         /* Assert reset to all except L4WD0 and L4TIMER0 */
262         socfpga_per_reset_all();
263         socfpga_watchdog_disable();
264
265         /* Configure the clock based on handoff */
266         cm_basic_init(gd->fdt_blob);
267
268 #ifdef CONFIG_HW_WATCHDOG
269         /* release osc1 watchdog timer 0 from reset */
270         socfpga_reset_deassert_osc1wd0();
271
272         /* reconfigure and enable the watchdog */
273         hw_watchdog_init();
274         schedule();
275 #endif /* CONFIG_HW_WATCHDOG */
276
277         config_dedicated_pins(gd->fdt_blob);
278         schedule();
279 }
280
281 /* board specific function prior loading SSBL / U-Boot proper */
282 void spl_board_prepare_for_boot(void)
283 {
284         writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() +
285                SYSMGR_A10_ROMCODE_INITSWSTATE);
286 }