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