xref: /optee_os/core/drivers/stm32_hpdma.c (revision 307d268b815db29daf70935bb4593b2fe5fefc0a)
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_gpio.h>
11 #include <drivers/stm32_rif.h>
12 #include <io.h>
13 #include <kernel/boot.h>
14 #include <kernel/delay.h>
15 #include <kernel/dt.h>
16 #include <kernel/dt_driver.h>
17 #include <kernel/panic.h>
18 #include <kernel/pm.h>
19 #include <libfdt.h>
20 #include <mm/core_memprot.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <stm32_util.h>
24 #include <trace.h>
25 
26 #define _HPDMA_SECCFGR			U(0x000)
27 #define _HPDMA_PRIVCFGR			U(0x004)
28 #define _HPDMA_RCFGLOCKR		U(0x008)
29 #define _HPDMA_CIDCFGR(x)		(U(0x054) + U(0x080) * (x))
30 #define _HPDMA_SEMCR(x)			(U(0x058) + U(0x080) * (x))
31 
32 /*
33  * CFGR register bitfields
34  */
35 #define _HPDMA_CFGR_ENABLE		BIT(31)
36 
37 /*
38  * CIDCFGR register bitfields
39  */
40 #define _HPDMA_CIDCFGR_SEMWL_MASK	GENMASK_32(23, 16)
41 #define _HPDMA_CIDCFGR_SCID_MASK	GENMASK_32(5, 4)
42 #define _HPDMA_CIDCFGR_CONF_MASK	(_CIDCFGR_CFEN |	 \
43 					 _CIDCFGR_SEMEN |	 \
44 					 _HPDMA_CIDCFGR_SCID_MASK |\
45 					 _HPDMA_CIDCFGR_SEMWL_MASK)
46 
47 /*
48  * PRIVCFGR register bitfields
49  */
50 #define _HPDMA_PRIVCFGR_MASK		GENMASK_32(15, 0)
51 
52 /*
53  * RCFGLOCKR register bitfields
54  */
55 #define _HPDMA_RCFGLOCKR_MASK		GENMASK_32(15, 0)
56 
57 /*
58  * SECCFGR register bitfields
59  */
60 #define _HPDMA_SECCFGR_EN		BIT(0)
61 #define _HPDMA_SECCFGR_MASK		GENMASK_32(15, 0)
62 
63 /*
64  * SEMCR register bitfields
65  */
66 #define _HPDMA_SEMCR_SCID_MASK		GENMASK_32(5, 4)
67 #define _HPDMA_SEMCR_SCID_SHIFT		U(4)
68 
69 /*
70  * Miscellaneous
71  */
72 
73 #define HPDMA_RIF_CHANNELS		U(16)
74 
75 #define HPDMA_NB_MAX_CID_SUPPORTED	U(3)
76 
77 struct hpdma_pdata {
78 	struct clk *hpdma_clock;
79 	struct rif_conf_data *conf_data;
80 	unsigned int nb_channels;
81 	vaddr_t base;
82 
83 	SLIST_ENTRY(hpdma_pdata) link;
84 };
85 
86 static SLIST_HEAD(, hpdma_pdata) hpdma_list =
87 		SLIST_HEAD_INITIALIZER(hpdma_list);
88 
89 /* This function expects HPDMA bus clock is enabled */
90 static TEE_Result apply_rif_config(struct hpdma_pdata *hpdma_d, bool is_tdcid)
91 {
92 	TEE_Result res = TEE_ERROR_ACCESS_DENIED;
93 	uint32_t cidcfgr = 0;
94 	unsigned int i = 0;
95 
96 	if (!hpdma_d->conf_data)
97 		return TEE_SUCCESS;
98 
99 	for (i = 0; i < HPDMA_RIF_CHANNELS; i++) {
100 		if (!(BIT(i) & hpdma_d->conf_data->access_mask[0]))
101 			continue;
102 		/*
103 		 * When TDCID, OP-TEE should be the one to set the CID filtering
104 		 * configuration. Clearing previous configuration prevents
105 		 * undesired events during the only legitimate configuration.
106 		 */
107 		if (is_tdcid)
108 			io_clrbits32(hpdma_d->base + _HPDMA_CIDCFGR(i),
109 				     _HPDMA_CIDCFGR_CONF_MASK);
110 
111 		cidcfgr = io_read32(hpdma_d->base + _HPDMA_CIDCFGR(i));
112 
113 		/* Check if the channel is in semaphore mode */
114 		if (!stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1))
115 			continue;
116 
117 		/* If not TDCID, we want to acquire semaphores assigned to us */
118 		res = stm32_rif_acquire_semaphore(hpdma_d->base +
119 						  _HPDMA_SEMCR(i),
120 						  HPDMA_NB_MAX_CID_SUPPORTED);
121 		if (res) {
122 			EMSG("Couldn't acquire semaphore for channel %u", i);
123 			return res;
124 		}
125 	}
126 
127 	/* Security and privilege RIF configuration */
128 	io_clrsetbits32(hpdma_d->base + _HPDMA_PRIVCFGR, _HPDMA_PRIVCFGR_MASK &
129 			hpdma_d->conf_data->access_mask[0],
130 			hpdma_d->conf_data->priv_conf[0]);
131 	io_clrsetbits32(hpdma_d->base + _HPDMA_SECCFGR, _HPDMA_SECCFGR_MASK &
132 			hpdma_d->conf_data->access_mask[0],
133 			hpdma_d->conf_data->sec_conf[0]);
134 
135 	/* Skip CID/semaphore configuration if not in TDCID state. */
136 	if (!is_tdcid)
137 		goto end;
138 
139 	for (i = 0; i < HPDMA_RIF_CHANNELS; i++) {
140 		if (!(BIT(i) & hpdma_d->conf_data->access_mask[0]))
141 			continue;
142 
143 		io_clrsetbits32(hpdma_d->base + _HPDMA_CIDCFGR(i),
144 				_HPDMA_CIDCFGR_CONF_MASK,
145 				hpdma_d->conf_data->cid_confs[i]);
146 
147 		cidcfgr = io_read32(hpdma_d->base + _HPDMA_CIDCFGR(i));
148 
149 		/*
150 		 * Take semaphore if the resource is in semaphore
151 		 * mode and secured.
152 		 */
153 		if (!stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1) ||
154 		    !(io_read32(hpdma_d->base + _HPDMA_SECCFGR) & BIT(i))) {
155 			res =
156 			stm32_rif_release_semaphore(hpdma_d->base +
157 						    _HPDMA_SEMCR(i),
158 						    HPDMA_NB_MAX_CID_SUPPORTED);
159 			if (res) {
160 				EMSG("Couldn't release semaphore for res%u", i);
161 				return TEE_ERROR_ACCESS_DENIED;
162 			}
163 		} else {
164 			res =
165 			stm32_rif_acquire_semaphore(hpdma_d->base +
166 						    _HPDMA_SEMCR(i),
167 						    HPDMA_NB_MAX_CID_SUPPORTED);
168 			if (res) {
169 				EMSG("Couldn't acquire semaphore for res%u", i);
170 				return TEE_ERROR_ACCESS_DENIED;
171 			}
172 		}
173 	}
174 
175 	/*
176 	 * Lock RIF configuration if configured. This cannot be undone until
177 	 * next reset.
178 	 */
179 	io_clrsetbits32(hpdma_d->base + _HPDMA_RCFGLOCKR, _HPDMA_RCFGLOCKR_MASK,
180 			hpdma_d->conf_data->lock_conf[0]);
181 
182 end:
183 	if (IS_ENABLED(CFG_TEE_CORE_DEBUG)) {
184 		/* Check that RIF config are applied, panic otherwise */
185 		if ((io_read32(hpdma_d->base + _HPDMA_PRIVCFGR) &
186 		     hpdma_d->conf_data->access_mask[0]) !=
187 		    hpdma_d->conf_data->priv_conf[0])
188 			panic("HPDMA channel priv conf is incorrect");
189 
190 		if ((io_read32(hpdma_d->base + _HPDMA_SECCFGR) &
191 		     hpdma_d->conf_data->access_mask[0]) !=
192 		    hpdma_d->conf_data->sec_conf[0])
193 			panic("HPDMA channel sec conf is incorrect");
194 	}
195 
196 	return TEE_SUCCESS;
197 }
198 
199 static TEE_Result parse_dt(const void *fdt, int node,
200 			   struct hpdma_pdata *hpdma_d)
201 {
202 	TEE_Result res = TEE_ERROR_GENERIC;
203 	unsigned int i = 0;
204 	int lenp = 0;
205 	const fdt32_t *cuint = NULL;
206 	struct dt_node_info info = { };
207 	struct io_pa_va addr = { };
208 
209 	fdt_fill_device_info(fdt, &info, node);
210 	assert(info.reg != DT_INFO_INVALID_REG &&
211 	       info.reg_size != DT_INFO_INVALID_REG_SIZE);
212 
213 	addr.pa = info.reg;
214 	hpdma_d->base = io_pa_or_va_secure(&addr, info.reg_size);
215 
216 	/* Gate the IP */
217 	res = clk_dt_get_by_index(fdt, node, 0, &hpdma_d->hpdma_clock);
218 	if (res)
219 		return res;
220 
221 	cuint = fdt_getprop(fdt, node, "st,protreg", &lenp);
222 	if (!cuint) {
223 		DMSG("No RIF configuration available");
224 		return TEE_SUCCESS;
225 	}
226 
227 	hpdma_d->conf_data = calloc(1, sizeof(*hpdma_d->conf_data));
228 	if (!hpdma_d->conf_data)
229 		panic();
230 
231 	hpdma_d->nb_channels = (unsigned int)(lenp / sizeof(uint32_t));
232 	assert(hpdma_d->nb_channels <= HPDMA_RIF_CHANNELS);
233 
234 	hpdma_d->conf_data->cid_confs = calloc(HPDMA_RIF_CHANNELS,
235 					       sizeof(uint32_t));
236 	hpdma_d->conf_data->sec_conf = calloc(1, sizeof(uint32_t));
237 	hpdma_d->conf_data->priv_conf = calloc(1, sizeof(uint32_t));
238 	hpdma_d->conf_data->access_mask = calloc(1, sizeof(uint32_t));
239 	hpdma_d->conf_data->lock_conf = calloc(1, sizeof(uint32_t));
240 	if (!hpdma_d->conf_data->cid_confs || !hpdma_d->conf_data->sec_conf ||
241 	    !hpdma_d->conf_data->priv_conf ||
242 	    !hpdma_d->conf_data->access_mask || !hpdma_d->conf_data->lock_conf)
243 		panic("Missing memory capacity for HPDMA RIF configuration");
244 
245 	for (i = 0; i < hpdma_d->nb_channels; i++)
246 		stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), hpdma_d->conf_data,
247 				    HPDMA_RIF_CHANNELS);
248 
249 	return TEE_SUCCESS;
250 }
251 
252 static void stm32_hpdma_pm_resume(struct hpdma_pdata *hpdma)
253 {
254 	if (apply_rif_config(hpdma, true))
255 		panic("Failed to resume HPDMA");
256 }
257 
258 static void stm32_hpdma_pm_suspend(struct hpdma_pdata *hpdma)
259 {
260 	size_t i = 0;
261 
262 	for (i = 0; i < HPDMA_RIF_CHANNELS; i++)
263 		hpdma->conf_data->cid_confs[i] = io_read32(hpdma->base +
264 							  _HPDMA_CIDCFGR(i)) &
265 						_HPDMA_CIDCFGR_CONF_MASK;
266 
267 	hpdma->conf_data->priv_conf[0] = io_read32(hpdma->base +
268 						  _HPDMA_PRIVCFGR) &
269 					_HPDMA_PRIVCFGR_MASK;
270 	hpdma->conf_data->sec_conf[0] = io_read32(hpdma->base +
271 						 _HPDMA_SECCFGR) &
272 				       _HPDMA_SECCFGR_MASK;
273 	hpdma->conf_data->lock_conf[0] = io_read32(hpdma->base +
274 						  _HPDMA_RCFGLOCKR) &
275 					_HPDMA_RCFGLOCKR_MASK;
276 
277 	/*
278 	 * The access mask is modified to restore the conf for all
279 	 * resources.
280 	 */
281 	hpdma->conf_data->access_mask[0] = GENMASK_32(HPDMA_RIF_CHANNELS - 1,
282 						      0);
283 }
284 
285 static TEE_Result
286 stm32_hpdma_pm(enum pm_op op, unsigned int pm_hint,
287 	       const struct pm_callback_handle *pm_handle)
288 {
289 	struct hpdma_pdata *hpdma = pm_handle->handle;
290 	TEE_Result res = TEE_ERROR_GENERIC;
291 	bool is_tdcid = false;
292 
293 	res = stm32_rifsc_check_tdcid(&is_tdcid);
294 	if (res)
295 		panic();
296 
297 	if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !is_tdcid)
298 		return TEE_SUCCESS;
299 
300 	res = clk_enable(hpdma->hpdma_clock);
301 	if (res)
302 		return res;
303 
304 	if (op == PM_OP_RESUME)
305 		stm32_hpdma_pm_resume(hpdma);
306 	else
307 		stm32_hpdma_pm_suspend(hpdma);
308 
309 	clk_disable(hpdma->hpdma_clock);
310 
311 	return TEE_SUCCESS;
312 }
313 
314 static TEE_Result stm32_hpdma_probe(const void *fdt, int node,
315 				    const void *compat_data __unused)
316 {
317 	TEE_Result res = TEE_ERROR_GENERIC;
318 	struct hpdma_pdata *hpdma_d = NULL;
319 	bool is_tdcid = false;
320 
321 	res = stm32_rifsc_check_tdcid(&is_tdcid);
322 	if (res)
323 		return res;
324 
325 	hpdma_d = calloc(1, sizeof(*hpdma_d));
326 	if (!hpdma_d)
327 		return TEE_ERROR_OUT_OF_MEMORY;
328 
329 	res = parse_dt(fdt, node, hpdma_d);
330 	if (res) {
331 		free(hpdma_d);
332 		return res;
333 	}
334 
335 	if (clk_enable(hpdma_d->hpdma_clock))
336 		panic("Cannot access hpdma clock");
337 
338 	res = apply_rif_config(hpdma_d, is_tdcid);
339 	if (res)
340 		panic("Failed to apply RIF config");
341 
342 	clk_disable(hpdma_d->hpdma_clock);
343 
344 	SLIST_INSERT_HEAD(&hpdma_list, hpdma_d, link);
345 
346 	register_pm_core_service_cb(stm32_hpdma_pm, hpdma_d, "stm32-hpdma");
347 
348 	return TEE_SUCCESS;
349 }
350 
351 static const struct dt_device_match stm32_hpdma_match_table[] = {
352 	{ .compatible = "st,stm32-dma3" },
353 	{ }
354 };
355 
356 DEFINE_DT_DRIVER(stm32_hpdma_dt_driver) = {
357 	.name = "st,stm32-hpdma",
358 	.match_table = stm32_hpdma_match_table,
359 	.probe = stm32_hpdma_probe,
360 };
361