Commit 7249fafb1a96c014dfc0d4ccf6ea937643199e67
1 parent
4ab333b765
Exists in
v2017.01-smarct4x
and in
37 other branches
arm: socfpga: Add command to control HPS-FPGA bridges
Add command to enable and disable the bridges between HPS and FPGA. This patch does have a checkpatch issue with the assembler portion, checkpatch correctly complains that there should be no whitespace before quoted newline. I do not agree that fixing this specific checkpatch issue will improve the readability, thus this one is not addressed. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Dinh Nguyen <dinguyen@altera.com> Cc: Pavel Machek <pavel@denx.de> Cc: Marek Vasut <marex@denx.de> Cc: Tom Rini <trini@ti.com> Cc: Albert Aribaud <albert.u.boot@aribaud.net> Cc: Wolfgang Denk <wd@denx.de>
Showing 1 changed file with 75 additions and 0 deletions Side-by-side Diff
arch/arm/cpu/armv7/socfpga/misc.c
... | ... | @@ -22,6 +22,8 @@ |
22 | 22 | (struct pl310_regs *)CONFIG_SYS_PL310_BASE; |
23 | 23 | static struct socfpga_system_manager *sysmgr_regs = |
24 | 24 | (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; |
25 | +static struct socfpga_reset_manager *reset_manager_base = | |
26 | + (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; | |
25 | 27 | static struct nic301_registers *nic301_regs = |
26 | 28 | (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; |
27 | 29 | static struct scu_registers *scu_regs = |
28 | 30 | |
... | ... | @@ -172,8 +174,14 @@ |
172 | 174 | writel(0x1, &nic301_regs->sdrdata); |
173 | 175 | } |
174 | 176 | |
177 | +static uint32_t iswgrp_handoff[8]; | |
178 | + | |
175 | 179 | int misc_init_r(void) |
176 | 180 | { |
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 | + | |
177 | 185 | socfpga_bridges_reset(1); |
178 | 186 | socfpga_nic301_slave_ns(); |
179 | 187 | |
... | ... | @@ -196,4 +204,71 @@ |
196 | 204 | socfpga_fpga_add(); |
197 | 205 | return 0; |
198 | 206 | } |
207 | + | |
208 | +static void socfpga_sdram_apply_static_cfg(void) | |
209 | +{ | |
210 | + const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; | |
211 | + const uint32_t applymask = 0x8; | |
212 | + uint32_t val = readl(staticcfg) | applymask; | |
213 | + | |
214 | + /* | |
215 | + * SDRAM staticcfg register specific: | |
216 | + * When applying the register setting, the CPU must not access | |
217 | + * SDRAM. Luckily for us, we can abuse i-cache here to help us | |
218 | + * circumvent the SDRAM access issue. The idea is to make sure | |
219 | + * that the code is in one full i-cache line by branching past | |
220 | + * it and back. Once it is in the i-cache, we execute the core | |
221 | + * of the code and apply the register settings. | |
222 | + * | |
223 | + * The code below uses 7 instructions, while the Cortex-A9 has | |
224 | + * 32-byte cachelines, thus the limit is 8 instructions total. | |
225 | + */ | |
226 | + asm volatile( | |
227 | + ".align 5 \n" | |
228 | + " b 2f \n" | |
229 | + "1: str %0, [%1] \n" | |
230 | + " dsb \n" | |
231 | + " isb \n" | |
232 | + " b 3f \n" | |
233 | + "2: b 1b \n" | |
234 | + "3: nop \n" | |
235 | + : : "r"(val), "r"(staticcfg) : "memory", "cc"); | |
236 | +} | |
237 | + | |
238 | +int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
239 | +{ | |
240 | + if (argc != 2) | |
241 | + return CMD_RET_USAGE; | |
242 | + | |
243 | + argv++; | |
244 | + | |
245 | + switch (*argv[0]) { | |
246 | + case 'e': /* Enable */ | |
247 | + writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); | |
248 | + socfpga_sdram_apply_static_cfg(); | |
249 | + writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); | |
250 | + writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); | |
251 | + writel(iswgrp_handoff[1], &nic301_regs->remap); | |
252 | + break; | |
253 | + case 'd': /* Disable */ | |
254 | + writel(0, &sysmgr_regs->fpgaintfgrp_module); | |
255 | + writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); | |
256 | + socfpga_sdram_apply_static_cfg(); | |
257 | + writel(0, &reset_manager_base->brg_mod_reset); | |
258 | + writel(1, &nic301_regs->remap); | |
259 | + break; | |
260 | + default: | |
261 | + return CMD_RET_USAGE; | |
262 | + } | |
263 | + | |
264 | + return 0; | |
265 | +} | |
266 | + | |
267 | +U_BOOT_CMD( | |
268 | + bridge, 2, 1, do_bridge, | |
269 | + "SoCFPGA HPS FPGA bridge control", | |
270 | + "enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" | |
271 | + "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" | |
272 | + "" | |
273 | +); |