GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / gpu / drm / amd / display / dc / gpio / dce120 / hw_translate_dce120.c
1 /*
2  * Copyright 2013-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 /*
27  * Pre-requisites: headers required by header of this unit
28  */
29
30 #include "hw_translate_dce120.h"
31
32 #include "dm_services.h"
33 #include "include/gpio_types.h"
34 #include "../hw_translate.h"
35
36 #include "dce/dce_12_0_offset.h"
37 #include "dce/dce_12_0_sh_mask.h"
38 #include "soc15_hw_ip.h"
39 #include "vega10_ip_offset.h"
40
41 /* begin *********************
42  * macros to expend register list macro defined in HW object header file */
43
44 #define BASE_INNER(seg) \
45         DCE_BASE__INST0_SEG ## seg
46
47 /* compile time expand base address. */
48 #define BASE(seg) \
49         BASE_INNER(seg)
50
51 #define REG(reg_name)\
52                 BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name
53
54 #define REGI(reg_name, block, id)\
55         BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
56                                 mm ## block ## id ## _ ## reg_name
57
58 /* macros to expend register list macro defined in HW object header file
59  * end *********************/
60
61 static bool offset_to_id(
62         uint32_t offset,
63         uint32_t mask,
64         enum gpio_id *id,
65         uint32_t *en)
66 {
67         switch (offset) {
68         /* GENERIC */
69         case REG(DC_GPIO_GENERIC_A):
70                 *id = GPIO_ID_GENERIC;
71                 switch (mask) {
72                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
73                         *en = GPIO_GENERIC_A;
74                         return true;
75                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
76                         *en = GPIO_GENERIC_B;
77                         return true;
78                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
79                         *en = GPIO_GENERIC_C;
80                         return true;
81                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
82                         *en = GPIO_GENERIC_D;
83                         return true;
84                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
85                         *en = GPIO_GENERIC_E;
86                         return true;
87                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
88                         *en = GPIO_GENERIC_F;
89                         return true;
90                 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
91                         *en = GPIO_GENERIC_G;
92                         return true;
93                 default:
94                         ASSERT_CRITICAL(false);
95                         return false;
96                 }
97         break;
98         /* HPD */
99         case REG(DC_GPIO_HPD_A):
100                 *id = GPIO_ID_HPD;
101                 switch (mask) {
102                 case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
103                         *en = GPIO_HPD_1;
104                         return true;
105                 case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
106                         *en = GPIO_HPD_2;
107                         return true;
108                 case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
109                         *en = GPIO_HPD_3;
110                         return true;
111                 case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
112                         *en = GPIO_HPD_4;
113                         return true;
114                 case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
115                         *en = GPIO_HPD_5;
116                         return true;
117                 case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
118                         *en = GPIO_HPD_6;
119                         return true;
120                 default:
121                         ASSERT_CRITICAL(false);
122                         return false;
123                 }
124         break;
125         /* SYNCA */
126         case REG(DC_GPIO_SYNCA_A):
127                 *id = GPIO_ID_SYNC;
128                 switch (mask) {
129                 case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK:
130                         *en = GPIO_SYNC_HSYNC_A;
131                         return true;
132                 case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK:
133                         *en = GPIO_SYNC_VSYNC_A;
134                         return true;
135                 default:
136                         ASSERT_CRITICAL(false);
137                         return false;
138                 }
139         break;
140         /* REG(DC_GPIO_GENLK_MASK */
141         case REG(DC_GPIO_GENLK_A):
142                 *id = GPIO_ID_GSL;
143                 switch (mask) {
144                 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
145                         *en = GPIO_GSL_GENLOCK_CLOCK;
146                         return true;
147                 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
148                         *en = GPIO_GSL_GENLOCK_VSYNC;
149                         return true;
150                 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
151                         *en = GPIO_GSL_SWAPLOCK_A;
152                         return true;
153                 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
154                         *en = GPIO_GSL_SWAPLOCK_B;
155                         return true;
156                 default:
157                         ASSERT_CRITICAL(false);
158                         return false;
159                 }
160         break;
161         /* DDC */
162         /* we don't care about the GPIO_ID for DDC
163          * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
164          * directly in the create method */
165         case REG(DC_GPIO_DDC1_A):
166                 *en = GPIO_DDC_LINE_DDC1;
167                 return true;
168         case REG(DC_GPIO_DDC2_A):
169                 *en = GPIO_DDC_LINE_DDC2;
170                 return true;
171         case REG(DC_GPIO_DDC3_A):
172                 *en = GPIO_DDC_LINE_DDC3;
173                 return true;
174         case REG(DC_GPIO_DDC4_A):
175                 *en = GPIO_DDC_LINE_DDC4;
176                 return true;
177         case REG(DC_GPIO_DDC5_A):
178                 *en = GPIO_DDC_LINE_DDC5;
179                 return true;
180         case REG(DC_GPIO_DDC6_A):
181                 *en = GPIO_DDC_LINE_DDC6;
182                 return true;
183         case REG(DC_GPIO_DDCVGA_A):
184                 *en = GPIO_DDC_LINE_DDC_VGA;
185                 return true;
186         /* GPIO_I2CPAD */
187         case REG(DC_GPIO_I2CPAD_A):
188                 *en = GPIO_DDC_LINE_I2C_PAD;
189                 return true;
190         /* Not implemented */
191         case REG(DC_GPIO_PWRSEQ_A):
192         case REG(DC_GPIO_PAD_STRENGTH_1):
193         case REG(DC_GPIO_PAD_STRENGTH_2):
194         case REG(DC_GPIO_DEBUG):
195                 return false;
196         /* UNEXPECTED */
197         default:
198                 ASSERT_CRITICAL(false);
199                 return false;
200         }
201 }
202
203 static bool id_to_offset(
204         enum gpio_id id,
205         uint32_t en,
206         struct gpio_pin_info *info)
207 {
208         bool result = true;
209
210         switch (id) {
211         case GPIO_ID_DDC_DATA:
212                 info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
213                 switch (en) {
214                 case GPIO_DDC_LINE_DDC1:
215                         info->offset = REG(DC_GPIO_DDC1_A);
216                 break;
217                 case GPIO_DDC_LINE_DDC2:
218                         info->offset = REG(DC_GPIO_DDC2_A);
219                 break;
220                 case GPIO_DDC_LINE_DDC3:
221                         info->offset = REG(DC_GPIO_DDC3_A);
222                 break;
223                 case GPIO_DDC_LINE_DDC4:
224                         info->offset = REG(DC_GPIO_DDC4_A);
225                 break;
226                 case GPIO_DDC_LINE_DDC5:
227                         info->offset = REG(DC_GPIO_DDC5_A);
228                 break;
229                 case GPIO_DDC_LINE_DDC6:
230                         info->offset = REG(DC_GPIO_DDC6_A);
231                 break;
232                 case GPIO_DDC_LINE_DDC_VGA:
233                         info->offset = REG(DC_GPIO_DDCVGA_A);
234                 break;
235                 case GPIO_DDC_LINE_I2C_PAD:
236                         info->offset = REG(DC_GPIO_I2CPAD_A);
237                 break;
238                 default:
239                         ASSERT_CRITICAL(false);
240                         result = false;
241                 }
242         break;
243         case GPIO_ID_DDC_CLOCK:
244                 info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
245                 switch (en) {
246                 case GPIO_DDC_LINE_DDC1:
247                         info->offset = REG(DC_GPIO_DDC1_A);
248                 break;
249                 case GPIO_DDC_LINE_DDC2:
250                         info->offset = REG(DC_GPIO_DDC2_A);
251                 break;
252                 case GPIO_DDC_LINE_DDC3:
253                         info->offset = REG(DC_GPIO_DDC3_A);
254                 break;
255                 case GPIO_DDC_LINE_DDC4:
256                         info->offset = REG(DC_GPIO_DDC4_A);
257                 break;
258                 case GPIO_DDC_LINE_DDC5:
259                         info->offset = REG(DC_GPIO_DDC5_A);
260                 break;
261                 case GPIO_DDC_LINE_DDC6:
262                         info->offset = REG(DC_GPIO_DDC6_A);
263                 break;
264                 case GPIO_DDC_LINE_DDC_VGA:
265                         info->offset = REG(DC_GPIO_DDCVGA_A);
266                 break;
267                 case GPIO_DDC_LINE_I2C_PAD:
268                         info->offset = REG(DC_GPIO_I2CPAD_A);
269                 break;
270                 default:
271                         ASSERT_CRITICAL(false);
272                         result = false;
273                 }
274         break;
275         case GPIO_ID_GENERIC:
276                 info->offset = REG(DC_GPIO_GENERIC_A);
277                 switch (en) {
278                 case GPIO_GENERIC_A:
279                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
280                 break;
281                 case GPIO_GENERIC_B:
282                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
283                 break;
284                 case GPIO_GENERIC_C:
285                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
286                 break;
287                 case GPIO_GENERIC_D:
288                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
289                 break;
290                 case GPIO_GENERIC_E:
291                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
292                 break;
293                 case GPIO_GENERIC_F:
294                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
295                 break;
296                 case GPIO_GENERIC_G:
297                         info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
298                 break;
299                 default:
300                         ASSERT_CRITICAL(false);
301                         result = false;
302                 }
303         break;
304         case GPIO_ID_HPD:
305                 info->offset = REG(DC_GPIO_HPD_A);
306                 switch (en) {
307                 case GPIO_HPD_1:
308                         info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
309                 break;
310                 case GPIO_HPD_2:
311                         info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
312                 break;
313                 case GPIO_HPD_3:
314                         info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
315                 break;
316                 case GPIO_HPD_4:
317                         info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
318                 break;
319                 case GPIO_HPD_5:
320                         info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
321                 break;
322                 case GPIO_HPD_6:
323                         info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
324                 break;
325                 default:
326                         ASSERT_CRITICAL(false);
327                         result = false;
328                 }
329         break;
330         case GPIO_ID_SYNC:
331                 switch (en) {
332                 case GPIO_SYNC_HSYNC_A:
333                         info->offset = REG(DC_GPIO_SYNCA_A);
334                         info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK;
335                 break;
336                 case GPIO_SYNC_VSYNC_A:
337                         info->offset = REG(DC_GPIO_SYNCA_A);
338                         info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK;
339                 break;
340                 case GPIO_SYNC_HSYNC_B:
341                 case GPIO_SYNC_VSYNC_B:
342                 default:
343                         ASSERT_CRITICAL(false);
344                         result = false;
345                 }
346         break;
347         case GPIO_ID_GSL:
348                 switch (en) {
349                 case GPIO_GSL_GENLOCK_CLOCK:
350                         info->offset = REG(DC_GPIO_GENLK_A);
351                         info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK;
352                 break;
353                 case GPIO_GSL_GENLOCK_VSYNC:
354                         info->offset = REG(DC_GPIO_GENLK_A);
355                         info->mask =
356                                 DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK;
357                 break;
358                 case GPIO_GSL_SWAPLOCK_A:
359                         info->offset = REG(DC_GPIO_GENLK_A);
360                         info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK;
361                 break;
362                 case GPIO_GSL_SWAPLOCK_B:
363                         info->offset = REG(DC_GPIO_GENLK_A);
364                         info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK;
365                 break;
366                 default:
367                         ASSERT_CRITICAL(false);
368                         result = false;
369                 }
370         break;
371         case GPIO_ID_VIP_PAD:
372         default:
373                 ASSERT_CRITICAL(false);
374                 result = false;
375         }
376
377         if (result) {
378                 info->offset_y = info->offset + 2;
379                 info->offset_en = info->offset + 1;
380                 info->offset_mask = info->offset - 1;
381
382                 info->mask_y = info->mask;
383                 info->mask_en = info->mask;
384                 info->mask_mask = info->mask;
385         }
386
387         return result;
388 }
389
390 /* function table */
391 static const struct hw_translate_funcs funcs = {
392         .offset_to_id = offset_to_id,
393         .id_to_offset = id_to_offset,
394 };
395
396 /*
397  * dal_hw_translate_dce120_init
398  *
399  * @brief
400  * Initialize Hw translate function pointers.
401  *
402  * @param
403  * struct hw_translate *tr - [out] struct of function pointers
404  *
405  */
406 void dal_hw_translate_dce120_init(struct hw_translate *tr)
407 {
408         tr->funcs = &funcs;
409 }