xref: /OK3568_Linux_fs/kernel/arch/mips/include/asm/mips-gic.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2017 Imagination Technologies
4*4882a593Smuzhiyun  * Author: Paul Burton <paul.burton@mips.com>
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef __MIPS_ASM_MIPS_CPS_H__
8*4882a593Smuzhiyun # error Please include asm/mips-cps.h rather than asm/mips-gic.h
9*4882a593Smuzhiyun #endif
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #ifndef __MIPS_ASM_MIPS_GIC_H__
12*4882a593Smuzhiyun #define __MIPS_ASM_MIPS_GIC_H__
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/bitops.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /* The base address of the GIC registers */
17*4882a593Smuzhiyun extern void __iomem *mips_gic_base;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Offsets from the GIC base address to various control blocks */
20*4882a593Smuzhiyun #define MIPS_GIC_SHARED_OFS	0x00000
21*4882a593Smuzhiyun #define MIPS_GIC_SHARED_SZ	0x08000
22*4882a593Smuzhiyun #define MIPS_GIC_LOCAL_OFS	0x08000
23*4882a593Smuzhiyun #define MIPS_GIC_LOCAL_SZ	0x04000
24*4882a593Smuzhiyun #define MIPS_GIC_REDIR_OFS	0x0c000
25*4882a593Smuzhiyun #define MIPS_GIC_REDIR_SZ	0x04000
26*4882a593Smuzhiyun #define MIPS_GIC_USER_OFS	0x10000
27*4882a593Smuzhiyun #define MIPS_GIC_USER_SZ	0x10000
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* For read-only shared registers */
30*4882a593Smuzhiyun #define GIC_ACCESSOR_RO(sz, off, name)					\
31*4882a593Smuzhiyun 	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* For read-write shared registers */
34*4882a593Smuzhiyun #define GIC_ACCESSOR_RW(sz, off, name)					\
35*4882a593Smuzhiyun 	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* For read-only local registers */
38*4882a593Smuzhiyun #define GIC_VX_ACCESSOR_RO(sz, off, name)				\
39*4882a593Smuzhiyun 	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
40*4882a593Smuzhiyun 	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* For read-write local registers */
43*4882a593Smuzhiyun #define GIC_VX_ACCESSOR_RW(sz, off, name)				\
44*4882a593Smuzhiyun 	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
45*4882a593Smuzhiyun 	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* For read-only shared per-interrupt registers */
48*4882a593Smuzhiyun #define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
49*4882a593Smuzhiyun static inline void __iomem *addr_gic_##name(unsigned int intr)		\
50*4882a593Smuzhiyun {									\
51*4882a593Smuzhiyun 	return mips_gic_base + (off) + (intr * (stride));		\
52*4882a593Smuzhiyun }									\
53*4882a593Smuzhiyun 									\
54*4882a593Smuzhiyun static inline unsigned int read_gic_##name(unsigned int intr)		\
55*4882a593Smuzhiyun {									\
56*4882a593Smuzhiyun 	BUILD_BUG_ON(sz != 32);						\
57*4882a593Smuzhiyun 	return __raw_readl(addr_gic_##name(intr));			\
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /* For read-write shared per-interrupt registers */
61*4882a593Smuzhiyun #define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
62*4882a593Smuzhiyun 	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
63*4882a593Smuzhiyun 									\
64*4882a593Smuzhiyun static inline void write_gic_##name(unsigned int intr,			\
65*4882a593Smuzhiyun 				    unsigned int val)			\
66*4882a593Smuzhiyun {									\
67*4882a593Smuzhiyun 	BUILD_BUG_ON(sz != 32);						\
68*4882a593Smuzhiyun 	__raw_writel(val, addr_gic_##name(intr));			\
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /* For read-only local per-interrupt registers */
72*4882a593Smuzhiyun #define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
73*4882a593Smuzhiyun 	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
74*4882a593Smuzhiyun 				 stride, vl_##name)			\
75*4882a593Smuzhiyun 	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
76*4882a593Smuzhiyun 				 stride, vo_##name)
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* For read-write local per-interrupt registers */
79*4882a593Smuzhiyun #define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
80*4882a593Smuzhiyun 	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
81*4882a593Smuzhiyun 				 stride, vl_##name)			\
82*4882a593Smuzhiyun 	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
83*4882a593Smuzhiyun 				 stride, vo_##name)
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /* For read-only shared bit-per-interrupt registers */
86*4882a593Smuzhiyun #define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
87*4882a593Smuzhiyun static inline void __iomem *addr_gic_##name(void)			\
88*4882a593Smuzhiyun {									\
89*4882a593Smuzhiyun 	return mips_gic_base + (off);					\
90*4882a593Smuzhiyun }									\
91*4882a593Smuzhiyun 									\
92*4882a593Smuzhiyun static inline unsigned int read_gic_##name(unsigned int intr)		\
93*4882a593Smuzhiyun {									\
94*4882a593Smuzhiyun 	void __iomem *addr = addr_gic_##name();				\
95*4882a593Smuzhiyun 	unsigned int val;						\
96*4882a593Smuzhiyun 									\
97*4882a593Smuzhiyun 	if (mips_cm_is64) {						\
98*4882a593Smuzhiyun 		addr += (intr / 64) * sizeof(uint64_t);			\
99*4882a593Smuzhiyun 		val = __raw_readq(addr) >> intr % 64;			\
100*4882a593Smuzhiyun 	} else {							\
101*4882a593Smuzhiyun 		addr += (intr / 32) * sizeof(uint32_t);			\
102*4882a593Smuzhiyun 		val = __raw_readl(addr) >> intr % 32;			\
103*4882a593Smuzhiyun 	}								\
104*4882a593Smuzhiyun 									\
105*4882a593Smuzhiyun 	return val & 0x1;						\
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun /* For read-write shared bit-per-interrupt registers */
109*4882a593Smuzhiyun #define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
110*4882a593Smuzhiyun 	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
111*4882a593Smuzhiyun 									\
112*4882a593Smuzhiyun static inline void write_gic_##name(unsigned int intr)			\
113*4882a593Smuzhiyun {									\
114*4882a593Smuzhiyun 	void __iomem *addr = addr_gic_##name();				\
115*4882a593Smuzhiyun 									\
116*4882a593Smuzhiyun 	if (mips_cm_is64) {						\
117*4882a593Smuzhiyun 		addr += (intr / 64) * sizeof(uint64_t);			\
118*4882a593Smuzhiyun 		__raw_writeq(BIT(intr % 64), addr);			\
119*4882a593Smuzhiyun 	} else {							\
120*4882a593Smuzhiyun 		addr += (intr / 32) * sizeof(uint32_t);			\
121*4882a593Smuzhiyun 		__raw_writel(BIT(intr % 32), addr);			\
122*4882a593Smuzhiyun 	}								\
123*4882a593Smuzhiyun }									\
124*4882a593Smuzhiyun 									\
125*4882a593Smuzhiyun static inline void change_gic_##name(unsigned int intr,			\
126*4882a593Smuzhiyun 				     unsigned int val)			\
127*4882a593Smuzhiyun {									\
128*4882a593Smuzhiyun 	void __iomem *addr = addr_gic_##name();				\
129*4882a593Smuzhiyun 									\
130*4882a593Smuzhiyun 	if (mips_cm_is64) {						\
131*4882a593Smuzhiyun 		uint64_t _val;						\
132*4882a593Smuzhiyun 									\
133*4882a593Smuzhiyun 		addr += (intr / 64) * sizeof(uint64_t);			\
134*4882a593Smuzhiyun 		_val = __raw_readq(addr);				\
135*4882a593Smuzhiyun 		_val &= ~BIT_ULL(intr % 64);				\
136*4882a593Smuzhiyun 		_val |= (uint64_t)val << (intr % 64);			\
137*4882a593Smuzhiyun 		__raw_writeq(_val, addr);				\
138*4882a593Smuzhiyun 	} else {							\
139*4882a593Smuzhiyun 		uint32_t _val;						\
140*4882a593Smuzhiyun 									\
141*4882a593Smuzhiyun 		addr += (intr / 32) * sizeof(uint32_t);			\
142*4882a593Smuzhiyun 		_val = __raw_readl(addr);				\
143*4882a593Smuzhiyun 		_val &= ~BIT(intr % 32);				\
144*4882a593Smuzhiyun 		_val |= val << (intr % 32);				\
145*4882a593Smuzhiyun 		__raw_writel(_val, addr);				\
146*4882a593Smuzhiyun 	}								\
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /* For read-only local bit-per-interrupt registers */
150*4882a593Smuzhiyun #define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name)			\
151*4882a593Smuzhiyun 	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
152*4882a593Smuzhiyun 				 vl_##name)				\
153*4882a593Smuzhiyun 	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
154*4882a593Smuzhiyun 				 vo_##name)
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun /* For read-write local bit-per-interrupt registers */
157*4882a593Smuzhiyun #define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name)			\
158*4882a593Smuzhiyun 	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
159*4882a593Smuzhiyun 				 vl_##name)				\
160*4882a593Smuzhiyun 	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
161*4882a593Smuzhiyun 				 vo_##name)
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun /* GIC_SH_CONFIG - Information about the GIC configuration */
164*4882a593Smuzhiyun GIC_ACCESSOR_RW(32, 0x000, config)
165*4882a593Smuzhiyun #define GIC_CONFIG_COUNTSTOP		BIT(28)
166*4882a593Smuzhiyun #define GIC_CONFIG_COUNTBITS		GENMASK(27, 24)
167*4882a593Smuzhiyun #define GIC_CONFIG_NUMINTERRUPTS	GENMASK(23, 16)
168*4882a593Smuzhiyun #define GIC_CONFIG_PVPS			GENMASK(6, 0)
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun /* GIC_SH_COUNTER - Shared global counter value */
171*4882a593Smuzhiyun GIC_ACCESSOR_RW(64, 0x010, counter)
172*4882a593Smuzhiyun GIC_ACCESSOR_RW(32, 0x010, counter_32l)
173*4882a593Smuzhiyun GIC_ACCESSOR_RW(32, 0x014, counter_32h)
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun /* GIC_SH_POL_* - Configures interrupt polarity */
176*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
177*4882a593Smuzhiyun #define GIC_POL_ACTIVE_LOW		0	/* when level triggered */
178*4882a593Smuzhiyun #define GIC_POL_ACTIVE_HIGH		1	/* when level triggered */
179*4882a593Smuzhiyun #define GIC_POL_FALLING_EDGE		0	/* when single-edge triggered */
180*4882a593Smuzhiyun #define GIC_POL_RISING_EDGE		1	/* when single-edge triggered */
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun /* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
183*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
184*4882a593Smuzhiyun #define GIC_TRIG_LEVEL			0
185*4882a593Smuzhiyun #define GIC_TRIG_EDGE			1
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun /* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
188*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
189*4882a593Smuzhiyun #define GIC_DUAL_SINGLE			0	/* when edge-triggered */
190*4882a593Smuzhiyun #define GIC_DUAL_DUAL			1	/* when edge-triggered */
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun /* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
193*4882a593Smuzhiyun GIC_ACCESSOR_RW(32, 0x280, wedge)
194*4882a593Smuzhiyun #define GIC_WEDGE_RW			BIT(31)
195*4882a593Smuzhiyun #define GIC_WEDGE_INTR			GENMASK(7, 0)
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun /* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
198*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun /* GIC_SH_SMASK_* - Set shared interrupt mask bits */
201*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /* GIC_SH_MASK_* - Read the current shared interrupt mask */
204*4882a593Smuzhiyun GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun /* GIC_SH_PEND_* - Read currently pending shared interrupts */
207*4882a593Smuzhiyun GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun /* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
210*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
211*4882a593Smuzhiyun #define GIC_MAP_PIN_MAP_TO_PIN		BIT(31)
212*4882a593Smuzhiyun #define GIC_MAP_PIN_MAP_TO_NMI		BIT(30)
213*4882a593Smuzhiyun #define GIC_MAP_PIN_MAP			GENMASK(5, 0)
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun /* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
216*4882a593Smuzhiyun GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun /* GIC_Vx_CTL - VP-level interrupt control */
219*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x000, ctl)
220*4882a593Smuzhiyun #define GIC_VX_CTL_FDC_ROUTABLE		BIT(4)
221*4882a593Smuzhiyun #define GIC_VX_CTL_SWINT_ROUTABLE	BIT(3)
222*4882a593Smuzhiyun #define GIC_VX_CTL_PERFCNT_ROUTABLE	BIT(2)
223*4882a593Smuzhiyun #define GIC_VX_CTL_TIMER_ROUTABLE	BIT(1)
224*4882a593Smuzhiyun #define GIC_VX_CTL_EIC			BIT(0)
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /* GIC_Vx_PEND - Read currently pending local interrupts */
227*4882a593Smuzhiyun GIC_VX_ACCESSOR_RO(32, 0x004, pend)
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun /* GIC_Vx_MASK - Read the current local interrupt mask */
230*4882a593Smuzhiyun GIC_VX_ACCESSOR_RO(32, 0x008, mask)
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun /* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
233*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun /* GIC_Vx_SMASK - Set local interrupt mask bits */
236*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x010, smask)
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
239*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun /* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
242*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun /* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
245*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun /* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
248*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun /* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
251*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun /* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
254*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun /* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
257*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun /* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
260*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun /* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
263*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(32, 0x080, other)
264*4882a593Smuzhiyun #define GIC_VX_OTHER_VPNUM		GENMASK(5, 0)
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun /* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
267*4882a593Smuzhiyun GIC_VX_ACCESSOR_RO(32, 0x088, ident)
268*4882a593Smuzhiyun #define GIC_VX_IDENT_VPNUM		GENMASK(5, 0)
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun /* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
271*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun /* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
274*4882a593Smuzhiyun GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun /**
277*4882a593Smuzhiyun  * enum mips_gic_local_interrupt - GIC local interrupts
278*4882a593Smuzhiyun  * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
279*4882a593Smuzhiyun  * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
280*4882a593Smuzhiyun  * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
281*4882a593Smuzhiyun  * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
282*4882a593Smuzhiyun  * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
283*4882a593Smuzhiyun  * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
284*4882a593Smuzhiyun  * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
285*4882a593Smuzhiyun  * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
286*4882a593Smuzhiyun  *
287*4882a593Smuzhiyun  * Enumerates interrupts provided by the GIC that are local to a VP.
288*4882a593Smuzhiyun  */
289*4882a593Smuzhiyun enum mips_gic_local_interrupt {
290*4882a593Smuzhiyun 	GIC_LOCAL_INT_WD,
291*4882a593Smuzhiyun 	GIC_LOCAL_INT_COMPARE,
292*4882a593Smuzhiyun 	GIC_LOCAL_INT_TIMER,
293*4882a593Smuzhiyun 	GIC_LOCAL_INT_PERFCTR,
294*4882a593Smuzhiyun 	GIC_LOCAL_INT_SWINT0,
295*4882a593Smuzhiyun 	GIC_LOCAL_INT_SWINT1,
296*4882a593Smuzhiyun 	GIC_LOCAL_INT_FDC,
297*4882a593Smuzhiyun 	GIC_NUM_LOCAL_INTRS
298*4882a593Smuzhiyun };
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun /**
301*4882a593Smuzhiyun  * mips_gic_present() - Determine whether a GIC is present
302*4882a593Smuzhiyun  *
303*4882a593Smuzhiyun  * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
304*4882a593Smuzhiyun  * the system that the kernel is running on.
305*4882a593Smuzhiyun  *
306*4882a593Smuzhiyun  * Return true if a GIC is present, else false.
307*4882a593Smuzhiyun  */
mips_gic_present(void)308*4882a593Smuzhiyun static inline bool mips_gic_present(void)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun 	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun /**
314*4882a593Smuzhiyun  * mips_gic_vx_map_reg() - Return GIC_Vx_<intr>_MAP register offset
315*4882a593Smuzhiyun  * @intr: A GIC local interrupt
316*4882a593Smuzhiyun  *
317*4882a593Smuzhiyun  * Determine the index of the GIC_VL_<intr>_MAP or GIC_VO_<intr>_MAP register
318*4882a593Smuzhiyun  * within the block of GIC map registers. This is almost the same as the order
319*4882a593Smuzhiyun  * of interrupts in the pending & mask registers, as used by enum
320*4882a593Smuzhiyun  * mips_gic_local_interrupt, but moves the FDC interrupt & thus offsets the
321*4882a593Smuzhiyun  * interrupts after it...
322*4882a593Smuzhiyun  *
323*4882a593Smuzhiyun  * Return: The map register index corresponding to @intr.
324*4882a593Smuzhiyun  *
325*4882a593Smuzhiyun  * The return value is suitable for use with the (read|write)_gic_v[lo]_map
326*4882a593Smuzhiyun  * accessor functions.
327*4882a593Smuzhiyun  */
328*4882a593Smuzhiyun static inline unsigned int
mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr)329*4882a593Smuzhiyun mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	/* WD, Compare & Timer are 1:1 */
332*4882a593Smuzhiyun 	if (intr <= GIC_LOCAL_INT_TIMER)
333*4882a593Smuzhiyun 		return intr;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	/* FDC moves to after Timer... */
336*4882a593Smuzhiyun 	if (intr == GIC_LOCAL_INT_FDC)
337*4882a593Smuzhiyun 		return GIC_LOCAL_INT_TIMER + 1;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	/* As a result everything else is offset by 1 */
340*4882a593Smuzhiyun 	return intr + 1;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun /**
344*4882a593Smuzhiyun  * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
345*4882a593Smuzhiyun  *
346*4882a593Smuzhiyun  * Determine the virq number to use for the coprocessor 0 count/compare
347*4882a593Smuzhiyun  * interrupt, which may be routed via the GIC.
348*4882a593Smuzhiyun  *
349*4882a593Smuzhiyun  * Returns the virq number or a negative error number.
350*4882a593Smuzhiyun  */
351*4882a593Smuzhiyun extern int gic_get_c0_compare_int(void);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun /**
354*4882a593Smuzhiyun  * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
355*4882a593Smuzhiyun  *
356*4882a593Smuzhiyun  * Determine the virq number to use for CPU performance counter interrupts,
357*4882a593Smuzhiyun  * which may be routed via the GIC.
358*4882a593Smuzhiyun  *
359*4882a593Smuzhiyun  * Returns the virq number or a negative error number.
360*4882a593Smuzhiyun  */
361*4882a593Smuzhiyun extern int gic_get_c0_perfcount_int(void);
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun /**
364*4882a593Smuzhiyun  * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
365*4882a593Smuzhiyun  *
366*4882a593Smuzhiyun  * Determine the virq number to use for fast debug channel (FDC) interrupts,
367*4882a593Smuzhiyun  * which may be routed via the GIC.
368*4882a593Smuzhiyun  *
369*4882a593Smuzhiyun  * Returns the virq number or a negative error number.
370*4882a593Smuzhiyun  */
371*4882a593Smuzhiyun extern int gic_get_c0_fdc_int(void);
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun #endif /* __MIPS_ASM_MIPS_CPS_H__ */
374