Merge tag 'drm-intel-next-2018-05-14' of git://anongit.freedesktop.org/drm/drm-intel...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / display / dc / inc / reg_helper.h
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_ */