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