xref: /openbmc/linux/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h (revision 5ef12cb4a3a78ffb331c03a795a15eea4ae35155)
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  */
24 
25 #ifndef DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
26 #define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
27 
28 #include "dm_services.h"
29 
30 /* macro for register read/write
31  * user of macro need to define
32  *
33  * CTX ==> macro to ptr to dc_context
34  *    eg. aud110->base.ctx
35  *
36  * REG ==> macro to location of register offset
37  *    eg. aud110->regs->reg
38  */
39 #define REG_READ(reg_name) \
40 		dm_read_reg(CTX, REG(reg_name))
41 
42 #define REG_WRITE(reg_name, value) \
43 		dm_write_reg(CTX, REG(reg_name), value)
44 
45 #ifdef REG_SET
46 #undef REG_SET
47 #endif
48 
49 #ifdef REG_GET
50 #undef REG_GET
51 #endif
52 
53 /* macro to set register fields. */
54 #define REG_SET_N(reg_name, n, initial_val, ...)	\
55 		generic_reg_update_ex(CTX, \
56 				REG(reg_name), \
57 				initial_val, \
58 				n, __VA_ARGS__)
59 
60 #define FN(reg_name, field) \
61 	FD(reg_name##__##field)
62 
63 #define REG_SET(reg_name, initial_val, field, val)	\
64 		REG_SET_N(reg_name, 1, initial_val, \
65 				FN(reg_name, field), val)
66 
67 #define REG_SET_2(reg, init_value, f1, v1, f2, v2)	\
68 		REG_SET_N(reg, 2, init_value, \
69 				FN(reg, f1), v1,\
70 				FN(reg, f2), v2)
71 
72 #define REG_SET_3(reg, init_value, f1, v1, f2, v2, f3, v3)	\
73 		REG_SET_N(reg, 3, init_value, \
74 				FN(reg, f1), v1,\
75 				FN(reg, f2), v2,\
76 				FN(reg, f3), v3)
77 
78 #define REG_SET_4(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4)	\
79 		REG_SET_N(reg, 4, init_value, \
80 				FN(reg, f1), v1,\
81 				FN(reg, f2), v2,\
82 				FN(reg, f3), v3,\
83 				FN(reg, f4), v4)
84 
85 #define REG_SET_5(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
86 		f5, v5)	\
87 		REG_SET_N(reg, 5, init_value, \
88 				FN(reg, f1), v1,\
89 				FN(reg, f2), v2,\
90 				FN(reg, f3), v3,\
91 				FN(reg, f4), v4,\
92 				FN(reg, f5), v5)
93 
94 #define REG_SET_6(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
95 		f5, v5, f6, v6)	\
96 		REG_SET_N(reg, 6, init_value, \
97 				FN(reg, f1), v1,\
98 				FN(reg, f2), v2,\
99 				FN(reg, f3), v3,\
100 				FN(reg, f4), v4,\
101 				FN(reg, f5), v5,\
102 				FN(reg, f6), v6)
103 
104 #define REG_SET_7(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
105 		f5, v5, f6, v6, f7, v7)	\
106 		REG_SET_N(reg, 7, init_value, \
107 				FN(reg, f1), v1,\
108 				FN(reg, f2), v2,\
109 				FN(reg, f3), v3,\
110 				FN(reg, f4), v4,\
111 				FN(reg, f5), v5,\
112 				FN(reg, f6), v6,\
113 				FN(reg, f7), v7)
114 
115 #define REG_SET_8(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
116 		f5, v5, f6, v6, f7, v7, f8, v8)	\
117 		REG_SET_N(reg, 8, init_value, \
118 				FN(reg, f1), v1,\
119 				FN(reg, f2), v2,\
120 				FN(reg, f3), v3,\
121 				FN(reg, f4), v4,\
122 				FN(reg, f5), v5,\
123 				FN(reg, f6), v6,\
124 				FN(reg, f7), v7,\
125 				FN(reg, f8), v8)
126 
127 #define REG_SET_9(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
128 		v5, f6, v6, f7, v7, f8, v8, f9, v9)	\
129 		REG_SET_N(reg, 9, init_value, \
130 				FN(reg, f1), v1,\
131 				FN(reg, f2), v2, \
132 				FN(reg, f3), v3, \
133 				FN(reg, f4), v4, \
134 				FN(reg, f5), v5, \
135 				FN(reg, f6), v6, \
136 				FN(reg, f7), v7, \
137 				FN(reg, f8), v8, \
138 				FN(reg, f9), v9)
139 
140 #define REG_SET_10(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
141 		v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10)	\
142 		REG_SET_N(reg, 10, init_value, \
143 				FN(reg, f1), v1,\
144 				FN(reg, f2), v2, \
145 				FN(reg, f3), v3, \
146 				FN(reg, f4), v4, \
147 				FN(reg, f5), v5, \
148 				FN(reg, f6), v6, \
149 				FN(reg, f7), v7, \
150 				FN(reg, f8), v8, \
151 				FN(reg, f9), v9, \
152 				FN(reg, f10), v10)
153 
154 /* macro to get register fields
155  * read given register and fill in field value in output parameter */
156 #define REG_GET(reg_name, field, val)	\
157 		generic_reg_get(CTX, REG(reg_name), \
158 				FN(reg_name, field), val)
159 
160 #define REG_GET_2(reg_name, f1, v1, f2, v2)	\
161 		generic_reg_get2(CTX, REG(reg_name), \
162 				FN(reg_name, f1), v1, \
163 				FN(reg_name, f2), v2)
164 
165 #define REG_GET_3(reg_name, f1, v1, f2, v2, f3, v3)	\
166 		generic_reg_get3(CTX, REG(reg_name), \
167 				FN(reg_name, f1), v1, \
168 				FN(reg_name, f2), v2, \
169 				FN(reg_name, f3), v3)
170 
171 #define REG_GET_4(reg_name, f1, v1, f2, v2, f3, v3, f4, v4)	\
172 		generic_reg_get4(CTX, REG(reg_name), \
173 				FN(reg_name, f1), v1, \
174 				FN(reg_name, f2), v2, \
175 				FN(reg_name, f3), v3, \
176 				FN(reg_name, f4), v4)
177 
178 #define REG_GET_5(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)	\
179 		generic_reg_get5(CTX, REG(reg_name), \
180 				FN(reg_name, f1), v1, \
181 				FN(reg_name, f2), v2, \
182 				FN(reg_name, f3), v3, \
183 				FN(reg_name, f4), v4, \
184 				FN(reg_name, f5), v5)
185 
186 /* macro to poll and wait for a register field to read back given value */
187 
188 #define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try)	\
189 		generic_reg_wait(CTX, \
190 				REG(reg_name), FN(reg_name, field), val,\
191 				delay_between_poll_us, max_try, __func__, __LINE__)
192 
193 /* macro to update (read, modify, write) register fields
194  */
195 #define REG_UPDATE_N(reg_name, n, ...)	\
196 		generic_reg_update_ex(CTX, \
197 				REG(reg_name), \
198 				REG_READ(reg_name), \
199 				n, __VA_ARGS__)
200 
201 #define REG_UPDATE(reg_name, field, val)	\
202 		REG_UPDATE_N(reg_name, 1, \
203 				FN(reg_name, field), val)
204 
205 #define REG_UPDATE_2(reg, f1, v1, f2, v2)	\
206 		REG_UPDATE_N(reg, 2,\
207 				FN(reg, f1), v1,\
208 				FN(reg, f2), v2)
209 
210 #define REG_UPDATE_3(reg, f1, v1, f2, v2, f3, v3)	\
211 		REG_UPDATE_N(reg, 3, \
212 				FN(reg, f1), v1,\
213 				FN(reg, f2), v2, \
214 				FN(reg, f3), v3)
215 
216 #define REG_UPDATE_4(reg, f1, v1, f2, v2, f3, v3, f4, v4)	\
217 		REG_UPDATE_N(reg, 4, \
218 				FN(reg, f1), v1,\
219 				FN(reg, f2), v2, \
220 				FN(reg, f3), v3, \
221 				FN(reg, f4), v4)
222 
223 #define REG_UPDATE_5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)	\
224 		REG_UPDATE_N(reg, 5, \
225 				FN(reg, f1), v1,\
226 				FN(reg, f2), v2, \
227 				FN(reg, f3), v3, \
228 				FN(reg, f4), v4, \
229 				FN(reg, f5), v5)
230 
231 #define REG_UPDATE_6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)	\
232 		REG_UPDATE_N(reg, 6, \
233 				FN(reg, f1), v1,\
234 				FN(reg, f2), v2, \
235 				FN(reg, f3), v3, \
236 				FN(reg, f4), v4, \
237 				FN(reg, f5), v5, \
238 				FN(reg, f6), v6)
239 
240 #define REG_UPDATE_7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)	\
241 		REG_UPDATE_N(reg, 7, \
242 				FN(reg, f1), v1,\
243 				FN(reg, f2), v2, \
244 				FN(reg, f3), v3, \
245 				FN(reg, f4), v4, \
246 				FN(reg, f5), v5, \
247 				FN(reg, f6), v6, \
248 				FN(reg, f7), v7)
249 
250 #define REG_UPDATE_8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)	\
251 		REG_UPDATE_N(reg, 8, \
252 				FN(reg, f1), v1,\
253 				FN(reg, f2), v2, \
254 				FN(reg, f3), v3, \
255 				FN(reg, f4), v4, \
256 				FN(reg, f5), v5, \
257 				FN(reg, f6), v6, \
258 				FN(reg, f7), v7, \
259 				FN(reg, f8), v8)
260 
261 #define REG_UPDATE_9(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9)	\
262 		REG_UPDATE_N(reg, 9, \
263 				FN(reg, f1), v1,\
264 				FN(reg, f2), v2, \
265 				FN(reg, f3), v3, \
266 				FN(reg, f4), v4, \
267 				FN(reg, f5), v5, \
268 				FN(reg, f6), v6, \
269 				FN(reg, f7), v7, \
270 				FN(reg, f8), v8, \
271 				FN(reg, f9), v9)
272 
273 #define REG_UPDATE_10(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10)\
274 		REG_UPDATE_N(reg, 10, \
275 				FN(reg, f1), v1,\
276 				FN(reg, f2), v2, \
277 				FN(reg, f3), v3, \
278 				FN(reg, f4), v4, \
279 				FN(reg, f5), v5, \
280 				FN(reg, f6), v6, \
281 				FN(reg, f7), v7, \
282 				FN(reg, f8), v8, \
283 				FN(reg, f9), v9, \
284 				FN(reg, f10), v10)
285 
286 #define REG_UPDATE_14(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
287 		v10, f11, v11, f12, v12, f13, v13, f14, v14)\
288 		REG_UPDATE_N(reg, 14, \
289 				FN(reg, f1), v1,\
290 				FN(reg, f2), v2, \
291 				FN(reg, f3), v3, \
292 				FN(reg, f4), v4, \
293 				FN(reg, f5), v5, \
294 				FN(reg, f6), v6, \
295 				FN(reg, f7), v7, \
296 				FN(reg, f8), v8, \
297 				FN(reg, f9), v9, \
298 				FN(reg, f10), v10, \
299 				FN(reg, f11), v11, \
300 				FN(reg, f12), v12, \
301 				FN(reg, f13), v13, \
302 				FN(reg, f14), v14)
303 
304 #define REG_UPDATE_19(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
305 		v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19)\
306 		REG_UPDATE_N(reg, 19, \
307 				FN(reg, f1), v1,\
308 				FN(reg, f2), v2, \
309 				FN(reg, f3), v3, \
310 				FN(reg, f4), v4, \
311 				FN(reg, f5), v5, \
312 				FN(reg, f6), v6, \
313 				FN(reg, f7), v7, \
314 				FN(reg, f8), v8, \
315 				FN(reg, f9), v9, \
316 				FN(reg, f10), v10, \
317 				FN(reg, f11), v11, \
318 				FN(reg, f12), v12, \
319 				FN(reg, f13), v13, \
320 				FN(reg, f14), v14, \
321 				FN(reg, f15), v15, \
322 				FN(reg, f16), v16, \
323 				FN(reg, f17), v17, \
324 				FN(reg, f18), v18, \
325 				FN(reg, f19), v19)
326 
327 #define REG_UPDATE_20(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
328 		v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19, f20, v20)\
329 		REG_UPDATE_N(reg, 20, \
330 				FN(reg, f1), v1,\
331 				FN(reg, f2), v2, \
332 				FN(reg, f3), v3, \
333 				FN(reg, f4), v4, \
334 				FN(reg, f5), v5, \
335 				FN(reg, f6), v6, \
336 				FN(reg, f7), v7, \
337 				FN(reg, f8), v8, \
338 				FN(reg, f9), v9, \
339 				FN(reg, f10), v10, \
340 				FN(reg, f11), v11, \
341 				FN(reg, f12), v12, \
342 				FN(reg, f13), v13, \
343 				FN(reg, f14), v14, \
344 				FN(reg, f15), v15, \
345 				FN(reg, f16), v16, \
346 				FN(reg, f17), v17, \
347 				FN(reg, f18), v18, \
348 				FN(reg, f19), v19, \
349 				FN(reg, f20), v20)
350 /* macro to update a register field to specified values in given sequences.
351  * useful when toggling bits
352  */
353 #define REG_UPDATE_SEQ(reg, field, value1, value2) \
354 {	uint32_t val = REG_UPDATE(reg, field, value1); \
355 	REG_SET(reg, val, field, value2); }
356 
357 /* macro to update fields in register 1 field at a time in given order */
358 #define REG_UPDATE_1BY1_2(reg, f1, v1, f2, v2) \
359 {	uint32_t val = REG_UPDATE(reg, f1, v1); \
360 	REG_SET(reg, val, f2, v2); }
361 
362 #define REG_UPDATE_1BY1_3(reg, f1, v1, f2, v2, f3, v3) \
363 {	uint32_t val = REG_UPDATE(reg, f1, v1); \
364 	val = REG_SET(reg, val, f2, v2); \
365 	REG_SET(reg, val, f3, v3); }
366 
367 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
368 		uint8_t shift, uint32_t mask, uint32_t *field_value);
369 
370 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
371 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
372 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2);
373 
374 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
375 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
376 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
377 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3);
378 
379 uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr,
380 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
381 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
382 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
383 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4);
384 
385 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
386 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
387 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
388 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
389 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
390 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5);
391 
392 #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */
393