1 /*
2  * Copyright (c) 2023 Intel Corporation
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _SEDI_REG_DEFS_H_
8 #define _SEDI_REG_DEFS_H_
9 
10 #define __SEDI_CONST_RO const
11 #define __SEDI_CONST_WO
12 #define __SEDI_CONST_RW
13 #define __SEDI_CONST_RO_V const
14 #define __SEDI_CONST_RW_V
15 #define __SEDI_CONST_RW_L
16 #define __SEDI_CONST_RW_1C
17 #define __SEDI_CONST_RW_1C_V
18 #define __SEDI_CONST_RW_1S_V
19 #define __SEDI_CONST_RSV const
20 
21 #define __SEDI_UNUSED __attribute__((unused))
22 
23 /* *************************************************
24  * Macros for constants defined for a SEDI register.
25  */
26 
27 /*
28  * The constant for the register base address of instance <N> of a SEDI component IP
29  */
30 #define SEDI_IREG_BASE(_comp, _instance) SEDI_##_comp##_##_instance##_REG_BASE
31 
32 /*
33  * The constant for the register base address of the only instance of a SEDI component IP
34  */
35 #define SEDI_REG_BASE(_comp) SEDI_##_comp##_REG_BASE
36 
37 /*
38  * REGO: The constant for a REGister address Offset.
39  */
40 #define SEDI_REGO(_comp, _reg) SEDI_REGO_##_comp##_##_reg
41 
42 /*
43  * REGR: The constant for a REGister Reset value.
44  */
45 #define SEDI_REGR(_comp, _reg) SEDI_REGR_##_comp##_##_reg
46 
47 /*
48  * REGT: The REGister Type.
49  *   uint32_t or uint64_t (BitWidth)
50  *   const (RO) or un-const (RW or WO)
51  */
52 #define SEDI_REGT(_comp, _reg) __typeof__(SEDI_REGR(_comp, _reg))
53 
54 /*
55  * REGBM: The REGister Bit Mask of a specific bit with offset _bit_off.
56  */
57 #define _SEDI_REGBM(_comp, _reg, _bit_off) ((SEDI_REGT(_comp, _reg))0x1 << (_bit_off))
58 
59 /* ***********************************************************
60  * Macros for constants defined for a SEDI register Bit Field.
61  */
62 
63 /*
64  * RBFO: The constant for the Bit Offset of a Register Bit Field.
65  */
66 #define SEDI_RBFO(_comp, _reg, _bf) SEDI_RBFO_##_comp##_##_reg##_##_bf
67 
68 /*
69  * RBFW: The constant for the Bit Width of a Register Bit Field.
70  */
71 #define SEDI_RBFW(_comp, _reg, _bf) SEDI_RBFW_##_comp##_##_reg##_##_bf
72 
73 /*
74  * RBFM: The constant for the Bit Mask of a Register Bit Field.
75  */
76 #define SEDI_RBFM(_comp, _reg, _bf) SEDI_RBFM_##_comp##_##_reg##_##_bf
77 
78 /*
79  * RBFR: The constant for the Reset value of a Register Bit Field.
80  */
81 #define SEDI_RBFR(_comp, _reg, _bf) SEDI_RBFR_##_comp##_##_reg##_##_bf
82 
83 /*
84  * RBFV: The constant for a Register Bit Field Value with name _value_name.
85  */
86 #define SEDI_RBFV(_comp, _reg, _bf, _value_name) SEDI_RBFV_##_comp##_##_reg##_##_bf##_##_value_name
87 
88 /*
89  * RBFVM: The Bit Mask of a Register Bit Field Value with name _value_name.
90  */
91 #define SEDI_RBFVM(_comp, _reg, _bf, _value_name)                                                  \
92 	(SEDI_RBFV(_comp, _reg, _bf, _value_name) << SEDI_RBFO(_comp, _reg, _bf))
93 
94 /*
95  * RBFM_VALUE: The Bit Mask of a Register Bit Field with value _value.
96  */
97 #define SEDI_RBFM_VALUE(_comp, _reg, _bf, _value)                                                  \
98 	(((SEDI_REGT(_comp, _reg))(_value) << SEDI_RBFO(_comp, _reg, _bf)) &                       \
99 	 SEDI_RBFM(_comp, _reg, _bf))
100 
101 /*
102  * RBFT: The Rister Bit Field Type.
103  *   uint32_t or uint64_t (BitWidth)
104  *   const (RO) or un-const (RW or WO)
105  */
106 #define SEDI_RBFT(_comp, _reg, _bf) __typeof__(SEDI_RBFR(_comp, _reg, _bf))
107 
108 /* **********************************************
109  * Macros to define constants for a SEDI register.
110  */
111 
112 #define SEDI_REG_BASE_DEFINE(_comp, _base_addr)                                                    \
113 	static const uint32_t SEDI_REG_BASE(_comp) = (_base_addr)
114 
115 #define SEDI_IREG_BASE_DEFINE(_comp, _instance, _base_addr)                                        \
116 	static const uint32_t SEDI_IREG_BASE(_comp, _instance) = (_base_addr)
117 
118 /*
119  * Define constants for a SEDI register.
120  * - REGO (REGister address Offset): address offset from the IP base address.
121  * - REGR (REGister Reset value)   : reset value after reset. It's const if the register is RO.
122  */
123 #define SEDI_REG_DEFINE(_comp, _reg, _offset, _access, _writable_bitmask, _reset_val)              \
124 	static const uint32_t SEDI_REGO(_comp, _reg) = (_offset);                                  \
125 	static __SEDI_CONST_##_access __typeof__(_reset_val)                                       \
126 		__SEDI_UNUSED SEDI_REGR(_comp, _reg) = (_reset_val)
127 
128 /*
129  * Define constants for a Register Bit Field (RBF)
130  * - RBFO (Register Bit Field Offset): bit offset of the RBF.
131  * - RBFW (Register Bit Field Width) : bit width of the RBF.
132  * - RBFM (Register Bit Field Mask)  : bit mask of the RBF.
133  */
134 #define SEDI_RBF_DEFINE(_comp, _reg, _bf, _offset, _width, _access, _reset_val)                    \
135 	static const uint32_t SEDI_RBFO(_comp, _reg, _bf) = (_offset);                             \
136 	static const uint32_t SEDI_RBFW(_comp, _reg, _bf) = (_width);                              \
137 	static const SEDI_REGT(_comp, _reg) SEDI_RBFM(_comp, _reg, _bf) =                          \
138 		(((_offset) + (_width)) >= sizeof(SEDI_REGT(_comp, _reg)) * 8) ?                   \
139 			((SEDI_REGT(_comp, _reg))(-1) &                                            \
140 			 ~(_SEDI_REGBM(_comp, _reg, _offset) - 1)) :                               \
141 			((_SEDI_REGBM(_comp, _reg, _width) - 1) << (_offset));                     \
142 	static __SEDI_CONST_##_access __typeof__(_reset_val)                                       \
143 		__SEDI_UNUSED SEDI_RBFR(_comp, _reg, _bf) = (_reset_val)
144 
145 /*
146  * Define a Register Bit Field Value (RBFV) with name _value_name
147  */
148 #define SEDI_RBFV_DEFINE(_comp, _reg, _bf, _value_name, _value)                                    \
149 	static const SEDI_REGT(_comp, _reg) SEDI_RBFV_##_comp##_##_reg##_##_bf##_##_value_name =   \
150 		(SEDI_REGT(_comp, _reg))(_value)
151 
152 /* ***************************************************************
153  * Macro operations of a register.
154  *   PREG: a register with pointer.
155  *   IREG: a register of instance <N> of a SEDI component IP.
156  *   REG : a register of the only instance of a SEDI component IP.
157  */
158 
159 /*
160  * The pointer of a SEDI register with/without const qualifier
161  */
162 
163 #define SEDI_IREG_PTR(_comp, _instance, _reg)                                                      \
164 	(volatile(SEDI_REGT(_comp, _reg) *)(SEDI_IREG_BASE(_comp, _instance) +                     \
165 					    SEDI_REGO(_comp, _reg)))
166 
167 #define SEDI_REG_PTR(_comp, _reg)                                                                  \
168 	((volatile SEDI_REGT(_comp, _reg) *)(SEDI_REG_BASE(_comp) + SEDI_REGO(_comp, _reg)))
169 
170 /*
171  * Get the register value
172  */
173 
174 #define SEDI_PREG_GET(_comp, _reg, _reg_addr)                                                      \
175 	({                                                                                         \
176 		volatile SEDI_REGT(_comp, _reg) * _addr = (_reg_addr);                             \
177 		*_addr;                                                                            \
178 	})
179 
180 #define SEDI_IREG_GET(_comp, _instance, _reg)                                                      \
181 	SEDI_PREG_GET(_comp, _reg, SEDI_IREG_PTR(_comp, _instance, _reg))
182 
183 #define SEDI_REG_GET(_comp, _reg) SEDI_PREG_GET(_comp, _reg, SEDI_REG_PTR(_comp, _reg))
184 
185 /*
186  * Set a value into a register.
187  */
188 #define SEDI_PREG_SET(_comp, _reg, _value, _reg_addr)                                              \
189 	({                                                                                         \
190 		volatile SEDI_REGT(_comp, _reg) * _addr = (_reg_addr);                             \
191 		*_addr = _value;                                                                   \
192 	})
193 
194 #define SEDI_IREG_SET(_comp, _instance, _reg, _value)                                              \
195 	SEDI_PREG_SET(_comp, _reg, _value, SEDI_IREG_PTR(_comp, _instance, _reg))
196 
197 #define SEDI_REG_SET(_comp, _reg, _value)                                                          \
198 	SEDI_PREG_SET(_comp, _reg, _value, SEDI_REG_PTR(_comp, _reg))
199 
200 /*
201  * Check if a register has a specific RBFV with name _value_name set.
202  */
203 #define SEDI_PREG_RBFV_IS_SET(_comp, _reg, _bf, _value_name, _reg_addr)                            \
204 	((SEDI_PREG_GET(_comp, _reg, _reg_addr) & SEDI_RBFM(_comp, _reg, _bf)) ==                  \
205 	 SEDI_RBFVM(_comp, _reg, _bf, _value_name))
206 
207 #define SEDI_IREG_RBFV_IS_SET(_comp, _instance, _reg, _bf, _value_name)                            \
208 	SEDI_PREG_RBFV_IS_SET(_comp, _reg, _bf, _value_name, SEDI_IREG_PTR(_comp, _instance, _reg))
209 
210 #define SEDI_REG_RBFV_IS_SET(_comp, _reg, _bf, _value_name)                                        \
211 	SEDI_PREG_RBFV_IS_SET(_comp, _reg, _bf, _value_name, SEDI_REG_PTR(_comp, _reg))
212 
213 /*
214  * Get the value of a Register Bit Field from a register.
215  */
216 #define SEDI_PREG_RBFV_GET(_comp, _reg, _bf, _reg_addr)                                            \
217 	((SEDI_PREG_GET(_comp, _reg, _reg_addr) & SEDI_RBFM(_comp, _reg, _bf)) >>                  \
218 	 SEDI_RBFO(_comp, _reg, _bf))
219 
220 #define SEDI_IREG_RBFV_GET(_comp, _instance, _reg, _bf)                                            \
221 	SEDI_PREG_RBFV_GET(_comp, _reg, _bf, SEDI_IREG_PTR(_comp, _instance, _reg))
222 
223 #define SEDI_REG_RBFV_GET(_comp, _reg, _bf)                                                        \
224 	SEDI_PREG_RBFV_GET(_comp, _reg, _bf, SEDI_REG_PTR(_comp, _reg))
225 
226 /*
227  * Set a RBFV with name _value_name into a register.
228  */
229 #define SEDI_PREG_RBFV_SET(_comp, _reg, _bf, _value_name, _reg_addr)                               \
230 	*(volatile SEDI_RBFT(_comp, _reg, _bf) *)(_reg_addr) =                                     \
231 		((SEDI_PREG_GET(_comp, _reg, _reg_addr) & ~SEDI_RBFM(_comp, _reg, _bf)) |          \
232 		 SEDI_RBFVM(_comp, _reg, _bf, _value_name))
233 
234 #define SEDI_IREG_RBFV_SET(_comp, _instance, _reg, _bf, _value_name)                               \
235 	SEDI_PREG_RBFV_SET(_comp, _reg, _bf, _value_name, SEDI_IREG_PTR(_comp, _instance, _reg))
236 
237 #define SEDI_REG_RBFV_SET(_comp, _reg, _bf, _value_name)                                           \
238 	SEDI_PREG_RBFV_SET(_comp, _reg, _bf, _value_name, SEDI_REG_PTR(_comp, _reg))
239 
240 /*
241  * Set a specific value into a Register Bit Field.
242  */
243 #define SEDI_PREG_RBF_SET(_comp, _reg, _bf, _value, _reg_addr)                                     \
244 	*(volatile SEDI_RBFT(_comp, _reg, _bf) *)(_reg_addr) =                                     \
245 		((SEDI_PREG_GET(_comp, _reg, _reg_addr) & ~SEDI_RBFM(_comp, _reg, _bf)) |          \
246 		 SEDI_RBFM_VALUE(_comp, _reg, _bf, _value))
247 
248 #define SEDI_IREG_RBF_SET(_comp, _instance, _reg, _bf, _value)                                     \
249 	SEDI_PREG_RBF_SET(_comp, _reg, _bf, _value, SEDI_IREG_PTR(_comp, _instance, _reg))
250 
251 #define SEDI_REG_RBF_SET(_comp, _reg, _bf, _value)                                                 \
252 	SEDI_PREG_RBF_SET(_comp, _reg, _bf, _value, SEDI_REG_PTR(_comp, _reg))
253 
254 #endif
255