1 | /* |
2 | * Copyright 2013-15 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 | |
26 | /* |
27 | * Pre-requisites: headers required by header of this unit |
28 | */ |
29 | |
30 | #include "hw_translate_dcn10.h" |
31 | |
32 | #include "dm_services.h" |
33 | #include "include/gpio_types.h" |
34 | #include "../hw_translate.h" |
35 | |
36 | #include "dcn/dcn_1_0_offset.h" |
37 | #include "dcn/dcn_1_0_sh_mask.h" |
38 | #include "soc15_hw_ip.h" |
39 | #include "vega10_ip_offset.h" |
40 | |
41 | /* begin ********************* |
42 | * macros to expend register list macro defined in HW object header file */ |
43 | |
44 | #define BASE_INNER(seg) \ |
45 | DCE_BASE__INST0_SEG ## seg |
46 | |
47 | /* compile time expand base address. */ |
48 | #define BASE(seg) \ |
49 | BASE_INNER(seg) |
50 | |
51 | #define REG(reg_name)\ |
52 | BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name |
53 | |
54 | #define REGI(reg_name, block, id)\ |
55 | BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
56 | mm ## block ## id ## _ ## reg_name |
57 | |
58 | /* macros to expend register list macro defined in HW object header file |
59 | * end *********************/ |
60 | |
61 | static bool offset_to_id( |
62 | uint32_t offset, |
63 | uint32_t mask, |
64 | enum gpio_id *id, |
65 | uint32_t *en) |
66 | { |
67 | switch (offset) { |
68 | /* GENERIC */ |
69 | case REG(DC_GPIO_GENERIC_A): |
70 | *id = GPIO_ID_GENERIC; |
71 | switch (mask) { |
72 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK: |
73 | *en = GPIO_GENERIC_A; |
74 | return true; |
75 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK: |
76 | *en = GPIO_GENERIC_B; |
77 | return true; |
78 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK: |
79 | *en = GPIO_GENERIC_C; |
80 | return true; |
81 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK: |
82 | *en = GPIO_GENERIC_D; |
83 | return true; |
84 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK: |
85 | *en = GPIO_GENERIC_E; |
86 | return true; |
87 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK: |
88 | *en = GPIO_GENERIC_F; |
89 | return true; |
90 | case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK: |
91 | *en = GPIO_GENERIC_G; |
92 | return true; |
93 | default: |
94 | ASSERT_CRITICAL(false); |
95 | return false; |
96 | } |
97 | break; |
98 | /* HPD */ |
99 | case REG(DC_GPIO_HPD_A): |
100 | *id = GPIO_ID_HPD; |
101 | switch (mask) { |
102 | case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK: |
103 | *en = GPIO_HPD_1; |
104 | return true; |
105 | case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK: |
106 | *en = GPIO_HPD_2; |
107 | return true; |
108 | case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK: |
109 | *en = GPIO_HPD_3; |
110 | return true; |
111 | case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK: |
112 | *en = GPIO_HPD_4; |
113 | return true; |
114 | case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK: |
115 | *en = GPIO_HPD_5; |
116 | return true; |
117 | case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK: |
118 | *en = GPIO_HPD_6; |
119 | return true; |
120 | default: |
121 | ASSERT_CRITICAL(false); |
122 | return false; |
123 | } |
124 | break; |
125 | /* SYNCA */ |
126 | case REG(DC_GPIO_SYNCA_A): |
127 | *id = GPIO_ID_SYNC; |
128 | switch (mask) { |
129 | case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK: |
130 | *en = GPIO_SYNC_HSYNC_A; |
131 | return true; |
132 | case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK: |
133 | *en = GPIO_SYNC_VSYNC_A; |
134 | return true; |
135 | default: |
136 | ASSERT_CRITICAL(false); |
137 | return false; |
138 | } |
139 | break; |
140 | /* REG(DC_GPIO_GENLK_MASK */ |
141 | case REG(DC_GPIO_GENLK_A): |
142 | *id = GPIO_ID_GSL; |
143 | switch (mask) { |
144 | case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK: |
145 | *en = GPIO_GSL_GENLOCK_CLOCK; |
146 | return true; |
147 | case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK: |
148 | *en = GPIO_GSL_GENLOCK_VSYNC; |
149 | return true; |
150 | case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK: |
151 | *en = GPIO_GSL_SWAPLOCK_A; |
152 | return true; |
153 | case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK: |
154 | *en = GPIO_GSL_SWAPLOCK_B; |
155 | return true; |
156 | default: |
157 | ASSERT_CRITICAL(false); |
158 | return false; |
159 | } |
160 | break; |
161 | /* DDC */ |
162 | /* we don't care about the GPIO_ID for DDC |
163 | * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK |
164 | * directly in the create method */ |
165 | case REG(DC_GPIO_DDC1_A): |
166 | *en = GPIO_DDC_LINE_DDC1; |
167 | return true; |
168 | case REG(DC_GPIO_DDC2_A): |
169 | *en = GPIO_DDC_LINE_DDC2; |
170 | return true; |
171 | case REG(DC_GPIO_DDC3_A): |
172 | *en = GPIO_DDC_LINE_DDC3; |
173 | return true; |
174 | case REG(DC_GPIO_DDC4_A): |
175 | *en = GPIO_DDC_LINE_DDC4; |
176 | return true; |
177 | case REG(DC_GPIO_DDC5_A): |
178 | *en = GPIO_DDC_LINE_DDC5; |
179 | return true; |
180 | case REG(DC_GPIO_DDC6_A): |
181 | *en = GPIO_DDC_LINE_DDC6; |
182 | return true; |
183 | case REG(DC_GPIO_DDCVGA_A): |
184 | *en = GPIO_DDC_LINE_DDC_VGA; |
185 | return true; |
186 | /* GPIO_I2CPAD */ |
187 | case REG(DC_GPIO_I2CPAD_A): |
188 | *en = GPIO_DDC_LINE_I2C_PAD; |
189 | return true; |
190 | /* Not implemented */ |
191 | case REG(DC_GPIO_PWRSEQ_A): |
192 | case REG(DC_GPIO_PAD_STRENGTH_1): |
193 | case REG(DC_GPIO_PAD_STRENGTH_2): |
194 | case REG(DC_GPIO_DEBUG): |
195 | return false; |
196 | /* UNEXPECTED */ |
197 | default: |
198 | ASSERT_CRITICAL(false); |
199 | return false; |
200 | } |
201 | } |
202 | |
203 | static bool id_to_offset( |
204 | enum gpio_id id, |
205 | uint32_t en, |
206 | struct gpio_pin_info *info) |
207 | { |
208 | bool result = true; |
209 | |
210 | switch (id) { |
211 | case GPIO_ID_DDC_DATA: |
212 | info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK; |
213 | switch (en) { |
214 | case GPIO_DDC_LINE_DDC1: |
215 | info->offset = REG(DC_GPIO_DDC1_A); |
216 | break; |
217 | case GPIO_DDC_LINE_DDC2: |
218 | info->offset = REG(DC_GPIO_DDC2_A); |
219 | break; |
220 | case GPIO_DDC_LINE_DDC3: |
221 | info->offset = REG(DC_GPIO_DDC3_A); |
222 | break; |
223 | case GPIO_DDC_LINE_DDC4: |
224 | info->offset = REG(DC_GPIO_DDC4_A); |
225 | break; |
226 | case GPIO_DDC_LINE_DDC5: |
227 | info->offset = REG(DC_GPIO_DDC5_A); |
228 | break; |
229 | case GPIO_DDC_LINE_DDC6: |
230 | info->offset = REG(DC_GPIO_DDC6_A); |
231 | break; |
232 | case GPIO_DDC_LINE_DDC_VGA: |
233 | info->offset = REG(DC_GPIO_DDCVGA_A); |
234 | break; |
235 | case GPIO_DDC_LINE_I2C_PAD: |
236 | info->offset = REG(DC_GPIO_I2CPAD_A); |
237 | break; |
238 | default: |
239 | ASSERT_CRITICAL(false); |
240 | result = false; |
241 | } |
242 | break; |
243 | case GPIO_ID_DDC_CLOCK: |
244 | info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK; |
245 | switch (en) { |
246 | case GPIO_DDC_LINE_DDC1: |
247 | info->offset = REG(DC_GPIO_DDC1_A); |
248 | break; |
249 | case GPIO_DDC_LINE_DDC2: |
250 | info->offset = REG(DC_GPIO_DDC2_A); |
251 | break; |
252 | case GPIO_DDC_LINE_DDC3: |
253 | info->offset = REG(DC_GPIO_DDC3_A); |
254 | break; |
255 | case GPIO_DDC_LINE_DDC4: |
256 | info->offset = REG(DC_GPIO_DDC4_A); |
257 | break; |
258 | case GPIO_DDC_LINE_DDC5: |
259 | info->offset = REG(DC_GPIO_DDC5_A); |
260 | break; |
261 | case GPIO_DDC_LINE_DDC6: |
262 | info->offset = REG(DC_GPIO_DDC6_A); |
263 | break; |
264 | case GPIO_DDC_LINE_DDC_VGA: |
265 | info->offset = REG(DC_GPIO_DDCVGA_A); |
266 | break; |
267 | case GPIO_DDC_LINE_I2C_PAD: |
268 | info->offset = REG(DC_GPIO_I2CPAD_A); |
269 | break; |
270 | default: |
271 | ASSERT_CRITICAL(false); |
272 | result = false; |
273 | } |
274 | break; |
275 | case GPIO_ID_GENERIC: |
276 | info->offset = REG(DC_GPIO_GENERIC_A); |
277 | switch (en) { |
278 | case GPIO_GENERIC_A: |
279 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK; |
280 | break; |
281 | case GPIO_GENERIC_B: |
282 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK; |
283 | break; |
284 | case GPIO_GENERIC_C: |
285 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK; |
286 | break; |
287 | case GPIO_GENERIC_D: |
288 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK; |
289 | break; |
290 | case GPIO_GENERIC_E: |
291 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK; |
292 | break; |
293 | case GPIO_GENERIC_F: |
294 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK; |
295 | break; |
296 | case GPIO_GENERIC_G: |
297 | info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK; |
298 | break; |
299 | default: |
300 | ASSERT_CRITICAL(false); |
301 | result = false; |
302 | } |
303 | break; |
304 | case GPIO_ID_HPD: |
305 | info->offset = REG(DC_GPIO_HPD_A); |
306 | switch (en) { |
307 | case GPIO_HPD_1: |
308 | info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; |
309 | break; |
310 | case GPIO_HPD_2: |
311 | info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK; |
312 | break; |
313 | case GPIO_HPD_3: |
314 | info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK; |
315 | break; |
316 | case GPIO_HPD_4: |
317 | info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK; |
318 | break; |
319 | case GPIO_HPD_5: |
320 | info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK; |
321 | break; |
322 | case GPIO_HPD_6: |
323 | info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK; |
324 | break; |
325 | default: |
326 | ASSERT_CRITICAL(false); |
327 | result = false; |
328 | } |
329 | break; |
330 | case GPIO_ID_SYNC: |
331 | switch (en) { |
332 | case GPIO_SYNC_HSYNC_A: |
333 | info->offset = REG(DC_GPIO_SYNCA_A); |
334 | info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK; |
335 | break; |
336 | case GPIO_SYNC_VSYNC_A: |
337 | info->offset = REG(DC_GPIO_SYNCA_A); |
338 | info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK; |
339 | break; |
340 | case GPIO_SYNC_HSYNC_B: |
341 | case GPIO_SYNC_VSYNC_B: |
342 | default: |
343 | ASSERT_CRITICAL(false); |
344 | result = false; |
345 | } |
346 | break; |
347 | case GPIO_ID_GSL: |
348 | switch (en) { |
349 | case GPIO_GSL_GENLOCK_CLOCK: |
350 | info->offset = REG(DC_GPIO_GENLK_A); |
351 | info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK; |
352 | break; |
353 | case GPIO_GSL_GENLOCK_VSYNC: |
354 | info->offset = REG(DC_GPIO_GENLK_A); |
355 | info->mask = |
356 | DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK; |
357 | break; |
358 | case GPIO_GSL_SWAPLOCK_A: |
359 | info->offset = REG(DC_GPIO_GENLK_A); |
360 | info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK; |
361 | break; |
362 | case GPIO_GSL_SWAPLOCK_B: |
363 | info->offset = REG(DC_GPIO_GENLK_A); |
364 | info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK; |
365 | break; |
366 | default: |
367 | ASSERT_CRITICAL(false); |
368 | result = false; |
369 | } |
370 | break; |
371 | case GPIO_ID_VIP_PAD: |
372 | default: |
373 | ASSERT_CRITICAL(false); |
374 | result = false; |
375 | } |
376 | |
377 | if (result) { |
378 | info->offset_y = info->offset + 2; |
379 | info->offset_en = info->offset + 1; |
380 | info->offset_mask = info->offset - 1; |
381 | |
382 | info->mask_y = info->mask; |
383 | info->mask_en = info->mask; |
384 | info->mask_mask = info->mask; |
385 | } |
386 | |
387 | return result; |
388 | } |
389 | |
390 | /* function table */ |
391 | static const struct hw_translate_funcs funcs = { |
392 | .offset_to_id = offset_to_id, |
393 | .id_to_offset = id_to_offset, |
394 | }; |
395 | |
396 | /* |
397 | * dal_hw_translate_dcn10_init |
398 | * |
399 | * @brief |
400 | * Initialize Hw translate function pointers. |
401 | * |
402 | * @param |
403 | * struct hw_translate *tr - [out] struct of function pointers |
404 | * |
405 | */ |
406 | void dal_hw_translate_dcn10_init(struct hw_translate *tr) |
407 | { |
408 | tr->funcs = &funcs; |
409 | } |
410 | |