1/*	$NetBSD: amdgpu_hw_translate_dcn21.c,v 1.2 2021/12/18 23:45:05 riastradh Exp $	*/
2
3/*
4 * Copyright 2018 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: AMD
25 *
26 */
27
28/*
29 * Pre-requisites: headers required by header of this unit
30 */
31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: amdgpu_hw_translate_dcn21.c,v 1.2 2021/12/18 23:45:05 riastradh Exp $");
33
34#include "hw_translate_dcn21.h"
35
36#include "dm_services.h"
37#include "include/gpio_types.h"
38#include "../hw_translate.h"
39
40#include "dcn/dcn_2_1_0_offset.h"
41#include "dcn/dcn_2_1_0_sh_mask.h"
42#include "renoir_ip_offset.h"
43
44
45
46
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) DMU_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/* macros to expend register list macro defined in HW object header file
66 * end *********************/
67
68
69static bool offset_to_id(
70	uint32_t offset,
71	uint32_t mask,
72	enum gpio_id *id,
73	uint32_t *en)
74{
75	switch (offset) {
76	/* GENERIC */
77	case REG(DC_GPIO_GENERIC_A):
78		*id = GPIO_ID_GENERIC;
79		switch (mask) {
80		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
81			*en = GPIO_GENERIC_A;
82			return true;
83		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
84			*en = GPIO_GENERIC_B;
85			return true;
86		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
87			*en = GPIO_GENERIC_C;
88			return true;
89		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
90			*en = GPIO_GENERIC_D;
91			return true;
92		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
93			*en = GPIO_GENERIC_E;
94			return true;
95		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
96			*en = GPIO_GENERIC_F;
97			return true;
98		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
99			*en = GPIO_GENERIC_G;
100			return true;
101		default:
102			ASSERT_CRITICAL(false);
103#ifdef PALLADIUM_SUPPORTED
104		*en = GPIO_DDC_LINE_DDC1;
105		return true;
106#endif
107			return false;
108		}
109	break;
110	/* HPD */
111	case REG(DC_GPIO_HPD_A):
112		*id = GPIO_ID_HPD;
113		switch (mask) {
114		case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
115			*en = GPIO_HPD_1;
116			return true;
117		case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
118			*en = GPIO_HPD_2;
119			return true;
120		case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
121			*en = GPIO_HPD_3;
122			return true;
123		case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
124			*en = GPIO_HPD_4;
125			return true;
126		case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
127			*en = GPIO_HPD_5;
128			return true;
129		case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
130			*en = GPIO_HPD_6;
131			return true;
132		default:
133			ASSERT_CRITICAL(false);
134			return false;
135		}
136	break;
137	/* REG(DC_GPIO_GENLK_MASK */
138	case REG(DC_GPIO_GENLK_A):
139		*id = GPIO_ID_GSL;
140		switch (mask) {
141		case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
142			*en = GPIO_GSL_GENLOCK_CLOCK;
143			return true;
144		case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
145			*en = GPIO_GSL_GENLOCK_VSYNC;
146			return true;
147		case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
148			*en = GPIO_GSL_SWAPLOCK_A;
149			return true;
150		case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
151			*en = GPIO_GSL_SWAPLOCK_B;
152			return true;
153		default:
154			ASSERT_CRITICAL(false);
155			return false;
156		}
157	break;
158	/* DDC */
159	/* we don't care about the GPIO_ID for DDC
160	 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
161	 * directly in the create method */
162	case REG(DC_GPIO_DDC1_A):
163		*en = GPIO_DDC_LINE_DDC1;
164		return true;
165	case REG(DC_GPIO_DDC2_A):
166		*en = GPIO_DDC_LINE_DDC2;
167		return true;
168	case REG(DC_GPIO_DDC3_A):
169		*en = GPIO_DDC_LINE_DDC3;
170		return true;
171	case REG(DC_GPIO_DDC4_A):
172		*en = GPIO_DDC_LINE_DDC4;
173		return true;
174	case REG(DC_GPIO_DDC5_A):
175		*en = GPIO_DDC_LINE_DDC5;
176		return true;
177	case REG(DC_GPIO_DDCVGA_A):
178		*en = GPIO_DDC_LINE_DDC_VGA;
179		return true;
180
181//	case REG(DC_GPIO_I2CPAD_A): not exit
182//	case REG(DC_GPIO_PWRSEQ_A):
183//	case REG(DC_GPIO_PAD_STRENGTH_1):
184//	case REG(DC_GPIO_PAD_STRENGTH_2):
185//	case REG(DC_GPIO_DEBUG):
186	/* UNEXPECTED */
187	default:
188//	case REG(DC_GPIO_SYNCA_A): not exist
189#ifdef PALLADIUM_SUPPORTED
190		*id = GPIO_ID_HPD;
191		*en = GPIO_DDC_LINE_DDC1;
192		return true;
193#endif
194		ASSERT_CRITICAL(false);
195		return false;
196	}
197}
198
199static bool id_to_offset(
200	enum gpio_id id,
201	uint32_t en,
202	struct gpio_pin_info *info)
203{
204	bool result = true;
205
206	switch (id) {
207	case GPIO_ID_DDC_DATA:
208		info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK;
209		switch (en) {
210		case GPIO_DDC_LINE_DDC1:
211			info->offset = REG(DC_GPIO_DDC1_A);
212		break;
213		case GPIO_DDC_LINE_DDC2:
214			info->offset = REG(DC_GPIO_DDC2_A);
215		break;
216		case GPIO_DDC_LINE_DDC3:
217			info->offset = REG(DC_GPIO_DDC3_A);
218		break;
219		case GPIO_DDC_LINE_DDC4:
220			info->offset = REG(DC_GPIO_DDC4_A);
221		break;
222		case GPIO_DDC_LINE_DDC5:
223			info->offset = REG(DC_GPIO_DDC5_A);
224		break;
225		case GPIO_DDC_LINE_DDC_VGA:
226			info->offset = REG(DC_GPIO_DDCVGA_A);
227		break;
228		case GPIO_DDC_LINE_I2C_PAD:
229		default:
230			ASSERT_CRITICAL(false);
231			result = false;
232		}
233	break;
234	case GPIO_ID_DDC_CLOCK:
235		info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK;
236		switch (en) {
237		case GPIO_DDC_LINE_DDC1:
238			info->offset = REG(DC_GPIO_DDC1_A);
239		break;
240		case GPIO_DDC_LINE_DDC2:
241			info->offset = REG(DC_GPIO_DDC2_A);
242		break;
243		case GPIO_DDC_LINE_DDC3:
244			info->offset = REG(DC_GPIO_DDC3_A);
245		break;
246		case GPIO_DDC_LINE_DDC4:
247			info->offset = REG(DC_GPIO_DDC4_A);
248		break;
249		case GPIO_DDC_LINE_DDC5:
250			info->offset = REG(DC_GPIO_DDC5_A);
251		break;
252		case GPIO_DDC_LINE_DDC_VGA:
253			info->offset = REG(DC_GPIO_DDCVGA_A);
254		break;
255		case GPIO_DDC_LINE_I2C_PAD:
256		default:
257			ASSERT_CRITICAL(false);
258			result = false;
259		}
260	break;
261	case GPIO_ID_GENERIC:
262		info->offset = REG(DC_GPIO_GENERIC_A);
263		switch (en) {
264		case GPIO_GENERIC_A:
265			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
266		break;
267		case GPIO_GENERIC_B:
268			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
269		break;
270		case GPIO_GENERIC_C:
271			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
272		break;
273		case GPIO_GENERIC_D:
274			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
275		break;
276		case GPIO_GENERIC_E:
277			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
278		break;
279		case GPIO_GENERIC_F:
280			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
281		break;
282		case GPIO_GENERIC_G:
283			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
284		break;
285		default:
286			ASSERT_CRITICAL(false);
287			result = false;
288		}
289	break;
290	case GPIO_ID_HPD:
291		info->offset = REG(DC_GPIO_HPD_A);
292		switch (en) {
293		case GPIO_HPD_1:
294			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
295		break;
296		case GPIO_HPD_2:
297			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
298		break;
299		case GPIO_HPD_3:
300			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
301		break;
302		case GPIO_HPD_4:
303			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
304		break;
305		case GPIO_HPD_5:
306			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
307		break;
308		case GPIO_HPD_6:
309			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
310		break;
311		default:
312			ASSERT_CRITICAL(false);
313#ifdef PALLADIUM_SUPPORTED
314			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
315			result = true;
316#endif
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_dcn10_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_dcn21_init(struct hw_translate *tr)
385{
386	tr->funcs = &funcs;
387}
388
389