]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0 |
35b9800f | 2 | /* |
3b4ee40f | 3 | * Copyright (C) 2016-2021 Intel Corporation |
35b9800f LFT |
4 | */ |
5 | ||
6 | #include <altera.h> | |
d678a59d | 7 | #include <common.h> |
35b9800f LFT |
8 | #include <errno.h> |
9 | #include <fdtdec.h> | |
691d719d | 10 | #include <init.h> |
35b9800f LFT |
11 | #include <miiphy.h> |
12 | #include <netdev.h> | |
13 | #include <ns16550.h> | |
3b4ee40f | 14 | #include <spi_flash.h> |
35b9800f LFT |
15 | #include <watchdog.h> |
16 | #include <asm/arch/misc.h> | |
17 | #include <asm/arch/pinmux.h> | |
18 | #include <asm/arch/reset_manager.h> | |
2e1de5bd | 19 | #include <asm/arch/reset_manager_arria10.h> |
35b9800f LFT |
20 | #include <asm/arch/sdram_arria10.h> |
21 | #include <asm/arch/system_manager.h> | |
22 | #include <asm/arch/nic301.h> | |
23 | #include <asm/io.h> | |
24 | #include <asm/pl310.h> | |
3b4ee40f | 25 | #include <linux/sizes.h> |
35b9800f LFT |
26 | |
27 | #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 0x08 | |
28 | #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 0x58 | |
29 | #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3 0x68 | |
30 | #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 0x18 | |
31 | #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 0x78 | |
32 | #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3 0x98 | |
33 | ||
3b4ee40f | 34 | #define REGULAR_BOOT_MAGIC 0xd15ea5e |
4720b83d | 35 | #define PERIPH_RBF_PROG_FORCE 0x50455249 |
3b4ee40f TFC |
36 | |
37 | #define QSPI_S25FL_SOFT_RESET_COMMAND 0x00f0ff82 | |
38 | #define QSPI_N25_SOFT_RESET_COMMAND 0x00000001 | |
39 | #define QSPI_NO_SOFT_RESET 0x00000000 | |
40 | ||
877ec6eb ACH |
41 | /* |
42 | * FPGA programming support for SoC FPGA Arria 10 | |
43 | */ | |
44 | static Altera_desc altera_fpga[] = { | |
45 | { | |
46 | /* Family */ | |
47 | Altera_SoCFPGA, | |
48 | /* Interface type */ | |
49 | fast_passive_parallel, | |
50 | /* No limitation as additional data will be ignored */ | |
51 | -1, | |
52 | /* No device function table */ | |
53 | NULL, | |
54 | /* Base interface address specified in driver */ | |
55 | NULL, | |
56 | /* No cookie implementation */ | |
57 | 0 | |
58 | }, | |
59 | }; | |
60 | ||
35b9800f LFT |
61 | #if defined(CONFIG_SPL_BUILD) |
62 | static struct pl310_regs *const pl310 = | |
65cc0e2a | 63 | (struct pl310_regs *)CFG_SYS_PL310_BASE; |
35b9800f LFT |
64 | static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base = |
65 | (void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS; | |
35b9800f | 66 | |
35b9800f LFT |
67 | /* |
68 | + * This function initializes security policies to be consistent across | |
69 | + * all logic units in the Arria 10. | |
70 | + * | |
71 | + * The idea is to set all security policies to be normal, nonsecure | |
72 | + * for all units. | |
73 | + */ | |
0b8f6378 | 74 | void socfpga_init_security_policies(void) |
35b9800f LFT |
75 | { |
76 | /* Put OCRAM in non-secure */ | |
77 | writel(0x003f0000, &noc_fw_ocram_base->region0); | |
78 | writel(0x1, &noc_fw_ocram_base->enable); | |
42f4b83b MV |
79 | |
80 | /* Put DDR in non-secure */ | |
81 | writel(0xffff0000, SOCFPGA_SDR_FIREWALL_L3_ADDRESS + 0xc); | |
82 | writel(0x1, SOCFPGA_SDR_FIREWALL_L3_ADDRESS); | |
83 | ||
84 | /* Enable priviledged and non-priviledged access to L4 peripherals */ | |
85 | writel(~0, SOCFPGA_NOC_L4_PRIV_FLT_OFST); | |
86 | ||
87 | /* Enable secure and non-secure transactions to bridges */ | |
88 | writel(~0, SOCFPGA_NOC_FW_H2F_SCR_OFST); | |
89 | writel(~0, SOCFPGA_NOC_FW_H2F_SCR_OFST + 4); | |
90 | ||
db5741f7 LFT |
91 | writel(0x0007FFFF, |
92 | socfpga_get_sysmgr_addr() + SYSMGR_A10_ECC_INTMASK_SET); | |
35b9800f LFT |
93 | } |
94 | ||
0b8f6378 | 95 | void socfpga_sdram_remap_zero(void) |
35b9800f | 96 | { |
35b9800f LFT |
97 | /* Configure the L2 controller to make SDRAM start at 0 */ |
98 | writel(0x1, &pl310->pl310_addr_filter_start); | |
35b9800f | 99 | } |
0b8f6378 MV |
100 | #endif |
101 | ||
35b9800f LFT |
102 | int arch_early_init_r(void) |
103 | { | |
0b8f6378 | 104 | /* Add device descriptor to FPGA device table */ |
877ec6eb | 105 | socfpga_fpga_add(&altera_fpga[0]); |
0b8f6378 | 106 | |
35b9800f LFT |
107 | return 0; |
108 | } | |
35b9800f | 109 | |
35b9800f LFT |
110 | /* |
111 | * Print CPU information | |
112 | */ | |
113 | #if defined(CONFIG_DISPLAY_CPUINFO) | |
114 | int print_cpuinfo(void) | |
115 | { | |
db5741f7 LFT |
116 | const u32 bootinfo = readl(socfpga_get_sysmgr_addr() + |
117 | SYSMGR_A10_BOOTINFO); | |
118 | const u32 bsel = SYSMGR_GET_BOOTINFO_BSEL(bootinfo); | |
35b9800f LFT |
119 | |
120 | puts("CPU: Altera SoCFPGA Arria 10\n"); | |
121 | ||
122 | printf("BOOT: %s\n", bsel_str[bsel].name); | |
123 | return 0; | |
124 | } | |
125 | #endif | |
126 | ||
72c347ce | 127 | void do_bridge_reset(int enable, unsigned int mask) |
2e1de5bd LFT |
128 | { |
129 | if (enable) | |
130 | socfpga_reset_deassert_bridges_handoff(); | |
131 | else | |
132 | socfpga_bridges_reset(); | |
133 | } | |
3b4ee40f | 134 | |
4720b83d TFC |
135 | /* |
136 | * This function set/unset flag with number "0x50455249" to | |
137 | * handoff register isw_handoff[7] - 0xffd0624c | |
138 | * This flag is used to force periph RBF program regardless FPGA status | |
139 | * and double periph RBF config are needed on some devices or boards to | |
140 | * stabilize the IO config system. | |
141 | */ | |
142 | void force_periph_program(unsigned int status) | |
143 | { | |
144 | if (status) | |
145 | writel(PERIPH_RBF_PROG_FORCE, socfpga_get_sysmgr_addr() + | |
146 | SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | |
147 | else | |
148 | writel(0, socfpga_get_sysmgr_addr() + | |
149 | SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | |
150 | } | |
151 | ||
152 | /* | |
153 | * This function is used to check whether | |
154 | * handoff register isw_handoff[7] contains | |
155 | * flag for forcing the periph RBF program "0x50455249". | |
156 | */ | |
157 | bool is_periph_program_force(void) | |
158 | { | |
159 | unsigned int status; | |
160 | ||
161 | status = readl(socfpga_get_sysmgr_addr() + | |
162 | SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | |
163 | ||
164 | if (status == PERIPH_RBF_PROG_FORCE) | |
165 | return true; | |
166 | else | |
167 | return false; | |
168 | } | |
169 | ||
3b4ee40f TFC |
170 | /* |
171 | * This function set/unset magic number "0xd15ea5e" to | |
172 | * handoff register isw_handoff[7] - 0xffd0624c | |
173 | * This magic number is part of boot progress tracking | |
174 | * and it's required for warm reset workaround on MPFE hang issue. | |
175 | */ | |
176 | void set_regular_boot(unsigned int status) | |
177 | { | |
178 | if (status) | |
179 | writel(REGULAR_BOOT_MAGIC, socfpga_get_sysmgr_addr() + | |
180 | SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | |
181 | else | |
182 | writel(0, socfpga_get_sysmgr_addr() + | |
183 | SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | |
184 | } | |
185 | ||
186 | /* | |
187 | * This function is used to check whether | |
188 | * handoff register isw_handoff[7] contains | |
189 | * magic number "0xd15ea5e". | |
190 | */ | |
191 | bool is_regular_boot_valid(void) | |
192 | { | |
193 | unsigned int status; | |
194 | ||
195 | status = readl(socfpga_get_sysmgr_addr() + | |
196 | SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | |
197 | ||
198 | if (status == REGULAR_BOOT_MAGIC) | |
199 | return true; | |
200 | else | |
201 | return false; | |
202 | } | |
203 | ||
204 | #if IS_ENABLED(CONFIG_CADENCE_QSPI) | |
205 | /* This function is used to trigger software reset | |
206 | * to the QSPI flash. On some boards, the QSPI flash reset may | |
207 | * not be connected to the HPS warm reset. | |
208 | */ | |
209 | int qspi_flash_software_reset(void) | |
210 | { | |
211 | struct udevice *flash; | |
212 | int ret; | |
213 | ||
214 | /* Get the flash info */ | |
215 | ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS, | |
216 | CONFIG_SF_DEFAULT_CS, | |
217 | CONFIG_SF_DEFAULT_SPEED, | |
218 | CONFIG_SF_DEFAULT_MODE, | |
219 | &flash); | |
220 | ||
221 | if (ret) { | |
222 | debug("Failed to initialize SPI flash at "); | |
223 | debug("%u:%u (error %d)\n", CONFIG_SF_DEFAULT_BUS, | |
224 | CONFIG_SF_DEFAULT_CS, ret); | |
225 | return -ENODEV; | |
226 | } | |
227 | ||
228 | if (!flash) | |
229 | return -EINVAL; | |
230 | ||
231 | /* | |
232 | * QSPI flash software reset command, for the case where | |
233 | * no HPS reset connected to QSPI flash reset | |
234 | */ | |
235 | if (!memcmp(flash->name, "N25", SZ_1 + SZ_2)) | |
236 | writel(QSPI_N25_SOFT_RESET_COMMAND, socfpga_get_sysmgr_addr() + | |
237 | SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); | |
238 | else if (!memcmp(flash->name, "S25FL", SZ_1 + SZ_4)) | |
239 | writel(QSPI_S25FL_SOFT_RESET_COMMAND, | |
240 | socfpga_get_sysmgr_addr() + | |
241 | SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); | |
242 | else /* No software reset */ | |
243 | writel(QSPI_NO_SOFT_RESET, socfpga_get_sysmgr_addr() + | |
244 | SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); | |
245 | ||
246 | return 0; | |
247 | } | |
248 | #endif | |
e26ecebc PA |
249 | |
250 | void dram_bank_mmu_setup(int bank) | |
251 | { | |
252 | struct bd_info *bd = gd->bd; | |
253 | u32 start, size; | |
254 | int i; | |
255 | ||
256 | /* If we're still in OCRAM, don't set the XN bit on it */ | |
257 | if (!(gd->flags & GD_FLG_RELOC)) { | |
258 | set_section_dcache( | |
65cc0e2a | 259 | CFG_SYS_INIT_RAM_ADDR >> MMU_SECTION_SHIFT, |
e26ecebc PA |
260 | DCACHE_WRITETHROUGH); |
261 | } | |
262 | ||
263 | /* | |
264 | * The default implementation of this function allows the DRAM dcache | |
265 | * to be enabled only after relocation. However, to speed up ECC | |
266 | * initialization, we want to be able to enable DRAM dcache before | |
267 | * relocation, so we don't check GD_FLG_RELOC (this assumes bd->bi_dram | |
268 | * is set first). | |
269 | */ | |
270 | start = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT; | |
271 | size = bd->bi_dram[bank].size >> MMU_SECTION_SHIFT; | |
272 | for (i = start; i < start + size; i++) | |
273 | set_section_dcache(i, DCACHE_DEFAULT_OPTION); | |
274 | } |