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

source code of linux/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_translate_dcn32.c