1 /*
2 * Copyright (c) 2026, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <common/debug.h>
8 #include <drivers/arm/gic600_multichip.h>
9 #include <drivers/arm/sfcp.h>
10 #include <drivers/arm/smmu_v3.h>
11 #include <lib/per_cpu/per_cpu.h>
12 #include <plat/arm/common/plat_arm.h>
13 #include <plat/common/platform.h>
14
15 #include <nrd_css_fw_def3.h>
16 #include <nrd_plat.h>
17 #include <nrd_variant.h>
18
19 #define RT_OWNER 0
20
21 /*
22 * Base addr of the frame that allocated by the platform
23 * intended for remote gic to local gic interrupt
24 * message communication
25 */
26 #define NRD_RGIC2LGIC_MESSREG_HNI_BASE UL(0x5FFF0000)
27
28 #if (PLATFORM_NODE_COUNT > 1)
29 /*
30 * NUMA node related information for a platform could be populated in by any
31 * means. This could come in via device tree, transfer list or could even be
32 * hardcoded. For rdv3cfg2, this is statically defined at the moment.
33 */
34 const uintptr_t per_cpu_nodes_base[] = {
35 (uintptr_t)PER_CPU_START,
36 (uintptr_t)NRD_REMOTE_CHIP_MEM_OFFSET(1),
37 (uintptr_t)NRD_REMOTE_CHIP_MEM_OFFSET(2),
38 (uintptr_t)NRD_REMOTE_CHIP_MEM_OFFSET(3)
39
40 };
41 #endif
42
43 #if (NRD_PLATFORM_VARIANT == 2)
44 static const mmap_region_t rdv3mc_dynamic_mmap[] = {
45 #if NRD_CHIP_COUNT > 1
46 NRD_CSS_SHARED_RAM_MMAP(1),
47 NRD_CSS_PERIPH_MMAP(1),
48 #endif
49 #if NRD_CHIP_COUNT > 2
50 NRD_CSS_SHARED_RAM_MMAP(2),
51 NRD_CSS_PERIPH_MMAP(2),
52 #endif
53 #if NRD_CHIP_COUNT > 3
54 NRD_CSS_SHARED_RAM_MMAP(3),
55 NRD_CSS_PERIPH_MMAP(3),
56 #endif
57 };
58
59 static struct gic600_multichip_data rdv3mc_multichip_data __init = {
60 .base_addrs = {
61 PLAT_ARM_GICD_BASE,
62 #if NRD_CHIP_COUNT > 1
63 PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
64 #endif
65 #if NRD_CHIP_COUNT > 2
66 PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
67 #endif
68 #if NRD_CHIP_COUNT > 3
69 PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
70 #endif
71 },
72 .rt_owner = RT_OWNER,
73 .chip_count = NRD_CHIP_COUNT,
74 .chip_addrs = {
75 {
76 NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16,
77 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
78 + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
79 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
80 + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
81 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
82 + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
83 },
84 #if NRD_CHIP_COUNT > 1
85 {
86 NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16,
87 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
88 + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
89 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
90 + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
91 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
92 + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
93 },
94 #endif
95 #if NRD_CHIP_COUNT > 2
96 {
97 NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16,
98 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
99 + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
100 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
101 + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
102 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
103 + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
104 },
105 #endif
106 #if NRD_CHIP_COUNT > 3
107 {
108 NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16,
109 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
110 + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
111 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
112 + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
113 (NRD_RGIC2LGIC_MESSREG_HNI_BASE
114 + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
115 }
116 #endif
117 },
118 .spi_ids = {
119 {PLAT_ARM_GICD_BASE, 32, 511},
120 #if NRD_CHIP_COUNT > 1
121 {PLAT_ARM_GICD_BASE, 512, 991},
122 #endif
123 #if NRD_CHIP_COUNT > 2
124 {PLAT_ARM_GICD_BASE, 4096, 4575},
125 #endif
126 #if NRD_CHIP_COUNT > 3
127 {PLAT_ARM_GICD_BASE, 4576, 5055},
128 #endif
129 }
130 };
131 #endif /* NRD_PLATFORM_VARIANT == 2 */
132
133 static uintptr_t rdv3mc_multichip_gicr_frames[] = {
134 /* Chip 0's GICR Base */
135 PLAT_ARM_GICR_BASE,
136 #if (NRD_PLATFORM_VARIANT == 2)
137 #if NRD_CHIP_COUNT > 1
138 /* Chip 1's GICR BASE */
139 PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
140 #endif
141 #if NRD_CHIP_COUNT > 2
142 /* Chip 2's GICR BASE */
143 PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
144 #endif
145 #if NRD_CHIP_COUNT > 3
146 /* Chip 3's GICR BASE */
147 PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
148 #endif
149 #endif /* NRD_PLATFORM_VARIANT == 2 */
150 UL(0) /* Zero Termination */
151 };
152
bl31_plat_arch_setup(void)153 void __init bl31_plat_arch_setup(void)
154 {
155 #if (NRD_PLATFORM_VARIANT == 2)
156 #if (PLATFORM_NODE_COUNT > 1)
157 int ret;
158 #endif
159 arm_bl31_plat_arch_setup();
160 #if (PLATFORM_NODE_COUNT > 1)
161 /* Add mmap for all remote chips */
162 for (int i = 1; i < ARRAY_SIZE(per_cpu_nodes_base); i++) {
163 ret = mmap_add_dynamic_region(
164 NRD_REMOTE_CHIP_MEM_OFFSET(i),
165 NRD_REMOTE_CHIP_MEM_OFFSET(i),
166 NRD_CSS_PAGE_ALIGN_CEIL((PER_CPU_END - PER_CPU_START)),
167 MT_MEMORY | MT_RW | EL3_PAS);
168 if (ret != 0) {
169 ERROR("Failed to add per-cpu mmap (ret=%d)", ret);
170 panic();
171 }
172 }
173 #endif
174
175 #if (NRD_PLATFORM_VARIANT == 2)
176 if (plat_arm_nrd_get_multi_chip_mode()) {
177 gic600_multichip_init(&rdv3mc_multichip_data);
178 }
179 #endif
180
181 #endif
182 gic_set_gicr_frames(rdv3mc_multichip_gicr_frames);
183 }
184
bl31_platform_setup(void)185 void bl31_platform_setup(void)
186 {
187 enum sfcp_error_t sfcp_err;
188
189 /*
190 * Perform SMMUv3 GPT configuration for the GPC SMMU present in system
191 * control block on RD-V3 platforms. This SMMUv3 initialization is
192 * not fatal.
193 *
194 * Don't perform smmuv3_security_init() for this instance of SMMUv3 as
195 * the global aborts need not be configured to allow the components in
196 * system control block send transations downstream to SMMUv3.
197 */
198 if (smmuv3_init(NRD_CSS_GPC_SMMUV3_BASE) != 0) {
199 WARN("Failed initializing System SMMU.\n");
200 }
201
202 #if (NRD_PLATFORM_VARIANT == 2)
203 int ret;
204 unsigned int i;
205
206 if (plat_arm_nrd_get_multi_chip_mode() == 0) {
207 ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
208 NRD_CHIP_COUNT);
209 panic();
210 } else {
211 INFO("Enabling multi-chip support for RD-V3 variant\n");
212
213 for (i = 0; i < ARRAY_SIZE(rdv3mc_dynamic_mmap); i++) {
214 ret = mmap_add_dynamic_region(
215 rdv3mc_dynamic_mmap[i].base_pa,
216 rdv3mc_dynamic_mmap[i].base_va,
217 rdv3mc_dynamic_mmap[i].size,
218 rdv3mc_dynamic_mmap[i].attr);
219 if (ret != 0) {
220 ERROR("Failed to add entry i: %d (ret=%d)\n",
221 i, ret);
222 panic();
223 }
224 }
225 }
226 #endif /* NRD_PLATFORM_VARIANT == 2 */
227 nrd_bl31_common_platform_setup();
228
229 /* Initialize SFCP for communications between AP and RSE */
230 sfcp_err = sfcp_init();
231 if (sfcp_err != SFCP_ERROR_SUCCESS) {
232 WARN("Failed initializing AP-RSE comms.\n");
233 }
234 }
235
236 #if RESET_TO_BL31
237 /*
238 * The GPT library might modify the gpt regions structure to optimize
239 * the layout, so the array cannot be constant.
240 */
241 static pas_region_t pas_regions[] = {
242 NRD_PAS_SHARED_SRAM,
243 NRD_PAS_SYSTEM_NCI,
244 NRD_PAS_DEBUG_NIC,
245 NRD_PAS_NS_UART,
246 NRD_PAS_REALM_UART,
247 NRD_PAS_AP_NS_WDOG,
248 NRD_PAS_AP_ROOT_WDOG,
249 NRD_PAS_AP_SECURE_WDOG,
250 NRD_PAS_SECURE_SRAM_ERB_AP,
251 NRD_PAS_NS_SRAM_ERB_AP,
252 NRD_PAS_ROOT_SRAM_ERB_AP,
253 NRD_PAS_REALM_SRAM_ERB_AP,
254 NRD_PAS_SECURE_SRAM_ERB_SCP,
255 NRD_PAS_NS_SRAM_ERB_SCP,
256 NRD_PAS_ROOT_SRAM_ERB_SCP,
257 NRD_PAS_REALM_SRAM_ERB_SCP,
258 NRD_PAS_SECURE_SRAM_ERB_MCP,
259 NRD_PAS_NS_SRAM_ERB_MCP,
260 NRD_PAS_ROOT_SRAM_ERB_MCP,
261 NRD_PAS_REALM_SRAM_ERB_MCP,
262 NRD_PAS_SECURE_SRAM_ERB_RSE,
263 NRD_PAS_NS_SRAM_ERB_RSE,
264 NRD_PAS_ROOT_SRAM_ERB_RSE,
265 NRD_PAS_REALM_SRAM_ERB_RSE,
266 NRD_PAS_RSE_SECURE_SRAM_ERB_RSM,
267 NRD_PAS_RSE_NS_SRAM_ERB_RSM,
268 NRD_PAS_SCP_SECURE_SRAM_ERB_RSM,
269 NRD_PAS_SCP_NS_SRAM_ERB_RSM,
270 NRD_PAS_MCP_SECURE_SRAM_ERB_RSM,
271 NRD_PAS_MCP_NS_SRAM_ERB_RSM,
272 NRD_PAS_AP_SCP_ROOT_MHU,
273 NRD_PAS_AP_MCP_NS_MHU,
274 NRD_PAS_AP_MCP_SECURE_MHU,
275 NRD_PAS_AP_MCP_ROOT_MHU,
276 NRD_PAS_AP_RSE_NS_MHU,
277 NRD_PAS_AP_RSE_SECURE_MHU,
278 NRD_PAS_AP_RSE_ROOT_MHU,
279 NRD_PAS_AP_RSE_REALM_MHU,
280 NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU,
281 NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR,
282 NRD_PAS_STM_SYSTEM_ITS,
283 NRD_PAS_SCP_MCP_RSE_SHARED_SRAM,
284 NRD_PAS_GIC,
285 NRD_PAS_NS_DRAM,
286 NRD_PAS_RMM,
287 NRD_PAS_L1GPT,
288 NRD_PAS_CMN,
289 NRD_PAS_LCP_PERIPHERAL,
290 NRD_PAS_DDR_IO,
291 NRD_PAS_SMMU_NCI_IO,
292 NRD_PAS_DRAM2_CHIP0,
293 #if NRD_CHIP_COUNT > 1
294 NRD_PAS_DRAM1_CHIP1,
295 NRD_PAS_DRAM2_CHIP1,
296 #endif
297 #if NRD_CHIP_COUNT > 2
298 NRD_PAS_DRAM1_CHIP2,
299 NRD_PAS_DRAM2_CHIP2,
300 #endif
301 #if NRD_CHIP_COUNT > 3
302 NRD_PAS_DRAM1_CHIP3,
303 NRD_PAS_DRAM2_CHIP3
304 #endif
305 };
306
307 static const arm_gpt_info_t arm_gpt_info = {
308 .pas_region_base = pas_regions,
309 .pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
310 .l0_base = (uintptr_t)ARM_L0_GPT_BASE,
311 .l1_base = (uintptr_t)ARM_L1_GPT_BASE,
312 .l0_size = (size_t)ARM_L0_GPT_SIZE,
313 .l1_size = (size_t)ARM_L1_GPT_SIZE,
314 .pps = GPCCR_PPS_256TB,
315 .pgs = GPCCR_PGS_4K
316 };
317
plat_arm_get_gpt_info(void)318 const arm_gpt_info_t *plat_arm_get_gpt_info(void)
319 {
320 return &arm_gpt_info;
321 }
322
323 #endif /* RESET_TO_BL31 */
324