| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| /* | |
| * Copyright (C) 2025 ARM Limited, All Rights Reserved. | |
| */ | |
| #ifndef __LINUX_IRQCHIP_ARM_GIC_V5_H | |
| #define __LINUX_IRQCHIP_ARM_GIC_V5_H | |
| #include <linux/iopoll.h> | |
| #include <linux/ioport.h> | |
| #include <asm/cacheflush.h> | |
| #include <asm/smp.h> | |
| #include <asm/sysreg.h> | |
| #define GICV5_IPIS_PER_CPU MAX_IPI | |
| /* | |
| * INTID handling | |
| */ | |
| #define GICV5_HWIRQ_ID GENMASK(23, 0) | |
| #define GICV5_HWIRQ_TYPE GENMASK(31, 29) | |
| #define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) | |
| #define GICV5_HWIRQ_TYPE_PPI UL(0x1) | |
| #define GICV5_HWIRQ_TYPE_LPI UL(0x2) | |
| #define GICV5_HWIRQ_TYPE_SPI UL(0x3) | |
| /* | |
| * Architected PPIs | |
| */ | |
| #define GICV5_ARCH_PPI_S_DB_PPI 0x0 | |
| #define GICV5_ARCH_PPI_RL_DB_PPI 0x1 | |
| #define GICV5_ARCH_PPI_NS_DB_PPI 0x2 | |
| #define GICV5_ARCH_PPI_SW_PPI 0x3 | |
| #define GICV5_ARCH_PPI_HACDBSIRQ 0xf | |
| #define GICV5_ARCH_PPI_CNTHVS 0x13 | |
| #define GICV5_ARCH_PPI_CNTHPS 0x14 | |
| #define GICV5_ARCH_PPI_PMBIRQ 0x15 | |
| #define GICV5_ARCH_PPI_COMMIRQ 0x16 | |
| #define GICV5_ARCH_PPI_PMUIRQ 0x17 | |
| #define GICV5_ARCH_PPI_CTIIRQ 0x18 | |
| #define GICV5_ARCH_PPI_GICMNT 0x19 | |
| #define GICV5_ARCH_PPI_CNTHP 0x1a | |
| #define GICV5_ARCH_PPI_CNTV 0x1b | |
| #define GICV5_ARCH_PPI_CNTHV 0x1c | |
| #define GICV5_ARCH_PPI_CNTPS 0x1d | |
| #define GICV5_ARCH_PPI_CNTP 0x1e | |
| #define GICV5_ARCH_PPI_TRBIRQ 0x1f | |
| /* | |
| * Tables attributes | |
| */ | |
| #define GICV5_NO_READ_ALLOC 0b0 | |
| #define GICV5_READ_ALLOC 0b1 | |
| #define GICV5_NO_WRITE_ALLOC 0b0 | |
| #define GICV5_WRITE_ALLOC 0b1 | |
| #define GICV5_NON_CACHE 0b00 | |
| #define GICV5_WB_CACHE 0b01 | |
| #define GICV5_WT_CACHE 0b10 | |
| #define GICV5_NON_SHARE 0b00 | |
| #define GICV5_OUTER_SHARE 0b10 | |
| #define GICV5_INNER_SHARE 0b11 | |
| /* | |
| * IRS registers and tables structures | |
| */ | |
| #define GICV5_IRS_IDR0 0x0000 | |
| #define GICV5_IRS_IDR1 0x0004 | |
| #define GICV5_IRS_IDR2 0x0008 | |
| #define GICV5_IRS_IDR5 0x0014 | |
| #define GICV5_IRS_IDR6 0x0018 | |
| #define GICV5_IRS_IDR7 0x001c | |
| #define GICV5_IRS_CR0 0x0080 | |
| #define GICV5_IRS_CR1 0x0084 | |
| #define GICV5_IRS_SYNCR 0x00c0 | |
| #define GICV5_IRS_SYNC_STATUSR 0x00c4 | |
| #define GICV5_IRS_SPI_SELR 0x0108 | |
| #define GICV5_IRS_SPI_CFGR 0x0114 | |
| #define GICV5_IRS_SPI_STATUSR 0x0118 | |
| #define GICV5_IRS_PE_SELR 0x0140 | |
| #define GICV5_IRS_PE_STATUSR 0x0144 | |
| #define GICV5_IRS_PE_CR0 0x0148 | |
| #define GICV5_IRS_IST_BASER 0x0180 | |
| #define GICV5_IRS_IST_CFGR 0x0190 | |
| #define GICV5_IRS_IST_STATUSR 0x0194 | |
| #define GICV5_IRS_MAP_L2_ISTR 0x01c0 | |
| #define GICV5_IRS_IDR0_VIRT BIT(6) | |
| #define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) | |
| #define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16) | |
| #define GICV5_IRS_IDR1_PRIORITY_BITS_1BITS 0b000 | |
| #define GICV5_IRS_IDR1_PRIORITY_BITS_2BITS 0b001 | |
| #define GICV5_IRS_IDR1_PRIORITY_BITS_3BITS 0b010 | |
| #define GICV5_IRS_IDR1_PRIORITY_BITS_4BITS 0b011 | |
| #define GICV5_IRS_IDR1_PRIORITY_BITS_5BITS 0b100 | |
| #define GICV5_IRS_IDR2_ISTMD_SZ GENMASK(19, 15) | |
| #define GICV5_IRS_IDR2_ISTMD BIT(14) | |
| #define GICV5_IRS_IDR2_IST_L2SZ GENMASK(13, 11) | |
| #define GICV5_IRS_IDR2_IST_LEVELS BIT(10) | |
| #define GICV5_IRS_IDR2_MIN_LPI_ID_BITS GENMASK(9, 6) | |
| #define GICV5_IRS_IDR2_LPI BIT(5) | |
| #define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0) | |
| #define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0) | |
| #define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0) | |
| #define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0) | |
| #define GICV5_IRS_IST_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(11), (r)) | |
| #define GICV5_IRS_IST_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(12), (r)) | |
| #define GICV5_IRS_IST_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(13), (r)) | |
| #define GICV5_IRS_CR0_IDLE BIT(1) | |
| #define GICV5_IRS_CR0_IRSEN BIT(0) | |
| #define GICV5_IRS_CR1_VPED_WA BIT(15) | |
| #define GICV5_IRS_CR1_VPED_RA BIT(14) | |
| #define GICV5_IRS_CR1_VMD_WA BIT(13) | |
| #define GICV5_IRS_CR1_VMD_RA BIT(12) | |
| #define GICV5_IRS_CR1_VPET_WA BIT(11) | |
| #define GICV5_IRS_CR1_VPET_RA BIT(10) | |
| #define GICV5_IRS_CR1_VMT_WA BIT(9) | |
| #define GICV5_IRS_CR1_VMT_RA BIT(8) | |
| #define GICV5_IRS_CR1_IST_WA BIT(7) | |
| #define GICV5_IRS_CR1_IST_RA BIT(6) | |
| #define GICV5_IRS_CR1_IC GENMASK(5, 4) | |
| #define GICV5_IRS_CR1_OC GENMASK(3, 2) | |
| #define GICV5_IRS_CR1_SH GENMASK(1, 0) | |
| #define GICV5_IRS_SYNCR_SYNC BIT(31) | |
| #define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0) | |
| #define GICV5_IRS_SPI_STATUSR_V BIT(1) | |
| #define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) | |
| #define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0) | |
| #define GICV5_IRS_SPI_CFGR_TM BIT(0) | |
| #define GICV5_IRS_PE_SELR_IAFFID GENMASK(15, 0) | |
| #define GICV5_IRS_PE_STATUSR_V BIT(1) | |
| #define GICV5_IRS_PE_STATUSR_IDLE BIT(0) | |
| #define GICV5_IRS_PE_CR0_DPS BIT(0) | |
| #define GICV5_IRS_IST_STATUSR_IDLE BIT(0) | |
| #define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16) | |
| #define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7) | |
| #define GICV5_IRS_IST_CFGR_L2SZ GENMASK(6, 5) | |
| #define GICV5_IRS_IST_CFGR_LPI_ID_BITS GENMASK(4, 0) | |
| #define GICV5_IRS_IST_CFGR_STRUCTURE_LINEAR 0b0 | |
| #define GICV5_IRS_IST_CFGR_STRUCTURE_TWO_LEVEL 0b1 | |
| #define GICV5_IRS_IST_CFGR_ISTSZ_4 0b00 | |
| #define GICV5_IRS_IST_CFGR_ISTSZ_8 0b01 | |
| #define GICV5_IRS_IST_CFGR_ISTSZ_16 0b10 | |
| #define GICV5_IRS_IST_CFGR_L2SZ_4K 0b00 | |
| #define GICV5_IRS_IST_CFGR_L2SZ_16K 0b01 | |
| #define GICV5_IRS_IST_CFGR_L2SZ_64K 0b10 | |
| #define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6) | |
| #define GICV5_IRS_IST_BASER_VALID BIT_ULL(0) | |
| #define GICV5_IRS_MAP_L2_ISTR_ID GENMASK(23, 0) | |
| #define GICV5_ISTL1E_VALID BIT_ULL(0) | |
| #define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) | |
| /* | |
| * ITS registers and tables structures | |
| */ | |
| #define GICV5_ITS_IDR1 0x0004 | |
| #define GICV5_ITS_IDR2 0x0008 | |
| #define GICV5_ITS_CR0 0x0080 | |
| #define GICV5_ITS_CR1 0x0084 | |
| #define GICV5_ITS_DT_BASER 0x00c0 | |
| #define GICV5_ITS_DT_CFGR 0x00d0 | |
| #define GICV5_ITS_DIDR 0x0100 | |
| #define GICV5_ITS_EIDR 0x0108 | |
| #define GICV5_ITS_INV_EVENTR 0x010c | |
| #define GICV5_ITS_INV_DEVICER 0x0110 | |
| #define GICV5_ITS_STATUSR 0x0120 | |
| #define GICV5_ITS_SYNCR 0x0140 | |
| #define GICV5_ITS_SYNC_STATUSR 0x0148 | |
| #define GICV5_ITS_IDR1_L2SZ GENMASK(10, 8) | |
| #define GICV5_ITS_IDR1_ITT_LEVELS BIT(7) | |
| #define GICV5_ITS_IDR1_DT_LEVELS BIT(6) | |
| #define GICV5_ITS_IDR1_DEVICEID_BITS GENMASK(5, 0) | |
| #define GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(8), (r)) | |
| #define GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(9), (r)) | |
| #define GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(10), (r)) | |
| #define GICV5_ITS_IDR2_XDMN_EVENTs GENMASK(6, 5) | |
| #define GICV5_ITS_IDR2_EVENTID_BITS GENMASK(4, 0) | |
| #define GICV5_ITS_CR0_IDLE BIT(1) | |
| #define GICV5_ITS_CR0_ITSEN BIT(0) | |
| #define GICV5_ITS_CR1_ITT_RA BIT(7) | |
| #define GICV5_ITS_CR1_DT_RA BIT(6) | |
| #define GICV5_ITS_CR1_IC GENMASK(5, 4) | |
| #define GICV5_ITS_CR1_OC GENMASK(3, 2) | |
| #define GICV5_ITS_CR1_SH GENMASK(1, 0) | |
| #define GICV5_ITS_DT_CFGR_STRUCTURE BIT(16) | |
| #define GICV5_ITS_DT_CFGR_L2SZ GENMASK(7, 6) | |
| #define GICV5_ITS_DT_CFGR_DEVICEID_BITS GENMASK(5, 0) | |
| #define GICV5_ITS_DT_BASER_ADDR_MASK GENMASK_ULL(55, 3) | |
| #define GICV5_ITS_INV_DEVICER_I BIT(31) | |
| #define GICV5_ITS_INV_DEVICER_EVENTID_BITS GENMASK(5, 1) | |
| #define GICV5_ITS_INV_DEVICER_L1 BIT(0) | |
| #define GICV5_ITS_DIDR_DEVICEID GENMASK_ULL(31, 0) | |
| #define GICV5_ITS_EIDR_EVENTID GENMASK(15, 0) | |
| #define GICV5_ITS_INV_EVENTR_I BIT(31) | |
| #define GICV5_ITS_INV_EVENTR_ITT_L2SZ GENMASK(2, 1) | |
| #define GICV5_ITS_INV_EVENTR_L1 BIT(0) | |
| #define GICV5_ITS_STATUSR_IDLE BIT(0) | |
| #define GICV5_ITS_SYNCR_SYNC BIT_ULL(63) | |
| #define GICV5_ITS_SYNCR_SYNCALL BIT_ULL(32) | |
| #define GICV5_ITS_SYNCR_DEVICEID GENMASK_ULL(31, 0) | |
| #define GICV5_ITS_SYNC_STATUSR_IDLE BIT(0) | |
| #define GICV5_DTL1E_VALID BIT_ULL(0) | |
| /* Note that there is no shift for the address by design */ | |
| #define GICV5_DTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) | |
| #define GICV5_DTL1E_SPAN GENMASK_ULL(63, 60) | |
| #define GICV5_DTL2E_VALID BIT_ULL(0) | |
| #define GICV5_DTL2E_ITT_L2SZ GENMASK_ULL(2, 1) | |
| /* Note that there is no shift for the address by design */ | |
| #define GICV5_DTL2E_ITT_ADDR_MASK GENMASK_ULL(55, 3) | |
| #define GICV5_DTL2E_ITT_DSWE BIT_ULL(57) | |
| #define GICV5_DTL2E_ITT_STRUCTURE BIT_ULL(58) | |
| #define GICV5_DTL2E_EVENT_ID_BITS GENMASK_ULL(63, 59) | |
| #define GICV5_ITTL1E_VALID BIT_ULL(0) | |
| /* Note that there is no shift for the address by design */ | |
| #define GICV5_ITTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) | |
| #define GICV5_ITTL1E_SPAN GENMASK_ULL(63, 60) | |
| #define GICV5_ITTL2E_LPI_ID GENMASK_ULL(23, 0) | |
| #define GICV5_ITTL2E_DAC GENMASK_ULL(29, 28) | |
| #define GICV5_ITTL2E_VIRTUAL BIT_ULL(30) | |
| #define GICV5_ITTL2E_VALID BIT_ULL(31) | |
| #define GICV5_ITTL2E_VM_ID GENMASK_ULL(47, 32) | |
| #define GICV5_ITS_DT_ITT_CFGR_L2SZ_4k 0b00 | |
| #define GICV5_ITS_DT_ITT_CFGR_L2SZ_16k 0b01 | |
| #define GICV5_ITS_DT_ITT_CFGR_L2SZ_64k 0b10 | |
| #define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR 0 | |
| #define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL 1 | |
| #define GICV5_ITS_HWIRQ_DEVICE_ID GENMASK_ULL(31, 0) | |
| #define GICV5_ITS_HWIRQ_EVENT_ID GENMASK_ULL(63, 32) | |
| /* | |
| * IWB registers | |
| */ | |
| #define GICV5_IWB_IDR0 0x0000 | |
| #define GICV5_IWB_CR0 0x0080 | |
| #define GICV5_IWB_WENABLE_STATUSR 0x00c0 | |
| #define GICV5_IWB_WENABLER 0x2000 | |
| #define GICV5_IWB_WTMR 0x4000 | |
| #define GICV5_IWB_IDR0_INT_DOMS GENMASK(14, 11) | |
| #define GICV5_IWB_IDR0_IW_RANGE GENMASK(10, 0) | |
| #define GICV5_IWB_CR0_IDLE BIT(1) | |
| #define GICV5_IWB_CR0_IWBEN BIT(0) | |
| #define GICV5_IWB_WENABLE_STATUSR_IDLE BIT(0) | |
| #define GICV5_GSI_IC_TYPE GENMASK(31, 29) | |
| #define GICV5_GSI_IWB_TYPE 0x7 | |
| #define GICV5_GSI_IWB_FRAME_ID GENMASK(28, 16) | |
| #define GICV5_GSI_IWB_WIRE GENMASK(15, 0) | |
| /* | |
| * Global Data structures and functions | |
| */ | |
| struct gicv5_chip_data { | |
| struct fwnode_handle *fwnode; | |
| struct irq_domain *ppi_domain; | |
| struct irq_domain *spi_domain; | |
| struct irq_domain *lpi_domain; | |
| struct irq_domain *ipi_domain; | |
| u32 global_spi_count; | |
| u8 cpuif_pri_bits; | |
| u8 cpuif_id_bits; | |
| u8 irs_pri_bits; | |
| bool virt_capable; | |
| struct { | |
| __le64 *l1ist_addr; | |
| u32 l2_size; | |
| u8 l2_bits; | |
| bool l2; | |
| } ist; | |
| }; | |
| extern struct gicv5_chip_data gicv5_global_data __read_mostly; | |
| struct gicv5_irs_chip_data { | |
| struct list_head entry; | |
| struct fwnode_handle *fwnode; | |
| void __iomem *irs_base; | |
| struct resource res; | |
| u32 flags; | |
| u32 spi_min; | |
| u32 spi_range; | |
| raw_spinlock_t spi_config_lock; | |
| }; | |
| static inline int gicv5_wait_for_op_s_atomic(void __iomem *addr, u32 offset, | |
| const char *reg_s, u32 mask, | |
| u32 *val) | |
| { | |
| void __iomem *reg = addr + offset; | |
| u32 tmp; | |
| int ret; | |
| ret = readl_poll_timeout_atomic(reg, tmp, tmp & mask, 1, 10 * USEC_PER_MSEC); | |
| if (unlikely(ret == -ETIMEDOUT)) { | |
| pr_err_ratelimited("%s timeout...\n", reg_s); | |
| return ret; | |
| } | |
| if (val) | |
| *val = tmp; | |
| return 0; | |
| } | |
| static inline int gicv5_wait_for_op_s(void __iomem *addr, u32 offset, | |
| const char *reg_s, u32 mask) | |
| { | |
| void __iomem *reg = addr + offset; | |
| u32 val; | |
| int ret; | |
| ret = readl_poll_timeout(reg, val, val & mask, 1, 10 * USEC_PER_MSEC); | |
| if (unlikely(ret == -ETIMEDOUT)) { | |
| pr_err_ratelimited("%s timeout...\n", reg_s); | |
| return ret; | |
| } | |
| return 0; | |
| } | |
| #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ | |
| gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) | |
| #define gicv5_wait_for_op(base, reg, mask) \ | |
| gicv5_wait_for_op_s(base, reg, #reg, mask) | |
| void __init gicv5_init_lpi_domain(void); | |
| void __init gicv5_free_lpi_domain(void); | |
| int gicv5_irs_of_probe(struct device_node *parent); | |
| int gicv5_irs_acpi_probe(void); | |
| void gicv5_irs_remove(void); | |
| int gicv5_irs_enable(void); | |
| void gicv5_irs_its_probe(void); | |
| int gicv5_irs_register_cpu(int cpuid); | |
| int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); | |
| struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); | |
| int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); | |
| int gicv5_irs_iste_alloc(u32 lpi); | |
| void gicv5_irs_syncr(void); | |
| /* Embedded in kvm.arch */ | |
| struct gicv5_vpe { | |
| bool resident; | |
| }; | |
| struct gicv5_its_devtab_cfg { | |
| union { | |
| struct { | |
| __le64 *devtab; | |
| } linear; | |
| struct { | |
| __le64 *l1devtab; | |
| __le64 **l2ptrs; | |
| } l2; | |
| }; | |
| u32 cfgr; | |
| }; | |
| struct gicv5_its_itt_cfg { | |
| union { | |
| struct { | |
| __le64 *itt; | |
| unsigned int num_ents; | |
| } linear; | |
| struct { | |
| __le64 *l1itt; | |
| __le64 **l2ptrs; | |
| unsigned int num_l1_ents; | |
| u8 l2sz; | |
| } l2; | |
| }; | |
| u8 event_id_bits; | |
| bool l2itt; | |
| }; | |
| void gicv5_init_lpis(u32 max); | |
| void gicv5_deinit_lpis(void); | |
| void __init gicv5_its_of_probe(struct device_node *parent); | |
| void __init gicv5_its_acpi_probe(void); | |
| #endif |