Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (C) 2017 Imagination Technologies
0004  * Author: Paul Burton <paul.burton@mips.com>
0005  */
0006 
0007 #ifndef __MIPS_ASM_MIPS_CPS_H__
0008 # error Please include asm/mips-cps.h rather than asm/mips-gic.h
0009 #endif
0010 
0011 #ifndef __MIPS_ASM_MIPS_GIC_H__
0012 #define __MIPS_ASM_MIPS_GIC_H__
0013 
0014 #include <linux/bitops.h>
0015 
0016 /* The base address of the GIC registers */
0017 extern void __iomem *mips_gic_base;
0018 
0019 /* Offsets from the GIC base address to various control blocks */
0020 #define MIPS_GIC_SHARED_OFS 0x00000
0021 #define MIPS_GIC_SHARED_SZ  0x08000
0022 #define MIPS_GIC_LOCAL_OFS  0x08000
0023 #define MIPS_GIC_LOCAL_SZ   0x04000
0024 #define MIPS_GIC_REDIR_OFS  0x0c000
0025 #define MIPS_GIC_REDIR_SZ   0x04000
0026 #define MIPS_GIC_USER_OFS   0x10000
0027 #define MIPS_GIC_USER_SZ    0x10000
0028 
0029 /* For read-only shared registers */
0030 #define GIC_ACCESSOR_RO(sz, off, name)                  \
0031     CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
0032 
0033 /* For read-write shared registers */
0034 #define GIC_ACCESSOR_RW(sz, off, name)                  \
0035     CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
0036 
0037 /* For read-only local registers */
0038 #define GIC_VX_ACCESSOR_RO(sz, off, name)               \
0039     CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)   \
0040     CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
0041 
0042 /* For read-write local registers */
0043 #define GIC_VX_ACCESSOR_RW(sz, off, name)               \
0044     CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)   \
0045     CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
0046 
0047 /* For read-only shared per-interrupt registers */
0048 #define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)         \
0049 static inline void __iomem *addr_gic_##name(unsigned int intr)      \
0050 {                                   \
0051     return mips_gic_base + (off) + (intr * (stride));       \
0052 }                                   \
0053                                     \
0054 static inline unsigned int read_gic_##name(unsigned int intr)       \
0055 {                                   \
0056     BUILD_BUG_ON(sz != 32);                     \
0057     return __raw_readl(addr_gic_##name(intr));          \
0058 }
0059 
0060 /* For read-write shared per-interrupt registers */
0061 #define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)         \
0062     GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)         \
0063                                     \
0064 static inline void write_gic_##name(unsigned int intr,          \
0065                     unsigned int val)           \
0066 {                                   \
0067     BUILD_BUG_ON(sz != 32);                     \
0068     __raw_writel(val, addr_gic_##name(intr));           \
0069 }
0070 
0071 /* For read-only local per-interrupt registers */
0072 #define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)      \
0073     GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,      \
0074                  stride, vl_##name)         \
0075     GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,      \
0076                  stride, vo_##name)
0077 
0078 /* For read-write local per-interrupt registers */
0079 #define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)      \
0080     GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,      \
0081                  stride, vl_##name)         \
0082     GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,      \
0083                  stride, vo_##name)
0084 
0085 /* For read-only shared bit-per-interrupt registers */
0086 #define GIC_ACCESSOR_RO_INTR_BIT(off, name)             \
0087 static inline void __iomem *addr_gic_##name(void)           \
0088 {                                   \
0089     return mips_gic_base + (off);                   \
0090 }                                   \
0091                                     \
0092 static inline unsigned int read_gic_##name(unsigned int intr)       \
0093 {                                   \
0094     void __iomem *addr = addr_gic_##name();             \
0095     unsigned int val;                       \
0096                                     \
0097     if (mips_cm_is64) {                     \
0098         addr += (intr / 64) * sizeof(uint64_t);         \
0099         val = __raw_readq(addr) >> intr % 64;           \
0100     } else {                            \
0101         addr += (intr / 32) * sizeof(uint32_t);         \
0102         val = __raw_readl(addr) >> intr % 32;           \
0103     }                               \
0104                                     \
0105     return val & 0x1;                       \
0106 }
0107 
0108 /* For read-write shared bit-per-interrupt registers */
0109 #define GIC_ACCESSOR_RW_INTR_BIT(off, name)             \
0110     GIC_ACCESSOR_RO_INTR_BIT(off, name)             \
0111                                     \
0112 static inline void write_gic_##name(unsigned int intr)          \
0113 {                                   \
0114     void __iomem *addr = addr_gic_##name();             \
0115                                     \
0116     if (mips_cm_is64) {                     \
0117         addr += (intr / 64) * sizeof(uint64_t);         \
0118         __raw_writeq(BIT(intr % 64), addr);         \
0119     } else {                            \
0120         addr += (intr / 32) * sizeof(uint32_t);         \
0121         __raw_writel(BIT(intr % 32), addr);         \
0122     }                               \
0123 }                                   \
0124                                     \
0125 static inline void change_gic_##name(unsigned int intr,         \
0126                      unsigned int val)          \
0127 {                                   \
0128     void __iomem *addr = addr_gic_##name();             \
0129                                     \
0130     if (mips_cm_is64) {                     \
0131         uint64_t _val;                      \
0132                                     \
0133         addr += (intr / 64) * sizeof(uint64_t);         \
0134         _val = __raw_readq(addr);               \
0135         _val &= ~BIT_ULL(intr % 64);                \
0136         _val |= (uint64_t)val << (intr % 64);           \
0137         __raw_writeq(_val, addr);               \
0138     } else {                            \
0139         uint32_t _val;                      \
0140                                     \
0141         addr += (intr / 32) * sizeof(uint32_t);         \
0142         _val = __raw_readl(addr);               \
0143         _val &= ~BIT(intr % 32);                \
0144         _val |= val << (intr % 32);             \
0145         __raw_writel(_val, addr);               \
0146     }                               \
0147 }
0148 
0149 /* For read-only local bit-per-interrupt registers */
0150 #define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name)          \
0151     GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,      \
0152                  vl_##name)             \
0153     GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,      \
0154                  vo_##name)
0155 
0156 /* For read-write local bit-per-interrupt registers */
0157 #define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name)          \
0158     GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,      \
0159                  vl_##name)             \
0160     GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,      \
0161                  vo_##name)
0162 
0163 /* GIC_SH_CONFIG - Information about the GIC configuration */
0164 GIC_ACCESSOR_RW(32, 0x000, config)
0165 #define GIC_CONFIG_COUNTSTOP        BIT(28)
0166 #define GIC_CONFIG_COUNTBITS        GENMASK(27, 24)
0167 #define GIC_CONFIG_NUMINTERRUPTS    GENMASK(23, 16)
0168 #define GIC_CONFIG_PVPS         GENMASK(6, 0)
0169 
0170 /* GIC_SH_COUNTER - Shared global counter value */
0171 GIC_ACCESSOR_RW(64, 0x010, counter)
0172 GIC_ACCESSOR_RW(32, 0x010, counter_32l)
0173 GIC_ACCESSOR_RW(32, 0x014, counter_32h)
0174 
0175 /* GIC_SH_POL_* - Configures interrupt polarity */
0176 GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
0177 #define GIC_POL_ACTIVE_LOW      0   /* when level triggered */
0178 #define GIC_POL_ACTIVE_HIGH     1   /* when level triggered */
0179 #define GIC_POL_FALLING_EDGE        0   /* when single-edge triggered */
0180 #define GIC_POL_RISING_EDGE     1   /* when single-edge triggered */
0181 
0182 /* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
0183 GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
0184 #define GIC_TRIG_LEVEL          0
0185 #define GIC_TRIG_EDGE           1
0186 
0187 /* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
0188 GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
0189 #define GIC_DUAL_SINGLE         0   /* when edge-triggered */
0190 #define GIC_DUAL_DUAL           1   /* when edge-triggered */
0191 
0192 /* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
0193 GIC_ACCESSOR_RW(32, 0x280, wedge)
0194 #define GIC_WEDGE_RW            BIT(31)
0195 #define GIC_WEDGE_INTR          GENMASK(7, 0)
0196 
0197 /* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
0198 GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
0199 
0200 /* GIC_SH_SMASK_* - Set shared interrupt mask bits */
0201 GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
0202 
0203 /* GIC_SH_MASK_* - Read the current shared interrupt mask */
0204 GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
0205 
0206 /* GIC_SH_PEND_* - Read currently pending shared interrupts */
0207 GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
0208 
0209 /* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
0210 GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
0211 #define GIC_MAP_PIN_MAP_TO_PIN      BIT(31)
0212 #define GIC_MAP_PIN_MAP_TO_NMI      BIT(30)
0213 #define GIC_MAP_PIN_MAP         GENMASK(5, 0)
0214 
0215 /* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
0216 GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
0217 
0218 /* GIC_Vx_CTL - VP-level interrupt control */
0219 GIC_VX_ACCESSOR_RW(32, 0x000, ctl)
0220 #define GIC_VX_CTL_FDC_ROUTABLE     BIT(4)
0221 #define GIC_VX_CTL_SWINT_ROUTABLE   BIT(3)
0222 #define GIC_VX_CTL_PERFCNT_ROUTABLE BIT(2)
0223 #define GIC_VX_CTL_TIMER_ROUTABLE   BIT(1)
0224 #define GIC_VX_CTL_EIC          BIT(0)
0225 
0226 /* GIC_Vx_PEND - Read currently pending local interrupts */
0227 GIC_VX_ACCESSOR_RO(32, 0x004, pend)
0228 
0229 /* GIC_Vx_MASK - Read the current local interrupt mask */
0230 GIC_VX_ACCESSOR_RO(32, 0x008, mask)
0231 
0232 /* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
0233 GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
0234 
0235 /* GIC_Vx_SMASK - Set local interrupt mask bits */
0236 GIC_VX_ACCESSOR_RW(32, 0x010, smask)
0237 
0238 /* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
0239 GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
0240 
0241 /* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
0242 GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
0243 
0244 /* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
0245 GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
0246 
0247 /* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
0248 GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
0249 
0250 /* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
0251 GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
0252 
0253 /* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
0254 GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
0255 
0256 /* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
0257 GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
0258 
0259 /* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
0260 GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
0261 
0262 /* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
0263 GIC_VX_ACCESSOR_RW(32, 0x080, other)
0264 #define GIC_VX_OTHER_VPNUM      GENMASK(5, 0)
0265 
0266 /* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
0267 GIC_VX_ACCESSOR_RO(32, 0x088, ident)
0268 #define GIC_VX_IDENT_VPNUM      GENMASK(5, 0)
0269 
0270 /* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
0271 GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
0272 
0273 /* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
0274 GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
0275 
0276 /**
0277  * enum mips_gic_local_interrupt - GIC local interrupts
0278  * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
0279  * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
0280  * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
0281  * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
0282  * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
0283  * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
0284  * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
0285  * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
0286  *
0287  * Enumerates interrupts provided by the GIC that are local to a VP.
0288  */
0289 enum mips_gic_local_interrupt {
0290     GIC_LOCAL_INT_WD,
0291     GIC_LOCAL_INT_COMPARE,
0292     GIC_LOCAL_INT_TIMER,
0293     GIC_LOCAL_INT_PERFCTR,
0294     GIC_LOCAL_INT_SWINT0,
0295     GIC_LOCAL_INT_SWINT1,
0296     GIC_LOCAL_INT_FDC,
0297     GIC_NUM_LOCAL_INTRS
0298 };
0299 
0300 /**
0301  * mips_gic_present() - Determine whether a GIC is present
0302  *
0303  * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
0304  * the system that the kernel is running on.
0305  *
0306  * Return true if a GIC is present, else false.
0307  */
0308 static inline bool mips_gic_present(void)
0309 {
0310     return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
0311 }
0312 
0313 /**
0314  * mips_gic_vx_map_reg() - Return GIC_Vx_<intr>_MAP register offset
0315  * @intr: A GIC local interrupt
0316  *
0317  * Determine the index of the GIC_VL_<intr>_MAP or GIC_VO_<intr>_MAP register
0318  * within the block of GIC map registers. This is almost the same as the order
0319  * of interrupts in the pending & mask registers, as used by enum
0320  * mips_gic_local_interrupt, but moves the FDC interrupt & thus offsets the
0321  * interrupts after it...
0322  *
0323  * Return: The map register index corresponding to @intr.
0324  *
0325  * The return value is suitable for use with the (read|write)_gic_v[lo]_map
0326  * accessor functions.
0327  */
0328 static inline unsigned int
0329 mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr)
0330 {
0331     /* WD, Compare & Timer are 1:1 */
0332     if (intr <= GIC_LOCAL_INT_TIMER)
0333         return intr;
0334 
0335     /* FDC moves to after Timer... */
0336     if (intr == GIC_LOCAL_INT_FDC)
0337         return GIC_LOCAL_INT_TIMER + 1;
0338 
0339     /* As a result everything else is offset by 1 */
0340     return intr + 1;
0341 }
0342 
0343 /**
0344  * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
0345  *
0346  * Determine the virq number to use for the coprocessor 0 count/compare
0347  * interrupt, which may be routed via the GIC.
0348  *
0349  * Returns the virq number or a negative error number.
0350  */
0351 extern int gic_get_c0_compare_int(void);
0352 
0353 /**
0354  * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
0355  *
0356  * Determine the virq number to use for CPU performance counter interrupts,
0357  * which may be routed via the GIC.
0358  *
0359  * Returns the virq number or a negative error number.
0360  */
0361 extern int gic_get_c0_perfcount_int(void);
0362 
0363 /**
0364  * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
0365  *
0366  * Determine the virq number to use for fast debug channel (FDC) interrupts,
0367  * which may be routed via the GIC.
0368  *
0369  * Returns the virq number or a negative error number.
0370  */
0371 extern int gic_get_c0_fdc_int(void);
0372 
0373 #endif /* __MIPS_ASM_MIPS_CPS_H__ */