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
61static 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
203static 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 */
391static 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 */
406void dal_hw_translate_dcn10_init(struct hw_translate *tr)
407{
408 tr->funcs = &funcs;
409}
410

source code of linux/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c