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