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