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

source code of linux/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c