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