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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.