1 /*
2  * Copyright (c) 2024, Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef NRFX_ZEPHYR_UTILS_H__
8 #define NRFX_ZEPHYR_UTILS_H__
9 
10 #include <zephyr/devicetree.h>
11 #include <zephyr/sys/util_macro.h>
12 
13 /*
14  * For chips with TrustZone support, MDK provides CMSIS-Core peripheral
15  * accessing symbols in two flavors, with secure and non-secure base address
16  * mappings. Their names contain the suffix _S or _NS, respectively.
17  * Because nrfx HALs and drivers require these peripheral accessing symbols
18  * without any suffixes, the following macro is provided that will translate
19  * their names according to the kind of the target that is built.
20  */
21 #if defined(NRF_TRUSTZONE_NONSECURE)
22 #define NRF_PERIPH(P) P##_NS
23 #else
24 #define NRF_PERIPH(P) P##_S
25 #endif
26 
27 #define NRFX_CONFIG_BIT_DT(node_id, prop, idx) BIT(DT_PROP_BY_IDX(node_id, prop, idx))
28 #define NRFX_CONFIG_MASK_DT(node_id, prop) \
29 	(COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
30 		(DT_FOREACH_PROP_ELEM_SEP(node_id, prop, NRFX_CONFIG_BIT_DT, (|))), \
31 		(0)))
32 
33 /* If global of local DPPIC peripherals are used, provide the following macro
34  * definitions required by the interconnect/apb layer:
35  * - NRFX_DPPI_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num)
36  * - NRFX_DPPI_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num)
37  * - NRFX_DPPI_PUB_OR_SUB_MASK(inst_num)
38  * - NRFX_DPPI_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num)
39  * - NRFX_INTERCONNECT_APB_GLOBAL_DPPI_DEFINE
40  * - NRFX_INTERCONNECT_APB_LOCAL_DPPI_DEFINE
41  * based on information from devicetree.
42  */
43 #if	DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || \
44 	DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_local)
45 /* Source (publish) channels masks generation. */
46 #define NRFX_DPPI_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \
47 	NRFX_CONFIG_MASK_DT(DT_NODELABEL(_CONCAT(dppic, inst_num)), source_channels)
48 
49 /* Sink (subscribe) channels masks generation. */
50 #define NRFX_DPPI_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \
51 	NRFX_CONFIG_MASK_DT(DT_NODELABEL(_CONCAT(dppic, inst_num)), sink_channels)
52 
53 #define NRFX_DPPI_PUB_OR_SUB_MASK(inst_num) \
54 	UTIL_OR(DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(dppic, inst_num)), source_channels), \
55 		DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(dppic, inst_num)), sink_channels))
56 
57 /* Variables names generation. */
58 #define NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels)
59 #define NRFX_DPPI_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \
60 	NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(dppic, inst_num)))
61 
62 /* Variables entries generation. */
63 #define NRFX_CONFIG_DPPI_CHANNELS_ENTRY(node_id) \
64 	static nrfx_atomic_t NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(node_id) \
65 		__attribute__((used)) = \
66 		NRFX_CONFIG_MASK_DT(node_id, source_channels) | \
67 		NRFX_CONFIG_MASK_DT(node_id, sink_channels);
68 #define NRFX_INTERCONNECT_APB_GLOBAL_DPPI_DEFINE \
69 	DT_FOREACH_STATUS_OKAY(nordic_nrf_dppic_global, NRFX_CONFIG_DPPI_CHANNELS_ENTRY)
70 #define NRFX_INTERCONNECT_APB_LOCAL_DPPI_DEFINE \
71 	DT_FOREACH_STATUS_OKAY(nordic_nrf_dppic_local, NRFX_CONFIG_DPPI_CHANNELS_ENTRY)
72 #endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || ... */
73 
74 /* If local or global DPPIC peripherals are used, provide the following macro
75  * definitions required by the interconnect/ipct layer:
76  * - NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num)
77  * - NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num)
78  * - NRFX_IPCT_PUB_OR_SUB_MASK(inst_num)
79  * - NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num)
80  * - NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE
81  * - NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE
82  * based on information from devicetree.
83  */
84 #if	DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || \
85 	DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_local)
86 /* Channels masks generation. */
87 #define NRFX_CONFIG_IPCT_MASK_DT(node_id) \
88 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, owned_channels), \
89 		(NRFX_CONFIG_MASK_DT(node_id, owned_channels)), \
90 		(COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, nordic_nrf_ipct_local), \
91 			(BIT_MASK(DT_PROP(node_id, channels))), (0))))
92 
93 #if defined(NRF_APPLICATION)
94 #define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpuapp_ipct)
95 #elif defined(NRF_RADIOCORE)
96 #define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpurad_ipct)
97 #endif
98 #define NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num) \
99 	COND_CODE_1(IS_EMPTY(inst_num), \
100 		(NRFX_CONFIG_IPCT_LOCAL_NODE), \
101 		(DT_NODELABEL(_CONCAT(ipct, inst_num))))
102 
103 #define NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \
104 	NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num))
105 
106 #define NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \
107 	NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num))
108 
109 #define NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) \
110 	COND_CODE_1(IS_EMPTY(inst_num), \
111 		(DT_NODE_HAS_STATUS_OKAY(NRFX_CONFIG_IPCT_LOCAL_NODE)), \
112 		(DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(ipct, inst_num)), owned_channels)))
113 
114 /* Variables names generation. */
115 #define NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels)
116 #define NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \
117 	COND_CODE_1(IS_EMPTY(inst_num), \
118 		(NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(NRFX_CONFIG_IPCT_LOCAL_NODE)), \
119 		(NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(ipct, inst_num)))))
120 
121 /* Variables entries generation. */
122 #define NRFX_CONFIG_IPCT_CHANNELS_ENTRY(node_id) \
123 	static nrfx_atomic_t NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) \
124 		__attribute__((used)) = \
125 		NRFX_CONFIG_IPCT_MASK_DT(node_id);
126 #define NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE \
127 	DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_local, NRFX_CONFIG_IPCT_CHANNELS_ENTRY)
128 #define NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE \
129 	DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_global, NRFX_CONFIG_IPCT_CHANNELS_ENTRY)
130 #endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || ... */
131 
132 #endif /* NRFX_ZEPHYR_UTILS_H__ */
133