18cef63d6SBoyan Karatotev /* 28cef63d6SBoyan Karatotev * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved. 38cef63d6SBoyan Karatotev * 48cef63d6SBoyan Karatotev * SPDX-License-Identifier: BSD-3-Clause 58cef63d6SBoyan Karatotev */ 68cef63d6SBoyan Karatotev 78cef63d6SBoyan Karatotev #ifndef GICV5_H 88cef63d6SBoyan Karatotev #define GICV5_H 913b62814SBoyan Karatotev 1013b62814SBoyan Karatotev #ifndef __ASSEMBLER__ 1113b62814SBoyan Karatotev #include <stdbool.h> 1213b62814SBoyan Karatotev #include <stdint.h> 13*dfb37a2dSBoyan Karatotev 14*dfb37a2dSBoyan Karatotev #include <lib/mmio.h> 1513b62814SBoyan Karatotev #endif 1613b62814SBoyan Karatotev 1713b62814SBoyan Karatotev #include <lib/utils_def.h> 1813b62814SBoyan Karatotev 1913b62814SBoyan Karatotev /* Interrupt Domain definitions */ 2013b62814SBoyan Karatotev #define INTDMN_S 0 2113b62814SBoyan Karatotev #define INTDMN_NS 1 2213b62814SBoyan Karatotev #define INTDMN_EL3 2 2313b62814SBoyan Karatotev #define INTDMN_RL 3 2413b62814SBoyan Karatotev 2513b62814SBoyan Karatotev /* Trigger modes */ 2613b62814SBoyan Karatotev #define TM_EDGE 0 2713b62814SBoyan Karatotev #define TM_LEVEL 1 2813b62814SBoyan Karatotev 2982b228baSBoyan Karatotev /* Architected PPI numbers */ 3082b228baSBoyan Karatotev #define PPI_TRBIRQ 31 3182b228baSBoyan Karatotev #define PPI_CNTP 30 3282b228baSBoyan Karatotev #define PPI_CNTPS 29 3382b228baSBoyan Karatotev #define PPI_CNTHV 28 3482b228baSBoyan Karatotev #define PPI_CNTV 27 3582b228baSBoyan Karatotev #define PPI_CNTHP 26 3682b228baSBoyan Karatotev #define PPI_GICMNT 25 3782b228baSBoyan Karatotev #define PPI_CTIIRQ 24 3882b228baSBoyan Karatotev #define PPI_PMUIRQ 23 3982b228baSBoyan Karatotev #define PPI_COMMIRQ 22 4082b228baSBoyan Karatotev #define PPI_PMBIRQ 21 4182b228baSBoyan Karatotev #define PPI_CNTHPS 20 4282b228baSBoyan Karatotev #define PPI_CNTHVS 19 4382b228baSBoyan Karatotev #define PPI_DB_NS 2 4482b228baSBoyan Karatotev #define PPI_DB_RL 1 4582b228baSBoyan Karatotev #define PPI_DB_S 0 4682b228baSBoyan Karatotev 47*dfb37a2dSBoyan Karatotev /* IRS register fields */ 48*dfb37a2dSBoyan Karatotev #define IRS_IDR6_SPI_IRS_RANGE_SHIFT 0 49*dfb37a2dSBoyan Karatotev #define IRS_IDR6_SPI_IRS_RANGE_WIDTH 24 50*dfb37a2dSBoyan Karatotev #define IRS_IDR7_SPI_BASE_SHIFT 0 51*dfb37a2dSBoyan Karatotev #define IRS_IDR7_SPI_BASE_WIDTH 24 52*dfb37a2dSBoyan Karatotev 53*dfb37a2dSBoyan Karatotev #define IRS_SPI_STATUSR_IDLE_BIT BIT(0) 54*dfb37a2dSBoyan Karatotev #define IRS_SPI_STATUSR_V_BIT BIT(1) 55*dfb37a2dSBoyan Karatotev 5613b62814SBoyan Karatotev #ifndef __ASSEMBLER__ 5713b62814SBoyan Karatotev 5882b228baSBoyan Karatotev #define _PPI_FIELD_SHIFT(_REG, _ppi_id) \ 5982b228baSBoyan Karatotev ((_ppi_id % (ICC_PPI_##_REG##_COUNT)) * (64 / ICC_PPI_##_REG##_COUNT)) 6082b228baSBoyan Karatotev 6182b228baSBoyan Karatotev #define write_icc_ppi_domainr(_var, _ppi_id, _value) \ 6282b228baSBoyan Karatotev do { \ 6382b228baSBoyan Karatotev _var |= (uint64_t)_value << _PPI_FIELD_SHIFT(DOMAINR, _ppi_id);\ 6482b228baSBoyan Karatotev } while (false) 6582b228baSBoyan Karatotev 66*dfb37a2dSBoyan Karatotev 67*dfb37a2dSBoyan Karatotev #define DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset) \ 68*dfb37a2dSBoyan Karatotev static inline void write_##_name(uintptr_t base, uint32_t val) \ 69*dfb37a2dSBoyan Karatotev { \ 70*dfb37a2dSBoyan Karatotev mmio_write_32(base + _offset, val); \ 71*dfb37a2dSBoyan Karatotev } 72*dfb37a2dSBoyan Karatotev 73*dfb37a2dSBoyan Karatotev #define DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset) \ 74*dfb37a2dSBoyan Karatotev static inline uint32_t read_##_name(uintptr_t base) \ 75*dfb37a2dSBoyan Karatotev { \ 76*dfb37a2dSBoyan Karatotev return mmio_read_32(base + _offset); \ 77*dfb37a2dSBoyan Karatotev } 78*dfb37a2dSBoyan Karatotev 79*dfb37a2dSBoyan Karatotev #define DEFINE_GICV5_MMIO_RW_FUNCS(_name, _offset) \ 80*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset) \ 81*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset) 82*dfb37a2dSBoyan Karatotev 83*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(irs_idr6, 0x0018) 84*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(irs_idr7, 0x001c) 85*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_selr, 0x0108) 86*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_domainr, 0x010c) 87*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_cfgr, 0x0114) 88*dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(irs_spi_statusr, 0x0118) 89*dfb37a2dSBoyan Karatotev 90*dfb37a2dSBoyan Karatotev #define WAIT_FOR_IDLE(base, reg, reg_up) \ 91*dfb37a2dSBoyan Karatotev do { \ 92*dfb37a2dSBoyan Karatotev while ((read_##reg(base) & reg_up##_IDLE_BIT) == 0U) {} \ 93*dfb37a2dSBoyan Karatotev } while (0) 94*dfb37a2dSBoyan Karatotev 95*dfb37a2dSBoyan Karatotev /* wait for IDLE but also check the V bit was set */ 96*dfb37a2dSBoyan Karatotev #define WAIT_FOR_VIDLE(base, reg, reg_up) \ 97*dfb37a2dSBoyan Karatotev do { \ 98*dfb37a2dSBoyan Karatotev uint32_t val; \ 99*dfb37a2dSBoyan Karatotev while (((val = read_##reg(base)) & reg_up##_IDLE_BIT) == 0U) {} \ 100*dfb37a2dSBoyan Karatotev assert((val & reg##_V_BIT) != 0U); \ 101*dfb37a2dSBoyan Karatotev } while (0) 102*dfb37a2dSBoyan Karatotev 103*dfb37a2dSBoyan Karatotev #define WAIT_FOR_VIDLE_IRS_SPI_STATUSR(base) \ 104*dfb37a2dSBoyan Karatotev WAIT_FOR_IDLE(base, irs_spi_statusr, IRS_SPI_STATUSR) 105*dfb37a2dSBoyan Karatotev 106*dfb37a2dSBoyan Karatotev struct gicv5_wire_props { 107*dfb37a2dSBoyan Karatotev /* continuous wire ID as seen by the attached component */ 108*dfb37a2dSBoyan Karatotev uint32_t id; 109*dfb37a2dSBoyan Karatotev /* use the INTDMN_XYZ macros */ 110*dfb37a2dSBoyan Karatotev uint8_t domain:2; 111*dfb37a2dSBoyan Karatotev /* use the TM_XYZ (eg. TM_EDGE) macros */ 112*dfb37a2dSBoyan Karatotev uint8_t tm:1; 113*dfb37a2dSBoyan Karatotev }; 114*dfb37a2dSBoyan Karatotev 115*dfb37a2dSBoyan Karatotev /* to describe every IRS in the system */ 116*dfb37a2dSBoyan Karatotev struct gicv5_irs { 117*dfb37a2dSBoyan Karatotev /* mapped device nGnRnE by the platform*/ 118*dfb37a2dSBoyan Karatotev uintptr_t el3_config_frame; 119*dfb37a2dSBoyan Karatotev struct gicv5_wire_props *spis; 120*dfb37a2dSBoyan Karatotev uint32_t num_spis; 121*dfb37a2dSBoyan Karatotev }; 122*dfb37a2dSBoyan Karatotev 12313b62814SBoyan Karatotev struct gicv5_driver_data { 124*dfb37a2dSBoyan Karatotev struct gicv5_irs *irss; 125*dfb37a2dSBoyan Karatotev uint32_t num_irss; 12613b62814SBoyan Karatotev }; 12713b62814SBoyan Karatotev 12813b62814SBoyan Karatotev extern const struct gicv5_driver_data plat_gicv5_driver_data; 12913b62814SBoyan Karatotev 13013b62814SBoyan Karatotev void gicv5_driver_init(); 13113b62814SBoyan Karatotev uint8_t gicv5_get_pending_interrupt_type(void); 13213b62814SBoyan Karatotev bool gicv5_has_interrupt_type(unsigned int type); 13382b228baSBoyan Karatotev void gicv5_enable_ppis(); 13413b62814SBoyan Karatotev #endif /* __ASSEMBLER__ */ 1358cef63d6SBoyan Karatotev #endif /* GICV5_H */ 136