]>
Commit | Line | Data |
---|---|---|
77754408 DN |
1 | /* |
2 | * Copyright (C) 2012 Altera Corporation <www.altera.com> | |
3 | * | |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
77754408 DN |
5 | */ |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/io.h> | |
230fe9b2 | 9 | #include <altera.h> |
99b97106 PM |
10 | #include <miiphy.h> |
11 | #include <netdev.h> | |
de6da925 | 12 | #include <asm/arch/reset_manager.h> |
45d6e677 | 13 | #include <asm/arch/system_manager.h> |
4e736869 | 14 | #include <asm/arch/dwmmc.h> |
60d804c2 | 15 | #include <asm/arch/nic301.h> |
13e81d45 | 16 | #include <asm/arch/scu.h> |
60d804c2 | 17 | #include <asm/pl310.h> |
77754408 DN |
18 | |
19 | DECLARE_GLOBAL_DATA_PTR; | |
20 | ||
60d804c2 MV |
21 | static struct pl310_regs *const pl310 = |
22 | (struct pl310_regs *)CONFIG_SYS_PL310_BASE; | |
45d6e677 PM |
23 | static struct socfpga_system_manager *sysmgr_regs = |
24 | (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; | |
7249fafb MV |
25 | static struct socfpga_reset_manager *reset_manager_base = |
26 | (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; | |
60d804c2 MV |
27 | static struct nic301_registers *nic301_regs = |
28 | (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; | |
13e81d45 PM |
29 | static struct scu_registers *scu_regs = |
30 | (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; | |
45d6e677 | 31 | |
77754408 DN |
32 | int dram_init(void) |
33 | { | |
34 | gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); | |
35 | return 0; | |
36 | } | |
23f23f23 | 37 | |
4ab333b7 MV |
38 | void enable_caches(void) |
39 | { | |
40 | #ifndef CONFIG_SYS_ICACHE_OFF | |
41 | icache_enable(); | |
42 | #endif | |
43 | #ifndef CONFIG_SYS_DCACHE_OFF | |
44 | dcache_enable(); | |
45 | #endif | |
46 | } | |
47 | ||
45d6e677 PM |
48 | /* |
49 | * DesignWare Ethernet initialization | |
50 | */ | |
51 | #ifdef CONFIG_DESIGNWARE_ETH | |
52 | int cpu_eth_init(bd_t *bis) | |
53 | { | |
54 | #if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS | |
55 | const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; | |
56 | #elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS | |
57 | const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; | |
58 | #else | |
59 | #error "Incorrect CONFIG_EMAC_BASE value!" | |
60 | #endif | |
61 | ||
62 | /* Initialize EMAC. This needs to be done at least once per boot. */ | |
63 | ||
64 | /* | |
65 | * Putting the EMAC controller to reset when configuring the PHY | |
66 | * interface select at System Manager | |
67 | */ | |
68 | socfpga_emac_reset(1); | |
69 | ||
70 | /* Clearing emac0 PHY interface select to 0 */ | |
71 | clrbits_le32(&sysmgr_regs->emacgrp_ctrl, | |
72 | SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); | |
73 | ||
74 | /* configure to PHY interface select choosed */ | |
75 | setbits_le32(&sysmgr_regs->emacgrp_ctrl, | |
76 | SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); | |
77 | ||
78 | /* Release the EMAC controller from reset */ | |
79 | socfpga_emac_reset(0); | |
80 | ||
81 | /* initialize and register the emac */ | |
82 | return designware_initialize(CONFIG_EMAC_BASE, | |
83 | CONFIG_PHY_INTERFACE_MODE); | |
84 | } | |
85 | #endif | |
86 | ||
4e736869 PM |
87 | #ifdef CONFIG_DWMMC |
88 | /* | |
89 | * Initializes MMC controllers. | |
90 | * to override, implement board_mmc_init() | |
91 | */ | |
92 | int cpu_mmc_init(bd_t *bis) | |
93 | { | |
94 | return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, | |
95 | CONFIG_HPS_SDMMC_BUSWIDTH, 0); | |
96 | } | |
97 | #endif | |
98 | ||
23f23f23 CLS |
99 | #if defined(CONFIG_DISPLAY_CPUINFO) |
100 | /* | |
101 | * Print CPU information | |
102 | */ | |
103 | int print_cpuinfo(void) | |
104 | { | |
d5a3d3c9 | 105 | puts("CPU: Altera SoCFPGA Platform\n"); |
23f23f23 CLS |
106 | return 0; |
107 | } | |
108 | #endif | |
109 | ||
110 | #if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ | |
111 | defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) | |
112 | int overwrite_console(void) | |
113 | { | |
114 | return 0; | |
115 | } | |
116 | #endif | |
117 | ||
230fe9b2 PM |
118 | #ifdef CONFIG_FPGA |
119 | /* | |
120 | * FPGA programming support for SoC FPGA Cyclone V | |
121 | */ | |
122 | static Altera_desc altera_fpga[] = { | |
123 | { | |
124 | /* Family */ | |
125 | Altera_SoCFPGA, | |
126 | /* Interface type */ | |
127 | fast_passive_parallel, | |
128 | /* No limitation as additional data will be ignored */ | |
129 | -1, | |
130 | /* No device function table */ | |
131 | NULL, | |
132 | /* Base interface address specified in driver */ | |
133 | NULL, | |
134 | /* No cookie implementation */ | |
135 | 0 | |
136 | }, | |
137 | }; | |
138 | ||
139 | /* add device descriptor to FPGA device table */ | |
140 | static void socfpga_fpga_add(void) | |
141 | { | |
142 | int i; | |
143 | fpga_init(); | |
144 | for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) | |
145 | fpga_add(fpga_altera, &altera_fpga[i]); | |
146 | } | |
147 | #else | |
148 | static inline void socfpga_fpga_add(void) {} | |
149 | #endif | |
150 | ||
de6da925 PM |
151 | int arch_cpu_init(void) |
152 | { | |
153 | /* | |
154 | * If the HW watchdog is NOT enabled, make sure it is not running, | |
155 | * for example because it was enabled in the preloader. This might | |
156 | * trigger a watchdog-triggered reboot of Linux kernel later. | |
157 | */ | |
158 | #ifndef CONFIG_HW_WATCHDOG | |
159 | socfpga_watchdog_reset(); | |
160 | #endif | |
161 | return 0; | |
162 | } | |
163 | ||
13e81d45 PM |
164 | /* |
165 | * Convert all NIC-301 AMBA slaves from secure to non-secure | |
166 | */ | |
167 | static void socfpga_nic301_slave_ns(void) | |
168 | { | |
169 | writel(0x1, &nic301_regs->lwhps2fpgaregs); | |
170 | writel(0x1, &nic301_regs->hps2fpgaregs); | |
171 | writel(0x1, &nic301_regs->acp); | |
172 | writel(0x1, &nic301_regs->rom); | |
173 | writel(0x1, &nic301_regs->ocram); | |
174 | writel(0x1, &nic301_regs->sdrdata); | |
175 | } | |
176 | ||
7249fafb MV |
177 | static uint32_t iswgrp_handoff[8]; |
178 | ||
fc520894 | 179 | int arch_early_init_r(void) |
23f23f23 | 180 | { |
7249fafb MV |
181 | int i; |
182 | for (i = 0; i < 8; i++) /* Cache initial SW setting regs */ | |
183 | iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]); | |
184 | ||
13e81d45 PM |
185 | socfpga_bridges_reset(1); |
186 | socfpga_nic301_slave_ns(); | |
187 | ||
188 | /* | |
189 | * Private components security: | |
190 | * U-Boot : configure private timer, global timer and cpu component | |
191 | * access as non secure for kernel stage (as required by Linux) | |
192 | */ | |
193 | setbits_le32(&scu_regs->sacr, 0xfff); | |
194 | ||
60d804c2 MV |
195 | /* Configure the L2 controller to make SDRAM start at 0 */ |
196 | #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET | |
197 | writel(0x2, &nic301_regs->remap); | |
198 | #else | |
199 | writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ | |
200 | writel(0x1, &pl310->pl310_addr_filter_start); | |
201 | #endif | |
202 | ||
230fe9b2 PM |
203 | /* Add device descriptor to FPGA device table */ |
204 | socfpga_fpga_add(); | |
a877bec3 SR |
205 | |
206 | #ifdef CONFIG_DESIGNWARE_SPI | |
207 | /* Get Designware SPI controller out of reset */ | |
208 | socfpga_spim_enable(); | |
209 | #endif | |
210 | ||
23f23f23 CLS |
211 | return 0; |
212 | } | |
7249fafb MV |
213 | |
214 | static void socfpga_sdram_apply_static_cfg(void) | |
215 | { | |
216 | const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; | |
217 | const uint32_t applymask = 0x8; | |
218 | uint32_t val = readl(staticcfg) | applymask; | |
219 | ||
220 | /* | |
221 | * SDRAM staticcfg register specific: | |
222 | * When applying the register setting, the CPU must not access | |
223 | * SDRAM. Luckily for us, we can abuse i-cache here to help us | |
224 | * circumvent the SDRAM access issue. The idea is to make sure | |
225 | * that the code is in one full i-cache line by branching past | |
226 | * it and back. Once it is in the i-cache, we execute the core | |
227 | * of the code and apply the register settings. | |
228 | * | |
229 | * The code below uses 7 instructions, while the Cortex-A9 has | |
230 | * 32-byte cachelines, thus the limit is 8 instructions total. | |
231 | */ | |
232 | asm volatile( | |
233 | ".align 5 \n" | |
234 | " b 2f \n" | |
235 | "1: str %0, [%1] \n" | |
236 | " dsb \n" | |
237 | " isb \n" | |
238 | " b 3f \n" | |
239 | "2: b 1b \n" | |
240 | "3: nop \n" | |
241 | : : "r"(val), "r"(staticcfg) : "memory", "cc"); | |
242 | } | |
243 | ||
244 | int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
245 | { | |
246 | if (argc != 2) | |
247 | return CMD_RET_USAGE; | |
248 | ||
249 | argv++; | |
250 | ||
251 | switch (*argv[0]) { | |
252 | case 'e': /* Enable */ | |
253 | writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); | |
254 | socfpga_sdram_apply_static_cfg(); | |
255 | writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); | |
256 | writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); | |
257 | writel(iswgrp_handoff[1], &nic301_regs->remap); | |
258 | break; | |
259 | case 'd': /* Disable */ | |
260 | writel(0, &sysmgr_regs->fpgaintfgrp_module); | |
261 | writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); | |
262 | socfpga_sdram_apply_static_cfg(); | |
263 | writel(0, &reset_manager_base->brg_mod_reset); | |
264 | writel(1, &nic301_regs->remap); | |
265 | break; | |
266 | default: | |
267 | return CMD_RET_USAGE; | |
268 | } | |
269 | ||
270 | return 0; | |
271 | } | |
272 | ||
273 | U_BOOT_CMD( | |
274 | bridge, 2, 1, do_bridge, | |
275 | "SoCFPGA HPS FPGA bridge control", | |
276 | "enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" | |
277 | "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" | |
278 | "" | |
279 | ); |