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