Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.14-rc5 391 lines 13 kB view raw
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 */ 17extern 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) \ 51static inline void __iomem *addr_gic_##name(unsigned int intr) \ 52{ \ 53 return mips_gic_base + (off) + (intr * (stride)); \ 54} \ 55 \ 56static 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 \ 66static 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) \ 97static inline void __iomem *addr_gic_##name(void) \ 98{ \ 99 return mips_gic_base + (off); \ 100} \ 101 \ 102static 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 \ 122static 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 \ 135static 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 */ 182GIC_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 */ 189GIC_ACCESSOR_RW(64, 0x010, counter) 190GIC_ACCESSOR_RW(32, 0x010, counter_32l) 191GIC_ACCESSOR_RW(32, 0x014, counter_32h) 192 193/* GIC_SH_POL_* - Configures interrupt polarity */ 194GIC_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 */ 201GIC_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 */ 206GIC_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 */ 211GIC_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 */ 216GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask) 217 218/* GIC_SH_SMASK_* - Set shared interrupt mask bits */ 219GIC_ACCESSOR_RW_INTR_BIT(0x380, smask) 220 221/* GIC_SH_MASK_* - Read the current shared interrupt mask */ 222GIC_ACCESSOR_RO_INTR_BIT(0x400, mask) 223 224/* GIC_SH_PEND_* - Read currently pending shared interrupts */ 225GIC_ACCESSOR_RO_INTR_BIT(0x480, pend) 226 227/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */ 228GIC_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 */ 234GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp) 235 236/* GIC_Vx_CTL - VP-level interrupt control */ 237GIC_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 */ 245GIC_VX_ACCESSOR_RO(32, 0x004, pend) 246 247/* GIC_Vx_MASK - Read the current local interrupt mask */ 248GIC_VX_ACCESSOR_RO(32, 0x008, mask) 249 250/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */ 251GIC_VX_ACCESSOR_RW(32, 0x00c, rmask) 252 253/* GIC_Vx_SMASK - Set local interrupt mask bits */ 254GIC_VX_ACCESSOR_RW(32, 0x010, smask) 255 256/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */ 257GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map) 258 259/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */ 260GIC_VX_ACCESSOR_RW(32, 0x040, wd_map) 261 262/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */ 263GIC_VX_ACCESSOR_RW(32, 0x044, compare_map) 264 265/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */ 266GIC_VX_ACCESSOR_RW(32, 0x048, timer_map) 267 268/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */ 269GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map) 270 271/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */ 272GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map) 273 274/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */ 275GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map) 276 277/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */ 278GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map) 279 280/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */ 281GIC_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 */ 285GIC_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 */ 289GIC_VX_ACCESSOR_RW(64, 0x0a0, compare) 290 291/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */ 292GIC_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 */ 307enum 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 */ 326static 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 */ 346static inline unsigned int 347mips_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 */ 369extern 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 */ 379extern 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 */ 389extern int gic_get_c0_fdc_int(void); 390 391#endif /* __MIPS_ASM_MIPS_CPS_H__ */