1 /* 2 * Copyright 2022 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 #include "hw_translate_dcn32.h" 30 31 #include "dm_services.h" 32 #include "include/gpio_types.h" 33 #include "../hw_translate.h" 34 35 #include "dcn/dcn_3_2_0_offset.h" 36 #include "dcn/dcn_3_2_0_sh_mask.h" 37 38 #define DCN_BASE__INST0_SEG2 0x000034C0 39 40 /* begin ********************* 41 * macros to expend register list macro defined in HW object header file */ 42 43 /* DCN */ 44 #define block HPD 45 #define reg_num 0 46 47 #undef BASE_INNER 48 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg 49 50 #define BASE(seg) BASE_INNER(seg) 51 52 #undef REG 53 #define REG(reg_name)\ 54 BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name 55 #define SF_HPD(reg_name, field_name, post_fix)\ 56 .field_name = reg_name ## __ ## field_name ## post_fix 57 58 59 /* macros to expend register list macro defined in HW object header file 60 * end *********************/ 61 62 63 static bool offset_to_id( 64 uint32_t offset, 65 uint32_t mask, 66 enum gpio_id *id, 67 uint32_t *en) 68 { 69 switch (offset) { 70 /* GENERIC */ 71 case REG(DC_GPIO_GENERIC_A): 72 *id = GPIO_ID_GENERIC; 73 switch (mask) { 74 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK: 75 *en = GPIO_GENERIC_A; 76 return true; 77 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK: 78 *en = GPIO_GENERIC_B; 79 return true; 80 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK: 81 *en = GPIO_GENERIC_C; 82 return true; 83 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK: 84 *en = GPIO_GENERIC_D; 85 return true; 86 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK: 87 *en = GPIO_GENERIC_E; 88 return true; 89 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK: 90 *en = GPIO_GENERIC_F; 91 return true; 92 default: 93 ASSERT_CRITICAL(false); 94 return false; 95 } 96 break; 97 /* HPD */ 98 case REG(DC_GPIO_HPD_A): 99 *id = GPIO_ID_HPD; 100 switch (mask) { 101 case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK: 102 *en = GPIO_HPD_1; 103 return true; 104 case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK: 105 *en = GPIO_HPD_2; 106 return true; 107 case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK: 108 *en = GPIO_HPD_3; 109 return true; 110 case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK: 111 *en = GPIO_HPD_4; 112 return true; 113 case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK: 114 *en = GPIO_HPD_5; 115 return true; 116 default: 117 ASSERT_CRITICAL(false); 118 return false; 119 } 120 break; 121 /* REG(DC_GPIO_GENLK_MASK */ 122 case REG(DC_GPIO_GENLK_A): 123 *id = GPIO_ID_GSL; 124 switch (mask) { 125 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK: 126 *en = GPIO_GSL_GENLOCK_CLOCK; 127 return true; 128 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK: 129 *en = GPIO_GSL_GENLOCK_VSYNC; 130 return true; 131 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK: 132 *en = GPIO_GSL_SWAPLOCK_A; 133 return true; 134 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK: 135 *en = GPIO_GSL_SWAPLOCK_B; 136 return true; 137 default: 138 ASSERT_CRITICAL(false); 139 return false; 140 } 141 break; 142 /* DDC */ 143 /* we don't care about the GPIO_ID for DDC 144 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK 145 * directly in the create method */ 146 case REG(DC_GPIO_DDC1_A): 147 *en = GPIO_DDC_LINE_DDC1; 148 return true; 149 case REG(DC_GPIO_DDC2_A): 150 *en = GPIO_DDC_LINE_DDC2; 151 return true; 152 case REG(DC_GPIO_DDC3_A): 153 *en = GPIO_DDC_LINE_DDC3; 154 return true; 155 case REG(DC_GPIO_DDC4_A): 156 *en = GPIO_DDC_LINE_DDC4; 157 return true; 158 case REG(DC_GPIO_DDC5_A): 159 *en = GPIO_DDC_LINE_DDC5; 160 return true; 161 case REG(DC_GPIO_DDCVGA_A): 162 *en = GPIO_DDC_LINE_DDC_VGA; 163 return true; 164 default: 165 ASSERT_CRITICAL(false); 166 return false; 167 } 168 } 169 170 static bool id_to_offset( 171 enum gpio_id id, 172 uint32_t en, 173 struct gpio_pin_info *info) 174 { 175 bool result = true; 176 177 switch (id) { 178 case GPIO_ID_DDC_DATA: 179 info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK; 180 switch (en) { 181 case GPIO_DDC_LINE_DDC1: 182 info->offset = REG(DC_GPIO_DDC1_A); 183 break; 184 case GPIO_DDC_LINE_DDC2: 185 info->offset = REG(DC_GPIO_DDC2_A); 186 break; 187 case GPIO_DDC_LINE_DDC3: 188 info->offset = REG(DC_GPIO_DDC3_A); 189 break; 190 case GPIO_DDC_LINE_DDC4: 191 info->offset = REG(DC_GPIO_DDC4_A); 192 break; 193 case GPIO_DDC_LINE_DDC5: 194 info->offset = REG(DC_GPIO_DDC5_A); 195 break; 196 case GPIO_DDC_LINE_DDC_VGA: 197 info->offset = REG(DC_GPIO_DDCVGA_A); 198 break; 199 case GPIO_DDC_LINE_I2C_PAD: 200 default: 201 ASSERT_CRITICAL(false); 202 result = false; 203 } 204 break; 205 case GPIO_ID_DDC_CLOCK: 206 info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK; 207 switch (en) { 208 case GPIO_DDC_LINE_DDC1: 209 info->offset = REG(DC_GPIO_DDC1_A); 210 break; 211 case GPIO_DDC_LINE_DDC2: 212 info->offset = REG(DC_GPIO_DDC2_A); 213 break; 214 case GPIO_DDC_LINE_DDC3: 215 info->offset = REG(DC_GPIO_DDC3_A); 216 break; 217 case GPIO_DDC_LINE_DDC4: 218 info->offset = REG(DC_GPIO_DDC4_A); 219 break; 220 case GPIO_DDC_LINE_DDC5: 221 info->offset = REG(DC_GPIO_DDC5_A); 222 break; 223 case GPIO_DDC_LINE_DDC_VGA: 224 info->offset = REG(DC_GPIO_DDCVGA_A); 225 break; 226 case GPIO_DDC_LINE_I2C_PAD: 227 default: 228 ASSERT_CRITICAL(false); 229 result = false; 230 } 231 break; 232 case GPIO_ID_GENERIC: 233 info->offset = REG(DC_GPIO_GENERIC_A); 234 switch (en) { 235 case GPIO_GENERIC_A: 236 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK; 237 break; 238 case GPIO_GENERIC_B: 239 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK; 240 break; 241 case GPIO_GENERIC_C: 242 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK; 243 break; 244 case GPIO_GENERIC_D: 245 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK; 246 break; 247 case GPIO_GENERIC_E: 248 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK; 249 break; 250 case GPIO_GENERIC_F: 251 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK; 252 break; 253 default: 254 ASSERT_CRITICAL(false); 255 result = false; 256 } 257 break; 258 case GPIO_ID_HPD: 259 info->offset = REG(DC_GPIO_HPD_A); 260 switch (en) { 261 case GPIO_HPD_1: 262 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; 263 break; 264 case GPIO_HPD_2: 265 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK; 266 break; 267 case GPIO_HPD_3: 268 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK; 269 break; 270 case GPIO_HPD_4: 271 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK; 272 break; 273 case GPIO_HPD_5: 274 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK; 275 break; 276 default: 277 ASSERT_CRITICAL(false); 278 result = false; 279 } 280 break; 281 case GPIO_ID_GSL: 282 switch (en) { 283 case GPIO_GSL_GENLOCK_CLOCK: 284 /*not implmented*/ 285 ASSERT_CRITICAL(false); 286 result = false; 287 break; 288 case GPIO_GSL_GENLOCK_VSYNC: 289 /*not implmented*/ 290 ASSERT_CRITICAL(false); 291 result = false; 292 break; 293 case GPIO_GSL_SWAPLOCK_A: 294 /*not implmented*/ 295 ASSERT_CRITICAL(false); 296 result = false; 297 break; 298 case GPIO_GSL_SWAPLOCK_B: 299 /*not implmented*/ 300 ASSERT_CRITICAL(false); 301 result = false; 302 303 break; 304 default: 305 ASSERT_CRITICAL(false); 306 result = false; 307 } 308 break; 309 case GPIO_ID_SYNC: 310 case GPIO_ID_VIP_PAD: 311 default: 312 ASSERT_CRITICAL(false); 313 result = false; 314 } 315 316 if (result) { 317 info->offset_y = info->offset + 2; 318 info->offset_en = info->offset + 1; 319 info->offset_mask = info->offset - 1; 320 321 info->mask_y = info->mask; 322 info->mask_en = info->mask; 323 info->mask_mask = info->mask; 324 } 325 326 return result; 327 } 328 329 /* function table */ 330 static const struct hw_translate_funcs funcs = { 331 .offset_to_id = offset_to_id, 332 .id_to_offset = id_to_offset, 333 }; 334 335 /* 336 * dal_hw_translate_dcn32_init 337 * 338 * @brief 339 * Initialize Hw translate function pointers. 340 * 341 * @param 342 * struct hw_translate *tr - [out] struct of function pointers 343 * 344 */ 345 void dal_hw_translate_dcn32_init(struct hw_translate *tr) 346 { 347 tr->funcs = &funcs; 348 } 349 350