1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2022-2024, STMicroelectronics
4 */
5
6 #include <arm.h>
7 #include <config.h>
8 #include <drivers/clk.h>
9 #include <drivers/clk_dt.h>
10 #include <drivers/stm32_rif.h>
11 #include <io.h>
12 #include <kernel/boot.h>
13 #include <kernel/delay.h>
14 #include <kernel/dt.h>
15 #include <kernel/dt_driver.h>
16 #include <kernel/panic.h>
17 #include <kernel/pm.h>
18 #include <libfdt.h>
19 #include <mm/core_memprot.h>
20 #include <stdbool.h>
21 #include <stdlib.h>
22 #include <stm32_util.h>
23 #include <trace.h>
24
25 #define IPCC_C1SECCFGR U(0x80)
26 #define IPCC_C1PRIVCFGR U(0x84)
27 #define IPCC_C1CIDCFGR U(0x88)
28 #define IPCC_C2SECCFGR U(0x90)
29 #define IPCC_C2PRIVCFGR U(0x94)
30 #define IPCC_C2CIDCFGR U(0x98)
31 #define IPCC_HWCFGR U(0x3F0)
32
33 /*
34 * CIDCFGR register bitfields
35 */
36 #define IPCC_CIDCFGR_CFEN BIT(0)
37 #define IPCC_CIDCFGR_SCID_MASK GENMASK_32(6, 4)
38 #define IPCC_CIDCFGR_CONF_MASK (_CIDCFGR_CFEN | \
39 IPCC_CIDCFGR_SCID_MASK)
40
41 /*
42 * PRIVCFGR register bitfields
43 */
44 #define IPCC_PRIVCFGR_MASK GENMASK_32(15, 0)
45
46 /*
47 * SECCFGR register bitfields
48 */
49 #define IPCC_SECCFGR_MASK GENMASK_32(15, 0)
50
51 /*
52 * IPCC_HWCFGR register bitfields
53 */
54 #define IPCC_HWCFGR_CHAN_MASK GENMASK_32(7, 0)
55
56 /*
57 * Miscellaneous
58 */
59 #define IPCC_NB_MAX_RIF_CHAN U(16)
60
61 struct ipcc_pdata {
62 /*
63 * An IPCC has nb_channels_cfg channel configuration for its
64 * (nb_channels_cfg / 2) bi-directionnal channels
65 */
66 unsigned int nb_channels_cfg;
67 struct clk *ipcc_clock;
68 vaddr_t base;
69 struct rif_conf_data *conf_data;
70 bool is_tdcid;
71
72 STAILQ_ENTRY(ipcc_pdata) link;
73 };
74
75 static STAILQ_HEAD(, ipcc_pdata) ipcc_list =
76 STAILQ_HEAD_INITIALIZER(ipcc_list);
77
78 /* This function expects IPCC bus clock is enabled */
apply_rif_config(struct ipcc_pdata * ipcc_d)79 static void apply_rif_config(struct ipcc_pdata *ipcc_d)
80 {
81 bool proc1_cidfilt = false;
82 bool proc2_cidfilt = false;
83 uint32_t priv_proc_1 = 0;
84 uint32_t priv_proc_2 = 0;
85 uint32_t sec_proc_1 = 0;
86 uint32_t sec_proc_2 = 0;
87 unsigned int cid1 = 0;
88 unsigned int cid2 = 0;
89 unsigned int i = 0;
90 bool is_cid_configured = false;
91
92 if (!ipcc_d->conf_data)
93 return;
94
95 /*
96 * Check that the number of channel supported by hardware
97 * is coherent with the config
98 */
99 assert((io_read32(ipcc_d->base + IPCC_HWCFGR) &
100 IPCC_HWCFGR_CHAN_MASK) >=
101 ipcc_d->nb_channels_cfg / 2);
102
103 /*
104 * When TDCID, OP-TEE should be the one to set the CID filtering
105 * configuration. Clearing previous configuration prevents
106 * undesired events during the only legitimate configuration.
107 */
108 if (ipcc_d->is_tdcid) {
109 /* IPCC Processor 1 */
110 io_clrbits32(ipcc_d->base + IPCC_C1CIDCFGR,
111 IPCC_CIDCFGR_CONF_MASK);
112
113 /* IPCC Processor 2 */
114 io_clrbits32(ipcc_d->base + IPCC_C2CIDCFGR,
115 IPCC_CIDCFGR_CONF_MASK);
116 }
117
118 cid1 = io_read32(ipcc_d->base + IPCC_C1CIDCFGR) &
119 IPCC_CIDCFGR_SCID_MASK;
120 cid2 = io_read32(ipcc_d->base + IPCC_C2CIDCFGR) &
121 IPCC_CIDCFGR_SCID_MASK;
122
123 proc1_cidfilt = io_read32(ipcc_d->base + IPCC_C1CIDCFGR) &
124 IPCC_CIDCFGR_CFEN;
125 proc2_cidfilt = io_read32(ipcc_d->base + IPCC_C2CIDCFGR) &
126 IPCC_CIDCFGR_CFEN;
127
128 /* Split the sec and priv configuration for IPCC processor 1 and 2 */
129 sec_proc_1 = ipcc_d->conf_data->sec_conf[0] &
130 GENMASK_32(IPCC_NB_MAX_RIF_CHAN - 1, 0);
131 priv_proc_1 = ipcc_d->conf_data->priv_conf[0] &
132 GENMASK_32(IPCC_NB_MAX_RIF_CHAN - 1, 0);
133
134 sec_proc_2 = (ipcc_d->conf_data->sec_conf[0] &
135 GENMASK_32((IPCC_NB_MAX_RIF_CHAN * 2) - 1,
136 IPCC_NB_MAX_RIF_CHAN)) >>
137 IPCC_NB_MAX_RIF_CHAN;
138 priv_proc_2 = (ipcc_d->conf_data->priv_conf[0] &
139 GENMASK_32((IPCC_NB_MAX_RIF_CHAN * 2) - 1,
140 IPCC_NB_MAX_RIF_CHAN)) >>
141 IPCC_NB_MAX_RIF_CHAN;
142
143 /* Security and privilege RIF configuration */
144 if (!proc1_cidfilt || cid1 == RIF_CID1) {
145 io_clrsetbits32(ipcc_d->base + IPCC_C1PRIVCFGR,
146 IPCC_PRIVCFGR_MASK, priv_proc_1);
147 io_clrsetbits32(ipcc_d->base + IPCC_C1SECCFGR,
148 IPCC_SECCFGR_MASK, sec_proc_1);
149 }
150 if (!proc2_cidfilt || cid2 == RIF_CID1) {
151 io_clrsetbits32(ipcc_d->base + IPCC_C2PRIVCFGR,
152 IPCC_PRIVCFGR_MASK, priv_proc_2);
153 io_clrsetbits32(ipcc_d->base + IPCC_C2SECCFGR,
154 IPCC_SECCFGR_MASK, sec_proc_2);
155 }
156
157 /*
158 * Evaluate RIF CID filtering configuration before setting it.
159 * Parsed configuration must have consistency. If CID filtering
160 * is enabled for an IPCC channel, then it must be the case for all
161 * channels of this processor. This is a configuration check.
162 */
163 for (i = 0; i < IPCC_NB_MAX_RIF_CHAN; i++) {
164 if (!(BIT(i) & ipcc_d->conf_data->access_mask[0]))
165 continue;
166
167 if (!is_cid_configured &&
168 (BIT(0) & ipcc_d->conf_data->cid_confs[i])) {
169 is_cid_configured = true;
170 if (i > 0)
171 panic("Inconsistent IPCC CID filtering RIF configuration");
172 }
173
174 if (is_cid_configured &&
175 !(BIT(0) & ipcc_d->conf_data->cid_confs[i]))
176 panic("Inconsistent IPCC CID filtering RIF configuration");
177 }
178
179 /* IPCC processor 1 CID filtering configuration */
180 if (!ipcc_d->is_tdcid)
181 return;
182
183 io_clrsetbits32(ipcc_d->base + IPCC_C1CIDCFGR,
184 IPCC_CIDCFGR_CONF_MASK,
185 ipcc_d->conf_data->cid_confs[0]);
186
187 /*
188 * Reset this field to evaluate CID filtering configuration
189 * for processor 2
190 */
191 is_cid_configured = false;
192
193 for (i = IPCC_NB_MAX_RIF_CHAN; i < IPCC_NB_MAX_RIF_CHAN * 2; i++) {
194 if (!(BIT(i) & ipcc_d->conf_data->access_mask[0]))
195 continue;
196
197 if (!is_cid_configured &&
198 (BIT(0) & ipcc_d->conf_data->cid_confs[i])) {
199 is_cid_configured = true;
200 if (i > IPCC_NB_MAX_RIF_CHAN)
201 panic("Inconsistent IPCC CID filtering RIF configuration");
202 }
203
204 if (is_cid_configured &&
205 !(BIT(0) & ipcc_d->conf_data->cid_confs[i]))
206 panic("Inconsistent IPCC CID filtering RIF configuration");
207 }
208
209 /* IPCC Processor 2 CID filtering configuration */
210 io_clrsetbits32(ipcc_d->base + IPCC_C2CIDCFGR,
211 IPCC_CIDCFGR_CONF_MASK,
212 ipcc_d->conf_data->cid_confs[IPCC_NB_MAX_RIF_CHAN]);
213 }
214
stm32_ipcc_pm_resume(struct ipcc_pdata * ipcc)215 static void stm32_ipcc_pm_resume(struct ipcc_pdata *ipcc)
216 {
217 apply_rif_config(ipcc);
218 }
219
stm32_ipcc_pm_suspend(struct ipcc_pdata * ipcc __unused)220 static void stm32_ipcc_pm_suspend(struct ipcc_pdata *ipcc __unused)
221 {
222 /*
223 * Do nothing because IPCC forbids RIF configuration read if CID
224 * filtering is enabled. We'll simply restore the device tree RIF
225 * configuration.
226 */
227 }
228
229 static TEE_Result
stm32_ipcc_pm(enum pm_op op,unsigned int pm_hint,const struct pm_callback_handle * pm_handle)230 stm32_ipcc_pm(enum pm_op op, unsigned int pm_hint,
231 const struct pm_callback_handle *pm_handle)
232 {
233 struct ipcc_pdata *ipcc = pm_handle->handle;
234 TEE_Result res = TEE_ERROR_GENERIC;
235
236 if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !ipcc->is_tdcid)
237 return TEE_SUCCESS;
238
239 res = clk_enable(ipcc->ipcc_clock);
240 if (res)
241 return res;
242
243 if (op == PM_OP_RESUME)
244 stm32_ipcc_pm_resume(ipcc);
245 else
246 stm32_ipcc_pm_suspend(ipcc);
247
248 clk_disable(ipcc->ipcc_clock);
249
250 return TEE_SUCCESS;
251 }
252
parse_dt(const void * fdt,int node,struct ipcc_pdata * ipcc_d)253 static TEE_Result parse_dt(const void *fdt, int node, struct ipcc_pdata *ipcc_d)
254 {
255 TEE_Result res = TEE_ERROR_GENERIC;
256 struct dt_node_info info = { };
257 const fdt32_t *cuint = NULL;
258 struct io_pa_va addr = { };
259 unsigned int i = 0;
260 int lenp = 0;
261
262 fdt_fill_device_info(fdt, &info, node);
263 assert(info.reg != DT_INFO_INVALID_REG &&
264 info.reg_size != DT_INFO_INVALID_REG_SIZE);
265
266 addr.pa = info.reg;
267 ipcc_d->base = io_pa_or_va_secure(&addr, info.reg_size);
268 assert(ipcc_d->base);
269
270 /* Gate the IP */
271 res = clk_dt_get_by_index(fdt, node, 0, &ipcc_d->ipcc_clock);
272 if (res)
273 return res;
274
275 cuint = fdt_getprop(fdt, node, "st,protreg", &lenp);
276 if (!cuint) {
277 DMSG("No RIF configuration available");
278 return TEE_SUCCESS;
279 }
280
281 ipcc_d->conf_data = calloc(1, sizeof(*ipcc_d->conf_data));
282 if (!ipcc_d->conf_data)
283 panic();
284
285 ipcc_d->nb_channels_cfg = (unsigned int)(lenp / sizeof(uint32_t));
286 assert(ipcc_d->nb_channels_cfg <= (IPCC_NB_MAX_RIF_CHAN * 2));
287
288 ipcc_d->conf_data->cid_confs = calloc(IPCC_NB_MAX_RIF_CHAN * 2,
289 sizeof(uint32_t));
290 ipcc_d->conf_data->sec_conf = calloc(1, sizeof(uint32_t));
291 ipcc_d->conf_data->priv_conf = calloc(1, sizeof(uint32_t));
292 ipcc_d->conf_data->access_mask = calloc(1, sizeof(uint32_t));
293 if (!ipcc_d->conf_data->cid_confs || !ipcc_d->conf_data->sec_conf ||
294 !ipcc_d->conf_data->priv_conf || !ipcc_d->conf_data->access_mask)
295 panic("Missing memory capacity for ipcc RIF configuration");
296
297 for (i = 0; i < ipcc_d->nb_channels_cfg; i++)
298 stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), ipcc_d->conf_data,
299 IPCC_NB_MAX_RIF_CHAN * 2);
300
301 return TEE_SUCCESS;
302 }
303
stm32_ipcc_probe(const void * fdt,int node,const void * compat_data __unused)304 static TEE_Result stm32_ipcc_probe(const void *fdt, int node,
305 const void *compat_data __unused)
306 {
307 TEE_Result res = TEE_ERROR_GENERIC;
308 struct ipcc_pdata *ipcc_d = NULL;
309
310 ipcc_d = calloc(1, sizeof(*ipcc_d));
311 if (!ipcc_d)
312 return TEE_ERROR_OUT_OF_MEMORY;
313
314 res = stm32_rifsc_check_tdcid(&ipcc_d->is_tdcid);
315 if (res)
316 goto err;
317
318 res = parse_dt(fdt, node, ipcc_d);
319 if (res)
320 goto err;
321
322 res = clk_enable(ipcc_d->ipcc_clock);
323 if (res)
324 panic("Cannot access IPCC clock");
325
326 apply_rif_config(ipcc_d);
327
328 clk_disable(ipcc_d->ipcc_clock);
329
330 STAILQ_INSERT_TAIL(&ipcc_list, ipcc_d, link);
331
332 register_pm_core_service_cb(stm32_ipcc_pm, ipcc_d, "stm32-ipcc");
333
334 return TEE_SUCCESS;
335
336 err:
337 /* Free all allocated resources */
338 if (ipcc_d->conf_data) {
339 free(ipcc_d->conf_data->access_mask);
340 free(ipcc_d->conf_data->cid_confs);
341 free(ipcc_d->conf_data->priv_conf);
342 free(ipcc_d->conf_data->sec_conf);
343 }
344 free(ipcc_d->conf_data);
345 free(ipcc_d);
346
347 return res;
348 }
349
350 static const struct dt_device_match stm32_ipcc_match_table[] = {
351 { .compatible = "st,stm32mp25-ipcc" },
352 { }
353 };
354
355 DEFINE_DT_DRIVER(stm32_ipcc_dt_driver) = {
356 .name = "st,stm32mp-ipcc",
357 .match_table = stm32_ipcc_match_table,
358 .probe = stm32_ipcc_probe,
359 };
360