This source file includes following definitions.
- set_reg_field_value_masks
- set_reg_field_values
- generic_reg_update_ex
- generic_reg_set_ex
- dm_read_reg_func
- generic_reg_get
- generic_reg_get2
- generic_reg_get3
- generic_reg_get4
- generic_reg_get5
- generic_reg_get6
- generic_reg_get7
- generic_reg_get8
- generic_reg_wait
- generic_write_indirect_reg
- generic_read_indirect_reg
- generic_indirect_reg_update_ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/delay.h>
31
32 #include "dm_services.h"
33 #include <stdarg.h>
34
35 struct dc_reg_value_masks {
36 uint32_t value;
37 uint32_t mask;
38 };
39
40 struct dc_reg_sequence {
41 uint32_t addr;
42 struct dc_reg_value_masks value_masks;
43 };
44
45 static inline void set_reg_field_value_masks(
46 struct dc_reg_value_masks *field_value_mask,
47 uint32_t value,
48 uint32_t mask,
49 uint8_t shift)
50 {
51 ASSERT(mask != 0);
52
53 field_value_mask->value = (field_value_mask->value & ~mask) | (mask & (value << shift));
54 field_value_mask->mask = field_value_mask->mask | mask;
55 }
56
57 static void set_reg_field_values(struct dc_reg_value_masks *field_value_mask,
58 uint32_t addr, int n,
59 uint8_t shift1, uint32_t mask1, uint32_t field_value1,
60 va_list ap)
61 {
62 uint32_t shift, mask, field_value;
63 int i = 1;
64
65
66 set_reg_field_value_masks(field_value_mask,
67 field_value1, mask1, shift1);
68
69 while (i < n) {
70 shift = va_arg(ap, uint32_t);
71 mask = va_arg(ap, uint32_t);
72 field_value = va_arg(ap, uint32_t);
73
74 set_reg_field_value_masks(field_value_mask,
75 field_value, mask, shift);
76 i++;
77 }
78 }
79
80 uint32_t generic_reg_update_ex(const struct dc_context *ctx,
81 uint32_t addr, int n,
82 uint8_t shift1, uint32_t mask1, uint32_t field_value1,
83 ...)
84 {
85 struct dc_reg_value_masks field_value_mask = {0};
86 uint32_t reg_val;
87 va_list ap;
88
89 va_start(ap, field_value1);
90
91 set_reg_field_values(&field_value_mask, addr, n, shift1, mask1,
92 field_value1, ap);
93
94 va_end(ap);
95
96
97 reg_val = dm_read_reg(ctx, addr);
98 reg_val = (reg_val & ~field_value_mask.mask) | field_value_mask.value;
99 dm_write_reg(ctx, addr, reg_val);
100 return reg_val;
101 }
102
103 uint32_t generic_reg_set_ex(const struct dc_context *ctx,
104 uint32_t addr, uint32_t reg_val, int n,
105 uint8_t shift1, uint32_t mask1, uint32_t field_value1,
106 ...)
107 {
108 struct dc_reg_value_masks field_value_mask = {0};
109 va_list ap;
110
111 va_start(ap, field_value1);
112
113 set_reg_field_values(&field_value_mask, addr, n, shift1, mask1,
114 field_value1, ap);
115
116 va_end(ap);
117
118
119
120 reg_val = (reg_val & ~field_value_mask.mask) | field_value_mask.value;
121 dm_write_reg(ctx, addr, reg_val);
122 return reg_val;
123 }
124
125 uint32_t dm_read_reg_func(
126 const struct dc_context *ctx,
127 uint32_t address,
128 const char *func_name)
129 {
130 uint32_t value;
131 #ifdef DM_CHECK_ADDR_0
132 if (address == 0) {
133 DC_ERR("invalid register read; address = 0\n");
134 return 0;
135 }
136 #endif
137 value = cgs_read_register(ctx->cgs_device, address);
138 trace_amdgpu_dc_rreg(&ctx->perf_trace->read_count, address, value);
139
140 return value;
141 }
142
143 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
144 uint8_t shift, uint32_t mask, uint32_t *field_value)
145 {
146 uint32_t reg_val = dm_read_reg(ctx, addr);
147 *field_value = get_reg_field_value_ex(reg_val, mask, shift);
148 return reg_val;
149 }
150
151 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
152 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
153 uint8_t shift2, uint32_t mask2, uint32_t *field_value2)
154 {
155 uint32_t reg_val = dm_read_reg(ctx, addr);
156 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
157 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
158 return reg_val;
159 }
160
161 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
162 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
163 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
164 uint8_t shift3, uint32_t mask3, uint32_t *field_value3)
165 {
166 uint32_t reg_val = dm_read_reg(ctx, addr);
167 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
168 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
169 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
170 return reg_val;
171 }
172
173 uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr,
174 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
175 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
176 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
177 uint8_t shift4, uint32_t mask4, uint32_t *field_value4)
178 {
179 uint32_t reg_val = dm_read_reg(ctx, addr);
180 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
181 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
182 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
183 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
184 return reg_val;
185 }
186
187 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
188 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
189 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
190 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
191 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
192 uint8_t shift5, uint32_t mask5, uint32_t *field_value5)
193 {
194 uint32_t reg_val = dm_read_reg(ctx, addr);
195 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
196 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
197 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
198 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
199 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
200 return reg_val;
201 }
202
203 uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
204 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
205 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
206 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
207 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
208 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
209 uint8_t shift6, uint32_t mask6, uint32_t *field_value6)
210 {
211 uint32_t reg_val = dm_read_reg(ctx, addr);
212 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
213 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
214 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
215 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
216 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
217 *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
218 return reg_val;
219 }
220
221 uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
222 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
223 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
224 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
225 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
226 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
227 uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
228 uint8_t shift7, uint32_t mask7, uint32_t *field_value7)
229 {
230 uint32_t reg_val = dm_read_reg(ctx, addr);
231 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
232 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
233 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
234 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
235 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
236 *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
237 *field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7);
238 return reg_val;
239 }
240
241 uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
242 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
243 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
244 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
245 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
246 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
247 uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
248 uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
249 uint8_t shift8, uint32_t mask8, uint32_t *field_value8)
250 {
251 uint32_t reg_val = dm_read_reg(ctx, addr);
252 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
253 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
254 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
255 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
256 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
257 *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
258 *field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7);
259 *field_value8 = get_reg_field_value_ex(reg_val, mask8, shift8);
260 return reg_val;
261 }
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 void generic_reg_wait(const struct dc_context *ctx,
294 uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value,
295 unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
296 const char *func_name, int line)
297 {
298 uint32_t field_value;
299 uint32_t reg_val;
300 int i;
301
302
303 ASSERT(delay_between_poll_us * time_out_num_tries <= 3000000);
304
305 for (i = 0; i <= time_out_num_tries; i++) {
306 if (i) {
307 if (delay_between_poll_us >= 1000)
308 msleep(delay_between_poll_us/1000);
309 else if (delay_between_poll_us > 0)
310 udelay(delay_between_poll_us);
311 }
312
313 reg_val = dm_read_reg(ctx, addr);
314
315 field_value = get_reg_field_value_ex(reg_val, mask, shift);
316
317 if (field_value == condition_value) {
318 if (i * delay_between_poll_us > 1000 &&
319 !IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
320 DC_LOG_DC("REG_WAIT taking a while: %dms in %s line:%d\n",
321 delay_between_poll_us * i / 1000,
322 func_name, line);
323 return;
324 }
325 }
326
327 DC_LOG_WARNING("REG_WAIT timeout %dus * %d tries - %s line:%d\n",
328 delay_between_poll_us, time_out_num_tries,
329 func_name, line);
330
331 if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
332 BREAK_TO_DEBUGGER();
333 }
334
335 void generic_write_indirect_reg(const struct dc_context *ctx,
336 uint32_t addr_index, uint32_t addr_data,
337 uint32_t index, uint32_t data)
338 {
339 dm_write_reg(ctx, addr_index, index);
340 dm_write_reg(ctx, addr_data, data);
341 }
342
343 uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
344 uint32_t addr_index, uint32_t addr_data,
345 uint32_t index)
346 {
347 uint32_t value = 0;
348
349 dm_write_reg(ctx, addr_index, index);
350 value = dm_read_reg(ctx, addr_data);
351
352 return value;
353 }
354
355
356 uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
357 uint32_t addr_index, uint32_t addr_data,
358 uint32_t index, uint32_t reg_val, int n,
359 uint8_t shift1, uint32_t mask1, uint32_t field_value1,
360 ...)
361 {
362 uint32_t shift, mask, field_value;
363 int i = 1;
364
365 va_list ap;
366
367 va_start(ap, field_value1);
368
369 reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
370
371 while (i < n) {
372 shift = va_arg(ap, uint32_t);
373 mask = va_arg(ap, uint32_t);
374 field_value = va_arg(ap, uint32_t);
375
376 reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift);
377 i++;
378 }
379
380 generic_write_indirect_reg(ctx, addr_index, addr_data, index, reg_val);
381 va_end(ap);
382
383 return reg_val;
384 }