mips-gic.h 11 KB

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