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