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