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