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 v4.15 347 lines 12 kB view raw
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 */ 21extern 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) \ 53static inline void __iomem *addr_gic_##name(unsigned int intr) \ 54{ \ 55 return mips_gic_base + (off) + (intr * (stride)); \ 56} \ 57 \ 58static 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 \ 68static 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) \ 91static inline void __iomem *addr_gic_##name(void) \ 92{ \ 93 return mips_gic_base + (off); \ 94} \ 95 \ 96static 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 \ 116static 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 \ 129static 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 */ 168GIC_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 */ 175GIC_ACCESSOR_RW(64, 0x010, counter) 176GIC_ACCESSOR_RW(32, 0x010, counter_32l) 177GIC_ACCESSOR_RW(32, 0x014, counter_32h) 178 179/* GIC_SH_POL_* - Configures interrupt polarity */ 180GIC_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 */ 187GIC_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 */ 192GIC_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 */ 197GIC_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 */ 202GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask) 203 204/* GIC_SH_SMASK_* - Set shared interrupt mask bits */ 205GIC_ACCESSOR_RW_INTR_BIT(0x380, smask) 206 207/* GIC_SH_MASK_* - Read the current shared interrupt mask */ 208GIC_ACCESSOR_RO_INTR_BIT(0x400, mask) 209 210/* GIC_SH_PEND_* - Read currently pending shared interrupts */ 211GIC_ACCESSOR_RO_INTR_BIT(0x480, pend) 212 213/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */ 214GIC_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 */ 220GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp) 221 222/* GIC_Vx_CTL - VP-level interrupt control */ 223GIC_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 */ 231GIC_VX_ACCESSOR_RO(32, 0x004, pend) 232 233/* GIC_Vx_MASK - Read the current local interrupt mask */ 234GIC_VX_ACCESSOR_RO(32, 0x008, mask) 235 236/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */ 237GIC_VX_ACCESSOR_RW(32, 0x00c, rmask) 238 239/* GIC_Vx_SMASK - Set local interrupt mask bits */ 240GIC_VX_ACCESSOR_RW(32, 0x010, smask) 241 242/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */ 243GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map) 244 245/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */ 246GIC_VX_ACCESSOR_RW(32, 0x040, wd_map) 247 248/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */ 249GIC_VX_ACCESSOR_RW(32, 0x044, compare_map) 250 251/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */ 252GIC_VX_ACCESSOR_RW(32, 0x048, timer_map) 253 254/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */ 255GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map) 256 257/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */ 258GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map) 259 260/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */ 261GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map) 262 263/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */ 264GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map) 265 266/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */ 267GIC_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 */ 271GIC_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 */ 275GIC_VX_ACCESSOR_RW(64, 0x0a0, compare) 276 277/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */ 278GIC_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 */ 293enum 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 */ 312static 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 */ 325extern 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 */ 335extern 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 */ 345extern int gic_get_c0_fdc_int(void); 346 347#endif /* __MIPS_ASM_MIPS_CPS_H__ */