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