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