xref: /dragonfly/sys/dev/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c (revision b843c749addef9340ee7d4e250b09fdd492602a1)
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_dcn10.h"
31 
32 #include "dm_services.h"
33 #include "include/gpio_types.h"
34 #include "../hw_translate.h"
35 
36 #include "dcn/dcn_1_0_offset.h"
37 #include "dcn/dcn_1_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 
offset_to_id(uint32_t offset,uint32_t mask,enum gpio_id * id,uint32_t * en)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 
id_to_offset(enum gpio_id id,uint32_t en,struct gpio_pin_info * info)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_dcn10_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  */
dal_hw_translate_dcn10_init(struct hw_translate * tr)406 void dal_hw_translate_dcn10_init(struct hw_translate *tr)
407 {
408           tr->funcs = &funcs;
409 }
410