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