0001
0002
0003
0004
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
0017 extern void __iomem *mips_gic_base;
0018
0019
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
0030 #define GIC_ACCESSOR_RO(sz, off, name) \
0031 CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
0032
0033
0034 #define GIC_ACCESSOR_RW(sz, off, name) \
0035 CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
0036
0037
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
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
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
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
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
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
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
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
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
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
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
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
0176 GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
0177 #define GIC_POL_ACTIVE_LOW 0
0178 #define GIC_POL_ACTIVE_HIGH 1
0179 #define GIC_POL_FALLING_EDGE 0
0180 #define GIC_POL_RISING_EDGE 1
0181
0182
0183 GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
0184 #define GIC_TRIG_LEVEL 0
0185 #define GIC_TRIG_EDGE 1
0186
0187
0188 GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
0189 #define GIC_DUAL_SINGLE 0
0190 #define GIC_DUAL_DUAL 1
0191
0192
0193 GIC_ACCESSOR_RW(32, 0x280, wedge)
0194 #define GIC_WEDGE_RW BIT(31)
0195 #define GIC_WEDGE_INTR GENMASK(7, 0)
0196
0197
0198 GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
0199
0200
0201 GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
0202
0203
0204 GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
0205
0206
0207 GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
0208
0209
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
0216 GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
0217
0218
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
0227 GIC_VX_ACCESSOR_RO(32, 0x004, pend)
0228
0229
0230 GIC_VX_ACCESSOR_RO(32, 0x008, mask)
0231
0232
0233 GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
0234
0235
0236 GIC_VX_ACCESSOR_RW(32, 0x010, smask)
0237
0238
0239 GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
0240
0241
0242 GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
0243
0244
0245 GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
0246
0247
0248 GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
0249
0250
0251 GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
0252
0253
0254 GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
0255
0256
0257 GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
0258
0259
0260 GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
0261
0262
0263 GIC_VX_ACCESSOR_RW(32, 0x080, other)
0264 #define GIC_VX_OTHER_VPNUM GENMASK(5, 0)
0265
0266
0267 GIC_VX_ACCESSOR_RO(32, 0x088, ident)
0268 #define GIC_VX_IDENT_VPNUM GENMASK(5, 0)
0269
0270
0271 GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
0272
0273
0274 GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
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
0302
0303
0304
0305
0306
0307
0308 static inline bool mips_gic_present(void)
0309 {
0310 return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 static inline unsigned int
0329 mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr)
0330 {
0331
0332 if (intr <= GIC_LOCAL_INT_TIMER)
0333 return intr;
0334
0335
0336 if (intr == GIC_LOCAL_INT_FDC)
0337 return GIC_LOCAL_INT_TIMER + 1;
0338
0339
0340 return intr + 1;
0341 }
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 extern int gic_get_c0_compare_int(void);
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 extern int gic_get_c0_perfcount_int(void);
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 extern int gic_get_c0_fdc_int(void);
0372
0373 #endif