xref: /linux/drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2026 Advanced Micro Devices, Inc.
4 
5 #include "hw_translate_dcn42.h"
6 
7 #include "dm_services.h"
8 #include "include/gpio_types.h"
9 #include "../hw_translate.h"
10 
11 
12 #include "dcn/dcn_4_2_0_offset.h"
13 #include "dcn/dcn_4_2_0_sh_mask.h"
14 #include "dpcs/dpcs_4_0_0_offset.h"
15 #include "dpcs/dpcs_4_0_0_sh_mask.h"
16 
17 #define DCN_BASE__INST0_SEG2                       0x000034C0
18 
19 /* begin *********************
20  * macros to expend register list macro defined in HW object header file */
21 
22 /* DCN */
23 #define block HPD
24 #define reg_num 0
25 
26 #undef BASE_INNER
27 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
28 
29 #define BASE(seg) BASE_INNER(seg)
30 
31 #undef REG
32 #define REG(reg_name)\
33 		(BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name)
34 #define SF_HPD(reg_name, field_name, post_fix)\
35 	.field_name = reg_name ## __ ## field_name ## post_fix
36 
37 
38 /* macros to expend register list macro defined in HW object header file
39  * end *********************/
40 
41 
42 static bool offset_to_id(
43 	uint32_t offset,
44 	uint32_t mask,
45 	enum gpio_id *id,
46 	uint32_t *en)
47 {
48 	(void)mask;
49 	switch (offset) {
50 	/* HPD */
51 	case REG(HPD0_DC_HPD_INT_STATUS):
52 		*id = GPIO_ID_HPD;
53 		*en = GPIO_HPD_1;
54 		return true;
55 	case REG(HPD1_DC_HPD_INT_STATUS):
56 		*id = GPIO_ID_HPD;
57 		*en = GPIO_HPD_2;
58 		return true;
59 	case REG(HPD2_DC_HPD_INT_STATUS):
60 		*id = GPIO_ID_HPD;
61 		*en = GPIO_HPD_3;
62 		return true;
63 	case REG(HPD3_DC_HPD_INT_STATUS):
64 		*id = GPIO_ID_HPD;
65 		*en = GPIO_HPD_4;
66 		return true;
67 	case REG(HPD4_DC_HPD_INT_STATUS):
68 		*id = GPIO_ID_HPD;
69 		*en = GPIO_HPD_5;
70 		return true;
71 	/* DDC */
72 	/* we don't care about the GPIO_ID for DDC
73 	 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
74 	 * directly in the create method
75 	 */
76 	case REG(DC_GPIO_DDC1_A):
77 		*en = GPIO_DDC_LINE_DDC1;
78 		return true;
79 	case REG(DC_GPIO_DDC2_A):
80 		*en = GPIO_DDC_LINE_DDC2;
81 		return true;
82 	case REG(DC_GPIO_DDC3_A):
83 		*en = GPIO_DDC_LINE_DDC3;
84 		return true;
85 	case REG(DC_GPIO_DDC4_A):
86 		*en = GPIO_DDC_LINE_DDC4;
87 		return true;
88 	case REG(DC_GPIO_DDC5_A):
89 		*en = GPIO_DDC_LINE_DDC5;
90 		return true;
91 	case REG(DC_GPIO_DDCVGA_A):
92 		*en = GPIO_DDC_LINE_DDC_VGA;
93 		return true;
94 	default:
95 		ASSERT_CRITICAL(false);
96 		return false;
97 	}
98 }
99 
100 
101 static bool id_to_offset(
102 	enum gpio_id id,
103 	uint32_t en,
104 	struct gpio_pin_info *info)
105 {
106 	bool result = true;
107 
108 	switch (id) {
109 	case GPIO_ID_DDC_DATA:
110 		info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
111 		switch (en) {
112 		case GPIO_DDC_LINE_DDC1:
113 			info->offset = REG(DC_GPIO_DDC1_A);
114 		break;
115 		case GPIO_DDC_LINE_DDC2:
116 			info->offset = REG(DC_GPIO_DDC2_A);
117 		break;
118 		case GPIO_DDC_LINE_DDC3:
119 			info->offset = REG(DC_GPIO_DDC3_A);
120 		break;
121 		case GPIO_DDC_LINE_DDC4:
122 			info->offset = REG(DC_GPIO_DDC4_A);
123 		break;
124 		case GPIO_DDC_LINE_DDC5:
125 			info->offset = REG(DC_GPIO_DDC5_A);
126 		break;
127 		case GPIO_DDC_LINE_DDC_VGA:
128 			info->offset = REG(DC_GPIO_DDCVGA_A);
129 		break;
130 		case GPIO_DDC_LINE_I2C_PAD:
131 		default:
132 			ASSERT_CRITICAL(false);
133 			result = false;
134 		}
135 	break;
136 	case GPIO_ID_DDC_CLOCK:
137 		info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
138 		switch (en) {
139 		case GPIO_DDC_LINE_DDC1:
140 			info->offset = REG(DC_GPIO_DDC1_A);
141 		break;
142 		case GPIO_DDC_LINE_DDC2:
143 			info->offset = REG(DC_GPIO_DDC2_A);
144 		break;
145 		case GPIO_DDC_LINE_DDC3:
146 			info->offset = REG(DC_GPIO_DDC3_A);
147 		break;
148 		case GPIO_DDC_LINE_DDC4:
149 			info->offset = REG(DC_GPIO_DDC4_A);
150 		break;
151 		case GPIO_DDC_LINE_DDC5:
152 			info->offset = REG(DC_GPIO_DDC5_A);
153 		break;
154 		case GPIO_DDC_LINE_DDC_VGA:
155 			info->offset = REG(DC_GPIO_DDCVGA_A);
156 		break;
157 		case GPIO_DDC_LINE_I2C_PAD:
158 		default:
159 			ASSERT_CRITICAL(false);
160 			result = false;
161 		}
162 	break;
163 	case GPIO_ID_SYNC:
164 	case GPIO_ID_VIP_PAD:
165 	default:
166 		ASSERT_CRITICAL(false);
167 		result = false;
168 	}
169 
170 	if (result) {
171 		info->offset_y = info->offset + 2;
172 		info->offset_en = info->offset + 1;
173 		info->offset_mask = info->offset - 1;
174 
175 		info->mask_y = info->mask;
176 		info->mask_en = info->mask;
177 		info->mask_mask = info->mask;
178 	}
179 
180 	return result;
181 }
182 
183 
184 /* function table */
185 static const struct hw_translate_funcs funcs = {
186 	.offset_to_id = offset_to_id,
187 	.id_to_offset = id_to_offset,
188 };
189 
190 
191 /*
192  * dal_hw_translate_dcn42_init
193  *
194  * @brief
195  * Initialize Hw translate function pointers.
196  *
197  * @param
198  * struct hw_translate *tr - [out] struct of function pointers
199  *
200  */
201 void dal_hw_translate_dcn42_init(struct hw_translate *tr)
202 {
203 	tr->funcs = &funcs;
204 }
205 
206 
207