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 
63 static 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 
170 static 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 */
330 static 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  */
345 void dal_hw_translate_dcn32_init(struct hw_translate *tr)
346 {
347 	tr->funcs = &funcs;
348 }
349 
350