~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/include/asm/mips-gic.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php