Home | History | Annotate | Line # | Download | only in dce120
      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 
     66 static 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 
    208 static 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 */
    396 static 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  */
    411 void dal_hw_translate_dce120_init(struct hw_translate *tr)
    412 {
    413 	tr->funcs = &funcs;
    414 }
    415