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