1/*
2 * Copyright 2020 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_dcn30.h"
30
31#include "dm_services.h"
32#include "include/gpio_types.h"
33#include "../hw_translate.h"
34
35
36#include "sienna_cichlid_ip_offset.h"
37#include "dcn/dcn_3_0_0_offset.h"
38#include "dcn/dcn_3_0_0_sh_mask.h"
39
40#include "nbio/nbio_7_4_offset.h"
41
42#include "dpcs/dpcs_3_0_0_offset.h"
43#include "dpcs/dpcs_3_0_0_sh_mask.h"
44
45#include "mmhub/mmhub_2_0_0_offset.h"
46#include "mmhub/mmhub_2_0_0_sh_mask.h"
47/* begin *********************
48 * macros to expend register list macro defined in HW object header file */
49
50/* DCN */
51#define block HPD
52#define reg_num 0
53
54#undef BASE_INNER
55#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
56
57#define BASE(seg) BASE_INNER(seg)
58
59#undef REG
60#define REG(reg_name)\
61		BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name
62#define SF_HPD(reg_name, field_name, post_fix)\
63	.field_name = reg_name ## __ ## field_name ## post_fix
64
65
66/* macros to expend register list macro defined in HW object header file
67 * end *********************/
68
69
70static bool offset_to_id(
71	uint32_t offset,
72	uint32_t mask,
73	enum gpio_id *id,
74	uint32_t *en)
75{
76	switch (offset) {
77	/* GENERIC */
78	case REG(DC_GPIO_GENERIC_A):
79		*id = GPIO_ID_GENERIC;
80		switch (mask) {
81		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
82			*en = GPIO_GENERIC_A;
83			return true;
84		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
85			*en = GPIO_GENERIC_B;
86			return true;
87		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
88			*en = GPIO_GENERIC_C;
89			return true;
90		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
91			*en = GPIO_GENERIC_D;
92			return true;
93		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
94			*en = GPIO_GENERIC_E;
95			return true;
96		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
97			*en = GPIO_GENERIC_F;
98			return true;
99		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
100			*en = GPIO_GENERIC_G;
101			return true;
102		default:
103			ASSERT_CRITICAL(false);
104			return false;
105		}
106	break;
107	/* HPD */
108	case REG(DC_GPIO_HPD_A):
109		*id = GPIO_ID_HPD;
110		switch (mask) {
111		case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
112			*en = GPIO_HPD_1;
113			return true;
114		case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
115			*en = GPIO_HPD_2;
116			return true;
117		case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
118			*en = GPIO_HPD_3;
119			return true;
120		case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
121			*en = GPIO_HPD_4;
122			return true;
123		case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
124			*en = GPIO_HPD_5;
125			return true;
126		case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
127			*en = GPIO_HPD_6;
128			return true;
129		default:
130			ASSERT_CRITICAL(false);
131			return false;
132		}
133	break;
134	/* REG(DC_GPIO_GENLK_MASK */
135	case REG(DC_GPIO_GENLK_A):
136		*id = GPIO_ID_GSL;
137		switch (mask) {
138		case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
139			*en = GPIO_GSL_GENLOCK_CLOCK;
140			return true;
141		case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
142			*en = GPIO_GSL_GENLOCK_VSYNC;
143			return true;
144		case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
145			*en = GPIO_GSL_SWAPLOCK_A;
146			return true;
147		case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
148			*en = GPIO_GSL_SWAPLOCK_B;
149			return true;
150		default:
151			ASSERT_CRITICAL(false);
152			return false;
153		}
154	break;
155	/* DDC */
156	/* we don't care about the GPIO_ID for DDC
157	 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
158	 * directly in the create method
159	 */
160	case REG(DC_GPIO_DDC1_A):
161		*en = GPIO_DDC_LINE_DDC1;
162		return true;
163	case REG(DC_GPIO_DDC2_A):
164		*en = GPIO_DDC_LINE_DDC2;
165		return true;
166	case REG(DC_GPIO_DDC3_A):
167		*en = GPIO_DDC_LINE_DDC3;
168		return true;
169	case REG(DC_GPIO_DDC4_A):
170		*en = GPIO_DDC_LINE_DDC4;
171		return true;
172	case REG(DC_GPIO_DDC5_A):
173		*en = GPIO_DDC_LINE_DDC5;
174		return true;
175	case REG(DC_GPIO_DDC6_A):
176		*en = GPIO_DDC_LINE_DDC6;
177		return true;
178	case REG(DC_GPIO_DDCVGA_A):
179		*en = GPIO_DDC_LINE_DDC_VGA;
180		return true;
181
182/*
183 *	case REG(DC_GPIO_I2CPAD_A): not exit
184 *	case REG(DC_GPIO_PWRSEQ_A):
185 *	case REG(DC_GPIO_PAD_STRENGTH_1):
186 *	case REG(DC_GPIO_PAD_STRENGTH_2):
187 *	case REG(DC_GPIO_DEBUG):
188 */
189	/* UNEXPECTED */
190	default:
191/*	case REG(DC_GPIO_SYNCA_A): not exist */
192		ASSERT_CRITICAL(false);
193		return false;
194	}
195}
196
197static bool id_to_offset(
198	enum gpio_id id,
199	uint32_t en,
200	struct gpio_pin_info *info)
201{
202	bool result = true;
203
204	switch (id) {
205	case GPIO_ID_DDC_DATA:
206		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_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_DDC6:
224			info->offset = REG(DC_GPIO_DDC6_A);
225		break;
226		case GPIO_DDC_LINE_DDC_VGA:
227			info->offset = REG(DC_GPIO_DDCVGA_A);
228		break;
229		case GPIO_DDC_LINE_I2C_PAD:
230		default:
231			ASSERT_CRITICAL(false);
232			result = false;
233		}
234	break;
235	case GPIO_ID_DDC_CLOCK:
236		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
237		switch (en) {
238		case GPIO_DDC_LINE_DDC1:
239			info->offset = REG(DC_GPIO_DDC1_A);
240		break;
241		case GPIO_DDC_LINE_DDC2:
242			info->offset = REG(DC_GPIO_DDC2_A);
243		break;
244		case GPIO_DDC_LINE_DDC3:
245			info->offset = REG(DC_GPIO_DDC3_A);
246		break;
247		case GPIO_DDC_LINE_DDC4:
248			info->offset = REG(DC_GPIO_DDC4_A);
249		break;
250		case GPIO_DDC_LINE_DDC5:
251			info->offset = REG(DC_GPIO_DDC5_A);
252		break;
253		case GPIO_DDC_LINE_DDC6:
254			info->offset = REG(DC_GPIO_DDC6_A);
255		break;
256		case GPIO_DDC_LINE_DDC_VGA:
257			info->offset = REG(DC_GPIO_DDCVGA_A);
258		break;
259		case GPIO_DDC_LINE_I2C_PAD:
260		default:
261			ASSERT_CRITICAL(false);
262			result = false;
263		}
264	break;
265	case GPIO_ID_GENERIC:
266		info->offset = REG(DC_GPIO_GENERIC_A);
267		switch (en) {
268		case GPIO_GENERIC_A:
269			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
270		break;
271		case GPIO_GENERIC_B:
272			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
273		break;
274		case GPIO_GENERIC_C:
275			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
276		break;
277		case GPIO_GENERIC_D:
278			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
279		break;
280		case GPIO_GENERIC_E:
281			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
282		break;
283		case GPIO_GENERIC_F:
284			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
285		break;
286		case GPIO_GENERIC_G:
287			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
288		break;
289		default:
290			ASSERT_CRITICAL(false);
291			result = false;
292		}
293	break;
294	case GPIO_ID_HPD:
295		info->offset = REG(DC_GPIO_HPD_A);
296		switch (en) {
297		case GPIO_HPD_1:
298			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
299		break;
300		case GPIO_HPD_2:
301			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
302		break;
303		case GPIO_HPD_3:
304			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
305		break;
306		case GPIO_HPD_4:
307			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
308		break;
309		case GPIO_HPD_5:
310			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
311		break;
312		case GPIO_HPD_6:
313			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
314		break;
315		default:
316			ASSERT_CRITICAL(false);
317			result = false;
318		}
319	break;
320	case GPIO_ID_GSL:
321		switch (en) {
322		case GPIO_GSL_GENLOCK_CLOCK:
323				/*not implmented*/
324			ASSERT_CRITICAL(false);
325			result = false;
326		break;
327		case GPIO_GSL_GENLOCK_VSYNC:
328			/*not implmented*/
329			ASSERT_CRITICAL(false);
330			result = false;
331		break;
332		case GPIO_GSL_SWAPLOCK_A:
333			/*not implmented*/
334			ASSERT_CRITICAL(false);
335			result = false;
336		break;
337		case GPIO_GSL_SWAPLOCK_B:
338			/*not implmented*/
339			ASSERT_CRITICAL(false);
340			result = false;
341
342		break;
343		default:
344			ASSERT_CRITICAL(false);
345			result = false;
346		}
347	break;
348	case GPIO_ID_SYNC:
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_dcn30_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_dcn30_init(struct hw_translate *tr)
385{
386	tr->funcs = &funcs;
387}
388
389