xref: /rk3399_ARM-atf/include/drivers/arm/gicv5.h (revision 5f2f471011f8d75d8f1b33e8da150681db84940d)
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>
13dfb37a2dSBoyan Karatotev 
14dfb37a2dSBoyan 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 
474db6bf9fSBoyan Karatotev /* Register fields common to all IRI components.
484db6bf9fSBoyan Karatotev  * They have the same name and offset in every config frame */
494db6bf9fSBoyan Karatotev #define IRI_AIDR_COMPONENT_SHIFT		8
504db6bf9fSBoyan Karatotev #define IRI_AIDR_COMPONENT_WIDTH		4
514db6bf9fSBoyan Karatotev #define IRI_AIDR_COMPONENT_IRS			0
524db6bf9fSBoyan Karatotev #define IRI_AIDR_COMPONENT_ITS			1
534db6bf9fSBoyan Karatotev #define IRI_AIDR_COMPONENT_IWB			2
544db6bf9fSBoyan Karatotev #define IRI_AIDR_ARCH_MAJOR_SHIFT		4
554db6bf9fSBoyan Karatotev #define IRI_AIDR_ARCH_MAJOR_WIDTH		4
564db6bf9fSBoyan Karatotev #define IRI_AIDR_ARCH_MAJOR_V5			0
574db6bf9fSBoyan Karatotev #define IRI_AIDR_ARCH_MINOR_SHIFT		0
584db6bf9fSBoyan Karatotev #define IRI_AIDR_ARCH_MINOR_WIDTH		4
594db6bf9fSBoyan Karatotev #define IRI_AIDR_ARCH_MINOR_P0			0
604db6bf9fSBoyan Karatotev 
61dfb37a2dSBoyan Karatotev /* IRS register fields */
62dfb37a2dSBoyan Karatotev #define IRS_IDR6_SPI_IRS_RANGE_SHIFT		0
63dfb37a2dSBoyan Karatotev #define IRS_IDR6_SPI_IRS_RANGE_WIDTH		24
64dfb37a2dSBoyan Karatotev #define IRS_IDR7_SPI_BASE_SHIFT			0
65dfb37a2dSBoyan Karatotev #define IRS_IDR7_SPI_BASE_WIDTH			24
66dfb37a2dSBoyan Karatotev 
67dfb37a2dSBoyan Karatotev #define IRS_SPI_STATUSR_IDLE_BIT		BIT(0)
68dfb37a2dSBoyan Karatotev #define IRS_SPI_STATUSR_V_BIT			BIT(1)
69dfb37a2dSBoyan Karatotev 
7071799209SBoyan Karatotev /* IWB register fields */
7171799209SBoyan Karatotev #define IWB_IDR0_DOMAINS_SHIFT			11
7271799209SBoyan Karatotev #define IWB_IDR0_DOMAINS_WIDTH			4
7371799209SBoyan Karatotev #define IWB_IDR0_IWRANGE_SHIFT			0
7471799209SBoyan Karatotev #define IWB_IDR0_IWRANGE_WIDTH			10
7571799209SBoyan Karatotev 
7671799209SBoyan Karatotev #define IWB_CR0_IWBEN_BIT			BIT(0)
7771799209SBoyan Karatotev #define IWB_CR0_IDLE_BIT			BIT(1)
7871799209SBoyan Karatotev 
7971799209SBoyan Karatotev #define IWB_WENABLE_STATUSR_IDLE_BIT		BIT(0)
8071799209SBoyan Karatotev #define IWB_WDOMAIN_STATUSR_IDLE_BIT		BIT(0)
8171799209SBoyan Karatotev 
8271799209SBoyan Karatotev #define IWB_WDOMAINR_DOMAINX_MASK		0x3
8371799209SBoyan Karatotev 
8413b62814SBoyan Karatotev #ifndef __ASSEMBLER__
8513b62814SBoyan Karatotev 
8682b228baSBoyan Karatotev #define _PPI_FIELD_SHIFT(_REG, _ppi_id)						\
8782b228baSBoyan Karatotev 	((_ppi_id % (ICC_PPI_##_REG##_COUNT)) * (64 / ICC_PPI_##_REG##_COUNT))
8882b228baSBoyan Karatotev 
8982b228baSBoyan Karatotev #define write_icc_ppi_domainr(_var, _ppi_id, _value)				\
9082b228baSBoyan Karatotev 	do {									\
9182b228baSBoyan Karatotev 		_var |=  (uint64_t)_value << _PPI_FIELD_SHIFT(DOMAINR, _ppi_id);\
9282b228baSBoyan Karatotev 	} while (false)
9382b228baSBoyan Karatotev 
94dfb37a2dSBoyan Karatotev 
95dfb37a2dSBoyan Karatotev #define DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset)				\
96dfb37a2dSBoyan Karatotev static inline void write_##_name(uintptr_t base, uint32_t val)			\
97dfb37a2dSBoyan Karatotev {										\
98dfb37a2dSBoyan Karatotev 	mmio_write_32(base + _offset, val);					\
99dfb37a2dSBoyan Karatotev }
100dfb37a2dSBoyan Karatotev 
101dfb37a2dSBoyan Karatotev #define DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset)				\
102dfb37a2dSBoyan Karatotev static inline uint32_t read_##_name(uintptr_t base)				\
103dfb37a2dSBoyan Karatotev {										\
104dfb37a2dSBoyan Karatotev 	return mmio_read_32(base + _offset);					\
105dfb37a2dSBoyan Karatotev }
106dfb37a2dSBoyan Karatotev 
10771799209SBoyan Karatotev #define DEFINE_GICV5_MMIO_WRITE_INDEXED_FUNC(_name, _offset)			\
10871799209SBoyan Karatotev static inline void write_##_name(uintptr_t base, uint16_t index, uint32_t val)	\
10971799209SBoyan Karatotev {										\
11071799209SBoyan Karatotev 	mmio_write_32(base + _offset + (index * sizeof(uint32_t)), val);	\
11171799209SBoyan Karatotev }
11271799209SBoyan Karatotev 
11371799209SBoyan Karatotev #define DEFINE_GICV5_MMIO_READ_INDEXED_FUNC(_name, _offset)			\
11471799209SBoyan Karatotev static inline uint32_t read_##_name(uintptr_t base, uint16_t index)		\
11571799209SBoyan Karatotev {										\
11671799209SBoyan Karatotev 	return mmio_read_32(base + _offset + (index * sizeof(uint32_t)));	\
11771799209SBoyan Karatotev }
11871799209SBoyan Karatotev 
119dfb37a2dSBoyan Karatotev #define DEFINE_GICV5_MMIO_RW_FUNCS(_name, _offset)				\
120dfb37a2dSBoyan Karatotev 	DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset)				\
121dfb37a2dSBoyan Karatotev 	DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset)
122dfb37a2dSBoyan Karatotev 
12371799209SBoyan Karatotev #define DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(_name, _offset)			\
12471799209SBoyan Karatotev 	DEFINE_GICV5_MMIO_READ_INDEXED_FUNC(_name, _offset)			\
12571799209SBoyan Karatotev 	DEFINE_GICV5_MMIO_WRITE_INDEXED_FUNC(_name, _offset)
12671799209SBoyan Karatotev 
1274db6bf9fSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(iri_aidr,			0x44)
1284db6bf9fSBoyan Karatotev 
12971799209SBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(iwb_idr0,			0x00)
13071799209SBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( iwb_cr0,			0x80)
13171799209SBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(iwb_wenable_statusr,	0xc0)
13271799209SBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(iwb_wdomain_statusr,	0xc4)
13371799209SBoyan Karatotev DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wenabler,	0x2000)
13471799209SBoyan Karatotev DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wtmr,		0x4000)
135*a6d29969SBoyan Karatotev DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wdomainr,	0x8000)
13671799209SBoyan Karatotev 
137dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(irs_idr6,			0x0018)
138dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(irs_idr7,			0x001c)
139dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_selr,		0x0108)
140dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_domainr,		0x010c)
141dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_cfgr,		0x0114)
142dfb37a2dSBoyan Karatotev DEFINE_GICV5_MMIO_READ_FUNC(irs_spi_statusr,		0x0118)
143dfb37a2dSBoyan Karatotev 
144dfb37a2dSBoyan Karatotev #define WAIT_FOR_IDLE(base, reg, reg_up)					\
145dfb37a2dSBoyan Karatotev 	do {									\
146dfb37a2dSBoyan Karatotev 		while ((read_##reg(base) & reg_up##_IDLE_BIT) == 0U) {}		\
147dfb37a2dSBoyan Karatotev 	} while (0)
148dfb37a2dSBoyan Karatotev 
149dfb37a2dSBoyan Karatotev /* wait for IDLE but also check the V bit was set */
150dfb37a2dSBoyan Karatotev #define WAIT_FOR_VIDLE(base, reg, reg_up)					\
151dfb37a2dSBoyan Karatotev 	do {									\
152dfb37a2dSBoyan Karatotev 		uint32_t val;							\
153dfb37a2dSBoyan Karatotev 		while (((val = read_##reg(base)) & reg_up##_IDLE_BIT) == 0U) {}	\
154dfb37a2dSBoyan Karatotev 		assert((val & reg##_V_BIT) != 0U);				\
155dfb37a2dSBoyan Karatotev 	} while (0)
156dfb37a2dSBoyan Karatotev 
157dfb37a2dSBoyan Karatotev #define WAIT_FOR_VIDLE_IRS_SPI_STATUSR(base)					\
158dfb37a2dSBoyan Karatotev 	WAIT_FOR_IDLE(base, irs_spi_statusr, IRS_SPI_STATUSR)
159dfb37a2dSBoyan Karatotev 
16071799209SBoyan Karatotev #define WAIT_FOR_IDLE_IWB_WENABLE_STATUSR(base)					\
16171799209SBoyan Karatotev 	WAIT_FOR_IDLE(base, iwb_wenable_statusr, IWB_WENABLE_STATUSR)
16271799209SBoyan Karatotev #define WAIT_FOR_IDLE_IWB_WDOMAIN_STATUSR(base)					\
16371799209SBoyan Karatotev 	WAIT_FOR_IDLE(base, iwb_wdomain_statusr, IWB_WDOMAIN_STATUSR)
16471799209SBoyan Karatotev #define WAIT_FOR_IDLE_IWB_CR0(base)						\
16571799209SBoyan Karatotev 	WAIT_FOR_IDLE(base, iwb_cr0, IWB_CR0)
16671799209SBoyan Karatotev 
167e2e90fa1SBoyan Karatotev #define WIRE_PROP_DESC(_id, _domain, _tm) \
168e2e90fa1SBoyan Karatotev 	{ \
169e2e90fa1SBoyan Karatotev 		.id = (_id), \
170e2e90fa1SBoyan Karatotev 		.domain = (_domain), \
171e2e90fa1SBoyan Karatotev 		.tm = (_tm), \
172e2e90fa1SBoyan Karatotev 	}
173e2e90fa1SBoyan Karatotev 
174dfb37a2dSBoyan Karatotev struct gicv5_wire_props {
175dfb37a2dSBoyan Karatotev 	/* continuous wire ID as seen by the attached component */
176dfb37a2dSBoyan Karatotev 	uint32_t id;
177dfb37a2dSBoyan Karatotev 	/* use the INTDMN_XYZ macros */
178dfb37a2dSBoyan Karatotev 	uint8_t domain:2;
179dfb37a2dSBoyan Karatotev 	/* use the TM_XYZ (eg. TM_EDGE) macros */
180dfb37a2dSBoyan Karatotev 	uint8_t tm:1;
181dfb37a2dSBoyan Karatotev };
182dfb37a2dSBoyan Karatotev 
183dfb37a2dSBoyan Karatotev /* to describe every IRS in the system */
184dfb37a2dSBoyan Karatotev struct gicv5_irs {
185dfb37a2dSBoyan Karatotev 	/* mapped device nGnRnE by the platform*/
186dfb37a2dSBoyan Karatotev 	uintptr_t el3_config_frame;
187dfb37a2dSBoyan Karatotev 	struct gicv5_wire_props *spis;
188dfb37a2dSBoyan Karatotev 	uint32_t num_spis;
189dfb37a2dSBoyan Karatotev };
190dfb37a2dSBoyan Karatotev 
19171799209SBoyan Karatotev /*
19271799209SBoyan Karatotev  * to describe every IWB in the system where EL3 is the MPPAS. IWBs that have
19371799209SBoyan Karatotev  * another world as an MPPAS need not be included
19471799209SBoyan Karatotev  */
19571799209SBoyan Karatotev struct gicv5_iwb {
19671799209SBoyan Karatotev 	/* mapped device nGnRnE by the platform*/
19771799209SBoyan Karatotev 	uintptr_t config_frame;
19871799209SBoyan Karatotev 	struct gicv5_wire_props *wires;
19971799209SBoyan Karatotev 	uint32_t num_wires;
20071799209SBoyan Karatotev };
20171799209SBoyan Karatotev 
20213b62814SBoyan Karatotev struct gicv5_driver_data {
203dfb37a2dSBoyan Karatotev 	struct gicv5_irs *irss;
20471799209SBoyan Karatotev 	struct gicv5_iwb *iwbs;
205dfb37a2dSBoyan Karatotev 	uint32_t num_irss;
20671799209SBoyan Karatotev 	uint32_t num_iwbs;
20713b62814SBoyan Karatotev };
20813b62814SBoyan Karatotev 
20913b62814SBoyan Karatotev extern const struct gicv5_driver_data plat_gicv5_driver_data;
21013b62814SBoyan Karatotev 
21113b62814SBoyan Karatotev void gicv5_driver_init();
21213b62814SBoyan Karatotev uint8_t gicv5_get_pending_interrupt_type(void);
21313b62814SBoyan Karatotev bool gicv5_has_interrupt_type(unsigned int type);
21482b228baSBoyan Karatotev void gicv5_enable_ppis();
21513b62814SBoyan Karatotev #endif /* __ASSEMBLER__ */
2168cef63d6SBoyan Karatotev #endif /* GICV5_H */
217