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