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 Inline Diff
arch/arm/cpu/armv7/socfpga/misc.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 Altera Corporation <www.altera.com> | 2 | * Copyright (C) 2012 Altera Corporation <www.altera.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <asm/io.h> | 8 | #include <asm/io.h> |
9 | #include <altera.h> | 9 | #include <altera.h> |
10 | #include <miiphy.h> | 10 | #include <miiphy.h> |
11 | #include <netdev.h> | 11 | #include <netdev.h> |
12 | #include <asm/arch/reset_manager.h> | 12 | #include <asm/arch/reset_manager.h> |
13 | #include <asm/arch/system_manager.h> | 13 | #include <asm/arch/system_manager.h> |
14 | #include <asm/arch/dwmmc.h> | 14 | #include <asm/arch/dwmmc.h> |
15 | #include <asm/arch/nic301.h> | 15 | #include <asm/arch/nic301.h> |
16 | #include <asm/arch/scu.h> | 16 | #include <asm/arch/scu.h> |
17 | #include <asm/pl310.h> | 17 | #include <asm/pl310.h> |
18 | 18 | ||
19 | DECLARE_GLOBAL_DATA_PTR; | 19 | DECLARE_GLOBAL_DATA_PTR; |
20 | 20 | ||
21 | static struct pl310_regs *const pl310 = | 21 | static struct pl310_regs *const pl310 = |
22 | (struct pl310_regs *)CONFIG_SYS_PL310_BASE; | 22 | (struct pl310_regs *)CONFIG_SYS_PL310_BASE; |
23 | static struct socfpga_system_manager *sysmgr_regs = | 23 | static struct socfpga_system_manager *sysmgr_regs = |
24 | (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; | 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 | static struct nic301_registers *nic301_regs = | 27 | static struct nic301_registers *nic301_regs = |
26 | (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; | 28 | (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; |
27 | static struct scu_registers *scu_regs = | 29 | static struct scu_registers *scu_regs = |
28 | (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; | 30 | (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; |
29 | 31 | ||
30 | int dram_init(void) | 32 | int dram_init(void) |
31 | { | 33 | { |
32 | gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); | 34 | gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); |
33 | return 0; | 35 | return 0; |
34 | } | 36 | } |
35 | 37 | ||
36 | void enable_caches(void) | 38 | void enable_caches(void) |
37 | { | 39 | { |
38 | #ifndef CONFIG_SYS_ICACHE_OFF | 40 | #ifndef CONFIG_SYS_ICACHE_OFF |
39 | icache_enable(); | 41 | icache_enable(); |
40 | #endif | 42 | #endif |
41 | #ifndef CONFIG_SYS_DCACHE_OFF | 43 | #ifndef CONFIG_SYS_DCACHE_OFF |
42 | dcache_enable(); | 44 | dcache_enable(); |
43 | #endif | 45 | #endif |
44 | } | 46 | } |
45 | 47 | ||
46 | /* | 48 | /* |
47 | * DesignWare Ethernet initialization | 49 | * DesignWare Ethernet initialization |
48 | */ | 50 | */ |
49 | #ifdef CONFIG_DESIGNWARE_ETH | 51 | #ifdef CONFIG_DESIGNWARE_ETH |
50 | int cpu_eth_init(bd_t *bis) | 52 | int cpu_eth_init(bd_t *bis) |
51 | { | 53 | { |
52 | #if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS | 54 | #if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS |
53 | const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; | 55 | const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; |
54 | #elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS | 56 | #elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS |
55 | const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; | 57 | const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; |
56 | #else | 58 | #else |
57 | #error "Incorrect CONFIG_EMAC_BASE value!" | 59 | #error "Incorrect CONFIG_EMAC_BASE value!" |
58 | #endif | 60 | #endif |
59 | 61 | ||
60 | /* Initialize EMAC. This needs to be done at least once per boot. */ | 62 | /* Initialize EMAC. This needs to be done at least once per boot. */ |
61 | 63 | ||
62 | /* | 64 | /* |
63 | * Putting the EMAC controller to reset when configuring the PHY | 65 | * Putting the EMAC controller to reset when configuring the PHY |
64 | * interface select at System Manager | 66 | * interface select at System Manager |
65 | */ | 67 | */ |
66 | socfpga_emac_reset(1); | 68 | socfpga_emac_reset(1); |
67 | 69 | ||
68 | /* Clearing emac0 PHY interface select to 0 */ | 70 | /* Clearing emac0 PHY interface select to 0 */ |
69 | clrbits_le32(&sysmgr_regs->emacgrp_ctrl, | 71 | clrbits_le32(&sysmgr_regs->emacgrp_ctrl, |
70 | SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); | 72 | SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); |
71 | 73 | ||
72 | /* configure to PHY interface select choosed */ | 74 | /* configure to PHY interface select choosed */ |
73 | setbits_le32(&sysmgr_regs->emacgrp_ctrl, | 75 | setbits_le32(&sysmgr_regs->emacgrp_ctrl, |
74 | SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); | 76 | SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); |
75 | 77 | ||
76 | /* Release the EMAC controller from reset */ | 78 | /* Release the EMAC controller from reset */ |
77 | socfpga_emac_reset(0); | 79 | socfpga_emac_reset(0); |
78 | 80 | ||
79 | /* initialize and register the emac */ | 81 | /* initialize and register the emac */ |
80 | return designware_initialize(CONFIG_EMAC_BASE, | 82 | return designware_initialize(CONFIG_EMAC_BASE, |
81 | CONFIG_PHY_INTERFACE_MODE); | 83 | CONFIG_PHY_INTERFACE_MODE); |
82 | } | 84 | } |
83 | #endif | 85 | #endif |
84 | 86 | ||
85 | #ifdef CONFIG_DWMMC | 87 | #ifdef CONFIG_DWMMC |
86 | /* | 88 | /* |
87 | * Initializes MMC controllers. | 89 | * Initializes MMC controllers. |
88 | * to override, implement board_mmc_init() | 90 | * to override, implement board_mmc_init() |
89 | */ | 91 | */ |
90 | int cpu_mmc_init(bd_t *bis) | 92 | int cpu_mmc_init(bd_t *bis) |
91 | { | 93 | { |
92 | return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, | 94 | return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, |
93 | CONFIG_HPS_SDMMC_BUSWIDTH, 0); | 95 | CONFIG_HPS_SDMMC_BUSWIDTH, 0); |
94 | } | 96 | } |
95 | #endif | 97 | #endif |
96 | 98 | ||
97 | #if defined(CONFIG_DISPLAY_CPUINFO) | 99 | #if defined(CONFIG_DISPLAY_CPUINFO) |
98 | /* | 100 | /* |
99 | * Print CPU information | 101 | * Print CPU information |
100 | */ | 102 | */ |
101 | int print_cpuinfo(void) | 103 | int print_cpuinfo(void) |
102 | { | 104 | { |
103 | puts("CPU: Altera SoCFPGA Platform\n"); | 105 | puts("CPU: Altera SoCFPGA Platform\n"); |
104 | return 0; | 106 | return 0; |
105 | } | 107 | } |
106 | #endif | 108 | #endif |
107 | 109 | ||
108 | #if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ | 110 | #if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ |
109 | defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) | 111 | defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) |
110 | int overwrite_console(void) | 112 | int overwrite_console(void) |
111 | { | 113 | { |
112 | return 0; | 114 | return 0; |
113 | } | 115 | } |
114 | #endif | 116 | #endif |
115 | 117 | ||
116 | #ifdef CONFIG_FPGA | 118 | #ifdef CONFIG_FPGA |
117 | /* | 119 | /* |
118 | * FPGA programming support for SoC FPGA Cyclone V | 120 | * FPGA programming support for SoC FPGA Cyclone V |
119 | */ | 121 | */ |
120 | static Altera_desc altera_fpga[] = { | 122 | static Altera_desc altera_fpga[] = { |
121 | { | 123 | { |
122 | /* Family */ | 124 | /* Family */ |
123 | Altera_SoCFPGA, | 125 | Altera_SoCFPGA, |
124 | /* Interface type */ | 126 | /* Interface type */ |
125 | fast_passive_parallel, | 127 | fast_passive_parallel, |
126 | /* No limitation as additional data will be ignored */ | 128 | /* No limitation as additional data will be ignored */ |
127 | -1, | 129 | -1, |
128 | /* No device function table */ | 130 | /* No device function table */ |
129 | NULL, | 131 | NULL, |
130 | /* Base interface address specified in driver */ | 132 | /* Base interface address specified in driver */ |
131 | NULL, | 133 | NULL, |
132 | /* No cookie implementation */ | 134 | /* No cookie implementation */ |
133 | 0 | 135 | 0 |
134 | }, | 136 | }, |
135 | }; | 137 | }; |
136 | 138 | ||
137 | /* add device descriptor to FPGA device table */ | 139 | /* add device descriptor to FPGA device table */ |
138 | static void socfpga_fpga_add(void) | 140 | static void socfpga_fpga_add(void) |
139 | { | 141 | { |
140 | int i; | 142 | int i; |
141 | fpga_init(); | 143 | fpga_init(); |
142 | for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) | 144 | for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) |
143 | fpga_add(fpga_altera, &altera_fpga[i]); | 145 | fpga_add(fpga_altera, &altera_fpga[i]); |
144 | } | 146 | } |
145 | #else | 147 | #else |
146 | static inline void socfpga_fpga_add(void) {} | 148 | static inline void socfpga_fpga_add(void) {} |
147 | #endif | 149 | #endif |
148 | 150 | ||
149 | int arch_cpu_init(void) | 151 | int arch_cpu_init(void) |
150 | { | 152 | { |
151 | /* | 153 | /* |
152 | * If the HW watchdog is NOT enabled, make sure it is not running, | 154 | * If the HW watchdog is NOT enabled, make sure it is not running, |
153 | * for example because it was enabled in the preloader. This might | 155 | * for example because it was enabled in the preloader. This might |
154 | * trigger a watchdog-triggered reboot of Linux kernel later. | 156 | * trigger a watchdog-triggered reboot of Linux kernel later. |
155 | */ | 157 | */ |
156 | #ifndef CONFIG_HW_WATCHDOG | 158 | #ifndef CONFIG_HW_WATCHDOG |
157 | socfpga_watchdog_reset(); | 159 | socfpga_watchdog_reset(); |
158 | #endif | 160 | #endif |
159 | return 0; | 161 | return 0; |
160 | } | 162 | } |
161 | 163 | ||
162 | /* | 164 | /* |
163 | * Convert all NIC-301 AMBA slaves from secure to non-secure | 165 | * Convert all NIC-301 AMBA slaves from secure to non-secure |
164 | */ | 166 | */ |
165 | static void socfpga_nic301_slave_ns(void) | 167 | static void socfpga_nic301_slave_ns(void) |
166 | { | 168 | { |
167 | writel(0x1, &nic301_regs->lwhps2fpgaregs); | 169 | writel(0x1, &nic301_regs->lwhps2fpgaregs); |
168 | writel(0x1, &nic301_regs->hps2fpgaregs); | 170 | writel(0x1, &nic301_regs->hps2fpgaregs); |
169 | writel(0x1, &nic301_regs->acp); | 171 | writel(0x1, &nic301_regs->acp); |
170 | writel(0x1, &nic301_regs->rom); | 172 | writel(0x1, &nic301_regs->rom); |
171 | writel(0x1, &nic301_regs->ocram); | 173 | writel(0x1, &nic301_regs->ocram); |
172 | writel(0x1, &nic301_regs->sdrdata); | 174 | writel(0x1, &nic301_regs->sdrdata); |
173 | } | 175 | } |
174 | 176 | ||
177 | static uint32_t iswgrp_handoff[8]; | ||
178 | |||
175 | int misc_init_r(void) | 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 | socfpga_bridges_reset(1); | 185 | socfpga_bridges_reset(1); |
178 | socfpga_nic301_slave_ns(); | 186 | socfpga_nic301_slave_ns(); |
179 | 187 | ||
180 | /* | 188 | /* |
181 | * Private components security: | 189 | * Private components security: |
182 | * U-Boot : configure private timer, global timer and cpu component | 190 | * U-Boot : configure private timer, global timer and cpu component |
183 | * access as non secure for kernel stage (as required by Linux) | 191 | * access as non secure for kernel stage (as required by Linux) |
184 | */ | 192 | */ |
185 | setbits_le32(&scu_regs->sacr, 0xfff); | 193 | setbits_le32(&scu_regs->sacr, 0xfff); |
186 | 194 | ||
187 | /* Configure the L2 controller to make SDRAM start at 0 */ | 195 | /* Configure the L2 controller to make SDRAM start at 0 */ |
188 | #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET | 196 | #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET |
189 | writel(0x2, &nic301_regs->remap); | 197 | writel(0x2, &nic301_regs->remap); |
190 | #else | 198 | #else |
191 | writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ | 199 | writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ |
192 | writel(0x1, &pl310->pl310_addr_filter_start); | 200 | writel(0x1, &pl310->pl310_addr_filter_start); |
193 | #endif | 201 | #endif |
194 | 202 | ||
195 | /* Add device descriptor to FPGA device table */ | 203 | /* Add device descriptor to FPGA device table */ |
196 | socfpga_fpga_add(); | 204 | socfpga_fpga_add(); |
197 | return 0; | 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 | ); | ||
199 | 274 |