xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/amd/display/dc/inc/reg_helper.h (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: reg_helper.h,v 1.2 2021/12/18 23:45:05 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2016 Advanced Micro Devices, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: AMD
25  */
26 
27 #ifndef DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
28 #define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
29 
30 #include "dm_services.h"
31 
32 /* macro for register read/write
33  * user of macro need to define
34  *
35  * CTX ==> macro to ptr to dc_context
36  *    eg. aud110->base.ctx
37  *
38  * REG ==> macro to location of register offset
39  *    eg. aud110->regs->reg
40  */
41 #define REG_READ(reg_name) \
42 		dm_read_reg(CTX, REG(reg_name))
43 
44 #define REG_WRITE(reg_name, value) \
45 		dm_write_reg(CTX, REG(reg_name), value)
46 
47 #ifdef REG_SET
48 #undef REG_SET
49 #endif
50 
51 #ifdef REG_GET
52 #undef REG_GET
53 #endif
54 
55 /* macro to set register fields. */
56 #define REG_SET_N(reg_name, n, initial_val, ...)	\
57 		generic_reg_set_ex(CTX, \
58 				REG(reg_name), \
59 				initial_val, \
60 				n, __VA_ARGS__)
61 
62 #define FN(reg_name, field) \
63 	FD(reg_name##__##field)
64 
65 #define REG_SET(reg_name, initial_val, field, val)	\
66 		REG_SET_N(reg_name, 1, initial_val, \
67 				FN(reg_name, field), val)
68 
69 #define REG_SET_2(reg, init_value, f1, v1, f2, v2)	\
70 		REG_SET_N(reg, 2, init_value, \
71 				FN(reg, f1), v1,\
72 				FN(reg, f2), v2)
73 
74 #define REG_SET_3(reg, init_value, f1, v1, f2, v2, f3, v3)	\
75 		REG_SET_N(reg, 3, init_value, \
76 				FN(reg, f1), v1,\
77 				FN(reg, f2), v2,\
78 				FN(reg, f3), v3)
79 
80 #define REG_SET_4(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4)	\
81 		REG_SET_N(reg, 4, init_value, \
82 				FN(reg, f1), v1,\
83 				FN(reg, f2), v2,\
84 				FN(reg, f3), v3,\
85 				FN(reg, f4), v4)
86 
87 #define REG_SET_5(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
88 		f5, v5)	\
89 		REG_SET_N(reg, 5, init_value, \
90 				FN(reg, f1), v1,\
91 				FN(reg, f2), v2,\
92 				FN(reg, f3), v3,\
93 				FN(reg, f4), v4,\
94 				FN(reg, f5), v5)
95 
96 #define REG_SET_6(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
97 		f5, v5, f6, v6)	\
98 		REG_SET_N(reg, 6, init_value, \
99 				FN(reg, f1), v1,\
100 				FN(reg, f2), v2,\
101 				FN(reg, f3), v3,\
102 				FN(reg, f4), v4,\
103 				FN(reg, f5), v5,\
104 				FN(reg, f6), v6)
105 
106 #define REG_SET_7(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
107 		f5, v5, f6, v6, f7, v7)	\
108 		REG_SET_N(reg, 7, init_value, \
109 				FN(reg, f1), v1,\
110 				FN(reg, f2), v2,\
111 				FN(reg, f3), v3,\
112 				FN(reg, f4), v4,\
113 				FN(reg, f5), v5,\
114 				FN(reg, f6), v6,\
115 				FN(reg, f7), v7)
116 
117 #define REG_SET_8(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
118 		f5, v5, f6, v6, f7, v7, f8, v8)	\
119 		REG_SET_N(reg, 8, init_value, \
120 				FN(reg, f1), v1,\
121 				FN(reg, f2), v2,\
122 				FN(reg, f3), v3,\
123 				FN(reg, f4), v4,\
124 				FN(reg, f5), v5,\
125 				FN(reg, f6), v6,\
126 				FN(reg, f7), v7,\
127 				FN(reg, f8), v8)
128 
129 #define REG_SET_9(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
130 		v5, f6, v6, f7, v7, f8, v8, f9, v9)	\
131 		REG_SET_N(reg, 9, init_value, \
132 				FN(reg, f1), v1,\
133 				FN(reg, f2), v2, \
134 				FN(reg, f3), v3, \
135 				FN(reg, f4), v4, \
136 				FN(reg, f5), v5, \
137 				FN(reg, f6), v6, \
138 				FN(reg, f7), v7, \
139 				FN(reg, f8), v8, \
140 				FN(reg, f9), v9)
141 
142 #define REG_SET_10(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
143 		v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10)	\
144 		REG_SET_N(reg, 10, init_value, \
145 				FN(reg, f1), v1,\
146 				FN(reg, f2), v2, \
147 				FN(reg, f3), v3, \
148 				FN(reg, f4), v4, \
149 				FN(reg, f5), v5, \
150 				FN(reg, f6), v6, \
151 				FN(reg, f7), v7, \
152 				FN(reg, f8), v8, \
153 				FN(reg, f9), v9, \
154 				FN(reg, f10), v10)
155 
156 /* macro to get register fields
157  * read given register and fill in field value in output parameter */
158 #define REG_GET(reg_name, field, val)	\
159 		generic_reg_get(CTX, REG(reg_name), \
160 				FN(reg_name, field), val)
161 
162 #define REG_GET_2(reg_name, f1, v1, f2, v2)	\
163 		generic_reg_get2(CTX, REG(reg_name), \
164 				FN(reg_name, f1), v1, \
165 				FN(reg_name, f2), v2)
166 
167 #define REG_GET_3(reg_name, f1, v1, f2, v2, f3, v3)	\
168 		generic_reg_get3(CTX, REG(reg_name), \
169 				FN(reg_name, f1), v1, \
170 				FN(reg_name, f2), v2, \
171 				FN(reg_name, f3), v3)
172 
173 #define REG_GET_4(reg_name, f1, v1, f2, v2, f3, v3, f4, v4)	\
174 		generic_reg_get4(CTX, REG(reg_name), \
175 				FN(reg_name, f1), v1, \
176 				FN(reg_name, f2), v2, \
177 				FN(reg_name, f3), v3, \
178 				FN(reg_name, f4), v4)
179 
180 #define REG_GET_5(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)	\
181 		generic_reg_get5(CTX, REG(reg_name), \
182 				FN(reg_name, f1), v1, \
183 				FN(reg_name, f2), v2, \
184 				FN(reg_name, f3), v3, \
185 				FN(reg_name, f4), v4, \
186 				FN(reg_name, f5), v5)
187 
188 #define REG_GET_6(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)	\
189 		generic_reg_get6(CTX, REG(reg_name), \
190 				FN(reg_name, f1), v1, \
191 				FN(reg_name, f2), v2, \
192 				FN(reg_name, f3), v3, \
193 				FN(reg_name, f4), v4, \
194 				FN(reg_name, f5), v5, \
195 				FN(reg_name, f6), v6)
196 
197 #define REG_GET_7(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)	\
198 		generic_reg_get7(CTX, REG(reg_name), \
199 				FN(reg_name, f1), v1, \
200 				FN(reg_name, f2), v2, \
201 				FN(reg_name, f3), v3, \
202 				FN(reg_name, f4), v4, \
203 				FN(reg_name, f5), v5, \
204 				FN(reg_name, f6), v6, \
205 				FN(reg_name, f7), v7)
206 
207 #define REG_GET_8(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)	\
208 		generic_reg_get8(CTX, REG(reg_name), \
209 				FN(reg_name, f1), v1, \
210 				FN(reg_name, f2), v2, \
211 				FN(reg_name, f3), v3, \
212 				FN(reg_name, f4), v4, \
213 				FN(reg_name, f5), v5, \
214 				FN(reg_name, f6), v6, \
215 				FN(reg_name, f7), v7, \
216 				FN(reg_name, f8), v8)
217 
218 /* macro to poll and wait for a register field to read back given value */
219 
220 #define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try)	\
221 		generic_reg_wait(CTX, \
222 				REG(reg_name), FN(reg_name, field), val,\
223 				delay_between_poll_us, max_try, __func__, __LINE__)
224 
225 /* macro to update (read, modify, write) register fields
226  */
227 #define REG_UPDATE_N(reg_name, n, ...)	\
228 		generic_reg_update_ex(CTX, \
229 				REG(reg_name), \
230 				n, __VA_ARGS__)
231 
232 #define REG_UPDATE(reg_name, field, val)	\
233 		REG_UPDATE_N(reg_name, 1, \
234 				FN(reg_name, field), val)
235 
236 #define REG_UPDATE_2(reg, f1, v1, f2, v2)	\
237 		REG_UPDATE_N(reg, 2,\
238 				FN(reg, f1), v1,\
239 				FN(reg, f2), v2)
240 
241 #define REG_UPDATE_3(reg, f1, v1, f2, v2, f3, v3)	\
242 		REG_UPDATE_N(reg, 3, \
243 				FN(reg, f1), v1,\
244 				FN(reg, f2), v2, \
245 				FN(reg, f3), v3)
246 
247 #define REG_UPDATE_4(reg, f1, v1, f2, v2, f3, v3, f4, v4)	\
248 		REG_UPDATE_N(reg, 4, \
249 				FN(reg, f1), v1,\
250 				FN(reg, f2), v2, \
251 				FN(reg, f3), v3, \
252 				FN(reg, f4), v4)
253 
254 #define REG_UPDATE_5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)	\
255 		REG_UPDATE_N(reg, 5, \
256 				FN(reg, f1), v1,\
257 				FN(reg, f2), v2, \
258 				FN(reg, f3), v3, \
259 				FN(reg, f4), v4, \
260 				FN(reg, f5), v5)
261 
262 #define REG_UPDATE_6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)	\
263 		REG_UPDATE_N(reg, 6, \
264 				FN(reg, f1), v1,\
265 				FN(reg, f2), v2, \
266 				FN(reg, f3), v3, \
267 				FN(reg, f4), v4, \
268 				FN(reg, f5), v5, \
269 				FN(reg, f6), v6)
270 
271 #define REG_UPDATE_7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)	\
272 		REG_UPDATE_N(reg, 7, \
273 				FN(reg, f1), v1,\
274 				FN(reg, f2), v2, \
275 				FN(reg, f3), v3, \
276 				FN(reg, f4), v4, \
277 				FN(reg, f5), v5, \
278 				FN(reg, f6), v6, \
279 				FN(reg, f7), v7)
280 
281 #define REG_UPDATE_8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)	\
282 		REG_UPDATE_N(reg, 8, \
283 				FN(reg, f1), v1,\
284 				FN(reg, f2), v2, \
285 				FN(reg, f3), v3, \
286 				FN(reg, f4), v4, \
287 				FN(reg, f5), v5, \
288 				FN(reg, f6), v6, \
289 				FN(reg, f7), v7, \
290 				FN(reg, f8), v8)
291 
292 #define REG_UPDATE_9(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9)	\
293 		REG_UPDATE_N(reg, 9, \
294 				FN(reg, f1), v1,\
295 				FN(reg, f2), v2, \
296 				FN(reg, f3), v3, \
297 				FN(reg, f4), v4, \
298 				FN(reg, f5), v5, \
299 				FN(reg, f6), v6, \
300 				FN(reg, f7), v7, \
301 				FN(reg, f8), v8, \
302 				FN(reg, f9), v9)
303 
304 #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)\
305 		REG_UPDATE_N(reg, 10, \
306 				FN(reg, f1), v1,\
307 				FN(reg, f2), v2, \
308 				FN(reg, f3), v3, \
309 				FN(reg, f4), v4, \
310 				FN(reg, f5), v5, \
311 				FN(reg, f6), v6, \
312 				FN(reg, f7), v7, \
313 				FN(reg, f8), v8, \
314 				FN(reg, f9), v9, \
315 				FN(reg, f10), v10)
316 
317 #define REG_UPDATE_14(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
318 		v10, f11, v11, f12, v12, f13, v13, f14, v14)\
319 		REG_UPDATE_N(reg, 14, \
320 				FN(reg, f1), v1,\
321 				FN(reg, f2), v2, \
322 				FN(reg, f3), v3, \
323 				FN(reg, f4), v4, \
324 				FN(reg, f5), v5, \
325 				FN(reg, f6), v6, \
326 				FN(reg, f7), v7, \
327 				FN(reg, f8), v8, \
328 				FN(reg, f9), v9, \
329 				FN(reg, f10), v10, \
330 				FN(reg, f11), v11, \
331 				FN(reg, f12), v12, \
332 				FN(reg, f13), v13, \
333 				FN(reg, f14), v14)
334 
335 #define REG_UPDATE_19(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
336 		v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19)\
337 		REG_UPDATE_N(reg, 19, \
338 				FN(reg, f1), v1,\
339 				FN(reg, f2), v2, \
340 				FN(reg, f3), v3, \
341 				FN(reg, f4), v4, \
342 				FN(reg, f5), v5, \
343 				FN(reg, f6), v6, \
344 				FN(reg, f7), v7, \
345 				FN(reg, f8), v8, \
346 				FN(reg, f9), v9, \
347 				FN(reg, f10), v10, \
348 				FN(reg, f11), v11, \
349 				FN(reg, f12), v12, \
350 				FN(reg, f13), v13, \
351 				FN(reg, f14), v14, \
352 				FN(reg, f15), v15, \
353 				FN(reg, f16), v16, \
354 				FN(reg, f17), v17, \
355 				FN(reg, f18), v18, \
356 				FN(reg, f19), v19)
357 
358 #define REG_UPDATE_20(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
359 		v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19, f20, v20)\
360 		REG_UPDATE_N(reg, 20, \
361 				FN(reg, f1), v1,\
362 				FN(reg, f2), v2, \
363 				FN(reg, f3), v3, \
364 				FN(reg, f4), v4, \
365 				FN(reg, f5), v5, \
366 				FN(reg, f6), v6, \
367 				FN(reg, f7), v7, \
368 				FN(reg, f8), v8, \
369 				FN(reg, f9), v9, \
370 				FN(reg, f10), v10, \
371 				FN(reg, f11), v11, \
372 				FN(reg, f12), v12, \
373 				FN(reg, f13), v13, \
374 				FN(reg, f14), v14, \
375 				FN(reg, f15), v15, \
376 				FN(reg, f16), v16, \
377 				FN(reg, f17), v17, \
378 				FN(reg, f18), v18, \
379 				FN(reg, f19), v19, \
380 				FN(reg, f20), v20)
381 /* macro to update a register field to specified values in given sequences.
382  * useful when toggling bits
383  */
384 #define REG_UPDATE_SEQ_2(reg, f1, v1, f2, v2) \
385 {	uint32_t val = REG_UPDATE(reg, f1, v1); \
386 	REG_SET(reg, val, f2, v2); }
387 
388 #define REG_UPDATE_SEQ_3(reg, f1, v1, f2, v2, f3, v3) \
389 {	uint32_t val = REG_UPDATE(reg, f1, v1); \
390 	val = REG_SET(reg, val, f2, v2); \
391 	REG_SET(reg, val, f3, v3); }
392 
393 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
394 		uint8_t shift, uint32_t mask, uint32_t *field_value);
395 
396 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
397 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
398 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2);
399 
400 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
401 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
402 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
403 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3);
404 
405 uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr,
406 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
407 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
408 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
409 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4);
410 
411 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
412 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
413 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
414 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
415 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
416 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5);
417 
418 uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
419 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
420 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
421 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
422 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
423 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
424 		uint8_t shift6, uint32_t mask6, uint32_t *field_value6);
425 
426 uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
427 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
428 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
429 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
430 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
431 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
432 		uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
433 		uint8_t shift7, uint32_t mask7, uint32_t *field_value7);
434 
435 uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
436 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
437 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
438 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
439 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
440 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
441 		uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
442 		uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
443 		uint8_t shift8, uint32_t mask8, uint32_t *field_value8);
444 
445 
446 /* indirect register access */
447 
448 #define IX_REG_SET_N(index_reg_name, data_reg_name, index, n, initial_val, ...)	\
449 		generic_indirect_reg_update_ex(CTX, \
450 				REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
451 				initial_val, \
452 				n, __VA_ARGS__)
453 
454 #define IX_REG_SET_2(index_reg_name, data_reg_name, index, init_value, f1, v1, f2, v2)	\
455 		IX_REG_SET_N(index_reg_name, data_reg_name, index, 2, init_value, \
456 				FN(reg, f1), v1,\
457 				FN(reg, f2), v2)
458 
459 
460 #define IX_REG_READ(index_reg_name, data_reg_name, index) \
461 		generic_read_indirect_reg(CTX, REG(index_reg_name), REG(data_reg_name), IND_REG(index))
462 
463 #define IX_REG_GET_N(index_reg_name, data_reg_name, index, n, ...) \
464 		generic_indirect_reg_get(CTX, REG(index_reg_name), REG(data_reg_name), \
465 				IND_REG(index), \
466 				n, __VA_ARGS__)
467 
468 #define IX_REG_GET(index_reg_name, data_reg_name, index, field, val) \
469 		IX_REG_GET_N(index_reg_name, data_reg_name, index, 1, \
470 				FN(data_reg_name, field), val)
471 
472 #define IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, n, ...)	\
473 		generic_indirect_reg_update_ex(CTX, \
474 				REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
475 				IX_REG_READ(index_reg_name, data_reg_name, index), \
476 				n, __VA_ARGS__)
477 
478 #define IX_REG_UPDATE_2(index_reg_name, data_reg_name, index, f1, v1, f2, v2)	\
479 		IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, 2,\
480 				FN(reg, f1), v1,\
481 				FN(reg, f2), v2)
482 
483 void generic_write_indirect_reg(const struct dc_context *ctx,
484 		uint32_t addr_index, uint32_t addr_data,
485 		uint32_t index, uint32_t data);
486 
487 uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
488 		uint32_t addr_index, uint32_t addr_data,
489 		uint32_t index);
490 
491 uint32_t generic_indirect_reg_get(const struct dc_context *ctx,
492 		uint32_t addr_index, uint32_t addr_data,
493 		uint32_t index, int n,
494 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
495 		...);
496 
497 uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
498 		uint32_t addr_index, uint32_t addr_data,
499 		uint32_t index, uint32_t reg_val, int n,
500 		uint8_t shift1, uint32_t mask1, uint32_t field_value1,
501 		...);
502 
503 /* register offload macros
504  *
505  * instead of MMIO to register directly, in some cases we want
506  * to gather register sequence and execute the register sequence
507  * from another thread so we optimize time required for lengthy ops
508  */
509 
510 /* start gathering register sequence */
511 #define REG_SEQ_START() \
512 	reg_sequence_start_gather(CTX)
513 
514 /* start execution of register sequence gathered since REG_SEQ_START */
515 #define REG_SEQ_SUBMIT() \
516 	reg_sequence_start_execute(CTX)
517 
518 /* wait for the last REG_SEQ_SUBMIT to finish */
519 #define REG_SEQ_WAIT_DONE() \
520 	reg_sequence_wait_done(CTX)
521 
522 #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */
523