| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* |
| 3 | * Copyright (C) 2025 ARM Limited, All Rights Reserved. |
| 4 | */ |
| 5 | #ifndef __LINUX_IRQCHIP_ARM_GIC_V5_H |
| 6 | #define __LINUX_IRQCHIP_ARM_GIC_V5_H |
| 7 | |
| 8 | #include <linux/iopoll.h> |
| 9 | |
| 10 | #include <asm/cacheflush.h> |
| 11 | #include <asm/smp.h> |
| 12 | #include <asm/sysreg.h> |
| 13 | |
| 14 | #define GICV5_IPIS_PER_CPU MAX_IPI |
| 15 | |
| 16 | /* |
| 17 | * INTID handling |
| 18 | */ |
| 19 | #define GICV5_HWIRQ_ID GENMASK(23, 0) |
| 20 | #define GICV5_HWIRQ_TYPE GENMASK(31, 29) |
| 21 | #define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) |
| 22 | |
| 23 | #define GICV5_HWIRQ_TYPE_PPI UL(0x1) |
| 24 | #define GICV5_HWIRQ_TYPE_LPI UL(0x2) |
| 25 | #define GICV5_HWIRQ_TYPE_SPI UL(0x3) |
| 26 | |
| 27 | /* |
| 28 | * Tables attributes |
| 29 | */ |
| 30 | #define GICV5_NO_READ_ALLOC 0b0 |
| 31 | #define GICV5_READ_ALLOC 0b1 |
| 32 | #define GICV5_NO_WRITE_ALLOC 0b0 |
| 33 | #define GICV5_WRITE_ALLOC 0b1 |
| 34 | |
| 35 | #define GICV5_NON_CACHE 0b00 |
| 36 | #define GICV5_WB_CACHE 0b01 |
| 37 | #define GICV5_WT_CACHE 0b10 |
| 38 | |
| 39 | #define GICV5_NON_SHARE 0b00 |
| 40 | #define GICV5_OUTER_SHARE 0b10 |
| 41 | #define GICV5_INNER_SHARE 0b11 |
| 42 | |
| 43 | /* |
| 44 | * IRS registers and tables structures |
| 45 | */ |
| 46 | #define GICV5_IRS_IDR1 0x0004 |
| 47 | #define GICV5_IRS_IDR2 0x0008 |
| 48 | #define GICV5_IRS_IDR5 0x0014 |
| 49 | #define GICV5_IRS_IDR6 0x0018 |
| 50 | #define GICV5_IRS_IDR7 0x001c |
| 51 | #define GICV5_IRS_CR0 0x0080 |
| 52 | #define GICV5_IRS_CR1 0x0084 |
| 53 | #define GICV5_IRS_SYNCR 0x00c0 |
| 54 | #define GICV5_IRS_SYNC_STATUSR 0x00c4 |
| 55 | #define GICV5_IRS_SPI_SELR 0x0108 |
| 56 | #define GICV5_IRS_SPI_CFGR 0x0114 |
| 57 | #define GICV5_IRS_SPI_STATUSR 0x0118 |
| 58 | #define GICV5_IRS_PE_SELR 0x0140 |
| 59 | #define GICV5_IRS_PE_STATUSR 0x0144 |
| 60 | #define GICV5_IRS_PE_CR0 0x0148 |
| 61 | #define GICV5_IRS_IST_BASER 0x0180 |
| 62 | #define GICV5_IRS_IST_CFGR 0x0190 |
| 63 | #define GICV5_IRS_IST_STATUSR 0x0194 |
| 64 | #define GICV5_IRS_MAP_L2_ISTR 0x01c0 |
| 65 | |
| 66 | #define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) |
| 67 | #define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16) |
| 68 | |
| 69 | #define GICV5_IRS_IDR1_PRIORITY_BITS_1BITS 0b000 |
| 70 | #define GICV5_IRS_IDR1_PRIORITY_BITS_2BITS 0b001 |
| 71 | #define GICV5_IRS_IDR1_PRIORITY_BITS_3BITS 0b010 |
| 72 | #define GICV5_IRS_IDR1_PRIORITY_BITS_4BITS 0b011 |
| 73 | #define GICV5_IRS_IDR1_PRIORITY_BITS_5BITS 0b100 |
| 74 | |
| 75 | #define GICV5_IRS_IDR2_ISTMD_SZ GENMASK(19, 15) |
| 76 | #define GICV5_IRS_IDR2_ISTMD BIT(14) |
| 77 | #define GICV5_IRS_IDR2_IST_L2SZ GENMASK(13, 11) |
| 78 | #define GICV5_IRS_IDR2_IST_LEVELS BIT(10) |
| 79 | #define GICV5_IRS_IDR2_MIN_LPI_ID_BITS GENMASK(9, 6) |
| 80 | #define GICV5_IRS_IDR2_LPI BIT(5) |
| 81 | #define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0) |
| 82 | |
| 83 | #define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0) |
| 84 | #define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0) |
| 85 | #define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0) |
| 86 | |
| 87 | #define GICV5_IRS_IST_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(11), (r)) |
| 88 | #define GICV5_IRS_IST_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(12), (r)) |
| 89 | #define GICV5_IRS_IST_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(13), (r)) |
| 90 | |
| 91 | #define GICV5_IRS_CR0_IDLE BIT(1) |
| 92 | #define GICV5_IRS_CR0_IRSEN BIT(0) |
| 93 | |
| 94 | #define GICV5_IRS_CR1_VPED_WA BIT(15) |
| 95 | #define GICV5_IRS_CR1_VPED_RA BIT(14) |
| 96 | #define GICV5_IRS_CR1_VMD_WA BIT(13) |
| 97 | #define GICV5_IRS_CR1_VMD_RA BIT(12) |
| 98 | #define GICV5_IRS_CR1_VPET_WA BIT(11) |
| 99 | #define GICV5_IRS_CR1_VPET_RA BIT(10) |
| 100 | #define GICV5_IRS_CR1_VMT_WA BIT(9) |
| 101 | #define GICV5_IRS_CR1_VMT_RA BIT(8) |
| 102 | #define GICV5_IRS_CR1_IST_WA BIT(7) |
| 103 | #define GICV5_IRS_CR1_IST_RA BIT(6) |
| 104 | #define GICV5_IRS_CR1_IC GENMASK(5, 4) |
| 105 | #define GICV5_IRS_CR1_OC GENMASK(3, 2) |
| 106 | #define GICV5_IRS_CR1_SH GENMASK(1, 0) |
| 107 | |
| 108 | #define GICV5_IRS_SYNCR_SYNC BIT(31) |
| 109 | |
| 110 | #define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0) |
| 111 | |
| 112 | #define GICV5_IRS_SPI_STATUSR_V BIT(1) |
| 113 | #define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) |
| 114 | |
| 115 | #define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0) |
| 116 | |
| 117 | #define GICV5_IRS_SPI_CFGR_TM BIT(0) |
| 118 | |
| 119 | #define GICV5_IRS_PE_SELR_IAFFID GENMASK(15, 0) |
| 120 | |
| 121 | #define GICV5_IRS_PE_STATUSR_V BIT(1) |
| 122 | #define GICV5_IRS_PE_STATUSR_IDLE BIT(0) |
| 123 | |
| 124 | #define GICV5_IRS_PE_CR0_DPS BIT(0) |
| 125 | |
| 126 | #define GICV5_IRS_IST_STATUSR_IDLE BIT(0) |
| 127 | |
| 128 | #define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16) |
| 129 | #define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7) |
| 130 | #define GICV5_IRS_IST_CFGR_L2SZ GENMASK(6, 5) |
| 131 | #define GICV5_IRS_IST_CFGR_LPI_ID_BITS GENMASK(4, 0) |
| 132 | |
| 133 | #define GICV5_IRS_IST_CFGR_STRUCTURE_LINEAR 0b0 |
| 134 | #define GICV5_IRS_IST_CFGR_STRUCTURE_TWO_LEVEL 0b1 |
| 135 | |
| 136 | #define GICV5_IRS_IST_CFGR_ISTSZ_4 0b00 |
| 137 | #define GICV5_IRS_IST_CFGR_ISTSZ_8 0b01 |
| 138 | #define GICV5_IRS_IST_CFGR_ISTSZ_16 0b10 |
| 139 | |
| 140 | #define GICV5_IRS_IST_CFGR_L2SZ_4K 0b00 |
| 141 | #define GICV5_IRS_IST_CFGR_L2SZ_16K 0b01 |
| 142 | #define GICV5_IRS_IST_CFGR_L2SZ_64K 0b10 |
| 143 | |
| 144 | #define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6) |
| 145 | #define GICV5_IRS_IST_BASER_VALID BIT_ULL(0) |
| 146 | |
| 147 | #define GICV5_IRS_MAP_L2_ISTR_ID GENMASK(23, 0) |
| 148 | |
| 149 | #define GICV5_ISTL1E_VALID BIT_ULL(0) |
| 150 | |
| 151 | #define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) |
| 152 | |
| 153 | /* |
| 154 | * ITS registers and tables structures |
| 155 | */ |
| 156 | #define GICV5_ITS_IDR1 0x0004 |
| 157 | #define GICV5_ITS_IDR2 0x0008 |
| 158 | #define GICV5_ITS_CR0 0x0080 |
| 159 | #define GICV5_ITS_CR1 0x0084 |
| 160 | #define GICV5_ITS_DT_BASER 0x00c0 |
| 161 | #define GICV5_ITS_DT_CFGR 0x00d0 |
| 162 | #define GICV5_ITS_DIDR 0x0100 |
| 163 | #define GICV5_ITS_EIDR 0x0108 |
| 164 | #define GICV5_ITS_INV_EVENTR 0x010c |
| 165 | #define GICV5_ITS_INV_DEVICER 0x0110 |
| 166 | #define GICV5_ITS_STATUSR 0x0120 |
| 167 | #define GICV5_ITS_SYNCR 0x0140 |
| 168 | #define GICV5_ITS_SYNC_STATUSR 0x0148 |
| 169 | |
| 170 | #define GICV5_ITS_IDR1_L2SZ GENMASK(10, 8) |
| 171 | #define GICV5_ITS_IDR1_ITT_LEVELS BIT(7) |
| 172 | #define GICV5_ITS_IDR1_DT_LEVELS BIT(6) |
| 173 | #define GICV5_ITS_IDR1_DEVICEID_BITS GENMASK(5, 0) |
| 174 | |
| 175 | #define GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(8), (r)) |
| 176 | #define GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(9), (r)) |
| 177 | #define GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(10), (r)) |
| 178 | |
| 179 | #define GICV5_ITS_IDR2_XDMN_EVENTs GENMASK(6, 5) |
| 180 | #define GICV5_ITS_IDR2_EVENTID_BITS GENMASK(4, 0) |
| 181 | |
| 182 | #define GICV5_ITS_CR0_IDLE BIT(1) |
| 183 | #define GICV5_ITS_CR0_ITSEN BIT(0) |
| 184 | |
| 185 | #define GICV5_ITS_CR1_ITT_RA BIT(7) |
| 186 | #define GICV5_ITS_CR1_DT_RA BIT(6) |
| 187 | #define GICV5_ITS_CR1_IC GENMASK(5, 4) |
| 188 | #define GICV5_ITS_CR1_OC GENMASK(3, 2) |
| 189 | #define GICV5_ITS_CR1_SH GENMASK(1, 0) |
| 190 | |
| 191 | #define GICV5_ITS_DT_CFGR_STRUCTURE BIT(16) |
| 192 | #define GICV5_ITS_DT_CFGR_L2SZ GENMASK(7, 6) |
| 193 | #define GICV5_ITS_DT_CFGR_DEVICEID_BITS GENMASK(5, 0) |
| 194 | |
| 195 | #define GICV5_ITS_DT_BASER_ADDR_MASK GENMASK_ULL(55, 3) |
| 196 | |
| 197 | #define GICV5_ITS_INV_DEVICER_I BIT(31) |
| 198 | #define GICV5_ITS_INV_DEVICER_EVENTID_BITS GENMASK(5, 1) |
| 199 | #define GICV5_ITS_INV_DEVICER_L1 BIT(0) |
| 200 | |
| 201 | #define GICV5_ITS_DIDR_DEVICEID GENMASK_ULL(31, 0) |
| 202 | |
| 203 | #define GICV5_ITS_EIDR_EVENTID GENMASK(15, 0) |
| 204 | |
| 205 | #define GICV5_ITS_INV_EVENTR_I BIT(31) |
| 206 | #define GICV5_ITS_INV_EVENTR_ITT_L2SZ GENMASK(2, 1) |
| 207 | #define GICV5_ITS_INV_EVENTR_L1 BIT(0) |
| 208 | |
| 209 | #define GICV5_ITS_STATUSR_IDLE BIT(0) |
| 210 | |
| 211 | #define GICV5_ITS_SYNCR_SYNC BIT_ULL(63) |
| 212 | #define GICV5_ITS_SYNCR_SYNCALL BIT_ULL(32) |
| 213 | #define GICV5_ITS_SYNCR_DEVICEID GENMASK_ULL(31, 0) |
| 214 | |
| 215 | #define GICV5_ITS_SYNC_STATUSR_IDLE BIT(0) |
| 216 | |
| 217 | #define GICV5_DTL1E_VALID BIT_ULL(0) |
| 218 | /* Note that there is no shift for the address by design */ |
| 219 | #define GICV5_DTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) |
| 220 | #define GICV5_DTL1E_SPAN GENMASK_ULL(63, 60) |
| 221 | |
| 222 | #define GICV5_DTL2E_VALID BIT_ULL(0) |
| 223 | #define GICV5_DTL2E_ITT_L2SZ GENMASK_ULL(2, 1) |
| 224 | /* Note that there is no shift for the address by design */ |
| 225 | #define GICV5_DTL2E_ITT_ADDR_MASK GENMASK_ULL(55, 3) |
| 226 | #define GICV5_DTL2E_ITT_DSWE BIT_ULL(57) |
| 227 | #define GICV5_DTL2E_ITT_STRUCTURE BIT_ULL(58) |
| 228 | #define GICV5_DTL2E_EVENT_ID_BITS GENMASK_ULL(63, 59) |
| 229 | |
| 230 | #define GICV5_ITTL1E_VALID BIT_ULL(0) |
| 231 | /* Note that there is no shift for the address by design */ |
| 232 | #define GICV5_ITTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) |
| 233 | #define GICV5_ITTL1E_SPAN GENMASK_ULL(63, 60) |
| 234 | |
| 235 | #define GICV5_ITTL2E_LPI_ID GENMASK_ULL(23, 0) |
| 236 | #define GICV5_ITTL2E_DAC GENMASK_ULL(29, 28) |
| 237 | #define GICV5_ITTL2E_VIRTUAL BIT_ULL(30) |
| 238 | #define GICV5_ITTL2E_VALID BIT_ULL(31) |
| 239 | #define GICV5_ITTL2E_VM_ID GENMASK_ULL(47, 32) |
| 240 | |
| 241 | #define GICV5_ITS_DT_ITT_CFGR_L2SZ_4k 0b00 |
| 242 | #define GICV5_ITS_DT_ITT_CFGR_L2SZ_16k 0b01 |
| 243 | #define GICV5_ITS_DT_ITT_CFGR_L2SZ_64k 0b10 |
| 244 | |
| 245 | #define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR 0 |
| 246 | #define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL 1 |
| 247 | |
| 248 | #define GICV5_ITS_HWIRQ_DEVICE_ID GENMASK_ULL(31, 0) |
| 249 | #define GICV5_ITS_HWIRQ_EVENT_ID GENMASK_ULL(63, 32) |
| 250 | |
| 251 | /* |
| 252 | * IWB registers |
| 253 | */ |
| 254 | #define GICV5_IWB_IDR0 0x0000 |
| 255 | #define GICV5_IWB_CR0 0x0080 |
| 256 | #define GICV5_IWB_WENABLE_STATUSR 0x00c0 |
| 257 | #define GICV5_IWB_WENABLER 0x2000 |
| 258 | #define GICV5_IWB_WTMR 0x4000 |
| 259 | |
| 260 | #define GICV5_IWB_IDR0_INT_DOMS GENMASK(14, 11) |
| 261 | #define GICV5_IWB_IDR0_IW_RANGE GENMASK(10, 0) |
| 262 | |
| 263 | #define GICV5_IWB_CR0_IDLE BIT(1) |
| 264 | #define GICV5_IWB_CR0_IWBEN BIT(0) |
| 265 | |
| 266 | #define GICV5_IWB_WENABLE_STATUSR_IDLE BIT(0) |
| 267 | |
| 268 | /* |
| 269 | * Global Data structures and functions |
| 270 | */ |
| 271 | struct gicv5_chip_data { |
| 272 | struct fwnode_handle *fwnode; |
| 273 | struct irq_domain *ppi_domain; |
| 274 | struct irq_domain *spi_domain; |
| 275 | struct irq_domain *lpi_domain; |
| 276 | struct irq_domain *ipi_domain; |
| 277 | u32 global_spi_count; |
| 278 | u8 cpuif_pri_bits; |
| 279 | u8 cpuif_id_bits; |
| 280 | u8 irs_pri_bits; |
| 281 | struct { |
| 282 | __le64 *l1ist_addr; |
| 283 | u32 l2_size; |
| 284 | u8 l2_bits; |
| 285 | bool l2; |
| 286 | } ist; |
| 287 | }; |
| 288 | |
| 289 | extern struct gicv5_chip_data gicv5_global_data __read_mostly; |
| 290 | |
| 291 | struct gicv5_irs_chip_data { |
| 292 | struct list_head entry; |
| 293 | struct fwnode_handle *fwnode; |
| 294 | void __iomem *irs_base; |
| 295 | u32 flags; |
| 296 | u32 spi_min; |
| 297 | u32 spi_range; |
| 298 | raw_spinlock_t spi_config_lock; |
| 299 | }; |
| 300 | |
| 301 | static inline int gicv5_wait_for_op_s_atomic(void __iomem *addr, u32 offset, |
| 302 | const char *reg_s, u32 mask, |
| 303 | u32 *val) |
| 304 | { |
| 305 | void __iomem *reg = addr + offset; |
| 306 | u32 tmp; |
| 307 | int ret; |
| 308 | |
| 309 | ret = readl_poll_timeout_atomic(reg, tmp, tmp & mask, 1, 10 * USEC_PER_MSEC); |
| 310 | if (unlikely(ret == -ETIMEDOUT)) { |
| 311 | pr_err_ratelimited("%s timeout...\n" , reg_s); |
| 312 | return ret; |
| 313 | } |
| 314 | |
| 315 | if (val) |
| 316 | *val = tmp; |
| 317 | |
| 318 | return 0; |
| 319 | } |
| 320 | |
| 321 | static inline int gicv5_wait_for_op_s(void __iomem *addr, u32 offset, |
| 322 | const char *reg_s, u32 mask) |
| 323 | { |
| 324 | void __iomem *reg = addr + offset; |
| 325 | u32 val; |
| 326 | int ret; |
| 327 | |
| 328 | ret = readl_poll_timeout(reg, val, val & mask, 1, 10 * USEC_PER_MSEC); |
| 329 | if (unlikely(ret == -ETIMEDOUT)) { |
| 330 | pr_err_ratelimited("%s timeout...\n" , reg_s); |
| 331 | return ret; |
| 332 | } |
| 333 | |
| 334 | return 0; |
| 335 | } |
| 336 | |
| 337 | #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ |
| 338 | gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) |
| 339 | |
| 340 | #define gicv5_wait_for_op(base, reg, mask) \ |
| 341 | gicv5_wait_for_op_s(base, reg, #reg, mask) |
| 342 | |
| 343 | void __init gicv5_init_lpi_domain(void); |
| 344 | void __init gicv5_free_lpi_domain(void); |
| 345 | |
| 346 | int gicv5_irs_of_probe(struct device_node *parent); |
| 347 | void gicv5_irs_remove(void); |
| 348 | int gicv5_irs_enable(void); |
| 349 | void gicv5_irs_its_probe(void); |
| 350 | int gicv5_irs_register_cpu(int cpuid); |
| 351 | int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); |
| 352 | struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); |
| 353 | int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); |
| 354 | int gicv5_irs_iste_alloc(u32 lpi); |
| 355 | void gicv5_irs_syncr(void); |
| 356 | |
| 357 | struct gicv5_its_devtab_cfg { |
| 358 | union { |
| 359 | struct { |
| 360 | __le64 *devtab; |
| 361 | } linear; |
| 362 | struct { |
| 363 | __le64 *l1devtab; |
| 364 | __le64 **l2ptrs; |
| 365 | } l2; |
| 366 | }; |
| 367 | u32 cfgr; |
| 368 | }; |
| 369 | |
| 370 | struct gicv5_its_itt_cfg { |
| 371 | union { |
| 372 | struct { |
| 373 | __le64 *itt; |
| 374 | unsigned int num_ents; |
| 375 | } linear; |
| 376 | struct { |
| 377 | __le64 *l1itt; |
| 378 | __le64 **l2ptrs; |
| 379 | unsigned int num_l1_ents; |
| 380 | u8 l2sz; |
| 381 | } l2; |
| 382 | }; |
| 383 | u8 event_id_bits; |
| 384 | bool l2itt; |
| 385 | }; |
| 386 | |
| 387 | void gicv5_init_lpis(u32 max); |
| 388 | void gicv5_deinit_lpis(void); |
| 389 | |
| 390 | int gicv5_alloc_lpi(void); |
| 391 | void gicv5_free_lpi(u32 lpi); |
| 392 | |
| 393 | void __init gicv5_its_of_probe(struct device_node *parent); |
| 394 | #endif |
| 395 | |