1 /*
2 * Copyright (c) 2020-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 <plat/arm/common/plat_arm.h>
10 #include <plat/common/platform.h>
11 #include <services/el3_spmc_ffa_memory.h>
12
13 #include <nrd_plat.h>
14 #include <rdn2_ras.h>
15
16 #define RT_OWNER 0
17 #define A4SID_CHIP_0 0x0
18 #define A4SID_CHIP_1 0x1
19 #define A4SID_CHIP_2 0x2
20 #define A4SID_CHIP_3 0x3
21
22 #if defined(IMAGE_BL31)
23 #if (NRD_PLATFORM_VARIANT == 2)
24 static const mmap_region_t rdn2mc_dynamic_mmap[] = {
25 #if NRD_CHIP_COUNT > 1
26 NRD_CSS_SHARED_RAM_MMAP(1),
27 NRD_CSS_PERIPH_MMAP(1),
28 #endif
29 #if NRD_CHIP_COUNT > 2
30 NRD_CSS_SHARED_RAM_MMAP(2),
31 NRD_CSS_PERIPH_MMAP(2),
32 #endif
33 #if NRD_CHIP_COUNT > 3
34 NRD_CSS_SHARED_RAM_MMAP(3),
35 NRD_CSS_PERIPH_MMAP(3),
36 #endif
37 };
38 #endif
39
40 #if (NRD_PLATFORM_VARIANT == 2)
41 static struct gic600_multichip_data rdn2mc_multichip_data __init = {
42 .base_addrs = {
43 PLAT_ARM_GICD_BASE,
44 #if NRD_CHIP_COUNT > 1
45 PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
46 #endif
47 #if NRD_CHIP_COUNT > 2
48 PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
49 #endif
50 #if NRD_CHIP_COUNT > 3
51 PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
52 #endif
53 },
54 .rt_owner = RT_OWNER,
55 .chip_count = NRD_CHIP_COUNT,
56 .chip_addrs = {
57 {
58 A4SID_CHIP_0,
59 A4SID_CHIP_1,
60 A4SID_CHIP_2,
61 A4SID_CHIP_3
62 },
63 #if NRD_CHIP_COUNT > 1
64 {
65 A4SID_CHIP_0,
66 A4SID_CHIP_1,
67 A4SID_CHIP_2,
68 A4SID_CHIP_3
69 },
70 #endif
71 #if NRD_CHIP_COUNT > 2
72 {
73 A4SID_CHIP_0,
74 A4SID_CHIP_1,
75 A4SID_CHIP_2,
76 A4SID_CHIP_3
77 },
78 #endif
79 #if NRD_CHIP_COUNT > 3
80 {
81 A4SID_CHIP_0,
82 A4SID_CHIP_1,
83 A4SID_CHIP_2,
84 A4SID_CHIP_3
85 }
86 #endif
87 },
88 .spi_ids = {
89 {PLAT_ARM_GICD_BASE,
90 NRD_CHIP0_SPI_MIN,
91 NRD_CHIP0_SPI_MAX},
92 #if NRD_CHIP_COUNT > 1
93 {PLAT_ARM_GICD_BASE,
94 NRD_CHIP1_SPI_MIN,
95 NRD_CHIP1_SPI_MAX},
96 #endif
97 #if NRD_CHIP_COUNT > 2
98 {PLAT_ARM_GICD_BASE,
99 NRD_CHIP2_SPI_MIN,
100 NRD_CHIP2_SPI_MAX},
101 #endif
102 #if NRD_CHIP_COUNT > 3
103 {PLAT_ARM_GICD_BASE,
104 NRD_CHIP3_SPI_MIN,
105 NRD_CHIP3_SPI_MAX},
106 #endif
107 }
108 };
109 #endif
110
111 static uintptr_t rdn2mc_multichip_gicr_frames[] = {
112 /* Chip 0's GICR Base */
113 PLAT_ARM_GICR_BASE,
114 #if (NRD_PLATFORM_VARIANT == 2)
115 #if NRD_CHIP_COUNT > 1
116 /* Chip 1's GICR BASE */
117 PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
118 #endif
119 #if NRD_CHIP_COUNT > 2
120 /* Chip 2's GICR BASE */
121 PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
122 #endif
123 #if NRD_CHIP_COUNT > 3
124 /* Chip 3's GICR BASE */
125 PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
126 #endif
127 #endif
128 UL(0) /* Zero Termination */
129 };
130 #endif /* IMAGE_BL31 */
131
plat_arm_nrd_get_platform_id(void)132 unsigned int plat_arm_nrd_get_platform_id(void)
133 {
134 return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
135 & SID_SYSTEM_ID_PART_NUM_MASK;
136 }
137
plat_arm_nrd_get_config_id(void)138 unsigned int plat_arm_nrd_get_config_id(void)
139 {
140 return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
141 }
142
plat_arm_nrd_get_multi_chip_mode(void)143 unsigned int plat_arm_nrd_get_multi_chip_mode(void)
144 {
145 return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
146 SID_MULTI_CHIP_MODE_MASK) >>
147 SID_MULTI_CHIP_MODE_SHIFT;
148 }
149
150 #if defined(IMAGE_BL31)
bl31_platform_setup(void)151 void bl31_platform_setup(void)
152 {
153 #if (NRD_PLATFORM_VARIANT == 2)
154 int ret;
155 unsigned int i;
156
157 if (plat_arm_nrd_get_multi_chip_mode() == 0) {
158 ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
159 NRD_CHIP_COUNT);
160 panic();
161 } else {
162 INFO("Enabling multi-chip support for RD-N2 variant\n");
163
164 for (i = 0; i < ARRAY_SIZE(rdn2mc_dynamic_mmap); i++) {
165 ret = mmap_add_dynamic_region(
166 rdn2mc_dynamic_mmap[i].base_pa,
167 rdn2mc_dynamic_mmap[i].base_va,
168 rdn2mc_dynamic_mmap[i].size,
169 rdn2mc_dynamic_mmap[i].attr);
170 if (ret != 0) {
171 ERROR("Failed to add dynamic mmap entry for"
172 " i: %d " "(ret=%d)\n", i, ret);
173 panic();
174 }
175 }
176
177 gic600_multichip_init(&rdn2mc_multichip_data);
178 }
179 #endif
180
181 nrd_bl31_common_platform_setup();
182
183 gic_set_gicr_frames(
184 rdn2mc_multichip_gicr_frames);
185
186 #if ENABLE_FEAT_RAS && FFH_SUPPORT
187 nrd_ras_platform_setup(&ras_config);
188 #endif
189 }
190 #endif /* IMAGE_BL31 */
191
192 #if SPMC_AT_EL3
193
194 #define DATASTORE_SIZE 1024
195
196 __section("arm_el3_tzc_dram") uint8_t plat_spmc_shmem_datastore[DATASTORE_SIZE];
197
plat_spmc_shmem_datastore_get(uint8_t ** datastore,size_t * size)198 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
199 {
200 *datastore = plat_spmc_shmem_datastore;
201 *size = DATASTORE_SIZE;
202 return 0;
203 }
204
205 /*
206 * Add dummy implementations of memory management related platform hooks.
207 * Memory share/lend operation are not required on RdN2 platform.
208 */
plat_spmc_shmem_begin(struct ffa_mtd * desc)209 int plat_spmc_shmem_begin(struct ffa_mtd *desc)
210 {
211 return 0;
212 }
213
plat_spmc_shmem_reclaim(struct ffa_mtd * desc)214 int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
215 {
216 return 0;
217 }
218
plat_spmd_handle_group0_interrupt(uint32_t intid)219 int plat_spmd_handle_group0_interrupt(uint32_t intid)
220 {
221 /*
222 * As of now, there are no sources of Group0 secure interrupt enabled
223 * for RDN2.
224 */
225 (void)intid;
226 return -1;
227 }
228 #endif
229