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 "dm_services.h"
31#include "include/gpio_types.h"
32#include "../hw_translate.h"
33
34#include "hw_translate_dce110.h"
35
36#include "dce/dce_11_0_d.h"
37#include "dce/dce_11_0_sh_mask.h"
38
39static bool offset_to_id(
40	uint32_t offset,
41	uint32_t mask,
42	enum gpio_id *id,
43	uint32_t *en)
44{
45	switch (offset) {
46	/* GENERIC */
47	case mmDC_GPIO_GENERIC_A:
48		*id = GPIO_ID_GENERIC;
49		switch (mask) {
50		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
51			*en = GPIO_GENERIC_A;
52			return true;
53		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
54			*en = GPIO_GENERIC_B;
55			return true;
56		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
57			*en = GPIO_GENERIC_C;
58			return true;
59		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
60			*en = GPIO_GENERIC_D;
61			return true;
62		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
63			*en = GPIO_GENERIC_E;
64			return true;
65		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
66			*en = GPIO_GENERIC_F;
67			return true;
68		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
69			*en = GPIO_GENERIC_G;
70			return true;
71		default:
72			ASSERT_CRITICAL(false);
73			return false;
74		}
75	break;
76	/* HPD */
77	case mmDC_GPIO_HPD_A:
78		*id = GPIO_ID_HPD;
79		switch (mask) {
80		case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
81			*en = GPIO_HPD_1;
82			return true;
83		case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
84			*en = GPIO_HPD_2;
85			return true;
86		case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
87			*en = GPIO_HPD_3;
88			return true;
89		case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
90			*en = GPIO_HPD_4;
91			return true;
92		case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
93			*en = GPIO_HPD_5;
94			return true;
95		case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
96			*en = GPIO_HPD_6;
97			return true;
98		default:
99			ASSERT_CRITICAL(false);
100			return false;
101		}
102	break;
103	/* SYNCA */
104	case mmDC_GPIO_SYNCA_A:
105		*id = GPIO_ID_SYNC;
106		switch (mask) {
107		case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK:
108			*en = GPIO_SYNC_HSYNC_A;
109			return true;
110		case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK:
111			*en = GPIO_SYNC_VSYNC_A;
112			return true;
113		default:
114			ASSERT_CRITICAL(false);
115			return false;
116		}
117	break;
118	/* mmDC_GPIO_GENLK_MASK */
119	case mmDC_GPIO_GENLK_A:
120		*id = GPIO_ID_GSL;
121		switch (mask) {
122		case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
123			*en = GPIO_GSL_GENLOCK_CLOCK;
124			return true;
125		case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
126			*en = GPIO_GSL_GENLOCK_VSYNC;
127			return true;
128		case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
129			*en = GPIO_GSL_SWAPLOCK_A;
130			return true;
131		case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
132			*en = GPIO_GSL_SWAPLOCK_B;
133			return true;
134		default:
135			ASSERT_CRITICAL(false);
136			return false;
137		}
138	break;
139	/* DDC */
140	/* we don't care about the GPIO_ID for DDC
141	 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
142	 * directly in the create method */
143	case mmDC_GPIO_DDC1_A:
144		*en = GPIO_DDC_LINE_DDC1;
145		return true;
146	case mmDC_GPIO_DDC2_A:
147		*en = GPIO_DDC_LINE_DDC2;
148		return true;
149	case mmDC_GPIO_DDC3_A:
150		*en = GPIO_DDC_LINE_DDC3;
151		return true;
152	case mmDC_GPIO_DDC4_A:
153		*en = GPIO_DDC_LINE_DDC4;
154		return true;
155	case mmDC_GPIO_DDC5_A:
156		*en = GPIO_DDC_LINE_DDC5;
157		return true;
158	case mmDC_GPIO_DDC6_A:
159		*en = GPIO_DDC_LINE_DDC6;
160		return true;
161	case mmDC_GPIO_DDCVGA_A:
162		*en = GPIO_DDC_LINE_DDC_VGA;
163		return true;
164	/* GPIO_I2CPAD */
165	case mmDC_GPIO_I2CPAD_A:
166		*en = GPIO_DDC_LINE_I2C_PAD;
167		return true;
168	/* Not implemented */
169	case mmDC_GPIO_PWRSEQ_A:
170	case mmDC_GPIO_PAD_STRENGTH_1:
171	case mmDC_GPIO_PAD_STRENGTH_2:
172	case mmDC_GPIO_DEBUG:
173		return false;
174	/* UNEXPECTED */
175	default:
176		ASSERT_CRITICAL(false);
177		return false;
178	}
179}
180
181static bool id_to_offset(
182	enum gpio_id id,
183	uint32_t en,
184	struct gpio_pin_info *info)
185{
186	bool result = true;
187
188	switch (id) {
189	case GPIO_ID_DDC_DATA:
190		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
191		switch (en) {
192		case GPIO_DDC_LINE_DDC1:
193			info->offset = mmDC_GPIO_DDC1_A;
194		break;
195		case GPIO_DDC_LINE_DDC2:
196			info->offset = mmDC_GPIO_DDC2_A;
197		break;
198		case GPIO_DDC_LINE_DDC3:
199			info->offset = mmDC_GPIO_DDC3_A;
200		break;
201		case GPIO_DDC_LINE_DDC4:
202			info->offset = mmDC_GPIO_DDC4_A;
203		break;
204		case GPIO_DDC_LINE_DDC5:
205			info->offset = mmDC_GPIO_DDC5_A;
206		break;
207		case GPIO_DDC_LINE_DDC6:
208			info->offset = mmDC_GPIO_DDC6_A;
209		break;
210		case GPIO_DDC_LINE_DDC_VGA:
211			info->offset = mmDC_GPIO_DDCVGA_A;
212		break;
213		case GPIO_DDC_LINE_I2C_PAD:
214			info->offset = mmDC_GPIO_I2CPAD_A;
215		break;
216		default:
217			ASSERT_CRITICAL(false);
218			result = false;
219		}
220	break;
221	case GPIO_ID_DDC_CLOCK:
222		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
223		switch (en) {
224		case GPIO_DDC_LINE_DDC1:
225			info->offset = mmDC_GPIO_DDC1_A;
226		break;
227		case GPIO_DDC_LINE_DDC2:
228			info->offset = mmDC_GPIO_DDC2_A;
229		break;
230		case GPIO_DDC_LINE_DDC3:
231			info->offset = mmDC_GPIO_DDC3_A;
232		break;
233		case GPIO_DDC_LINE_DDC4:
234			info->offset = mmDC_GPIO_DDC4_A;
235		break;
236		case GPIO_DDC_LINE_DDC5:
237			info->offset = mmDC_GPIO_DDC5_A;
238		break;
239		case GPIO_DDC_LINE_DDC6:
240			info->offset = mmDC_GPIO_DDC6_A;
241		break;
242		case GPIO_DDC_LINE_DDC_VGA:
243			info->offset = mmDC_GPIO_DDCVGA_A;
244		break;
245		case GPIO_DDC_LINE_I2C_PAD:
246			info->offset = mmDC_GPIO_I2CPAD_A;
247		break;
248		default:
249			ASSERT_CRITICAL(false);
250			result = false;
251		}
252	break;
253	case GPIO_ID_GENERIC:
254		info->offset = mmDC_GPIO_GENERIC_A;
255		switch (en) {
256		case GPIO_GENERIC_A:
257			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
258		break;
259		case GPIO_GENERIC_B:
260			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
261		break;
262		case GPIO_GENERIC_C:
263			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
264		break;
265		case GPIO_GENERIC_D:
266			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
267		break;
268		case GPIO_GENERIC_E:
269			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
270		break;
271		case GPIO_GENERIC_F:
272			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
273		break;
274		case GPIO_GENERIC_G:
275			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
276		break;
277		default:
278			ASSERT_CRITICAL(false);
279			result = false;
280		}
281	break;
282	case GPIO_ID_HPD:
283		info->offset = mmDC_GPIO_HPD_A;
284		switch (en) {
285		case GPIO_HPD_1:
286			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
287		break;
288		case GPIO_HPD_2:
289			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
290		break;
291		case GPIO_HPD_3:
292			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
293		break;
294		case GPIO_HPD_4:
295			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
296		break;
297		case GPIO_HPD_5:
298			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
299		break;
300		case GPIO_HPD_6:
301			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
302		break;
303		default:
304			ASSERT_CRITICAL(false);
305			result = false;
306		}
307	break;
308	case GPIO_ID_SYNC:
309		switch (en) {
310		case GPIO_SYNC_HSYNC_A:
311			info->offset = mmDC_GPIO_SYNCA_A;
312			info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK;
313		break;
314		case GPIO_SYNC_VSYNC_A:
315			info->offset = mmDC_GPIO_SYNCA_A;
316			info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK;
317		break;
318		case GPIO_SYNC_HSYNC_B:
319		case GPIO_SYNC_VSYNC_B:
320		default:
321			ASSERT_CRITICAL(false);
322			result = false;
323		}
324	break;
325	case GPIO_ID_GSL:
326		switch (en) {
327		case GPIO_GSL_GENLOCK_CLOCK:
328			info->offset = mmDC_GPIO_GENLK_A;
329			info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK;
330		break;
331		case GPIO_GSL_GENLOCK_VSYNC:
332			info->offset = mmDC_GPIO_GENLK_A;
333			info->mask =
334				DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK;
335		break;
336		case GPIO_GSL_SWAPLOCK_A:
337			info->offset = mmDC_GPIO_GENLK_A;
338			info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK;
339		break;
340		case GPIO_GSL_SWAPLOCK_B:
341			info->offset = mmDC_GPIO_GENLK_A;
342			info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK;
343		break;
344		default:
345			ASSERT_CRITICAL(false);
346			result = false;
347		}
348	break;
349	case GPIO_ID_VIP_PAD:
350	default:
351		ASSERT_CRITICAL(false);
352		result = false;
353	}
354
355	if (result) {
356		info->offset_y = info->offset + 2;
357		info->offset_en = info->offset + 1;
358		info->offset_mask = info->offset - 1;
359
360		info->mask_y = info->mask;
361		info->mask_en = info->mask;
362		info->mask_mask = info->mask;
363	}
364
365	return result;
366}
367
368/* function table */
369static const struct hw_translate_funcs funcs = {
370	.offset_to_id = offset_to_id,
371	.id_to_offset = id_to_offset,
372};
373
374/*
375 * dal_hw_translate_dce110_init
376 *
377 * @brief
378 * Initialize Hw translate function pointers.
379 *
380 * @param
381 * struct hw_translate *tr - [out] struct of function pointers
382 *
383 */
384void dal_hw_translate_dce110_init(struct hw_translate *tr)
385{
386	tr->funcs = &funcs;
387}
388