]>
Commit | Line | Data |
---|---|---|
bf93b448 AD |
1 | /* |
2 | * Copyright 2017 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 | */ | |
4562236b HW |
23 | /* |
24 | * dc_helper.c | |
25 | * | |
26 | * Created on: Aug 30, 2016 | |
27 | * Author: agrodzov | |
28 | */ | |
29 | #include "dm_services.h" | |
30 | #include <stdarg.h> | |
31 | ||
32 | uint32_t generic_reg_update_ex(const struct dc_context *ctx, | |
33 | uint32_t addr, uint32_t reg_val, int n, | |
34 | uint8_t shift1, uint32_t mask1, uint32_t field_value1, | |
35 | ...) | |
36 | { | |
37 | uint32_t shift, mask, field_value; | |
38 | int i = 1; | |
39 | ||
40 | va_list ap; | |
41 | va_start(ap, field_value1); | |
42 | ||
43 | reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1); | |
44 | ||
45 | while (i < n) { | |
46 | shift = va_arg(ap, uint32_t); | |
47 | mask = va_arg(ap, uint32_t); | |
48 | field_value = va_arg(ap, uint32_t); | |
49 | ||
50 | reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift); | |
51 | i++; | |
52 | } | |
53 | ||
54 | dm_write_reg(ctx, addr, reg_val); | |
55 | va_end(ap); | |
56 | ||
57 | return reg_val; | |
58 | } | |
59 | ||
60 | uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, | |
61 | uint8_t shift, uint32_t mask, uint32_t *field_value) | |
62 | { | |
63 | uint32_t reg_val = dm_read_reg(ctx, addr); | |
64 | *field_value = get_reg_field_value_ex(reg_val, mask, shift); | |
65 | return reg_val; | |
66 | } | |
67 | ||
68 | uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr, | |
69 | uint8_t shift1, uint32_t mask1, uint32_t *field_value1, | |
70 | uint8_t shift2, uint32_t mask2, uint32_t *field_value2) | |
71 | { | |
72 | uint32_t reg_val = dm_read_reg(ctx, addr); | |
73 | *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); | |
74 | *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); | |
75 | return reg_val; | |
76 | } | |
77 | ||
78 | uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr, | |
79 | uint8_t shift1, uint32_t mask1, uint32_t *field_value1, | |
80 | uint8_t shift2, uint32_t mask2, uint32_t *field_value2, | |
81 | uint8_t shift3, uint32_t mask3, uint32_t *field_value3) | |
82 | { | |
83 | uint32_t reg_val = dm_read_reg(ctx, addr); | |
84 | *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); | |
85 | *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); | |
86 | *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); | |
87 | return reg_val; | |
88 | } | |
89 | ||
98d2cc2b AW |
90 | uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr, |
91 | uint8_t shift1, uint32_t mask1, uint32_t *field_value1, | |
92 | uint8_t shift2, uint32_t mask2, uint32_t *field_value2, | |
93 | uint8_t shift3, uint32_t mask3, uint32_t *field_value3, | |
94 | uint8_t shift4, uint32_t mask4, uint32_t *field_value4) | |
95 | { | |
96 | uint32_t reg_val = dm_read_reg(ctx, addr); | |
97 | *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); | |
98 | *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); | |
99 | *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); | |
100 | *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); | |
101 | return reg_val; | |
102 | } | |
103 | ||
4562236b HW |
104 | uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr, |
105 | uint8_t shift1, uint32_t mask1, uint32_t *field_value1, | |
106 | uint8_t shift2, uint32_t mask2, uint32_t *field_value2, | |
107 | uint8_t shift3, uint32_t mask3, uint32_t *field_value3, | |
108 | uint8_t shift4, uint32_t mask4, uint32_t *field_value4, | |
109 | uint8_t shift5, uint32_t mask5, uint32_t *field_value5) | |
110 | { | |
111 | uint32_t reg_val = dm_read_reg(ctx, addr); | |
112 | *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); | |
113 | *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); | |
114 | *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); | |
115 | *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); | |
116 | *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5); | |
117 | return reg_val; | |
118 | } | |
119 | ||
120 | /* note: va version of this is pretty bad idea, since there is a output parameter pass by pointer | |
121 | * compiler won't be able to check for size match and is prone to stack corruption type of bugs | |
122 | ||
123 | uint32_t generic_reg_get(const struct dc_context *ctx, | |
124 | uint32_t addr, int n, ...) | |
125 | { | |
126 | uint32_t shift, mask; | |
127 | uint32_t *field_value; | |
128 | uint32_t reg_val; | |
129 | int i = 0; | |
130 | ||
131 | reg_val = dm_read_reg(ctx, addr); | |
132 | ||
133 | va_list ap; | |
134 | va_start(ap, n); | |
135 | ||
136 | while (i < n) { | |
137 | shift = va_arg(ap, uint32_t); | |
138 | mask = va_arg(ap, uint32_t); | |
139 | field_value = va_arg(ap, uint32_t *); | |
140 | ||
141 | *field_value = get_reg_field_value_ex(reg_val, mask, shift); | |
142 | i++; | |
143 | } | |
144 | ||
145 | va_end(ap); | |
146 | ||
147 | return reg_val; | |
148 | } | |
149 | */ | |
150 | ||
151 | uint32_t generic_reg_wait(const struct dc_context *ctx, | |
152 | uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value, | |
153 | unsigned int delay_between_poll_us, unsigned int time_out_num_tries, | |
daf6b57d | 154 | const char *func_name, int line) |
4562236b HW |
155 | { |
156 | uint32_t field_value; | |
157 | uint32_t reg_val; | |
158 | int i; | |
159 | ||
8a5d8245 TC |
160 | /* something is terribly wrong if time out is > 200ms. (5Hz) */ |
161 | ASSERT(delay_between_poll_us * time_out_num_tries <= 200000); | |
162 | ||
f0558542 DL |
163 | if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { |
164 | /* 35 seconds */ | |
165 | delay_between_poll_us = 35000; | |
166 | time_out_num_tries = 1000; | |
167 | } | |
11589813 | 168 | |
4562236b HW |
169 | for (i = 0; i <= time_out_num_tries; i++) { |
170 | if (i) { | |
755d3bcf | 171 | if (delay_between_poll_us >= 1000) |
4562236b | 172 | msleep(delay_between_poll_us/1000); |
755d3bcf EY |
173 | else if (delay_between_poll_us > 0) |
174 | udelay(delay_between_poll_us); | |
4562236b HW |
175 | } |
176 | ||
177 | reg_val = dm_read_reg(ctx, addr); | |
178 | ||
179 | field_value = get_reg_field_value_ex(reg_val, mask, shift); | |
180 | ||
42cf181b DL |
181 | if (field_value == condition_value) { |
182 | if (i * delay_between_poll_us > 1000) | |
183 | dm_output_to_console("REG_WAIT taking a while: %dms in %s line:%d\n", | |
184 | delay_between_poll_us * i / 1000, | |
185 | func_name, line); | |
4562236b | 186 | return reg_val; |
42cf181b | 187 | } |
4562236b HW |
188 | } |
189 | ||
daf6b57d | 190 | dm_error("REG_WAIT timeout %dus * %d tries - %s line:%d\n", |
8a5d8245 TC |
191 | delay_between_poll_us, time_out_num_tries, |
192 | func_name, line); | |
f0558542 DL |
193 | |
194 | if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) | |
11589813 DL |
195 | BREAK_TO_DEBUGGER(); |
196 | ||
4562236b HW |
197 | return reg_val; |
198 | } |