xref: /rk3399_ARM-atf/include/drivers/arm/gicv5.h (revision dfb37a2df579ccf0e92c97515452b13ce2c9fba8)
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