1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017, 2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #ifndef _FSL_IRQSTEER_H_
10 #define _FSL_IRQSTEER_H_
11
12 #include "fsl_common.h"
13
14 /*!
15 * @addtogroup irqsteer
16 * @{
17 */
18
19 /*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23 /*! @name Driver version */
24 /*@{*/
25 /*!< Version 2.0.2. */
26 #define FSL_IRQSTEER_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
27 /*@}*/
28
29 /*!
30 * @brief Use the IRQSTEER driver IRQ Handler or not.
31 *
32 * When define as 1, IRQSTEER driver implements the IRQSTEER ISR, otherwise user
33 * shall implement it. Currently the IRQSTEER ISR is only available for Cortex-M
34 * platforms.
35 */
36 #if defined(__CORTEX_M)
37 #ifndef FSL_IRQSTEER_USE_DRIVER_IRQ_HANDLER
38 #define FSL_IRQSTEER_USE_DRIVER_IRQ_HANDLER 1
39 #endif
40 #else
41 #define FSL_IRQSTEER_USE_DRIVER_IRQ_HANDLER 0
42 #endif /* __CORTEX_M */
43
44 /*!
45 * @brief IRQSTEER_Init/IRQSTEER_Deinit enables/disables IRQSTEER master interrupt or not.
46 *
47 * When define as 1, IRQSTEER_Init will enable the IRQSTEER master interrupt in
48 * system level interrupt controller (such as NVIC, GIC), IRQSTEER_Deinit will
49 * disable it. Otherwise IRQSTEER_Init/IRQSTEER_Deinit won't touch.
50 */
51 #ifndef FSL_IRQSTEER_ENABLE_MASTER_INT
52 #define FSL_IRQSTEER_ENABLE_MASTER_INT 1
53 #endif
54
55 /*! @brief IRQSTEER interrupt source register width. */
56 #define IRQSTEER_INT_SRC_REG_WIDTH 32U
57
58 /*! @brief IRQSTEER aggregated interrupt source number for each master. */
59 #define IRQSTEER_INT_MASTER_AGGREGATED_INT_NUM 64U
60
61 /*! @brief IRQSTEER interrupt source mapping register index. */
62 #define IRQSTEER_INT_SRC_REG_INDEX(irq) \
63 (((uint32_t)FSL_FEATURE_IRQSTEER_CHn_MASK_COUNT - 1U) - \
64 ((irq - (uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX) / IRQSTEER_INT_SRC_REG_WIDTH))
65
66 /*! @brief IRQSTEER interrupt source mapping bit offset. */
67 #define IRQSTEER_INT_SRC_BIT_OFFSET(irq) \
68 ((irq - (uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX) % IRQSTEER_INT_SRC_REG_WIDTH)
69
70 /*! @brief IRQSTEER interrupt source number. */
71 #define IRQSTEER_INT_SRC_NUM(regIndex, bitOffset) \
72 ((((uint32_t)FSL_FEATURE_IRQSTEER_CHn_MASK_COUNT - 1U - (regIndex)) * (IRQSTEER_INT_SRC_REG_WIDTH)) + (bitOffset))
73
74 /*! @brief IRQSTEER interrupt groups. */
75 typedef enum _irqsteer_int_group
76 {
77 kIRQSTEER_InterruptGroup0, /*!< Interrupt Group 0: interrupt source 31 - 0 */
78 kIRQSTEER_InterruptGroup1, /*!< Interrupt Group 1: interrupt source 63 - 32 */
79 kIRQSTEER_InterruptGroup2, /*!< Interrupt Group 2: interrupt source 95 - 64 */
80 kIRQSTEER_InterruptGroup3, /*!< Interrupt Group 3: interrupt source 127 - 96 */
81 kIRQSTEER_InterruptGroup4, /*!< Interrupt Group 4: interrupt source 159 - 128 */
82 kIRQSTEER_InterruptGroup5, /*!< Interrupt Group 5: interrupt source 191 - 160 */
83 kIRQSTEER_InterruptGroup6, /*!< Interrupt Group 6: interrupt source 223 - 192 */
84 kIRQSTEER_InterruptGroup7, /*!< Interrupt Group 7: interrupt source 255 - 224 */
85 kIRQSTEER_InterruptGroup8, /*!< Interrupt Group 8: interrupt source 287 - 256 */
86 kIRQSTEER_InterruptGroup9, /*!< Interrupt Group 9: interrupt source 319 - 288 */
87 kIRQSTEER_InterruptGroup10, /*!< Interrupt Group 10: interrupt source 351 - 320 */
88 kIRQSTEER_InterruptGroup11, /*!< Interrupt Group 11: interrupt source 383 - 352 */
89 kIRQSTEER_InterruptGroup12, /*!< Interrupt Group 12: interrupt source 415 - 384 */
90 kIRQSTEER_InterruptGroup13, /*!< Interrupt Group 13: interrupt source 447 - 416 */
91 kIRQSTEER_InterruptGroup14, /*!< Interrupt Group 14: interrupt source 479 - 448 */
92 kIRQSTEER_InterruptGroup15 /*!< Interrupt Group 15: interrupt source 511 - 480 */
93 } irqsteer_int_group_t;
94
95 /*! @brief IRQSTEER master interrupts mapping. */
96 typedef enum _irqsteer_int_master
97 {
98 kIRQSTEER_InterruptMaster0, /*!< Interrupt Master 0: interrupt source 63 - 0 */
99 kIRQSTEER_InterruptMaster1, /*!< Interrupt Master 1: interrupt source 127 - 64 */
100 kIRQSTEER_InterruptMaster2, /*!< Interrupt Master 2: interrupt source 191 - 128 */
101 kIRQSTEER_InterruptMaster3, /*!< Interrupt Master 3: interrupt source 255 - 192 */
102 kIRQSTEER_InterruptMaster4, /*!< Interrupt Master 4: interrupt source 319 - 256 */
103 kIRQSTEER_InterruptMaster5, /*!< Interrupt Master 5: interrupt source 383 - 320 */
104 kIRQSTEER_InterruptMaster6, /*!< Interrupt Master 6: interrupt source 447 - 384 */
105 kIRQSTEER_InterruptMaster7, /*!< Interrupt Master 7: interrupt source 511 - 448 */
106 } irqsteer_int_master_t;
107
108 /*******************************************************************************
109 * API
110 ******************************************************************************/
111
112 #if defined(__cplusplus)
113 extern "C" {
114 #endif
115
116 /*! @name Initialization and deinitialization */
117 /*@{*/
118
119 /*!
120 * @brief Initializes the IRQSTEER module.
121 *
122 * This function enables the clock gate for the specified IRQSTEER.
123 *
124 * @param base IRQSTEER peripheral base address.
125 */
126 void IRQSTEER_Init(IRQSTEER_Type *base);
127
128 /*!
129 * @brief Deinitializes an IRQSTEER instance for operation.
130 *
131 * The clock gate for the specified IRQSTEER is disabled.
132 *
133 * @param base IRQSTEER peripheral base address.
134 */
135 void IRQSTEER_Deinit(IRQSTEER_Type *base);
136
137 /*@}*/
138
139 /*! @name Sources */
140 /*@{*/
141
142 /*!
143 * @brief Enables an interrupt source.
144 *
145 * @param base IRQSTEER peripheral base address.
146 * @param irq Interrupt to be routed. The interrupt must be an IRQSTEER source.
147 */
IRQSTEER_EnableInterrupt(IRQSTEER_Type * base,IRQn_Type irq)148 static inline void IRQSTEER_EnableInterrupt(IRQSTEER_Type *base, IRQn_Type irq)
149 {
150 assert((uint32_t)irq >= (uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX);
151
152 base->CHn_MASK[((uint32_t)IRQSTEER_INT_SRC_REG_INDEX(((uint32_t)irq)))] |=
153 (1UL << ((uint32_t)IRQSTEER_INT_SRC_BIT_OFFSET(((uint32_t)irq))));
154 }
155
156 /*!
157 * @brief Disables an interrupt source.
158 *
159 * @param base IRQSTEER peripheral base address.
160 * @param irq Interrupt source number. The interrupt must be an IRQSTEER source.
161 */
IRQSTEER_DisableInterrupt(IRQSTEER_Type * base,IRQn_Type irq)162 static inline void IRQSTEER_DisableInterrupt(IRQSTEER_Type *base, IRQn_Type irq)
163 {
164 assert(((uint32_t)irq) >= ((uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX));
165
166 base->CHn_MASK[(IRQSTEER_INT_SRC_REG_INDEX(((uint32_t)irq)))] &=
167 ~(1UL << ((uint32_t)IRQSTEER_INT_SRC_BIT_OFFSET(((uint32_t)irq))));
168 }
169
170 /*!
171 * @brief Check if an interrupt source is enabled.
172 *
173 * @param base IRQSTEER peripheral base address.
174 * @param irq Interrupt to be queried. The interrupt must be an IRQSTEER source.
175 * @return true if the interrupt is not masked, false otherwise.
176 */
IRQSTEER_InterruptIsEnabled(IRQSTEER_Type * base,IRQn_Type irq)177 static inline bool IRQSTEER_InterruptIsEnabled(IRQSTEER_Type *base, IRQn_Type irq)
178 {
179 assert((uint32_t)irq >= (uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX);
180
181 return base->CHn_MASK[((uint32_t)IRQSTEER_INT_SRC_REG_INDEX(((uint32_t)irq)))] &
182 (1UL << ((uint32_t)IRQSTEER_INT_SRC_BIT_OFFSET(((uint32_t)irq))));
183 }
184
185 /*!
186 * @brief Sets/Forces an interrupt.
187 *
188 * @param base IRQSTEER peripheral base address.
189 * @param irq Interrupt to be set/forced. The interrupt must be an IRQSTEER source.
190 * @param set Switcher of the interrupt set/force function. "true" means to set. "false" means not (normal operation).
191 * @note This function is not affected by the function @ref IRQSTEER_DisableInterrupt
192 * and @ref IRQSTEER_EnableInterrupt.
193 */
IRQSTEER_SetInterrupt(IRQSTEER_Type * base,IRQn_Type irq,bool set)194 static inline void IRQSTEER_SetInterrupt(IRQSTEER_Type *base, IRQn_Type irq, bool set)
195 {
196 assert(((uint32_t)irq) >= ((uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX));
197
198 if (set)
199 {
200 base->CHn_SET[((uint32_t)IRQSTEER_INT_SRC_REG_INDEX(((uint32_t)irq)))] |=
201 (1UL << ((uint32_t)IRQSTEER_INT_SRC_BIT_OFFSET(((uint32_t)irq))));
202 }
203 else
204 {
205 base->CHn_SET[((uint32_t)IRQSTEER_INT_SRC_REG_INDEX(((uint32_t)irq)))] &=
206 ~(1UL << ((uint32_t)IRQSTEER_INT_SRC_BIT_OFFSET(((uint32_t)irq))));
207 }
208 }
209
210 /*!
211 * @brief Enables a master interrupt. By default, all the master interrupts are enabled.
212 *
213 * @param base IRQSTEER peripheral base address.
214 * @param intMasterIndex Master index of interrupt sources to be routed, options available in enumeration
215 * ::irqsteer_int_master_t.
216 *
217 * For example, to enable the interrupt sources of master 1:
218 * @code
219 * IRQSTEER_EnableMasterInterrupt(IRQSTEER_M4_0, kIRQSTEER_InterruptMaster1);
220 * @endcode
221 */
IRQSTEER_EnableMasterInterrupt(IRQSTEER_Type * base,irqsteer_int_master_t intMasterIndex)222 static inline void IRQSTEER_EnableMasterInterrupt(IRQSTEER_Type *base, irqsteer_int_master_t intMasterIndex)
223 {
224 base->CHn_MINTDIS &= ~(1UL << ((uint32_t)intMasterIndex));
225 }
226
227 /*!
228 * @brief Disables a master interrupt.
229 *
230 * @param base IRQSTEER peripheral base address.
231 * @param intMasterIndex Master index of interrupt sources to be disabled, options available in enumeration
232 * ::irqsteer_int_master_t.
233 *
234 * For example, to disable the interrupt sources of master 1:
235 * @code
236 * IRQSTEER_DisableMasterInterrupt(IRQSTEER_M4_0, kIRQSTEER_InterruptMaster1);
237 * @endcode
238 */
IRQSTEER_DisableMasterInterrupt(IRQSTEER_Type * base,irqsteer_int_master_t intMasterIndex)239 static inline void IRQSTEER_DisableMasterInterrupt(IRQSTEER_Type *base, irqsteer_int_master_t intMasterIndex)
240 {
241 base->CHn_MINTDIS |= (1UL << ((uint32_t)intMasterIndex));
242 }
243
244 /*@}*/
245
246 /*! @name Status */
247 /*@{*/
248
249 /*!
250 * @brief Checks the status of one specific IRQSTEER interrupt.
251 *
252 * @param base IRQSTEER peripheral base address.
253 * @param irq Interrupt source status to be checked. The interrupt must be an IRQSTEER source.
254 * @return The interrupt status. "true" means interrupt set. "false" means not.
255 *
256 * For example, to check whether interrupt from output 0 of Display 1 is set:
257 * @code
258 * if (IRQSTEER_IsInterruptSet(IRQSTEER_DISPLAY1_INT_OUT0)
259 * {
260 * ...
261 * }
262 * @endcode
263 */
IRQSTEER_IsInterruptSet(IRQSTEER_Type * base,IRQn_Type irq)264 static inline bool IRQSTEER_IsInterruptSet(IRQSTEER_Type *base, IRQn_Type irq)
265 {
266 assert(((uint32_t)irq) >= ((uint32_t)FSL_FEATURE_IRQSTEER_IRQ_START_INDEX));
267
268 return (bool)(base->CHn_STATUS[((uint32_t)(IRQSTEER_INT_SRC_REG_INDEX(((uint32_t)irq))))] &
269 (1UL << ((uint32_t)(IRQSTEER_INT_SRC_BIT_OFFSET(((uint32_t)irq))))));
270 }
271
272 /*!
273 * @brief Checks the status of IRQSTEER master interrupt.
274 * The master interrupt status represents at least one interrupt is asserted or not among ALL interrupts.
275 *
276 * @param base IRQSTEER peripheral base address.
277 * @return The master interrupt status. "true" means at least one interrupt set. "false" means not.
278 * @note The master interrupt status is not affected by the function @ref IRQSTEER_DisableMasterInterrupt.
279 */
IRQSTEER_IsMasterInterruptSet(IRQSTEER_Type * base)280 static inline bool IRQSTEER_IsMasterInterruptSet(IRQSTEER_Type *base)
281 {
282 return (bool)(base->CHn_MSTRSTAT & IRQSTEER_CHn_MSTRSTAT_STATUS_MASK);
283 }
284
285 /*!
286 * @brief Gets the status of IRQSTEER group interrupt.
287 * The group interrupt status represents all the interrupt status within the group specified.
288 * This API aims for facilitating the status return of one set of interrupts.
289 *
290 * @param base IRQSTEER peripheral base address.
291 * @param intGroupIndex Index of the interrupt group status to get.
292 * @return The mask of the group interrupt status.
293 * Bit[n] set means the source with bit offset n in group intGroupIndex of IRQSTEER is asserted.
294 */
IRQSTEER_GetGroupInterruptStatus(IRQSTEER_Type * base,irqsteer_int_group_t intGroupIndex)295 static inline uint32_t IRQSTEER_GetGroupInterruptStatus(IRQSTEER_Type *base, irqsteer_int_group_t intGroupIndex)
296 {
297 return (base->CHn_STATUS[intGroupIndex]);
298 }
299
300 /*!
301 * @brief Gets the next interrupt source (currently set) of one specific master.
302 *
303 * @param base IRQSTEER peripheral base address.
304 * @param intMasterIndex Master index of interrupt sources, options available in enumeration ::irqsteer_int_master_t.
305 * @return The current set next interrupt source number of one specific master.
306 * Return IRQSTEER_INT_Invalid if no interrupt set.
307 */
308 IRQn_Type IRQSTEER_GetMasterNextInterrupt(IRQSTEER_Type *base, irqsteer_int_master_t intMasterIndex);
309
310 /*!
311 * @brief Get the number of interrupt for a given master.
312 *
313 * @param base IRQSTEER peripheral base address.
314 * @param intMasterIndex Master index of interrupt sources, options available in
315 * enumeration ::irqsteer_int_master_t.
316 * @return Number of interrupts for a given master.
317 */
318 uint32_t IRQSTEER_GetMasterIrqCount(IRQSTEER_Type *base, irqsteer_int_master_t intMasterIndex);
319
320 /*!
321 * @brief Get the status of the interrupts a master is in charge of.
322 *
323 * What this function does is it takes the CHn_STATUS registers associated
324 * with the interrupts a master is in charge of and puts them in 64-bit
325 * variable. The order they are put in the 64-bit variable is the following:
326 * CHn_STATUS[i] : CHn_STATUS[i + 1], where CHn_STATUS[i + 1] is placed in
327 * the least significant half of the 64-bit variable. Assuming a master is
328 * in charge of 64 interrupts, the user may use the result of this function
329 * as such: BIT(i) & IRQSTEER_GetMasterInterrupts() to check if interrupt i
330 * is asserted.
331 *
332 * @param base IRQSTEER peripheral base address.
333 * @param intMasterIndex Master index of interrupt sources, options available in
334 * enumeration ::irqsteer_int_master_t.
335 * @return 64-bit variable containing the status of the interrupts a master is in charge of.
336 */
337 uint64_t IRQSTEER_GetMasterInterruptsStatus(IRQSTEER_Type *base, irqsteer_int_master_t intMasterIndex);
338
339 /*@}*/
340
341 #if defined(__cplusplus)
342 }
343 #endif
344
345 /*! @} */
346
347 #endif /* _FSL_INTMUX_H_ */
348