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