1/*	$NetBSD: amdgpu_hw_translate_dcn20.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_dcn20.c,v 1.2 2021/12/18 23:45:05 riastradh Exp $");
33
34#include "hw_translate_dcn20.h"
35
36#include "dm_services.h"
37#include "include/gpio_types.h"
38#include "../hw_translate.h"
39
40#include "dcn/dcn_1_0_offset.h"
41#include "dcn/dcn_1_0_sh_mask.h"
42#include "soc15_hw_ip.h"
43#include "vega10_ip_offset.h"
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) 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	case REG(DC_GPIO_DDC1_A):
160		*en = GPIO_DDC_LINE_DDC1;
161		return true;
162	case REG(DC_GPIO_DDC2_A):
163		*en = GPIO_DDC_LINE_DDC2;
164		return true;
165	case REG(DC_GPIO_DDC3_A):
166		*en = GPIO_DDC_LINE_DDC3;
167		return true;
168	case REG(DC_GPIO_DDC4_A):
169		*en = GPIO_DDC_LINE_DDC4;
170		return true;
171	case REG(DC_GPIO_DDC5_A):
172		*en = GPIO_DDC_LINE_DDC5;
173		return true;
174	case REG(DC_GPIO_DDC6_A):
175		*en = GPIO_DDC_LINE_DDC6;
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		ASSERT_CRITICAL(false);
190		return false;
191	}
192}
193
194static bool id_to_offset(
195	enum gpio_id id,
196	uint32_t en,
197	struct gpio_pin_info *info)
198{
199	bool result = true;
200
201	switch (id) {
202	case GPIO_ID_DDC_DATA:
203		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
204		switch (en) {
205		case GPIO_DDC_LINE_DDC1:
206			info->offset = REG(DC_GPIO_DDC1_A);
207		break;
208		case GPIO_DDC_LINE_DDC2:
209			info->offset = REG(DC_GPIO_DDC2_A);
210		break;
211		case GPIO_DDC_LINE_DDC3:
212			info->offset = REG(DC_GPIO_DDC3_A);
213		break;
214		case GPIO_DDC_LINE_DDC4:
215			info->offset = REG(DC_GPIO_DDC4_A);
216		break;
217		case GPIO_DDC_LINE_DDC5:
218			info->offset = REG(DC_GPIO_DDC5_A);
219		break;
220		case GPIO_DDC_LINE_DDC6:
221			info->offset = REG(DC_GPIO_DDC6_A);
222		break;
223		case GPIO_DDC_LINE_DDC_VGA:
224			info->offset = REG(DC_GPIO_DDCVGA_A);
225		break;
226		case GPIO_DDC_LINE_I2C_PAD:
227		default:
228			ASSERT_CRITICAL(false);
229			result = false;
230		}
231	break;
232	case GPIO_ID_DDC_CLOCK:
233		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
234		switch (en) {
235		case GPIO_DDC_LINE_DDC1:
236			info->offset = REG(DC_GPIO_DDC1_A);
237		break;
238		case GPIO_DDC_LINE_DDC2:
239			info->offset = REG(DC_GPIO_DDC2_A);
240		break;
241		case GPIO_DDC_LINE_DDC3:
242			info->offset = REG(DC_GPIO_DDC3_A);
243		break;
244		case GPIO_DDC_LINE_DDC4:
245			info->offset = REG(DC_GPIO_DDC4_A);
246		break;
247		case GPIO_DDC_LINE_DDC5:
248			info->offset = REG(DC_GPIO_DDC5_A);
249		break;
250		case GPIO_DDC_LINE_DDC6:
251			info->offset = REG(DC_GPIO_DDC6_A);
252		break;
253		case GPIO_DDC_LINE_DDC_VGA:
254			info->offset = REG(DC_GPIO_DDCVGA_A);
255		break;
256		case GPIO_DDC_LINE_I2C_PAD:
257		default:
258			ASSERT_CRITICAL(false);
259			result = false;
260		}
261	break;
262	case GPIO_ID_GENERIC:
263		info->offset = REG(DC_GPIO_GENERIC_A);
264		switch (en) {
265		case GPIO_GENERIC_A:
266			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
267		break;
268		case GPIO_GENERIC_B:
269			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
270		break;
271		case GPIO_GENERIC_C:
272			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
273		break;
274		case GPIO_GENERIC_D:
275			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
276		break;
277		case GPIO_GENERIC_E:
278			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
279		break;
280		case GPIO_GENERIC_F:
281			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
282		break;
283		case GPIO_GENERIC_G:
284			info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
285		break;
286		default:
287			ASSERT_CRITICAL(false);
288			result = false;
289		}
290	break;
291	case GPIO_ID_HPD:
292		info->offset = REG(DC_GPIO_HPD_A);
293		switch (en) {
294		case GPIO_HPD_1:
295			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
296		break;
297		case GPIO_HPD_2:
298			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
299		break;
300		case GPIO_HPD_3:
301			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
302		break;
303		case GPIO_HPD_4:
304			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
305		break;
306		case GPIO_HPD_5:
307			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
308		break;
309		case GPIO_HPD_6:
310			info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
311		break;
312		default:
313			ASSERT_CRITICAL(false);
314			result = false;
315		}
316	break;
317	case GPIO_ID_GSL:
318		switch (en) {
319		case GPIO_GSL_GENLOCK_CLOCK:
320				/*not implmented*/
321			ASSERT_CRITICAL(false);
322			result = false;
323		break;
324		case GPIO_GSL_GENLOCK_VSYNC:
325			/*not implmented*/
326			ASSERT_CRITICAL(false);
327			result = false;
328		break;
329		case GPIO_GSL_SWAPLOCK_A:
330			/*not implmented*/
331			ASSERT_CRITICAL(false);
332			result = false;
333		break;
334		case GPIO_GSL_SWAPLOCK_B:
335			/*not implmented*/
336			ASSERT_CRITICAL(false);
337			result = false;
338
339		break;
340		default:
341			ASSERT_CRITICAL(false);
342			result = false;
343		}
344	break;
345	case GPIO_ID_SYNC:
346	case GPIO_ID_VIP_PAD:
347	default:
348		ASSERT_CRITICAL(false);
349		result = false;
350	}
351
352	if (result) {
353		info->offset_y = info->offset + 2;
354		info->offset_en = info->offset + 1;
355		info->offset_mask = info->offset - 1;
356
357		info->mask_y = info->mask;
358		info->mask_en = info->mask;
359		info->mask_mask = info->mask;
360	}
361
362	return result;
363}
364
365/* function table */
366static const struct hw_translate_funcs funcs = {
367	.offset_to_id = offset_to_id,
368	.id_to_offset = id_to_offset,
369};
370
371/*
372 * dal_hw_translate_dcn10_init
373 *
374 * @brief
375 * Initialize Hw translate function pointers.
376 *
377 * @param
378 * struct hw_translate *tr - [out] struct of function pointers
379 *
380 */
381void dal_hw_translate_dcn20_init(struct hw_translate *tr)
382{
383	tr->funcs = &funcs;
384}
385
386