xref: /rk3399_ARM-atf/include/drivers/arm/gicv5.h (revision 71799209def08f4afdc49555246268cf1300a2d7)
1 /*
2  * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef GICV5_H
8 #define GICV5_H
9 
10 #ifndef __ASSEMBLER__
11 #include <stdbool.h>
12 #include <stdint.h>
13 
14 #include <lib/mmio.h>
15 #endif
16 
17 #include <lib/utils_def.h>
18 
19 /* Interrupt Domain definitions */
20 #define INTDMN_S				0
21 #define INTDMN_NS				1
22 #define INTDMN_EL3				2
23 #define INTDMN_RL				3
24 
25 /* Trigger modes */
26 #define TM_EDGE					0
27 #define TM_LEVEL				1
28 
29 /* Architected PPI numbers */
30 #define PPI_TRBIRQ				31
31 #define PPI_CNTP				30
32 #define PPI_CNTPS				29
33 #define PPI_CNTHV				28
34 #define PPI_CNTV				27
35 #define PPI_CNTHP				26
36 #define PPI_GICMNT				25
37 #define PPI_CTIIRQ				24
38 #define PPI_PMUIRQ				23
39 #define PPI_COMMIRQ				22
40 #define PPI_PMBIRQ				21
41 #define PPI_CNTHPS				20
42 #define PPI_CNTHVS				19
43 #define PPI_DB_NS				2
44 #define PPI_DB_RL				1
45 #define PPI_DB_S				0
46 
47 /* IRS register fields */
48 #define IRS_IDR6_SPI_IRS_RANGE_SHIFT		0
49 #define IRS_IDR6_SPI_IRS_RANGE_WIDTH		24
50 #define IRS_IDR7_SPI_BASE_SHIFT			0
51 #define IRS_IDR7_SPI_BASE_WIDTH			24
52 
53 #define IRS_SPI_STATUSR_IDLE_BIT		BIT(0)
54 #define IRS_SPI_STATUSR_V_BIT			BIT(1)
55 
56 /* IWB register fields */
57 #define IWB_IDR0_DOMAINS_SHIFT			11
58 #define IWB_IDR0_DOMAINS_WIDTH			4
59 #define IWB_IDR0_IWRANGE_SHIFT			0
60 #define IWB_IDR0_IWRANGE_WIDTH			10
61 
62 #define IWB_CR0_IWBEN_BIT			BIT(0)
63 #define IWB_CR0_IDLE_BIT			BIT(1)
64 
65 #define IWB_WENABLE_STATUSR_IDLE_BIT		BIT(0)
66 #define IWB_WDOMAIN_STATUSR_IDLE_BIT		BIT(0)
67 
68 #define IWB_WDOMAINR_DOMAINX_MASK		0x3
69 
70 #ifndef __ASSEMBLER__
71 
72 #define _PPI_FIELD_SHIFT(_REG, _ppi_id)						\
73 	((_ppi_id % (ICC_PPI_##_REG##_COUNT)) * (64 / ICC_PPI_##_REG##_COUNT))
74 
75 #define write_icc_ppi_domainr(_var, _ppi_id, _value)				\
76 	do {									\
77 		_var |=  (uint64_t)_value << _PPI_FIELD_SHIFT(DOMAINR, _ppi_id);\
78 	} while (false)
79 
80 
81 #define DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset)				\
82 static inline void write_##_name(uintptr_t base, uint32_t val)			\
83 {										\
84 	mmio_write_32(base + _offset, val);					\
85 }
86 
87 #define DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset)				\
88 static inline uint32_t read_##_name(uintptr_t base)				\
89 {										\
90 	return mmio_read_32(base + _offset);					\
91 }
92 
93 #define DEFINE_GICV5_MMIO_WRITE_INDEXED_FUNC(_name, _offset)			\
94 static inline void write_##_name(uintptr_t base, uint16_t index, uint32_t val)	\
95 {										\
96 	mmio_write_32(base + _offset + (index * sizeof(uint32_t)), val);	\
97 }
98 
99 #define DEFINE_GICV5_MMIO_READ_INDEXED_FUNC(_name, _offset)			\
100 static inline uint32_t read_##_name(uintptr_t base, uint16_t index)		\
101 {										\
102 	return mmio_read_32(base + _offset + (index * sizeof(uint32_t)));	\
103 }
104 
105 #define DEFINE_GICV5_MMIO_RW_FUNCS(_name, _offset)				\
106 	DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset)				\
107 	DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset)
108 
109 #define DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(_name, _offset)			\
110 	DEFINE_GICV5_MMIO_READ_INDEXED_FUNC(_name, _offset)			\
111 	DEFINE_GICV5_MMIO_WRITE_INDEXED_FUNC(_name, _offset)
112 
113 DEFINE_GICV5_MMIO_READ_FUNC(iwb_idr0,			0x00)
114 DEFINE_GICV5_MMIO_RW_FUNCS( iwb_cr0,			0x80)
115 DEFINE_GICV5_MMIO_READ_FUNC(iwb_wenable_statusr,	0xc0)
116 DEFINE_GICV5_MMIO_READ_FUNC(iwb_wdomain_statusr,	0xc4)
117 DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wenabler,	0x2000)
118 DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wtmr,		0x4000)
119 DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wdomainr,	0x6000)
120 
121 DEFINE_GICV5_MMIO_READ_FUNC(irs_idr6,			0x0018)
122 DEFINE_GICV5_MMIO_READ_FUNC(irs_idr7,			0x001c)
123 DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_selr,		0x0108)
124 DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_domainr,		0x010c)
125 DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_cfgr,		0x0114)
126 DEFINE_GICV5_MMIO_READ_FUNC(irs_spi_statusr,		0x0118)
127 
128 #define WAIT_FOR_IDLE(base, reg, reg_up)					\
129 	do {									\
130 		while ((read_##reg(base) & reg_up##_IDLE_BIT) == 0U) {}		\
131 	} while (0)
132 
133 /* wait for IDLE but also check the V bit was set */
134 #define WAIT_FOR_VIDLE(base, reg, reg_up)					\
135 	do {									\
136 		uint32_t val;							\
137 		while (((val = read_##reg(base)) & reg_up##_IDLE_BIT) == 0U) {}	\
138 		assert((val & reg##_V_BIT) != 0U);				\
139 	} while (0)
140 
141 #define WAIT_FOR_VIDLE_IRS_SPI_STATUSR(base)					\
142 	WAIT_FOR_IDLE(base, irs_spi_statusr, IRS_SPI_STATUSR)
143 
144 #define WAIT_FOR_IDLE_IWB_WENABLE_STATUSR(base)					\
145 	WAIT_FOR_IDLE(base, iwb_wenable_statusr, IWB_WENABLE_STATUSR)
146 #define WAIT_FOR_IDLE_IWB_WDOMAIN_STATUSR(base)					\
147 	WAIT_FOR_IDLE(base, iwb_wdomain_statusr, IWB_WDOMAIN_STATUSR)
148 #define WAIT_FOR_IDLE_IWB_CR0(base)						\
149 	WAIT_FOR_IDLE(base, iwb_cr0, IWB_CR0)
150 
151 struct gicv5_wire_props {
152 	/* continuous wire ID as seen by the attached component */
153 	uint32_t id;
154 	/* use the INTDMN_XYZ macros */
155 	uint8_t domain:2;
156 	/* use the TM_XYZ (eg. TM_EDGE) macros */
157 	uint8_t tm:1;
158 };
159 
160 /* to describe every IRS in the system */
161 struct gicv5_irs {
162 	/* mapped device nGnRnE by the platform*/
163 	uintptr_t el3_config_frame;
164 	struct gicv5_wire_props *spis;
165 	uint32_t num_spis;
166 };
167 
168 /*
169  * to describe every IWB in the system where EL3 is the MPPAS. IWBs that have
170  * another world as an MPPAS need not be included
171  */
172 struct gicv5_iwb {
173 	/* mapped device nGnRnE by the platform*/
174 	uintptr_t config_frame;
175 	struct gicv5_wire_props *wires;
176 	uint32_t num_wires;
177 };
178 
179 struct gicv5_driver_data {
180 	struct gicv5_irs *irss;
181 	struct gicv5_iwb *iwbs;
182 	uint32_t num_irss;
183 	uint32_t num_iwbs;
184 };
185 
186 extern const struct gicv5_driver_data plat_gicv5_driver_data;
187 
188 void gicv5_driver_init();
189 uint8_t gicv5_get_pending_interrupt_type(void);
190 bool gicv5_has_interrupt_type(unsigned int type);
191 void gicv5_enable_ppis();
192 #endif /* __ASSEMBLER__ */
193 #endif /* GICV5_H */
194