1 /*
2  * Copyright (c) 2022 - 2025, 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 #include <nrfx.h>
34 
35 #if defined(HALTIUM_XXAA)
36 
37 #include <soc/interconnect/ipct/nrfx_interconnect_ipct_haltium_global.h>
38 #include <soc/interconnect/ipct/nrfx_interconnect_ipct.h>
39 #include <soc/interconnect/apb/nrfx_interconnect_apb.h>
40 
41 #if defined(NRF_RADIOCORE)
42     #include <soc/interconnect/ipct/nrfx_interconnect_ipct_haltium_radiocore.h>
43 #elif defined(NRF_APPLICATION)
44     #include <soc/interconnect/ipct/nrfx_interconnect_ipct_haltium_application.h>
45 #elif defined(NRF_PPR)
46     #include <soc/interconnect/ipct/nrfx_interconnect_ipct_haltium_ppr.h>
47 #elif defined(NRF_FLPR)
48     #include <soc/interconnect/ipct/nrfx_interconnect_ipct_haltium_flpr.h>
49 #else
50     #include <soc/interconnect/ipct/nrfx_interconnect_ipct_haltium_ext.h>
51 #endif
52 
53 NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE;
54 NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE;
55 static const nrfx_interconnect_ipct_t m_local_ipct_interconnect[] =
56                                       NRFX_INTERCONNECT_IPCT_LOCAL_IPCT_PROP;
57 static const nrfx_interconnect_ipct_t m_global_ipct_interconnect[] =
58                                       NRFX_INTERCONNECT_IPCT_GLOBAL_IPCT_PROP;
59 
nrfx_interconnect_ipct_domain_get(nrfx_interconnect_ipct_t const * p_ipct_prop)60 nrf_domain_t nrfx_interconnect_ipct_domain_get(nrfx_interconnect_ipct_t const * p_ipct_prop)
61 {
62     return (nrf_domain_t)nrf_address_domain_get((uint32_t)p_ipct_prop->p_ipct);
63 }
64 
65 /* Set of macros to allow calculation of array index where given index is located.
66  * We create a structure with fields for each instance which has non-zero
67  * CHANNEL_MASK. Then offsetof is used to get the index of the given instance.
68  */
69 #define _IPCT_STRUCT_ELEM(periph_name, prefix, inst_num, _) \
70     NRFX_COND_CODE_1(NRFX_IS_EMPTY(inst_num), (), \
71             (NRFX_COND_CODE_1(NRFX_IPCT_OWNED_MASK(inst_num), \
72                               (uint8_t NRFX_CONCAT(dummy, inst_num);), ())))
73 
74 #define IPCT_IDX_STRUCT() \
75     struct ipct_idx_dummy_struct { \
76         NRFX_FOREACH_PRESENT(IPCT, _IPCT_STRUCT_ELEM, (), (), _) \
77     }
78 
79 #define IPCT_IDX(inst_num) \
80     NRFX_COND_CODE_1(NRFX_IPCT_OWNED_MASK(inst_num), \
81             (offsetof(struct ipct_idx_dummy_struct, NRFX_CONCAT(dummy, inst_num))), \
82             (-1))
83 
84 IPCT_IDX_STRUCT();
85 
86 static const int ipct_main_idx = IPCT_IDX(NRFX_INTERCONNECT_MAIN_IPCT_INSTANCE);
87 
nrfx_interconnect_ipct_main_get(void)88 nrfx_interconnect_ipct_t const * nrfx_interconnect_ipct_main_get(void)
89 {
90     return ipct_main_idx >= 0 ? &m_global_ipct_interconnect[ipct_main_idx] : NULL;
91 }
92 
nrfx_interconnect_ipct_get(nrfx_interconnect_apb_t const * p_apb_prop)93 nrfx_interconnect_ipct_t const * nrfx_interconnect_ipct_get(nrfx_interconnect_apb_t const * p_apb_prop)
94 {
95     uint8_t bus = nrf_address_bus_get((uint32_t)p_apb_prop->p_dppi, p_apb_prop->size);
96 
97     if (nrfx_interconnect_apb_domain_get(p_apb_prop) == NRF_DOMAIN_GLOBAL)
98     {
99         for (uint8_t i = 0; i < NRFX_ARRAY_SIZE(m_global_ipct_interconnect); i++)
100         {
101             // Check if some IPCT is on the same bus
102             if (nrf_address_bus_get((uint32_t)m_global_ipct_interconnect[i].p_ipct, p_apb_prop->size) == bus)
103             {
104                 return &m_global_ipct_interconnect[i];
105             }
106         }
107         // The power domain connected to `bus` doesn't contain its own IPCT peripheral
108         for (uint8_t i = 0; i < nrfx_interconnect_apb_global_num_of_get(); i++)
109         {
110             // Check whether it is possible to connect via DPPI
111             if (nrf_apb_interconnect_by_idx_global_get(i)->p_dppi == p_apb_prop->p_dppi)
112             {
113                 return nrfx_interconnect_ipct_main_get();
114             }
115         }
116     }
117     else
118     {
119         return &m_local_ipct_interconnect[0];
120     }
121     return NULL;
122 }
123 
nrfx_interconnect_ipct_global_num_of_get(void)124 size_t nrfx_interconnect_ipct_global_num_of_get(void)
125 {
126     return NRFX_ARRAY_SIZE(m_global_ipct_interconnect);
127 }
128 
nrfx_interconnect_ipct_global_by_idx_get(uint8_t idx)129 nrfx_interconnect_ipct_t const * nrfx_interconnect_ipct_global_by_idx_get(uint8_t idx)
130 {
131     return idx < NRFX_ARRAY_SIZE(m_global_ipct_interconnect) ? &m_global_ipct_interconnect[idx] : NULL;
132 }
133 
134 #endif // defined(HALTIUM_XXAA)
135