1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021-2025, STMicroelectronics
4 */
5
6 #include <drivers/stm32_rif.h>
7 #include <dt-bindings/interrupt-controller/irq.h>
8 #include <io.h>
9 #include <kernel/boot.h>
10 #include <kernel/dt.h>
11 #include <kernel/dt_driver.h>
12 #include <kernel/interrupt.h>
13 #include <kernel/pm.h>
14 #include <kernel/spinlock.h>
15 #include <libfdt.h>
16 #include <mm/core_memprot.h>
17 #include <tee_api_types.h>
18 #include <util.h>
19
20 /* Registers */
21 #define _EXTI_RTSR(n) (0x000U + (n) * 0x20U)
22 #define _EXTI_FTSR(n) (0x004U + (n) * 0x20U)
23 #define _EXTI_RPR(n) (0x00cU + (n) * 0x20U)
24 #define _EXTI_FPR(n) (0x010U + (n) * 0x20U)
25 #define _EXTI_SECCFGR(n) (0x014U + (n) * 0x20U)
26 #define _EXTI_PRIVCFGR(n) (0x018U + (n) * 0x20U)
27 #define _EXTI_CR(n) (0x060U + (n) * 4U)
28 #define _EXTI_LOCKR 0x070U
29 #define _EXTI_C1IMR(n) (0x080U + (n) * 0x10U)
30 #define _EXTI_EnCIDCFGR(n) (0x180U + (n) * 4U)
31 #define _EXTI_CmCIDCFGR(n) (0x300U + (n) * 4U)
32 #define _EXTI_TRG(n) (0x3ecU - (n) * 4U) /* HWCFGR2..4 */
33 #define _EXTI_HWCFGR1 0x3f0U
34
35 /* SECCFGR register bitfields */
36 #define _EXTI_SECCFGR_MASK GENMASK_32(31, 0)
37
38 /* PRIVCFGR register bitfields */
39 #define _EXTI_PRIVCFGR_MASK GENMASK_32(31, 0)
40
41 /* LOCKR register bitfields */
42 #define _EXTI_LOCKR_GLOCK BIT(0)
43
44 /* CIDCFGR register bitfields */
45 #define _EXTI_CIDCFGR_CFEN BIT(0)
46 #define _EXTI_CIDCFGR_SCID_MASK GENMASK_32(6, 4)
47 #define _EXTI_CIDCFGR_SCID_SHIFT 4U
48 #define _EXTI_CIDCFGR_CONF_MASK (_EXTI_CIDCFGR_CFEN | \
49 _EXTI_CIDCFGR_SCID_MASK)
50
51 /* _EXTI_HWCFGR1 bit fields */
52 #define _EXTI_HWCFGR1_NBEVENTS_MASK GENMASK_32(7, 0)
53 #define _EXTI_HWCFGR1_NBEVENTS_SHIFT 0U
54 #define _EXTI_HWCFGR1_NBCPUS_MASK GENMASK_32(11, 8)
55 #define _EXTI_HWCFGR1_NBCPUS_SHIFT 8U
56 #define _EXTI_HWCFGR1_CIDWIDTH_MASK GENMASK_32(27, 24)
57 #define _EXTI_HWCFGR1_CIDWIDTH_SHIFT 24U
58
59 #define _EXTI_MAX_CR 4U
60 #define _EXTI_BANK_NR 3U
61 #define _EXTI_LINES_PER_BANK 32U
62
63 #define _EXTI_CID1 0x1U
64
65 /*
66 * struct stm32_exti_itr_hierarchy - EXTI line interrupt hierarchy
67 * @this: An EXTI interrupt number and its EXTI interrupt controller
68 * @parent: The interrupt (number and controller) that drives the interrupt
69 */
70 struct stm32_exti_itr_hierarchy {
71 struct itr_desc this;
72 struct itr_desc parent;
73 };
74
75 struct stm32_exti_pdata {
76 struct itr_chip chip;
77 vaddr_t base;
78 unsigned int lock;
79 uint32_t hwcfgr1;
80 uint32_t trg[_EXTI_BANK_NR];
81 uint32_t wake_active[_EXTI_BANK_NR];
82 uint32_t mask_cache[_EXTI_BANK_NR];
83 uint32_t imr_cache[_EXTI_BANK_NR];
84 uint32_t seccfgr_cache[_EXTI_BANK_NR];
85 uint32_t privcfgr_cache[_EXTI_BANK_NR];
86 uint32_t access_mask[_EXTI_BANK_NR];
87 uint32_t rtsr_cache[_EXTI_BANK_NR];
88 uint32_t ftsr_cache[_EXTI_BANK_NR];
89 uint32_t port_sel_cache[_EXTI_MAX_CR];
90 uint32_t *e_cids;
91 uint32_t *c_cids;
92 struct stm32_exti_itr_hierarchy *
93 hierarchy[_EXTI_LINES_PER_BANK * _EXTI_BANK_NR];
94 bool glock;
95 };
96
97 static struct stm32_exti_pdata *
itr_chip_to_stm32_exti_pdata(struct itr_chip * chip)98 itr_chip_to_stm32_exti_pdata(struct itr_chip *chip)
99 {
100 return container_of(chip, struct stm32_exti_pdata, chip);
101 }
102
stm32_exti_get_bank(uint32_t exti_line)103 static unsigned int stm32_exti_get_bank(uint32_t exti_line)
104 {
105 if (exti_line < _EXTI_LINES_PER_BANK)
106 return 0;
107
108 if (exti_line < 2 * _EXTI_LINES_PER_BANK)
109 return 1;
110
111 if (exti_line < 3 * _EXTI_LINES_PER_BANK)
112 return 2;
113
114 panic();
115 }
116
stm32_exti_maxcid(const struct stm32_exti_pdata * exti)117 static inline uint32_t stm32_exti_maxcid(const struct stm32_exti_pdata *exti)
118 {
119 uint32_t bitfield = (exti->hwcfgr1 & _EXTI_HWCFGR1_CIDWIDTH_MASK) >>
120 _EXTI_HWCFGR1_CIDWIDTH_SHIFT;
121
122 return BIT(bitfield) - 1;
123 }
124
stm32_exti_nbevents(const struct stm32_exti_pdata * exti)125 static inline uint32_t stm32_exti_nbevents(const struct stm32_exti_pdata *exti)
126 {
127 uint32_t bitfield = (exti->hwcfgr1 & _EXTI_HWCFGR1_NBEVENTS_MASK) >>
128 _EXTI_HWCFGR1_NBEVENTS_SHIFT;
129
130 return bitfield + 1;
131 }
132
stm32_exti_nbcpus(const struct stm32_exti_pdata * exti)133 static inline uint32_t stm32_exti_nbcpus(const struct stm32_exti_pdata *exti)
134 {
135 uint32_t bitfield = (exti->hwcfgr1 & _EXTI_HWCFGR1_NBCPUS_MASK) >>
136 _EXTI_HWCFGR1_NBCPUS_SHIFT;
137
138 return bitfield + 1;
139 }
140
141 static bool
stm32_exti_event_is_configurable(const struct stm32_exti_pdata * exti,unsigned int exti_line)142 stm32_exti_event_is_configurable(const struct stm32_exti_pdata *exti,
143 unsigned int exti_line)
144 {
145 unsigned int i = stm32_exti_get_bank(exti_line);
146 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
147
148 return exti->trg[i] & mask;
149 }
150
stm32_exti_set_type(struct stm32_exti_pdata * exti,uint32_t exti_line,uint32_t type)151 static void stm32_exti_set_type(struct stm32_exti_pdata *exti,
152 uint32_t exti_line, uint32_t type)
153 {
154 unsigned int i = stm32_exti_get_bank(exti_line);
155 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
156 uint32_t r_trig = 0;
157 uint32_t f_trig = 0;
158 uint32_t exceptions = 0;
159
160 switch (type) {
161 case IRQ_TYPE_EDGE_RISING:
162 r_trig |= mask;
163 f_trig &= ~mask;
164 break;
165 case IRQ_TYPE_EDGE_FALLING:
166 r_trig &= ~mask;
167 f_trig |= mask;
168 break;
169 case IRQ_TYPE_EDGE_BOTH:
170 r_trig |= mask;
171 f_trig |= mask;
172 break;
173 default:
174 EMSG("Unsupported interrupt type 0x%"PRIx32, type);
175 panic();
176 }
177
178 exceptions = cpu_spin_lock_xsave(&exti->lock);
179
180 io_mask32(exti->base + _EXTI_RTSR(i), r_trig, mask);
181 io_mask32(exti->base + _EXTI_FTSR(i), f_trig, mask);
182
183 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
184 }
185
stm32_exti_mask(struct stm32_exti_pdata * exti,uint32_t exti_line)186 static void stm32_exti_mask(struct stm32_exti_pdata *exti, uint32_t exti_line)
187 {
188 unsigned int i = stm32_exti_get_bank(exti_line);
189 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
190 uint32_t exceptions = 0;
191
192 exceptions = cpu_spin_lock_xsave(&exti->lock);
193
194 io_clrbits32(exti->base + _EXTI_C1IMR(i), mask);
195 exti->mask_cache[i] &= ~mask;
196
197 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
198 }
199
stm32_exti_unmask(struct stm32_exti_pdata * exti,uint32_t exti_line)200 static void stm32_exti_unmask(struct stm32_exti_pdata *exti,
201 uint32_t exti_line)
202 {
203 unsigned int i = stm32_exti_get_bank(exti_line);
204 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
205 uint32_t exceptions = 0;
206
207 exceptions = cpu_spin_lock_xsave(&exti->lock);
208
209 io_setbits32(exti->base + _EXTI_C1IMR(i), mask);
210 exti->mask_cache[i] |= mask;
211
212 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
213 }
214
stm32_exti_enable_wake(struct stm32_exti_pdata * exti,uint32_t exti_line)215 static void stm32_exti_enable_wake(struct stm32_exti_pdata *exti,
216 uint32_t exti_line)
217 {
218 unsigned int i = stm32_exti_get_bank(exti_line);
219 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
220 uint32_t exceptions = 0;
221
222 exceptions = cpu_spin_lock_xsave(&exti->lock);
223
224 exti->wake_active[i] |= mask;
225
226 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
227 }
228
stm32_exti_disable_wake(struct stm32_exti_pdata * exti,uint32_t exti_line)229 static void stm32_exti_disable_wake(struct stm32_exti_pdata *exti,
230 uint32_t exti_line)
231 {
232 unsigned int i = stm32_exti_get_bank(exti_line);
233 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
234 uint32_t exceptions = 0;
235
236 exceptions = cpu_spin_lock_xsave(&exti->lock);
237
238 exti->wake_active[i] &= ~mask;
239
240 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
241 }
242
stm32_exti_clear(struct stm32_exti_pdata * exti,uint32_t exti_line)243 static void stm32_exti_clear(struct stm32_exti_pdata *exti, uint32_t exti_line)
244 {
245 unsigned int i = stm32_exti_get_bank(exti_line);
246 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
247 uint32_t exceptions = 0;
248
249 exceptions = cpu_spin_lock_xsave(&exti->lock);
250
251 io_setbits32(exti->base + _EXTI_RPR(i), mask);
252 io_setbits32(exti->base + _EXTI_FPR(i), mask);
253
254 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
255 }
256
stm32_exti_set_tz(struct stm32_exti_pdata * exti,uint32_t exti_line)257 static void stm32_exti_set_tz(struct stm32_exti_pdata *exti,
258 uint32_t exti_line)
259 {
260 unsigned int i = stm32_exti_get_bank(exti_line);
261 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
262 uint32_t exceptions = 0;
263
264 exceptions = cpu_spin_lock_xsave(&exti->lock);
265
266 io_setbits32(exti->base + _EXTI_SECCFGR(i), mask);
267
268 cpu_spin_unlock_xrestore(&exti->lock, exceptions);
269 }
270
271 static struct itr_desc *
stm32_exti_get_parent_itr(struct stm32_exti_pdata * exti,size_t it)272 stm32_exti_get_parent_itr(struct stm32_exti_pdata *exti, size_t it)
273 {
274 if (!exti || it >= stm32_exti_nbevents(exti) || !exti->hierarchy[it])
275 panic();
276
277 return &exti->hierarchy[it]->parent;
278 }
279
280 /* Enable an interrupt */
stm32_exti_op_enable(struct itr_chip * chip,size_t it)281 static void stm32_exti_op_enable(struct itr_chip *chip, size_t it)
282 {
283 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
284 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
285
286 stm32_exti_unmask(exti, it);
287
288 interrupt_enable(parent->chip, parent->itr_num);
289 }
290
291 /* Disable an interrupt */
stm32_exti_op_disable(struct itr_chip * chip,size_t it)292 static void stm32_exti_op_disable(struct itr_chip *chip, size_t it)
293 {
294 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
295 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
296
297 stm32_exti_mask(exti, it);
298
299 interrupt_disable(parent->chip, parent->itr_num);
300 }
301
302 /* Mask an interrupt, may be called from an interrupt context */
stm32_exti_op_mask(struct itr_chip * chip,size_t it)303 static void stm32_exti_op_mask(struct itr_chip *chip, size_t it)
304 {
305 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
306 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
307
308 stm32_exti_mask(exti, it);
309
310 interrupt_mask(parent->chip, parent->itr_num);
311 }
312
313 /* Unmask an interrupt, may be called from an interrupt context */
stm32_exti_op_unmask(struct itr_chip * chip,size_t it)314 static void stm32_exti_op_unmask(struct itr_chip *chip, size_t it)
315 {
316 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
317 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
318
319 stm32_exti_unmask(exti, it);
320
321 interrupt_unmask(parent->chip, parent->itr_num);
322 }
323
324 /* Raise per-cpu interrupt (optional) */
stm32_exti_op_raise_pi(struct itr_chip * chip,size_t it)325 static void stm32_exti_op_raise_pi(struct itr_chip *chip, size_t it)
326 {
327 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
328 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
329
330 if (interrupt_can_raise_pi(parent->chip))
331 interrupt_raise_pi(parent->chip, parent->itr_num);
332 }
333
334 /* Raise a SGI (optional) */
stm32_exti_op_raise_sgi(struct itr_chip * chip,size_t it,uint32_t cpu_mask)335 static void stm32_exti_op_raise_sgi(struct itr_chip *chip, size_t it,
336 uint32_t cpu_mask)
337 {
338 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
339 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
340
341 if (interrupt_can_raise_sgi(parent->chip))
342 interrupt_raise_sgi(parent->chip, parent->itr_num, cpu_mask);
343 }
344
345 /* Set interrupt/cpu affinity (optional) */
stm32_exti_op_set_affinity(struct itr_chip * chip,size_t it,uint8_t cpu_mask)346 static void stm32_exti_op_set_affinity(struct itr_chip *chip, size_t it,
347 uint8_t cpu_mask)
348 {
349 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
350 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
351
352 if (interrupt_can_set_affinity(parent->chip))
353 interrupt_set_affinity(parent->chip, parent->itr_num,
354 cpu_mask);
355 }
356
357 /* Enable/disable power-management wake-on of an interrupt (optional) */
stm32_exti_op_set_wake(struct itr_chip * chip,size_t it,bool on)358 static void stm32_exti_op_set_wake(struct itr_chip *chip, size_t it,
359 bool on)
360 {
361 struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
362 struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
363
364 if (on)
365 stm32_exti_enable_wake(exti, it);
366 else
367 stm32_exti_disable_wake(exti, it);
368
369 if (interrupt_can_set_wake(parent->chip))
370 interrupt_set_wake(parent->chip, parent->itr_num, on);
371 }
372
373 static const struct itr_ops stm32_exti_ops = {
374 .enable = stm32_exti_op_enable,
375 .disable = stm32_exti_op_disable,
376 .mask = stm32_exti_op_mask,
377 .unmask = stm32_exti_op_unmask,
378 .raise_pi = stm32_exti_op_raise_pi,
379 .raise_sgi = stm32_exti_op_raise_sgi,
380 .set_affinity = stm32_exti_op_set_affinity,
381 .set_wake = stm32_exti_op_set_wake,
382 };
383 DECLARE_KEEP_PAGER(stm32_exti_ops);
384
stm32_exti_rif_check_access(struct stm32_exti_pdata * exti,uint32_t exti_line)385 static TEE_Result stm32_exti_rif_check_access(struct stm32_exti_pdata *exti,
386 uint32_t exti_line)
387 {
388 unsigned int i = stm32_exti_get_bank(exti_line);
389 uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
390
391 /* only configured as secure and privileged */
392 if (!((exti->seccfgr_cache[i] & exti->privcfgr_cache[i] &
393 exti->access_mask[i]) & mask))
394 return TEE_ERROR_ACCESS_DENIED;
395
396 if ((exti->e_cids[exti_line] & _EXTI_CIDCFGR_CFEN) &&
397 ((exti->e_cids[exti_line] & _EXTI_CIDCFGR_SCID_MASK) !=
398 SHIFT_U32(_EXTI_CID1, _EXTI_CIDCFGR_SCID_SHIFT)))
399 return TEE_ERROR_ACCESS_DENIED;
400
401 return TEE_SUCCESS;
402 }
403
stm32_exti_rif_parse_dt(struct stm32_exti_pdata * exti,const void * fdt,int node)404 static void stm32_exti_rif_parse_dt(struct stm32_exti_pdata *exti,
405 const void *fdt, int node)
406 {
407 struct rif_conf_data conf_data = { };
408 const fdt32_t *cuint = NULL;
409 uint32_t rif_conf = 0;
410 unsigned int i = 0;
411 int len = 0;
412
413 if (fdt_getprop(fdt, node, "st,glocked", NULL))
414 exti->glock = true;
415 else
416 DMSG("No global lock on RIF configuration");
417
418 cuint = fdt_getprop(fdt, node, "st,protreg", &len);
419 if (!cuint) {
420 DMSG("No RIF configuration available");
421 return;
422 }
423
424 exti->e_cids = calloc(stm32_exti_nbevents(exti), sizeof(uint32_t));
425 exti->c_cids = calloc(stm32_exti_nbcpus(exti), sizeof(uint32_t));
426 if (!exti->e_cids || !exti->c_cids)
427 panic("Out of memory");
428
429 conf_data.cid_confs = exti->e_cids;
430 conf_data.sec_conf = exti->seccfgr_cache;
431 conf_data.priv_conf = exti->privcfgr_cache;
432 conf_data.access_mask = exti->access_mask;
433
434 for (i = 0; i < len / sizeof(uint32_t); i++) {
435 rif_conf = fdt32_to_cpu(cuint[i]);
436
437 stm32_rif_parse_cfg(rif_conf, &conf_data,
438 stm32_exti_nbevents(exti));
439 }
440
441 cuint = fdt_getprop(fdt, node, "st,proccid", &len);
442 if (!cuint)
443 panic("No RIF configuration available");
444
445 for (i = 0; i < len / (2 * sizeof(uint32_t)); i++) {
446 unsigned int pos = fdt32_to_cpu(cuint[2 * i]);
447 uint32_t c_cid = fdt32_to_cpu(cuint[2 * i + 1]);
448
449 if (pos == 0 || pos > stm32_exti_nbcpus(exti))
450 panic("CID position out of range");
451
452 if (c_cid > stm32_exti_maxcid(exti))
453 panic("CID out of range");
454
455 exti->c_cids[pos - 1] = SHIFT_U32(c_cid, _CIDCFGR_SCID_SHIFT) |
456 _EXTI_CIDCFGR_CFEN;
457 }
458 }
459
stm32_exti_rif_apply(const struct stm32_exti_pdata * exti)460 static TEE_Result stm32_exti_rif_apply(const struct stm32_exti_pdata *exti)
461 {
462 TEE_Result res = TEE_ERROR_GENERIC;
463 unsigned int bit_offset = 0;
464 bool is_tdcid = false;
465 uint32_t event = 0;
466 unsigned int i = 0;
467
468 res = stm32_rifsc_check_tdcid(&is_tdcid);
469 if (res)
470 return res;
471
472 /*
473 * If TDCID, clear EnCIDCFGR and CmCIDCFGR to prevent undesired
474 * events during the following configuration.
475 */
476
477 if (is_tdcid) {
478 for (event = 0; event < stm32_exti_nbevents(exti); event++) {
479 i = stm32_exti_get_bank(event);
480 bit_offset = event % _EXTI_LINES_PER_BANK;
481
482 if (!(BIT(bit_offset) & exti->access_mask[i]))
483 continue;
484
485 io_clrbits32(exti->base + _EXTI_EnCIDCFGR(event),
486 _EXTI_CIDCFGR_CONF_MASK);
487 }
488
489 for (i = 0; i < stm32_exti_nbcpus(exti); i++)
490 io_clrbits32(exti->base + _EXTI_CmCIDCFGR(i),
491 _EXTI_CIDCFGR_CONF_MASK);
492 }
493
494 /* Security and privilege RIF configuration */
495 for (i = 0; i < _EXTI_BANK_NR; i++) {
496 if (!exti->access_mask[i])
497 continue;
498
499 io_clrsetbits32(exti->base + _EXTI_PRIVCFGR(i),
500 _EXTI_PRIVCFGR_MASK & exti->access_mask[i],
501 exti->privcfgr_cache[i]);
502 io_clrsetbits32(exti->base + _EXTI_SECCFGR(i),
503 _EXTI_SECCFGR_MASK & exti->access_mask[i],
504 exti->seccfgr_cache[i]);
505 }
506
507 if (!is_tdcid)
508 return TEE_SUCCESS;
509
510 /* If TDCID, configure EnCIDCFGR and CmCIDCFGR */
511 for (event = 0; event < stm32_exti_nbevents(exti); event++) {
512 i = stm32_exti_get_bank(event);
513 bit_offset = event % _EXTI_LINES_PER_BANK;
514
515 if (!(BIT(bit_offset) & exti->access_mask[i]))
516 continue;
517
518 io_clrsetbits32(exti->base + _EXTI_EnCIDCFGR(event),
519 _EXTI_CIDCFGR_CONF_MASK, exti->e_cids[event]);
520 }
521 for (i = 0; i < stm32_exti_nbcpus(exti); i++) {
522 if (!(exti->c_cids[i] & _EXTI_CIDCFGR_CFEN))
523 continue;
524
525 io_clrsetbits32(exti->base + _EXTI_CmCIDCFGR(i),
526 _EXTI_CIDCFGR_CONF_MASK, exti->c_cids[i]);
527 }
528
529 /* If TDCID, configure global lock */
530 if (exti->glock)
531 io_setbits32(exti->base + _EXTI_LOCKR, _EXTI_LOCKR_GLOCK);
532
533 return TEE_SUCCESS;
534 }
535
stm32_exti_rif_save(struct stm32_exti_pdata * exti)536 static void stm32_exti_rif_save(struct stm32_exti_pdata *exti)
537 {
538 unsigned int bit_offset = 0;
539 bool is_tdcid = false;
540 uint32_t event = 0;
541 unsigned int i = 0;
542
543 for (i = 0; i < _EXTI_BANK_NR; i++) {
544 if (!exti->access_mask[i])
545 continue;
546
547 exti->privcfgr_cache[i] =
548 io_read32(exti->base + _EXTI_PRIVCFGR(i));
549 exti->seccfgr_cache[i] =
550 io_read32(exti->base + _EXTI_SECCFGR(i));
551 }
552
553 stm32_rifsc_check_tdcid(&is_tdcid);
554 if (!is_tdcid)
555 return;
556
557 for (event = 0; event < stm32_exti_nbevents(exti); event++) {
558 i = stm32_exti_get_bank(event);
559 bit_offset = event % _EXTI_LINES_PER_BANK;
560
561 if (!(BIT(bit_offset) & exti->access_mask[i]))
562 continue;
563
564 exti->e_cids[event] = io_read32(exti->base +
565 _EXTI_EnCIDCFGR(event));
566 }
567 for (i = 0; i < stm32_exti_nbcpus(exti); i++)
568 exti->c_cids[i] = io_read32(exti->base + _EXTI_CmCIDCFGR(i));
569 }
570
stm32_exti_pm_suspend(struct stm32_exti_pdata * exti)571 static void stm32_exti_pm_suspend(struct stm32_exti_pdata *exti)
572 {
573 uint32_t base = exti->base;
574 uint32_t i = 0;
575
576 if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti))
577 stm32_exti_rif_save(exti);
578
579 for (i = 0; i < _EXTI_BANK_NR; i++) {
580 /* Save ftsr, rtsr and seccfgr registers */
581 exti->ftsr_cache[i] = io_read32(base + _EXTI_FTSR(i));
582 exti->rtsr_cache[i] = io_read32(base + _EXTI_RTSR(i));
583 exti->seccfgr_cache[i] = io_read32(base + _EXTI_SECCFGR(i));
584 }
585
586 /* Save EXTI port selection */
587 for (i = 0; i < _EXTI_MAX_CR; i++)
588 exti->port_sel_cache[i] = io_read32(base + _EXTI_CR(i));
589 }
590
stm32_exti_pm_resume(struct stm32_exti_pdata * exti)591 static void stm32_exti_pm_resume(struct stm32_exti_pdata *exti)
592 {
593 uint32_t base = exti->base;
594 uint32_t i = 0;
595
596 for (i = 0; i < _EXTI_BANK_NR; i++) {
597 /* Restore ftsr, rtsr and seccfgr registers */
598 io_write32(base + _EXTI_FTSR(i), exti->ftsr_cache[i]);
599 io_write32(base + _EXTI_RTSR(i), exti->rtsr_cache[i]);
600 io_write32(base + _EXTI_SECCFGR(i), exti->seccfgr_cache[i]);
601 }
602
603 /* Restore EXTI port selection */
604 for (i = 0; i < _EXTI_MAX_CR; i++)
605 io_write32(base + _EXTI_CR(i), exti->port_sel_cache[i]);
606
607 if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti))
608 stm32_exti_rif_apply(exti);
609 }
610
611 /* PM function: configure the wake_up line for OP-TEE */
stm32_exti_configure_wake(struct stm32_exti_pdata * exti)612 static void stm32_exti_configure_wake(struct stm32_exti_pdata *exti)
613 {
614 uint32_t i = 0;
615
616 for (i = 0; i < _EXTI_BANK_NR; i++) {
617 /* save IMR value, lost in Standby */
618 exti->imr_cache[i] = io_read32(exti->base + _EXTI_C1IMR(i));
619 /* deactivate in IMR the interruption activated in OP-TEE */
620 io_clrbits32(exti->base + _EXTI_C1IMR(i), exti->mask_cache[i]);
621 /* activate in IMR for OP-TEE wakeup interruption */
622 io_setbits32(exti->base + _EXTI_C1IMR(i), exti->wake_active[i]);
623 }
624 }
625
stm32_exti_restore_wake(struct stm32_exti_pdata * exti)626 static void stm32_exti_restore_wake(struct stm32_exti_pdata *exti)
627 {
628 uint32_t i = 0;
629
630 /* restore saved IMR value: interruption secure/unsecure */
631 for (i = 0; i < _EXTI_BANK_NR; i++)
632 io_write32(exti->base + _EXTI_C1IMR(i), exti->imr_cache[i]);
633 }
634
635 static TEE_Result
stm32_exti_pm(enum pm_op op,unsigned int pm_hint,const struct pm_callback_handle * pm_handle)636 stm32_exti_pm(enum pm_op op, unsigned int pm_hint,
637 const struct pm_callback_handle *pm_handle)
638 {
639 struct stm32_exti_pdata *exti =
640 (struct stm32_exti_pdata *)PM_CALLBACK_GET_HANDLE(pm_handle);
641
642 if (op == PM_OP_SUSPEND)
643 stm32_exti_configure_wake(exti);
644 else
645 stm32_exti_restore_wake(exti);
646
647 if (!PM_HINT_IS_STATE(pm_hint, CONTEXT))
648 return TEE_SUCCESS;
649
650 if (op == PM_OP_SUSPEND)
651 stm32_exti_pm_suspend(exti);
652 else
653 stm32_exti_pm_resume(exti);
654
655 return TEE_SUCCESS;
656 }
657 DECLARE_KEEP_PAGER(stm32_exti_pm);
658
stm32_exti_it_handler(struct itr_handler * h)659 static enum itr_return stm32_exti_it_handler(struct itr_handler *h)
660 {
661 struct stm32_exti_itr_hierarchy *hierarchy = h->data;
662 struct itr_desc *itr_desc = &hierarchy->this;
663 struct stm32_exti_pdata *exti =
664 itr_chip_to_stm32_exti_pdata(itr_desc->chip);
665
666 interrupt_call_handlers(itr_desc->chip, itr_desc->itr_num);
667
668 if (stm32_exti_event_is_configurable(exti, itr_desc->itr_num))
669 stm32_exti_clear(exti, itr_desc->itr_num);
670
671 return ITRR_HANDLED;
672 }
673 DECLARE_KEEP_PAGER(stm32_exti_it_handler);
674
675 /* Callback for "interrupts" and "interrupts-extended" DT node properties */
676 static TEE_Result
stm32_exti_dt_get_chip_cb(struct dt_pargs * pargs,void * priv_data,struct itr_desc * itr_desc)677 stm32_exti_dt_get_chip_cb(struct dt_pargs *pargs, void *priv_data,
678 struct itr_desc *itr_desc)
679 {
680 struct stm32_exti_pdata *exti = priv_data;
681 struct stm32_exti_itr_hierarchy *hierarchy = NULL;
682 size_t exti_line = 0;
683 uint32_t type = 0;
684 TEE_Result res = TEE_ERROR_GENERIC;
685
686 if (pargs->args_count != 2)
687 return TEE_ERROR_GENERIC;
688
689 exti_line = pargs->args[0];
690 type = pargs->args[1];
691
692 itr_desc->chip = &exti->chip;
693 itr_desc->itr_num = exti_line;
694
695 if (exti_line >= stm32_exti_nbevents(exti))
696 return TEE_ERROR_GENERIC;
697
698 /* With RIF, check the permission */
699 if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti)) {
700 res = stm32_exti_rif_check_access(exti, exti_line);
701 if (res)
702 return res;
703 }
704
705 hierarchy = exti->hierarchy[exti_line];
706 if (!hierarchy) {
707 hierarchy = calloc(1, sizeof(*hierarchy));
708 if (!hierarchy)
709 return TEE_ERROR_OUT_OF_MEMORY;
710 exti->hierarchy[exti_line] = hierarchy;
711 }
712
713 hierarchy->this.chip = &exti->chip;
714 hierarchy->this.itr_num = exti_line;
715
716 res = interrupt_dt_get_by_index(pargs->fdt, pargs->phandle_node,
717 exti_line,
718 &hierarchy->parent.chip,
719 &hierarchy->parent.itr_num);
720 if (res)
721 return res;
722
723 res = interrupt_create_handler(hierarchy->parent.chip,
724 hierarchy->parent.itr_num,
725 stm32_exti_it_handler, hierarchy,
726 ITRF_TRIGGER_LEVEL, NULL);
727 if (res)
728 return res;
729
730 /* set_type valid for configurable events only */
731 if (stm32_exti_event_is_configurable(exti, exti_line))
732 stm32_exti_set_type(exti, exti_line, type);
733
734 /* Without RIF, predate the line by setting it as secure */
735 if (!IS_ENABLED(CFG_STM32_RIF) || !stm32_exti_maxcid(exti))
736 stm32_exti_set_tz(exti, exti_line);
737
738 return TEE_SUCCESS;
739 }
740
stm32_exti_probe(const void * fdt,int node,const void * comp_data __unused)741 static TEE_Result stm32_exti_probe(const void *fdt, int node,
742 const void *comp_data __unused)
743 {
744 struct stm32_exti_pdata *exti = NULL;
745 TEE_Result res = TEE_ERROR_GENERIC;
746 struct io_pa_va base = { };
747 size_t reg_size = 0;
748 unsigned int i = 0;
749
750 exti = calloc(1, sizeof(*exti));
751 if (!exti)
752 panic("Out of memory");
753
754 exti->lock = SPINLOCK_UNLOCK;
755 exti->chip.ops = &stm32_exti_ops;
756 exti->chip.name = strdup(fdt_get_name(fdt, node, NULL));
757
758 res = itr_chip_dt_only_init(&exti->chip);
759 if (res)
760 panic();
761
762 if (fdt_reg_info(fdt, node, &base.pa, ®_size))
763 panic();
764
765 exti->base = io_pa_or_va_secure(&base, reg_size);
766 assert(exti->base);
767
768 exti->hwcfgr1 = io_read32(exti->base + _EXTI_HWCFGR1);
769 for (i = 0; i < _EXTI_BANK_NR; i++)
770 exti->trg[i] = io_read32(exti->base + _EXTI_TRG(i));
771
772 if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti)) {
773 stm32_exti_rif_parse_dt(exti, fdt, node);
774 res = stm32_exti_rif_apply(exti);
775 if (res)
776 goto err;
777 }
778
779 res = interrupt_register_provider(fdt, node, stm32_exti_dt_get_chip_cb,
780 exti);
781 if (res)
782 goto err;
783
784 register_pm_core_service_cb(stm32_exti_pm, exti, "stm32-exti");
785
786 return TEE_SUCCESS;
787
788 err:
789 free(exti->e_cids);
790 free(exti->c_cids);
791 free((char *)exti->chip.name);
792 free(exti);
793 return res;
794 }
795
796 static const struct dt_device_match stm32_exti_match_table[] = {
797 { .compatible = "st,stm32mp1-exti" },
798 { }
799 };
800
801 DEFINE_DT_DRIVER(stm32_exti_dt_driver) = {
802 .name = "stm32-exti",
803 .match_table = stm32_exti_match_table,
804 .probe = &stm32_exti_probe,
805 };
806