mips-gic.h 12 KB

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