xref: /freebsd/sys/contrib/alpine-hal/al_hal_udma_iofic.h (revision 7ef62cebc2f965b0f640263e179276928885e33d)
1 /*-
2 *******************************************************************************
3 Copyright (C) 2015 Annapurna Labs Ltd.
4 
5 This file may be licensed under the terms of the Annapurna Labs Commercial
6 License Agreement.
7 
8 Alternatively, this file can be distributed under the terms of the GNU General
9 Public License V2 as published by the Free Software Foundation and can be
10 found at http://www.gnu.org/licenses/gpl-2.0.html
11 
12 Alternatively, redistribution and use in source and binary forms, with or
13 without modification, are permitted provided that the following conditions are
14 met:
15 
16     *     Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
18 
19     *     Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in
21 the documentation and/or other materials provided with the
22 distribution.
23 
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 
35 *******************************************************************************/
36 
37 /**
38  * @defgroup group_udma_interrupts UDMA I/O Fabric Interrupt Controller
39  * @ingroup group_udma_api
40  *  UDMA IOFIC API
41  *  @{
42  * @file   al_hal_udma_iofic.h
43  *
44  * @brief C Header file for programming the interrupt controller that found
45  * in UDMA based units. These APIs rely and use some the Interrupt controller
46  * API under al_hal_iofic.h
47  */
48 
49 #ifndef __AL_HAL_UDMA_IOFIC_H__
50 #define __AL_HAL_UDMA_IOFIC_H__
51 
52 #include <al_hal_common.h>
53 #include <al_hal_iofic.h>
54 #include <al_hal_udma_regs.h>
55 
56 /* *INDENT-OFF* */
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60 /* *INDENT-ON* */
61 
62 /**
63  * Interrupt Mode
64  * This is the interrupt mode for the primary interrupt level The secondary
65  * interrupt level does not have mode and it is always a level sensitive
66  * interrupt that is reflected in group D of the primary.
67  */
68 enum al_iofic_mode {
69 	AL_IOFIC_MODE_LEGACY, /**< level-sensitive interrupt wire */
70 	AL_IOFIC_MODE_MSIX_PER_Q, /**< per UDMA queue MSI-X interrupt */
71 	AL_IOFIC_MODE_MSIX_PER_GROUP
72 };
73 
74 /** interrupt controller level (primary/secondary) */
75 enum al_udma_iofic_level {
76 	AL_UDMA_IOFIC_LEVEL_PRIMARY,
77 	AL_UDMA_IOFIC_LEVEL_SECONDARY
78 };
79 
80 /*
81  * The next four groups represents the standard 4 groups in the primary
82  * interrupt controller of each bus-master unit in the I/O Fabric.
83  * The first two groups can be used when accessing the secondary interrupt
84  * controller as well.
85  */
86 #define AL_INT_GROUP_A		0 /**< summary of the below events */
87 #define AL_INT_GROUP_B		1 /**< RX completion queues */
88 #define AL_INT_GROUP_C		2 /**< TX completion queues */
89 #define AL_INT_GROUP_D		3 /**< Misc */
90 
91 /*******************************************************************************
92  * Primary interrupt controller, group A bits
93  ******************************************************************************/
94 /* Group A bits which are just summary bits of GROUP B, C and D */
95 #define AL_INT_GROUP_A_GROUP_B_SUM	AL_BIT(0)
96 #define AL_INT_GROUP_A_GROUP_C_SUM	AL_BIT(1)
97 #define AL_INT_GROUP_A_GROUP_D_SUM	AL_BIT(2)
98 
99 /*******************************************************************************
100  * MSIX entry indices
101  ******************************************************************************/
102 /** MSIX entry index for summary of group D in group A */
103 #define AL_INT_MSIX_GROUP_A_SUM_D_IDX 	2
104 /** MSIX entry index for RX completion queue 0 */
105 #define AL_INT_MSIX_RX_COMPLETION_START	3
106 
107 /*******************************************************************************
108  * Primary interrupt controller, group D bits
109  ******************************************************************************/
110 #define AL_INT_GROUP_D_CROSS_MAIL_BOXES	\
111 			(AL_BIT(0) | AL_BIT(1) | AL_BIT(2) | AL_BIT(3))
112 /** Summary of secondary interrupt controller, group A) */
113 #define AL_INT_GROUP_D_M2S	AL_BIT(8)
114 /** Summary of secondary interrupt controller, group B) */
115 #define AL_INT_GROUP_D_S2M	AL_BIT(9)
116 #define AL_INT_GROUP_D_SW_TIMER_INT	AL_BIT(10)
117 #define AL_INT_GROUP_D_APP_EXT_INT	AL_BIT(11)
118 #define AL_INT_GROUP_D_ALL			\
119 			AL_INT_GROUP_D_CROSS_MAIL_BOXES | \
120 			AL_INT_GROUP_D_M2S | \
121 			AL_INT_GROUP_D_S2M | \
122 			AL_INT_GROUP_D_SW_TIMER_INT | \
123 			AL_INT_GROUP_D_APP_EXT_INT
124 
125 /*
126  * Until this point, all description above is for Groups A/B/C/D in the PRIMARY
127  * Interrupt controller.
128  * Following are definitions related to the secondary interrupt controller with
129  * two cause registers (group A and group B) that covers UDMA M2S/S2M errors.
130  * Secondary interrupt controller summary bits are not mapped to the Processor
131  * GIC directly, rather they are represented in Group D of the primary interrupt
132  * controller.
133  */
134 
135 /******************************************************************************
136  * Secondary interrupt Controller, Group A, which holds the TX (M2S) error
137  * interrupt bits
138  ******************************************************************************/
139 
140 /**
141  * MSIx response
142  * MSIX Bus generator response error, the Bus response received with error indication
143  */
144 #define AL_INT_2ND_GROUP_A_M2S_MSIX_RESP		AL_BIT(27)
145 /**
146  * MSIx timeout	MSIX Bus generator timeout error.
147  * The generator didn't receive bus response for the MSIx write transaction.
148  */
149 #define AL_INT_2ND_GROUP_A_M2S_MSIX_TO			AL_BIT(26)
150 /** Prefetch header buffer parity error */
151 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_HDR_PARITY	AL_BIT(25)
152 /** Prefetch descriptor buffer parity error */
153 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_DESC_PARITY	AL_BIT(24)
154 /** Data buffer parity error */
155 #define AL_INT_2ND_GROUP_A_M2S_DATA_PARITY		AL_BIT(23)
156 /** Data header buffer parity error */
157 #define AL_INT_2ND_GROUP_A_M2S_HDR_PARITY		AL_BIT(22)
158 /** Completion coalescing buffer parity error */
159 #define AL_INT_2ND_GROUP_A_M2S_COMPL_COAL_PARITY	AL_BIT(21)
160 /** UNACK packets buffer parity error */
161 #define AL_INT_2ND_GROUP_A_M2S_UNACK_PKT_PARITY		AL_BIT(20)
162 /** ACK packets buffer parity error */
163 #define AL_INT_2ND_GROUP_A_M2S_ACK_PKT_PARITY		AL_BIT(19)
164 /** AXI data buffer parity error */
165 #define AL_INT_2ND_GROUP_A_M2S_AX_DATA_PARITY		AL_BIT(18)
166 /**
167  * Prefetch Ring ID error
168  * A wrong RingId was received while prefetching submission descriptor. This
169  * could indicate a software bug or hardware failure, unless the UDMA is
170  * working in a mode to ignore RingId (the al_udma_iofic_config() API can be
171  * used to configure the UDMA to ignore the Ring ID check)
172  */
173 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_RING_ID		AL_BIT(17)
174 /**
175  * Prefetch last
176  * Error in last bit indication of the descriptor
177  * Descriptor with Last bit asserted is read from the queue to the prefetch
178  * FIFO when the prefetch engine is not in a middle of packet processing (a
179  * descriptor with First bit asserted should be read first to indicate start of
180  * packet)
181  */
182 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_LAST		AL_BIT(16)
183 /**
184  * Prefetch first
185  * Error in first bit indication of the descriptor
186  * Descriptor with First bit asserted is read from the queue to the prefetch
187  * FIFO while the prefetch engine is in a middle of packet processing ( a
188  * descriptor with Last bit asserted should be read to indicate end of packet
189  * before starting a new one)
190  */
191 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_FIRST		AL_BIT(15)
192 /**
193  * Prefetch max descriptors
194  * Number of descriptors per packet exceeds the configurable maximum
195  * descriptors per packet. This could indicate a software bug or a hardware
196  * failure.  (The al_udma_m2s_max_descs_set() API is used to configure the
197  * maximum descriptors per packet)
198  */
199 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_MAX_DESC	AL_BIT(14)
200 /**
201  * Packet length
202  * Packet length exceeds the configurable maximum packet size.  The
203  * al_udma_m2s_packet_size_cfg_set() API is used to configure the maximum
204  * packet size)
205  */
206 #define AL_INT_2ND_GROUP_A_M2S_PKT_LEN			AL_BIT(13)
207 /**
208  * Prefetch AXI timeout
209  * Bus request to I/O Fabric timeout error
210  */
211 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_TO		AL_BIT(12)
212 /**
213  * Prefetch AXI response
214  * Bus response from I/O Fabric error
215  */
216 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_RESP	AL_BIT(11)
217 /**
218  * Prefetch AXI parity
219  * Bus parity error on descriptor being prefetched
220  */
221 #define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_PARITY	AL_BIT(10)
222 /**
223  * Data AXI timeout
224  * Bus request to I/O Fabric timeout error
225  */
226 #define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_TO		AL_BIT(9)
227 /**
228  * Data AXI response
229  * Bus response from I/O Fabric error
230  */
231 #define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_RESP		AL_BIT(8)
232 /**
233  * Data AXI parity
234  * Bus parity error on data being read
235  */
236 #define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_PARITY		AL_BIT(7)
237 /**
238  * Completion AXI timeout
239  * Bus request to I/O Fabric timeout error
240  */
241 #define AL_INT_2ND_GROUP_A_M2S_CONPL_AXI_TO		AL_BIT(6)
242 /**
243  * Completion AXI response
244  * Bus response from I/O Fabric error
245  */
246 #define AL_INT_2ND_GROUP_A_M2S_COMPL_AXI_RESP		AL_BIT(5)
247 /**
248  * Completion AXI parity
249  * Bus generator internal SRAM parity error
250  */
251 #define AL_INT_2ND_GROUP_A_M2S_COMP_AXI_PARITY		AL_BIT(4)
252 /**
253  * Stream timeout
254  * Application stream interface timeout indicating a failure at the Application
255  * layer (RAID, Ethernet etc)
256  */
257 #define AL_INT_2ND_GROUP_A_M2S_STRM_TO			AL_BIT(3)
258 /**
259  * Stream response
260  * Application stream interface response error indicating a failure at the
261  * Application layer (RAID, Ethernet etc)
262  */
263 #define AL_INT_2ND_GROUP_A_M2S_STRM_RESP		AL_BIT(2)
264 /**
265  * Stream parity
266  * Application stream interface parity error indicating a failure at the
267  * Application layer (RAID, Ethernet etc)
268  */
269 #define AL_INT_2ND_GROUP_A_M2S_STRM_PARITY		 AL_BIT(1)
270 /**
271  * Stream completion mismatch
272  * Application stream interface, packet serial mismatch error indicating a
273  * failure at the Application layer (RAID, Ethernet etc)
274  */
275 #define AL_INT_2ND_GROUP_A_M2S_STRM_COMPL_MISMATCH	AL_BIT(0)
276 
277 /*******************************************************************************
278  * Secondary interrupt Controller, Group B, which holds the RX (S2M) error
279  * interrupt bits
280  ******************************************************************************/
281 
282 /** Prefetch descriptor buffer parity error */
283 #define AL_INT_2ND_GROUP_B_S2M_PREFETCH_DESC_PARITY	AL_BIT(30)
284 /** Completion coalescing buffer parity error */
285 #define AL_INT_2ND_GROUP_B_S2M_COMPL_COAL_PARITY	AL_BIT(29)
286 /** PRE-UNACK packets buffer parity error */
287 #define AL_INT_2ND_GROUP_B_S2M_PRE_UNACK_PKT_PARITY	AL_BIT(28)
288 /** UNACK packets buffer parity error */
289 #define AL_INT_2ND_GROUP_B_S2M_UNACK_PKT_PARITY		AL_BIT(27)
290 /** Data buffer parity error */
291 #define AL_INT_2ND_GROUP_B_S2M_DATA_PARITY		AL_BIT(26)
292 /** Data header buffer parity error */
293 #define AL_INT_2ND_GROUP_B_S2M_DATA_HDR_PARITY		AL_BIT(25)
294 /**
295  * Packet length
296  * Application stream interface, Data counter length mismatch with metadata
297  * packet length indicating a failure at the Application layer (RAID, Ethernet
298  * etc)
299  */
300 #define AL_INT_2ND_GROUP_B_S2M_PKT_LEN			AL_BIT(24)
301 /**
302  * Stream last
303  * Application stream interface, error in Last bit indication, this error is
304  * asserted when a 'last' indication is asserted on the stream interface
305  * (between the application and the UDMA) when the interface is not in the
306  * middle of packet, meaning that there was no 'first' indication before. This
307  * indicates a failure at the application layer.
308  */
309 #define AL_INT_2ND_GROUP_B_S2M_STRM_LAST		AL_BIT(23)
310 /**
311  * Stream first
312  * Application stream interface error in first bit indication, this error is
313  * asserted when a 'first' indication is asserted on the stream interface
314  * (between the application and the UDMA) when the interface is in the middle
315  * of packet, meaning that there was a 'first' indication before and the UDMA
316  * is waiting for a 'last' indication to end the packet. This indicates a
317  * failure at the application layer.
318  */
319 #define AL_INT_2ND_GROUP_B_S2M_STRM_FIRST		AL_BIT(22)
320 /**
321  * Stream data
322  * Application stream interface, error indication during data transaction
323  */
324 #define AL_INT_2ND_GROUP_B_S2M_STRM_DATA		AL_BIT(21)
325 /**
326  * Stream Data parity
327  * Application stream interface, parity error during data transaction
328  */
329 #define AL_INT_2ND_GROUP_B_S2M_STRM_DATA_PARITY		AL_BIT(20)
330 /**
331  * Stream Header error
332  * Application stream interface, error indication during header transaction
333  */
334 #define AL_INT_2ND_GROUP_B_S2M_STRM_HDR			AL_BIT(19)
335 /**
336  * Stream Header parity
337  * Application stream interface, parity error during header transaction
338  */
339 #define AL_INT_2ND_GROUP_B_S2M_STRM_HDR_PARITY		AL_BIT(18)
340 /**
341  * Completion UNACK
342  * Completion write, UNACK timeout due to completion FIFO back pressure
343  */
344 #define AL_INT_2ND_GROUP_B_S2M_COMPL_UNACK		AL_BIT(17)
345 /**
346  * Completion stream
347  * Completion write, UNACK timeout due to stream ACK FIFO back pressure
348  */
349 #define AL_INT_2ND_GROUP_B_S2M_COMPL_STRM		AL_BIT(16)
350 /**
351  * Completion AXI timeout
352  * Bus request to I/O Fabric timeout error
353  */
354 #define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_TO		AL_BIT(15)
355 /**
356  * Completion AXI response
357  * Bus response from I/O Fabric error
358  */
359 #define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_RESP		AL_BIT(14)
360 /**
361  * Completion AXI parity
362  * Completion Bus generator internal SRAM parity error
363  */
364 #define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_PARITY		AL_BIT(13)
365 /**
366  * Prefetch saturate
367  * Prefetch engine, packet length counter saturated (32 bit) , this is caused
368  * by an error at the application layer which sends packet data without
369  * 'last'/'first' indication.
370  */
371 #define AL_INT_2ND_GROUP_B_S2M_PREFETCH_SAT		AL_BIT(12)
372 /**
373  * Prefetch ring ID
374  * Prefetch engine, Ring ID is not matching the expected RingID. This could
375  * indicate a software bug or hardware failure, unless the UDMA is working in a
376  * mode to ignore RingId  (the al_udma_iofic_config() API can be used to
377  * configure the UDMA to ignore the Ring ID check)
378  */
379 #define AL_INT_2ND_GROUP_B_S2M_PREFETCH_RING_ID		AL_BIT(11)
380 /**
381  * Prefetch AXI timeout
382  * Bus request to I/O Fabric timeout error
383  */
384 #define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_TO		AL_BIT(10)
385 /**
386  * Prefetch AXI response
387  * Bus response from I/O Fabric error
388  */
389 #define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_RESP	AL_BIT(9)
390 /**
391  * Prefetch AXI parity
392  * Bus parity error on descriptor being prefetched
393  */
394 #define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_PARITY	AL_BIT(8)
395 /**
396  * No descriptors hint
397  * Data write, Hint to the SW that there are not enough descriptors in the
398  * queue for the current received packet. This is considered a hint and not an
399  * error, as it could be a normal situation in certain application. The S2M
400  * UDMA behavior when it runs out of Rx Descriptor is controlled by driver
401  * which can use this hint to add more descriptors to the Rx queue.
402  */
403 #define AL_INT_2ND_GROUP_B_S2M_NO_DESC_HINT		AL_BIT(7)
404 /**
405  * No descriptors timeout
406  * Data write, Timeout indication when there are not enough descriptors for the
407  * current packet and the timeout expires. The S2M UDMA behavior when it runs
408  * out of Rx Descriptor is controlled by driver which can use this hint to add
409  * more descriptors to the Rx queue. The al_udma_s2m_no_desc_cfg_set() is used
410  * to configure theUDMA S2M timeout and behavior when there are no Rx
411  * descriptors for the received packet.
412  */
413 #define AL_INT_2ND_GROUP_B_S2M_NO_DESC_TO		AL_BIT(6)
414 /**
415  * Promotion indication
416  * Data write, the data write engine checks the queue number of the two packets
417  * at the head of the data FIFO, the data write engine notify the prefetch
418  * engine to promote these queue numbers in the prefetch scheduler to make sure
419  * that these queue will have RX descriptors for these packets. This error
420  * indicates that the prefetch promotion didn't work for the second packet in
421  * the FIFO. This is an indication used for system debug and not an error.
422  */
423 #define AL_INT_2ND_GROUP_B_S2M_PROM_IND			AL_BIT(5)
424 /**
425  * Header split ignored
426  * Data write, The application requested header split but the buffer descriptor
427  * doesn't include a second buffer for the header
428  */
429 #define AL_INT_2ND_GROUP_B_S2M_HDR_SPLT_IGNORED		AL_BIT(4)
430 /**
431  * Header split length
432  * Data write, The application requested header split and the length of the
433  * second buffer allocated for the header is not enough for the requested
434  * header length. The remaining of the header is written to buffer 1 (data
435  * buffer).
436  */
437 #define AL_INT_2ND_GROUP_B_S2M_HDR_SPLT_LEN		AL_BIT(3)
438 /**
439  * Data AXI timeout
440  * Bus request to I/O Fabric timeout error
441  */
442 #define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_TO		AL_BIT(2)
443 /**
444  * Data AXI response
445  * Bus response from I/O Fabric error
446  */
447 #define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_RESP		AL_BIT(1)
448 /**
449  * Data AXI parity
450  * Bus parity error on data being read
451  */
452 #define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_PARITY		AL_BIT(0)
453 
454 /*******************************************************************************
455  * Configurations
456  ******************************************************************************/
457 
458 /**
459  * Configure the UDMA interrupt controller registers, interrupts will are kept
460  * masked.
461  * This is a static setting that should be called while initialized the
462  * interrupt controller within a given UDMA, and should not be modified during
463  * runtime unless the UDMA is completely disabled. The first argument sets the
464  * interrupt and MSIX modes. The m2s/s2m errors/abort are a set of bit-wise
465  * masks to define the behaviour of the UDMA once an error happens: The _abort
466  * will put the UDMA in abort state once an error happens The _error bitmask
467  * will indicate and error in the secondary cause register but will not abort.
468  * The bit-mask that the _errors_disable and _aborts_disable are described in
469  * 'AL_INT_2ND_GROUP_A_*' and 'AL_INT_2ND_GROUP_B_*'
470  *
471  * @param regs pointer to unit registers
472  * @param mode interrupt scheme mode (legacy, MSI-X..)
473  * @param m2s_errors_disable
474  * 	  This is a bit-wise mask, to indicate which one of the error causes in
475  * 	  secondary interrupt group_A should generate an interrupt. When a bit is
476  * 	  set, the error cause is ignored.
477  * 	  Recommended value: 0 (enable all errors).
478  * @param m2s_aborts_disable
479  * 	  This is a bit-wise mask, to indicate which one of the error causes in
480  * 	  secondary interrupt group_A should automatically put the UDMA in
481  * 	  abort state. When a bit is set, the error cause does cause an abort.
482  * 	  Recommended value: 0 (enable all aborts).
483  * @param s2m_errors_disable
484  * 	  This is a bit-wise mask, to indicate which one of the error causes in
485  * 	  secondary interrupt group_A should generate an interrupt. When a bit is
486  * 	  set, the error cause is ignored.
487  * 	  Recommended value: 0xE0 (disable hint errors).
488  * @param s2m_aborts_disable
489  * 	  This is a bit-wise mask, to indicate which one of the error causes in
490  * 	  secondary interrupt group_A should automatically put the UDMA in
491  * 	  abort state. When a bit is set, the error cause does cause an abort.
492  * 	  Recommended value: 0xE0 (disable hint aborts).
493  *
494  * @return 0 on success. -EINVAL otherwise.
495  */
496 int al_udma_iofic_config(struct unit_regs __iomem *regs,
497 			enum al_iofic_mode mode,
498 			uint32_t	m2s_errors_disable,
499 			uint32_t	m2s_aborts_disable,
500 			uint32_t	s2m_errors_disable,
501 			uint32_t	s2m_aborts_disable);
502 /**
503  * return the offset of the unmask register for a given group.
504  * this function can be used when the upper layer wants to directly
505  * access the unmask regiter and bypass the al_udma_iofic_unmask() API.
506  *
507  * @param regs pointer to udma registers
508  * @param level the interrupt controller level (primary / secondary)
509  * @param group the interrupt group ('AL_INT_GROUP_*')
510  * @return the offset of the unmask register.
511  */
512 uint32_t __iomem * al_udma_iofic_unmask_offset_get(
513 	struct unit_regs __iomem	*regs,
514 	enum al_udma_iofic_level	level,
515 	int				group);
516 
517 /**
518  * Get the interrupt controller base address for either the primary or secondary
519  * interrupt controller
520  *
521  * @param regs pointer to udma unit registers
522  * @param level the interrupt controller level (primary / secondary)
523  *
524  * @returns	The interrupt controller base address
525  *
526  */
527 static INLINE void __iomem *al_udma_iofic_reg_base_get(
528 	struct unit_regs __iomem	*regs,
529 	enum al_udma_iofic_level	level)
530 {
531 	void __iomem *iofic_regs = (level == AL_UDMA_IOFIC_LEVEL_PRIMARY) ?
532 		(void __iomem *)&regs->gen.interrupt_regs.main_iofic :
533 		(void __iomem *)&regs->gen.interrupt_regs.secondary_iofic_ctrl;
534 
535 	return iofic_regs;
536 }
537 
538 /**
539  * Check the interrupt controller level/group validity
540  *
541  * @param level the interrupt controller level (primary / secondary)
542  * @param group the interrupt group ('AL_INT_GROUP_*')
543  *
544  * @returns	0 - invalid, 1 - valid
545  *
546  */
547 static INLINE int al_udma_iofic_level_and_group_valid(
548 	enum al_udma_iofic_level	level,
549 	int				group)
550 {
551 	if (((level == AL_UDMA_IOFIC_LEVEL_PRIMARY) && (group >= 0) && (group < 4)) ||
552 		((level == AL_UDMA_IOFIC_LEVEL_SECONDARY) && (group >= 0) && (group < 2)))
553 		return 1;
554 
555 	return 0;
556 }
557 /**
558  * unmask specific interrupts for a given group
559  * this functions uses the interrupt mask clear register to guarantee atomicity
560  * it's safe to call it while the mask is changed by the HW (auto mask) or another cpu.
561  *
562  * @param regs pointer to udma unit registers
563  * @param level the interrupt controller level (primary / secondary)
564  * @param group the interrupt group ('AL_INT_GROUP_*')
565  * @param mask bitwise of interrupts to unmask, set bits will be unmasked.
566  */
567 static INLINE void al_udma_iofic_unmask(
568 	struct unit_regs __iomem	*regs,
569 	enum al_udma_iofic_level	level,
570 	int				group,
571 	uint32_t			mask)
572 {
573 	al_assert(al_udma_iofic_level_and_group_valid(level, group));
574 	al_iofic_unmask(al_udma_iofic_reg_base_get(regs, level), group, mask);
575 }
576 
577 /**
578  * mask specific interrupts for a given group
579  * this functions modifies interrupt mask register, the callee must make sure
580  * the mask is not changed by another cpu.
581  *
582  * @param regs pointer to udma unit registers
583  * @param level the interrupt controller level (primary / secondary)
584  * @param group the interrupt group ('AL_INT_GROUP_*')
585  * @param mask bitwise of interrupts to mask, set bits will be masked.
586  */
587 static INLINE void al_udma_iofic_mask(
588 	struct unit_regs __iomem	*regs,
589 	enum al_udma_iofic_level	level,
590 	int				group,
591 	uint32_t			mask)
592 {
593 	al_assert(al_udma_iofic_level_and_group_valid(level, group));
594 	al_iofic_mask(al_udma_iofic_reg_base_get(regs, level), group, mask);
595 }
596 
597 /**
598  * read interrupt cause register for a given group
599  * this will clear the set bits if the Clear on Read mode enabled.
600  * @param regs pointer to udma unit registers
601  * @param level the interrupt controller level (primary / secondary)
602  * @param group the interrupt group ('AL_INT_GROUP_*')
603  */
604 static INLINE uint32_t al_udma_iofic_read_cause(
605 	struct unit_regs __iomem	*regs,
606 	enum al_udma_iofic_level	level,
607 	int				group)
608 {
609 	al_assert(al_udma_iofic_level_and_group_valid(level, group));
610 	return al_iofic_read_cause(al_udma_iofic_reg_base_get(regs, level), group);
611 }
612 
613 /**
614  * clear bits in the interrupt cause register for a given group
615  *
616  * @param regs pointer to udma unit registers
617  * @param level the interrupt controller level (primary / secondary)
618  * @param group the interrupt group ('AL_INT_GROUP_*')
619  * @param mask bitwise of bits to be cleared, set bits will be cleared.
620  */
621 static INLINE void al_udma_iofic_clear_cause(
622 	struct unit_regs __iomem	*regs,
623 	enum al_udma_iofic_level	level,
624 	int				group,
625 	uint32_t		mask)
626 {
627 	al_assert(al_udma_iofic_level_and_group_valid(level, group));
628 	al_iofic_clear_cause(al_udma_iofic_reg_base_get(regs, level), group, mask);
629 }
630 
631 #endif
632 /** @} end of UDMA group */
633