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