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 "dce/dce_12_0_offset.h"
37#include "dce/dce_12_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
61static 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
203static 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 */
391static 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_dce120_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 */
406void dal_hw_translate_dce120_init(struct hw_translate *tr)
407{
408	tr->funcs = &funcs;
409}
410