xref: /rk3399_ARM-atf/drivers/st/rif/stm32mp2_risaf.c (revision 681296444e508e722565c6713effd2cf346a4dcf)
1 /*
2  * Copyright (c) 2025-2026, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <drivers/clk.h>
13 #include <drivers/delay_timer.h>
14 #include <drivers/st/stm32mp2_risaf.h>
15 #include <dt-bindings/soc/rif.h>
16 #include <lib/mmio.h>
17 #include <libfdt.h>
18 #include <plat/common/platform.h>
19 
20 #include <platform_def.h>
21 #include <stm32mp_fconf_getter.h>
22 
23 static struct stm32mp2_risaf_platdata stm32mp2_risaf;
24 static int region_per_instance[RISAF_MAX_INSTANCE];
25 
26 #if ENABLE_ASSERTIONS
valid_protreg_id(int instance,uint32_t id)27 static bool valid_protreg_id(int instance, uint32_t id)
28 {
29 	uint32_t max_id;
30 
31 	max_id = mmio_read_32(stm32mp2_risaf.base[instance] + _RISAF_HWCFGR);
32 	max_id = (max_id & _RISAF_HWCFGR_CFG1_MASK) >> _RISAF_HWCFGR_CFG1_SHIFT;
33 
34 	return id < max_id;
35 }
36 
valid_instance(int instance)37 static bool valid_instance(int instance)
38 {
39 	return (instance < RISAF_MAX_INSTANCE) && (stm32mp2_risaf.base[instance] != 0U);
40 }
41 #endif
42 
risaf_is_hw_encryption_functional(int instance)43 static bool risaf_is_hw_encryption_functional(int instance)
44 {
45 	return (mmio_read_32(stm32mp2_risaf.base[instance] + _RISAF_SR) & _RISAF_SR_ENCDIS) !=
46 	       _RISAF_SR_ENCDIS;
47 }
48 
check_region_boundaries(int instance,uintptr_t addr,size_t len)49 static int check_region_boundaries(int instance, uintptr_t addr, size_t len)
50 {
51 	uintptr_t end_address;
52 	uintptr_t mem_base = stm32_risaf_get_memory_base(instance);
53 
54 	if ((addr < mem_base) || (len == 0U)) {
55 		return -EINVAL;
56 	}
57 
58 	/* Get physical end address */
59 	end_address = mem_base + stm32_risaf_get_memory_size(instance) - 1U;
60 	if ((addr > end_address) || ((addr - 1U + len) > end_address)) {
61 		return -EINVAL;
62 	}
63 
64 	if ((stm32mp2_risaf.granularity[instance] == 0U) ||
65 	    ((addr % stm32mp2_risaf.granularity[instance]) != 0U) ||
66 	    ((len % stm32mp2_risaf.granularity[instance]) != 0U)) {
67 		return -EINVAL;
68 	}
69 
70 	return 0;
71 }
72 
do_regions_overlap(uintptr_t addr1,size_t len1,uintptr_t addr2,size_t len2)73 static bool do_regions_overlap(uintptr_t addr1, size_t len1, uintptr_t addr2, size_t len2)
74 {
75 	return !((addr1 >= (addr2 + len2)) || (addr2 >= (addr1 + len1)));
76 }
77 
check_region_overlap(void)78 static int check_region_overlap(void)
79 {
80 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
81 	int i;
82 	uintptr_t addr;
83 	size_t length;
84 	int instance;
85 	int region_id;
86 
87 	if (pdata->nregions <= 1) {
88 		/*
89 		 * No region found, or first region found.
90 		 * No need to check overlap with previous ones.
91 		 */
92 		return 0;
93 	}
94 
95 	region_id = pdata->nregions - 1;
96 	addr = pdata->region[region_id].addr;
97 	length = pdata->region[region_id].len;
98 	instance = pdata->region[region_id].instance;
99 
100 	for (i = 0; i < region_id; i++) {
101 		if (pdata->region[i].instance != instance) {
102 			continue;
103 		}
104 
105 		if (do_regions_overlap(addr, length,
106 				       pdata->region[i].addr, pdata->region[i].len)) {
107 			ERROR("RISAF%d: Regions %d and %d overlap\n", instance + 1, region_id, i);
108 			return -EINVAL;
109 		}
110 	}
111 
112 	return 0;
113 }
114 
risaf_configure_region(int instance,uint32_t region_id,uint32_t cfg,uint32_t cid_cfg,uintptr_t saddr,uintptr_t eaddr)115 static int risaf_configure_region(int instance, uint32_t region_id, uint32_t cfg,
116 				  uint32_t cid_cfg, uintptr_t saddr, uintptr_t eaddr)
117 {
118 	uintptr_t base = stm32mp2_risaf.base[instance];
119 	uint32_t hwcfgr;
120 	uint32_t mask_lsb;
121 	uint32_t mask_msb;
122 	uint32_t mask;
123 
124 	assert(valid_instance(instance));
125 	assert(valid_protreg_id(instance, region_id));
126 
127 	mmio_clrbits_32(base + _RISAF_REG_CFGR(region_id), _RISAF_REG_CFGR_BREN);
128 
129 	/* Get address mask depending on RISAF instance HW configuration */
130 	hwcfgr =  mmio_read_32(base + _RISAF_HWCFGR);
131 	mask_lsb = (hwcfgr & _RISAF_HWCFGR_CFG3_MASK) >> _RISAF_HWCFGR_CFG3_SHIFT;
132 	mask_msb = mask_lsb + ((hwcfgr & _RISAF_HWCFGR_CFG4_MASK) >> _RISAF_HWCFGR_CFG4_SHIFT) - 1U;
133 	mask = GENMASK_32(mask_msb, mask_lsb);
134 
135 	mmio_clrsetbits_32(base + _RISAF_REG_STARTR(region_id), mask,
136 			   (saddr - stm32_risaf_get_memory_base(instance)) & mask);
137 	mmio_clrsetbits_32(base + _RISAF_REG_ENDR(region_id), mask,
138 			   (eaddr - stm32_risaf_get_memory_base(instance)) & mask);
139 
140 	mmio_clrsetbits_32(base + _RISAF_REG_CIDCFGR(region_id), _RISAF_REG_CIDCFGR_ALL_MASK,
141 			   cid_cfg & _RISAF_REG_CIDCFGR_ALL_MASK);
142 
143 	mmio_clrsetbits_32(base + _RISAF_REG_CFGR(region_id),
144 			   _RISAF_REG_CFGR_ALL_MASK, cfg & _RISAF_REG_CFGR_ALL_MASK);
145 
146 	if ((cfg & _RISAF_REG_CFGR_ENC) != 0U) {
147 		if (!risaf_is_hw_encryption_functional(instance)) {
148 			ERROR("RISAF%d: encryption disabled\n", instance + 1);
149 			return -EIO;
150 		}
151 
152 		if ((cfg & _RISAF_REG_CFGR_SEC) != _RISAF_REG_CFGR_SEC) {
153 			ERROR("RISAF%d: encryption on non secure area\n", instance + 1);
154 			return -EIO;
155 		}
156 	}
157 
158 	return 0;
159 }
160 
risaf_conf_protreg(void)161 static void risaf_conf_protreg(void)
162 {
163 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
164 	int idx;
165 
166 	for (idx = 0; idx < RISAF_MAX_INSTANCE; idx++) {
167 		int n;
168 
169 		if (pdata->base[idx] == 0) {
170 			continue;
171 		}
172 
173 		if (clk_enable(pdata->clock[idx]) != 0) {
174 			ERROR("%s: RISAF@%lx clock failed\n", __func__, pdata->base[idx]);
175 			panic();
176 		}
177 
178 		for (n = 0; n < pdata->nregions; n++) {
179 			uint32_t id;
180 			uint32_t value;
181 			uint32_t cfg;
182 			uint32_t cid_cfg;
183 			uintptr_t start_addr;
184 			uintptr_t end_addr;
185 
186 			if (pdata->region[n].instance != idx) {
187 				continue;
188 			}
189 
190 			value = pdata->region[n].cfg;
191 			id = (value & DT_RISAF_REG_ID_MASK);
192 			assert(valid_protreg_id(idx, id));
193 
194 			cfg = (((value & DT_RISAF_EN_MASK) >> DT_RISAF_EN_SHIFT) <<
195 			       _RISAF_REG_CFGR_BREN_SHIFT) |
196 			      (((value & DT_RISAF_SEC_MASK) >> DT_RISAF_SEC_SHIFT) <<
197 			       _RISAF_REG_CFGR_SEC_SHIFT) |
198 #if STM32MP21
199 			      (((value & DT_RISAF_ENC_MASK) >> DT_RISAF_ENC_SHIFT) <<
200 			       _RISAF_REG_CFGR_ENC_SHIFT) |
201 #else /* !STM32MP21 */
202 			      (((value & DT_RISAF_ENC_MASK) >> (DT_RISAF_ENC_SHIFT + 1)) <<
203 			       _RISAF_REG_CFGR_ENC_SHIFT) |
204 #endif /* STM32MP21 */
205 			      (((value & DT_RISAF_PRIV_MASK) >> DT_RISAF_PRIV_SHIFT) <<
206 			       _RISAF_REG_CFGR_PRIVC_SHIFT);
207 
208 			cid_cfg = (((value & DT_RISAF_WRITE_MASK) >> DT_RISAF_WRITE_SHIFT) <<
209 				   _RISAF_REG_CIDCFGR_WRENC_SHIFT) |
210 				  (((value & DT_RISAF_READ_MASK) >> DT_RISAF_READ_SHIFT) <<
211 				   _RISAF_REG_CIDCFGR_RDENC_SHIFT);
212 
213 			start_addr = pdata->region[n].addr;
214 			end_addr = (start_addr - 1U) + pdata->region[n].len;
215 
216 			if (risaf_configure_region(idx, id, cfg, cid_cfg,
217 						   start_addr, end_addr) < 0) {
218 				ERROR("%s: failed to configure region %u of RISAF@%lx\n",
219 				      __func__, id, pdata->base[idx]);
220 				panic();
221 			}
222 		}
223 
224 		clk_disable(pdata->clock[idx]);
225 	}
226 }
227 
risaf_get_dt_node(struct dt_node_info * info,int offset)228 static int risaf_get_dt_node(struct dt_node_info *info, int offset)
229 {
230 	return dt_get_node(info, offset, DT_RISAF_COMPAT);
231 }
232 
risaf_get_instance_from_region(uintptr_t address,size_t length)233 static int risaf_get_instance_from_region(uintptr_t address, size_t length)
234 {
235 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
236 	unsigned int idx;
237 	int instance = -1;
238 
239 	for (idx = 0U; idx < RISAF_MAX_INSTANCE; idx++) {
240 		if (pdata->base[idx] == 0U) {
241 			continue;
242 		}
243 
244 		if (check_region_boundaries(idx, address, length) == 0) {
245 			instance = idx;
246 		}
247 	}
248 
249 	return instance;
250 }
251 
252 /*
253  * Register region in platfoirm data structure if parameters are valid.
254  * If instance is known, related entry parameter is filled, else it is equal to -1.
255  */
risaf_register_region(void * fdt,int node,int instance)256 static int risaf_register_region(void *fdt, int node, int instance)
257 {
258 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
259 	const fdt32_t *cuint;
260 	int len = 0;
261 	int inst;
262 	uintptr_t address;
263 	size_t length;
264 	uint32_t protreg;
265 
266 	/*  Get address and length */
267 	cuint = fdt_getprop(fdt, node, "reg", &len);
268 	if ((cuint == NULL) || (len != RISAF_REGION_REG_SIZE)) {
269 		ERROR("RISAF: No or bad reg entry in DT\n");
270 		return -EINVAL;
271 	}
272 
273 	address = (uintptr_t)fdt32_to_cpu(cuint[0]) << 32;
274 	address |= fdt32_to_cpu(cuint[1]);
275 	length = (size_t)fdt32_to_cpu(cuint[2]) << 32;
276 	length |= fdt32_to_cpu(cuint[3]);
277 
278 	/* Get instance */
279 	inst = risaf_get_instance_from_region(address, length);
280 	if (inst < 0) {
281 		ERROR("RISAF: No instance found in DT\n");
282 		return -EINVAL;
283 	}
284 
285 	if ((instance != -1) && (inst != instance)) {
286 		ERROR("RISAF%d: Region not located in expected address space\n", instance + 1);
287 		return -EINVAL;
288 	}
289 
290 	/* Get protreg configuration */
291 	cuint = fdt_getprop(fdt, node, "st,protreg", &len);
292 	if ((cuint == NULL) || (len != RISAF_REGION_PROTREG_SIZE)) {
293 		ERROR("RISAF%d: No or bad st,protreg entry in DT\n", inst + 1);
294 		return -EINVAL;
295 	}
296 
297 	protreg = fdt32_to_cpu(*cuint);
298 
299 	/* Check if region max is reached for the current instance */
300 	region_per_instance[inst]++;
301 	if (region_per_instance[inst] > stm32_risaf_get_max_region(inst)) {
302 		ERROR("RISAF%d: Too many entries in DT\n", inst + 1);
303 		return -EINVAL;
304 	}
305 
306 	if (check_region_boundaries(inst, address, length) != 0) {
307 		ERROR("RISAF%d: Region %d exceeds limits\n", inst + 1, pdata->nregions);
308 		return -EINVAL;
309 	}
310 
311 	/* Register region configuration */
312 	pdata->region[pdata->nregions].instance = inst;
313 	pdata->region[pdata->nregions].cfg = protreg;
314 	pdata->region[pdata->nregions].addr = address;
315 	pdata->region[pdata->nregions].len = length;
316 	pdata->nregions++;
317 
318 	if (check_region_overlap() != 0) {
319 		return -EINVAL;
320 	}
321 
322 	return 0;
323 }
324 
325 /*
326  * From DT, retrieve base address, clock ID and all region information for each RISAF instance.
327  * Check boundaries for each region and overlap for each instance.
328  */
risaf_parse_fdt(void)329 static int risaf_parse_fdt(void)
330 {
331 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
332 	struct dt_node_info risaf_info;
333 	int node = -1;
334 	void *fdt;
335 
336 	if (fdt_get_address(&fdt) == 0) {
337 		return -ENOENT;
338 	}
339 
340 	for (node = risaf_get_dt_node(&risaf_info, node); node >= 0;
341 	     node = risaf_get_dt_node(&risaf_info, node)) {
342 		int idx;
343 		int nregions;
344 		int inst_maxregions;
345 		int i;
346 		int len = 0;
347 		const fdt32_t *conf_list;
348 		uint32_t granularity;
349 
350 		idx = stm32_risaf_get_instance(risaf_info.base);
351 		if ((idx < 0) || (risaf_info.clock < 0)) {
352 			continue;
353 		}
354 
355 		pdata->base[idx] = risaf_info.base;
356 		pdata->clock[idx] = (unsigned long)risaf_info.clock;
357 
358 		/* Get IP region granularity */
359 		if (clk_enable(pdata->clock[idx]) != 0) {
360 			ERROR("%s: clock enable failed.\n", __func__);
361 			panic();
362 		}
363 
364 		granularity = mmio_read_32(pdata->base[idx] + _RISAF_HWCFGR);
365 		clk_disable(pdata->clock[idx]);
366 		granularity = BIT_32((granularity & _RISAF_HWCFGR_CFG3_MASK) >>
367 				  _RISAF_HWCFGR_CFG3_SHIFT);
368 		pdata->granularity[idx] = granularity;
369 
370 		conf_list = fdt_getprop(fdt, node, "memory-region", &len);
371 		if (conf_list == NULL) {
372 			len = 0;
373 		}
374 
375 		nregions = (unsigned int)len / sizeof(uint32_t);
376 
377 		inst_maxregions = stm32_risaf_get_max_region(idx);
378 		if (inst_maxregions <= 0) {
379 			continue;
380 		}
381 
382 		if ((nregions > inst_maxregions) ||
383 		    ((pdata->nregions + nregions) > RISAF_MAX_REGION)) {
384 			ERROR("RISAF%d: Too many entries in DT\n", idx + 1);
385 			return -EINVAL;
386 		}
387 
388 		for (i = 0; i < nregions; i++) {
389 			int pnode = 0;
390 
391 			pnode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(conf_list[i]));
392 			if (pnode < 0) {
393 				continue;
394 			}
395 
396 			if (risaf_register_region(fdt, pnode, idx) != 0) {
397 				ERROR("RISAF%d: Region %d error\n", idx + 1, pdata->nregions);
398 				return -EINVAL;
399 			}
400 		}
401 	}
402 
403 	return 0;
404 }
405 
406 static uintptr_t risaf_base[RISAF_MAX_INSTANCE];
407 static unsigned long risaf_clock[RISAF_MAX_INSTANCE];
408 static uint32_t risaf_granularity[RISAF_MAX_INSTANCE];
409 static struct stm32mp2_risaf_region risaf_region[RISAF_MAX_REGION];
410 
411 /* Construct platform data structure */
risaf_get_platdata(struct stm32mp2_risaf_platdata * pdata)412 static int risaf_get_platdata(struct stm32mp2_risaf_platdata *pdata)
413 {
414 	pdata->base = risaf_base;
415 	pdata->clock = risaf_clock;
416 	pdata->granularity = risaf_granularity;
417 	pdata->region = risaf_region;
418 
419 	return 0;
420 }
421 
422 /*
423  * @brief  Write the encryption key for a given instance.
424  * @param  instance: RISAF instance ID.
425  *         key: Pointer to the encryption key buffer.
426  * @retval 0 if OK, negative value else.
427  */
stm32mp2_risaf_write_encryption_key(int instance,uint8_t * key)428 int stm32mp2_risaf_write_encryption_key(int instance, uint8_t *key)
429 {
430 	uint64_t timeout_ref;
431 	uint32_t i;
432 	uintptr_t base = stm32mp2_risaf.base[instance];
433 
434 	assert(key != NULL);
435 
436 	if (base == 0U) {
437 		return -EINVAL;
438 	}
439 
440 	for (i = 0U; i < RISAF_ENCRYPTION_KEY_SIZE_IN_BYTES; i += sizeof(uint32_t)) {
441 		uint32_t key_val = 0U;
442 
443 		memcpy(&key_val, key + i, sizeof(uint32_t));
444 
445 		mmio_write_32(base + _RISAF_KEYR + i, key_val);
446 	}
447 
448 	timeout_ref = timeout_init_us(RISAF_TIMEOUT_1MS_IN_US);
449 
450 	while (((mmio_read_32(base + _RISAF_SR) & _RISAF_SR_KEYVALID) != _RISAF_SR_KEYVALID) ||
451 	       ((mmio_read_32(base + _RISAF_SR) & _RISAF_SR_KEYRDY) != _RISAF_SR_KEYRDY)) {
452 		if (timeout_elapsed(timeout_ref)) {
453 			return -EIO;
454 		}
455 	}
456 
457 	return 0;
458 }
459 
460 #if STM32MP21
risaf_get_mce_key_size(int instance,uint32_t * size)461 static int risaf_get_mce_key_size(int instance, uint32_t *size)
462 {
463 	struct dt_node_info risaf_info;
464 	int node = -1;
465 	void *fdt;
466 
467 	if (fdt_get_address(&fdt) == 0) {
468 		return -ENOENT;
469 	}
470 
471 	for (node = risaf_get_dt_node(&risaf_info, node); node >= 0;
472 	     node = risaf_get_dt_node(&risaf_info, node)) {
473 		int idx;
474 		const fdt32_t *cuint = NULL;
475 
476 		idx = stm32_risaf_get_instance(risaf_info.base);
477 		if (idx != instance) {
478 			continue;
479 		}
480 
481 		cuint = fdt_getprop(fdt, node, "st,mce-keysize-bits", NULL);
482 		if (cuint == NULL) {
483 			/* Property not set, affect default value */
484 			*size = RISAF_MCE_KEY_128BITS_SIZE_IN_BYTES;
485 		} else {
486 			*size = (uint32_t)fdt32_to_cpu(*cuint) / 8;
487 		}
488 
489 		return 0;
490 	}
491 
492 	return -ENODEV;
493 }
494 
495 /*
496  * @brief  Write the MCE key for a given instance.
497  * @param  instance: RISAF instance ID.
498  *         key: Pointer to the MCE key buffer.
499  *         size: MCE key size in bytes.
500  * @retval 0 if OK, negative value else.
501  */
stm32mp2_risaf_write_mce_key(int instance,uint8_t * key)502 int stm32mp2_risaf_write_mce_key(int instance, uint8_t *key)
503 {
504 	uint64_t timeout_ref;
505 	uint32_t i;
506 	uint32_t size;
507 	uintptr_t base = stm32mp2_risaf.base[instance];
508 
509 	assert(key != NULL);
510 
511 	if (base == 0U) {
512 		return -EINVAL;
513 	}
514 
515 	if (risaf_get_mce_key_size(instance, &size) != 0) {
516 		return -EINVAL;
517 	}
518 
519 	if (size == RISAF_MCE_KEY_128BITS_SIZE_IN_BYTES) {
520 		mmio_write_32(base + _RISAF_XCR,
521 			      _RISAF_XCR_CIPHERSEL_AES128 << _RISAF_XCR_CIPHERSEL_SHIFT);
522 	} else if (size == RISAF_MCE_KEY_256BITS_SIZE_IN_BYTES) {
523 		mmio_write_32(base + _RISAF_XCR,
524 			      _RISAF_XCR_CIPHERSEL_AES256 << _RISAF_XCR_CIPHERSEL_SHIFT);
525 	} else {
526 		return -EINVAL;
527 	}
528 
529 	for (i = 0U; i < size; i += sizeof(uint32_t)) {
530 		uint32_t key_val = 0U;
531 
532 		memcpy(&key_val, key + i, sizeof(uint32_t));
533 
534 		mmio_write_32(base + _RISAF_MKEYR + i, key_val);
535 	}
536 
537 	timeout_ref = timeout_init_us(RISAF_TIMEOUT_1MS_IN_US);
538 
539 	while (((mmio_read_32(base + _RISAF_XSR) & _RISAF_XSR_MKVALID) != _RISAF_XSR_MKVALID)) {
540 		if (timeout_elapsed(timeout_ref)) {
541 			return -EIO;
542 		}
543 	}
544 
545 	return 0;
546 }
547 #endif /* STM32MP21 */
548 
549 /*
550  * @brief  Lock the RISAF IP registers for a given instance.
551  * @param  instance: RISAF instance ID.
552  * @retval 0 if OK, negative value else.
553  */
stm32mp2_risaf_lock(int instance)554 int stm32mp2_risaf_lock(int instance)
555 {
556 	uintptr_t base = stm32mp2_risaf.base[instance];
557 
558 	if (base == 0U) {
559 		return -EINVAL;
560 	}
561 
562 	mmio_setbits_32(base + _RISAF_CR, _RISAF_CR_GLOCK);
563 
564 	return 0;
565 }
566 
567 /*
568  * @brief  Get the RISAF lock state for a given instance.
569  * @param  instance: RISAF instance ID.
570  *         state: lock state, true if locked, false else.
571  * @retval 0 if OK, negative value else.
572  */
stm32mp2_risaf_is_locked(int instance,bool * state)573 int stm32mp2_risaf_is_locked(int instance, bool *state)
574 {
575 	uintptr_t base = stm32mp2_risaf.base[instance];
576 
577 	if (base == 0U) {
578 		return -EINVAL;
579 	}
580 
581 	*state = (mmio_read_32(base + _RISAF_CR) & _RISAF_CR_GLOCK) == _RISAF_CR_GLOCK;
582 
583 	return 0;
584 }
585 
stm32mp2_risaf_init(void)586 int stm32mp2_risaf_init(void)
587 {
588 	int err;
589 
590 	err = risaf_get_platdata(&stm32mp2_risaf);
591 	if (err != 0) {
592 		return err;
593 	}
594 
595 	err = risaf_parse_fdt();
596 	if (err != 0) {
597 		return err;
598 	}
599 
600 	risaf_conf_protreg();
601 
602 	return err;
603 }
604 
risaf_parse_fwconfig(uintptr_t config)605 static int risaf_parse_fwconfig(uintptr_t config)
606 {
607 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
608 	unsigned int i;
609 	int node;
610 	int subnode;
611 	const void *fdt = (const void *)config;
612 	const char *compatible_str = "st,stm32mp2-mem-firewall";
613 
614 	node = fdt_node_offset_by_compatible(fdt, -1, compatible_str);
615 	if (node < 0) {
616 		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
617 		return node;
618 	}
619 
620 	fdt_for_each_subnode(subnode, fdt, node) {
621 		if (risaf_register_region((void *)fdt, subnode, -1) != 0) {
622 			ERROR("RISAF: Region %d error\n", pdata->nregions);
623 			return -EINVAL;
624 		}
625 	}
626 
627 	for (i = 0U; i < RISAF_MAX_INSTANCE; i++) {
628 		if ((region_per_instance[i] == 0) && (stm32_risaf_get_max_region(i) != 0)) {
629 			INFO("RISAF%u: No configuration in DT, use default\n", i + 1);
630 		}
631 	}
632 
633 	return 0;
634 }
635 
fconf_populate_risaf(uintptr_t config)636 static int fconf_populate_risaf(uintptr_t config)
637 {
638 	int err;
639 
640 	err = risaf_parse_fwconfig(config);
641 	if (err != 0) {
642 		return err;
643 	}
644 
645 	risaf_conf_protreg();
646 
647 	return err;
648 }
649 
650 FCONF_REGISTER_POPULATOR(FW_CONFIG, risaf_config, fconf_populate_risaf);
651