1 /*
2  * Copyright (c) 2023 - 2024, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef NRFX_IDS_H__
35 #define NRFX_IDS_H__
36 
37 #include <nrfx.h>
38 
39 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
40     #include <nrfx_ipc.h>
41 #elif defined(HALTIUM_XXAA)
42     #include <nrfx_vevif.h>
43     #include <nrfx_bellboard.h>
44     #include <haly/nrfy_vpr.h>
45 #else
46     #error "No inter-domain signalling supported."
47 #endif
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 /**
54  * @defgroup nrfx_ids Generic inter-domain signalling layer.
55  * @{
56  * @ingroup nrfx
57  * @ingroup nrf_ipc
58  * @ingroup nrf_vevif
59  * @ingroup nrf_bellboard
60  *
61  * @brief Helper layer that provides the common functionality for the inter-domain signalling (IDS) mechanisms.
62  */
63 
64 /**
65  * @brief IDS event handler callback.
66  *
67  * @param[in] event_idx IDS event index.
68  * @param[in] p_context User context.
69  */
70 typedef void (*nrfx_ids_event_handler_t)(uint8_t event_idx, void * p_context);
71 
72 /** @brief Structure for the IDS instance. */
73 typedef struct
74 {
75     uint8_t drv_inst_idx; ///< Index of the instance. For internal use only.
76     uint8_t int_idx;      ///< Interrupt index. For internal use only.
77 } nrfx_ids_t;
78 
79 #ifndef __NRFX_DOXYGEN__
80 enum {
81 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
82 #if NRFX_CHECK(NRFX_IPC_ENABLED)
83     NRFX_IDS0_INST_IDX,
84 #endif
85 #elif defined(HALTIUM_XXAA)
86 #if defined(ISA_RISCV)
87 #if NRFX_CHECK(NRFX_VEVIF_ENABLED)
88     NRFX_IDS0_INST_IDX,
89 #endif
90 #elif defined(ISA_ARM)
91 #if NRFX_CHECK(NRFX_BELLBOARD0_ENABLED)
92     NRFX_IDS0_INST_IDX,
93 #endif
94 #if NRFX_CHECK(NRFX_BELLBOARD1_ENABLED)
95     NRFX_IDS1_INST_IDX,
96 #endif
97 #if NRFX_CHECK(NRFX_BELLBOARD2_ENABLED)
98     NRFX_IDS2_INST_IDX,
99 #endif
100 #if NRFX_CHECK(NRFX_BELLBOARD3_ENABLED)
101     NRFX_IDS3_INST_IDX,
102 #endif
103 #endif /* HALTIUM_XXAA */
104 #endif
105     NRFX_IDS_ENABLED_COUNT
106 };
107 #endif /* __NRFX_DOXYGEN__ */
108 
109 /** @brief Macro for creating a IDS instance. */
110 #define NRFX_IDS_INSTANCE(id)                               \
111 {                                                           \
112     .drv_inst_idx = NRFX_CONCAT_3(NRFX_IDS, id, _INST_IDX), \
113     .int_idx      = id,                                     \
114 }
115 
116 /** @brief Macro for creating channel bitmask associated with specified channel index. */
117 #define NRFX_IDS_CHANNEL(channel) (0x1UL << (channel))
118 
119 #if defined(HALTIUM_XXAA) || defined(__NRFX_DOXYGEN__)
120 /** @brief IDS domains. */
121 typedef enum
122 {
123     NRFX_IDS_DOMAIN_SEC  = 1,                         ///< Reserved. */
124     NRFX_IDS_DOMAIN_APP  = NRF_PROCESSOR_APPLICATION, ///< Application domain. */
125     NRFX_IDS_DOMAIN_NET  = NRF_PROCESSOR_RADIOCORE,   ///< Network domain. */
126     NRFX_IDS_DOMAIN_SYSC = 12,                        ///< Reserved. */
127     NRFX_IDS_DOMAIN_PPR  = NRF_PROCESSOR_PPR,         ///< Peripheral Processor */
128     NRFX_IDS_DOMAIN_FLPR = NRF_PROCESSOR_FLPR,        ///< Fast Lightweight Processor */
129 #if defined(NRFX_IDS_DOMAIN_ENUM_EXT)
130     NRFX_IDS_DOMAIN_ENUM_EXT
131 #endif
132 } nrfx_ids_domain_t;
133 #elif defined(NRF5340_XXAA)
134 typedef enum
135 {
136     NRFX_IDS_DOMAIN_APP, ///< Application domain. */
137     NRFX_IDS_DOMAIN_NET, ///< Network domain. */
138 } nrfx_ids_domain_t;
139 #elif defined(NRF9160_XXAA)
140 typedef enum
141 {
142     NRFX_IDS_DOMAIN_APP,   ///< Application domain. */
143     NRFX_IDS_DOMAIN_MODEM, ///< LTE modem domain. */
144 } nrfx_ids_domain_t;
145 
146 #endif
147 
148 /** @brief Symbol specifying maximum number of available events triggered. */
149 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
150 #define NRFX_IDS_EVENTS_TRIGGERED_COUNT IPC_CONF_NUM
151 #elif defined(HALTIUM_XXAA)
152 #if defined(ISA_ARM)
153 #define NRFX_IDS_EVENTS_TRIGGERED_COUNT NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT
154 #else /* ISA_RISCV */
155 #define NRFX_IDS_EVENTS_TRIGGERED_COUNT NRF_VPR_EVENTS_TRIGGERED_COUNT
156 #endif
157 #endif
158 
159 /**
160  * @brief Function for initializing the IDS instance.
161  *
162  * @param[in] p_instance         Pointer to IDS instance.
163  * @param[in] interrupt_priority Interrupt priority.
164  * @param[in] event_handler      Function to be called on interrupt.
165  * @param[in] p_context          Context passed to the event handler.
166  * @param[in] p_config           Pointer to the structure containing peripheral-specific configuration. Can be NULL.
167  *
168  * @retval NRFX_SUCCESS       Driver successfully initialized.
169  * @retval NRFX_ERROR_ALREADY Driver already initialized.
170  */
nrfx_ids_init(nrfx_ids_t const * p_instance,uint8_t interrupt_priority,nrfx_ids_event_handler_t event_handler,void * p_context,void const * p_config)171 __STATIC_INLINE nrfx_err_t nrfx_ids_init(nrfx_ids_t const *       p_instance,
172                                          uint8_t                  interrupt_priority,
173                                          nrfx_ids_event_handler_t event_handler,
174                                          void *                   p_context,
175                                          void const *             p_config)
176 {
177 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
178     (void)p_instance;
179     nrfx_err_t err_code = nrfx_ipc_init(interrupt_priority,
180                                         (nrfx_ipc_handler_t)event_handler,
181                                         p_context);
182     if (err_code == NRFX_SUCCESS)
183     {
184         nrfx_ipc_config_load((nrfx_ipc_config_t const *)p_config);
185     }
186     return err_code;
187 #elif defined(HALTIUM_XXAA)
188 #if defined(ISA_ARM)
189     (void)p_config;
190     return nrfx_bellboard_init((nrfx_bellboard_t const *)p_instance,
191                                interrupt_priority,
192                                (nrfx_bellboard_event_handler_t)event_handler,
193                                p_context);
194 #else /* ISA_RISCV */
195     (void)p_instance;
196     (void)p_config;
197     return nrfx_vevif_init((nrf_vpr_clic_priority_t)interrupt_priority,
198                            (nrfx_vevif_event_handler_t)event_handler,
199                            p_context);
200 #endif
201 #endif /* HALTIUM_XXAA */
202 }
203 
204 /**
205  * @brief Function for uninitializing the IDS instance.
206  *
207  * @param[in] p_instance Pointer to IDS instance.
208  */
nrfx_ids_uninit(nrfx_ids_t const * p_instance)209 __STATIC_INLINE void nrfx_ids_uninit(nrfx_ids_t const * p_instance)
210 {
211 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
212     (void)p_instance;
213     nrfx_ipc_uninit();
214 #elif defined(HALTIUM_XXAA)
215 #if defined(ISA_ARM)
216     nrfx_bellboard_uninit((nrfx_bellboard_t const *)p_instance);
217 #else /* ISA_RISCV */
218     (void)p_instance;
219     nrfx_vevif_uninit();
220 #endif
221 #endif /* HALTIUM_XXAA */
222 }
223 
224 /**
225  * @brief Function for enabling specified interrupts in the IDS instance.
226  *
227  * @param[in] p_instance Pointer to IDS instance.
228  * @param[in] mask       Mask of interrupts to be enabled.
229  */
nrfx_ids_int_enable(nrfx_ids_t const * p_instance,uint32_t mask)230 __STATIC_INLINE void nrfx_ids_int_enable(nrfx_ids_t const * p_instance, uint32_t mask)
231 {
232 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
233     (void)p_instance;
234     nrfx_ipc_receive_event_group_enable(mask);
235 #elif defined(HALTIUM_XXAA)
236 #if defined(ISA_ARM)
237     nrfx_bellboard_int_enable((nrfx_bellboard_t const *)p_instance, mask);
238 #else /* ISA_RISCV */
239     (void)p_instance;
240     nrfx_vevif_int_enable(mask);
241 #endif
242 #endif /* HALTIUM_XXAA */
243 }
244 
245 /**
246  * @brief Function for disabling interrupt in the IDS instance.
247  *
248  * @param[in] p_instance Pointer to IDS instance.
249  * @param[in] mask       Mask of interrupts to be disabled.
250  */
nrfx_ids_int_disable(nrfx_ids_t const * p_instance,uint32_t mask)251 __STATIC_INLINE void nrfx_ids_int_disable(nrfx_ids_t const * p_instance, uint32_t mask)
252 {
253 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
254     (void)p_instance;
255     nrfx_ipc_receive_event_group_disable(mask);
256 #elif defined(HALTIUM_XXAA)
257 #if defined(ISA_ARM)
258     nrfx_bellboard_int_disable((nrfx_bellboard_t const *)p_instance, mask);
259 #else /* ISA_RISCV */
260     (void)p_instance;
261     nrfx_vevif_int_disable(mask);
262 #endif  /* HALTIUM_XXAA */
263 #endif
264 }
265 
266 /**
267  * @brief Function for conveying the inter-domain signal to the specified domain.
268  *
269  * @param[in] p_instance Pointer to IDS instance.
270  * @param[in] domain     Domain to be signalled. May be NULL for peripherals that have only one connection.
271  * @param[in] channel    Inter-domain channel for conveying the signal.
272  */
nrfx_ids_signal(nrfx_ids_t * p_instance,nrfx_ids_domain_t domain,uint8_t channel)273 __STATIC_INLINE void nrfx_ids_signal(nrfx_ids_t *      p_instance,
274                                      nrfx_ids_domain_t domain,
275                                      uint8_t           channel)
276 {
277     NRFX_ASSERT(channel < NRFX_IDS_EVENTS_TRIGGERED_COUNT);
278 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
279     (void)domain;
280     (void)p_instance;
281     nrfx_ipc_signal(channel);
282 #elif defined(HALTIUM_XXAA)
283     (void)p_instance;
284     NRF_BELLBOARD_Type * p_bell = NULL;
285     NRF_VPR_Type       * p_vpr  = NULL;
286     switch (domain)
287     {
288         case NRFX_IDS_DOMAIN_APP:
289             p_bell = NRF_APPLICATION_BELLBOARD;
290             break;
291 
292         case NRFX_IDS_DOMAIN_NET:
293             p_bell = NRF_RADIOCORE_BELLBOARD;
294             break;
295 
296         case NRFX_IDS_DOMAIN_SEC:
297             p_bell = (NRF_BELLBOARD_Type *)NRF_SECDOMBELLBOARD;
298             break;
299 
300         case NRFX_IDS_DOMAIN_SYSC:
301             p_vpr = (NRF_VPR_Type *)NRF_VPR120;
302             break;
303 
304         case NRFX_IDS_DOMAIN_FLPR:
305             p_vpr = NRF_VPR121;
306             break;
307 
308         case NRFX_IDS_DOMAIN_PPR:
309             p_vpr = NRF_VPR130;
310             break;
311 
312 #if defined(NRFX_IDS_DOMAIN_EXT)
313         NRFX_IDS_DOMAIN_EXT
314 #endif
315 
316         default:
317             NRFX_ASSERT(0);
318             break;
319     }
320 
321     if (p_bell)
322     {
323         nrfy_bellboard_task_trigger(p_bell, nrf_bellboard_trigger_task_get(channel));
324     }
325     else
326     {
327         nrfy_vpr_task_trigger(p_vpr, nrfy_vpr_trigger_task_get(channel));
328     }
329 #endif
330 }
331 
332 /** @} */
333 
334 #if defined(NRF5340_XXAA) || defined(NRF9160_XXAA)
335 #if NRFX_CHECK(NRFX_IPC_ENABLED)
336 #define nrfx_ids_0_irq_handler nrfx_ipc_irq_handler
337 #endif
338 #elif defined(HALTIUM_XXAA)
339 #if defined(ISA_RISCV)
340 #if NRFX_CHECK(NRFX_VEVIF_ENABLED)
341 #define nrfx_ids_0_irq_handler nrfx_vevif_0_irq_handler
342 #define nrfx_ids_1_irq_handler nrfx_vevif_1_irq_handler
343 #define nrfx_ids_2_irq_handler nrfx_vevif_2_irq_handler
344 #define nrfx_ids_3_irq_handler nrfx_vevif_3_irq_handler
345 #define nrfx_ids_4_irq_handler nrfx_vevif_4_irq_handler
346 #define nrfx_ids_5_irq_handler nrfx_vevif_5_irq_handler
347 #define nrfx_ids_6_irq_handler nrfx_vevif_6_irq_handler
348 #define nrfx_ids_7_irq_handler nrfx_vevif_7_irq_handler
349 #define nrfx_ids_8_irq_handler nrfx_vevif_8_irq_handler
350 #define nrfx_ids_9_irq_handler nrfx_vevif_9_irq_handler
351 #define nrfx_ids_10_irq_handler nrfx_vevif_10_irq_handler
352 #define nrfx_ids_11_irq_handler nrfx_vevif_11_irq_handler
353 #define nrfx_ids_12_irq_handler nrfx_vevif_12_irq_handler
354 #define nrfx_ids_13_irq_handler nrfx_vevif_13_irq_handler
355 #define nrfx_ids_14_irq_handler nrfx_vevif_14_irq_handler
356 #define nrfx_ids_15_irq_handler nrfx_vevif_15_irq_handler
357 #define nrfx_ids_16_irq_handler nrfx_vevif_16_irq_handler
358 #define nrfx_ids_17_irq_handler nrfx_vevif_17_irq_handler
359 #define nrfx_ids_18_irq_handler nrfx_vevif_18_irq_handler
360 #define nrfx_ids_19_irq_handler nrfx_vevif_19_irq_handler
361 #define nrfx_ids_20_irq_handler nrfx_vevif_20_irq_handler
362 #define nrfx_ids_21_irq_handler nrfx_vevif_21_irq_handler
363 #define nrfx_ids_22_irq_handler nrfx_vevif_22_irq_handler
364 #define nrfx_ids_23_irq_handler nrfx_vevif_23_irq_handler
365 #define nrfx_ids_24_irq_handler nrfx_vevif_24_irq_handler
366 #define nrfx_ids_25_irq_handler nrfx_vevif_25_irq_handler
367 #define nrfx_ids_26_irq_handler nrfx_vevif_26_irq_handler
368 #define nrfx_ids_27_irq_handler nrfx_vevif_27_irq_handler
369 #define nrfx_ids_28_irq_handler nrfx_vevif_28_irq_handler
370 #define nrfx_ids_29_irq_handler nrfx_vevif_29_irq_handler
371 #define nrfx_ids_30_irq_handler nrfx_vevif_30_irq_handler
372 #define nrfx_ids_31_irq_handler nrfx_vevif_31_irq_handler
373 #endif
374 #elif defined(ISA_ARM)
375 #if NRFX_CHECK(NRFX_BELLBOARD0_ENABLED)
376 #define nrfx_ids_0_irq_handler nrfx_bellboard_0_irq_handler
377 #endif
378 #if NRFX_CHECK(NRFX_BELLBOARD1_ENABLED)
379 #define nrfx_ids_1_irq_handler nrfx_bellboard_1_irq_handler
380 #endif
381 #if NRFX_CHECK(NRFX_BELLBOARD2_ENABLED)
382 #define nrfx_ids_2_irq_handler nrfx_bellboard_2_irq_handler
383 #endif
384 #if NRFX_CHECK(NRFX_BELLBOARD3_ENABLED)
385 #define nrfx_ids_3_irq_handler nrfx_bellboard_3_irq_handler
386 #endif
387 #endif
388 #endif /* HALTIUM_XXAA */
389 
390 #ifdef __cplusplus
391 }
392 #endif
393 
394 #endif // NRFX_IDS_H__
395