1 /* 2 * Copyright 2018 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_dcn21.h" 30 31 #include "dm_services.h" 32 #include "include/gpio_types.h" 33 #include "../hw_translate.h" 34 35 #include "dcn/dcn_2_1_0_offset.h" 36 #include "dcn/dcn_2_1_0_sh_mask.h" 37 #include "renoir_ip_offset.h" 38 39 40 41 42 /* begin ********************* 43 * macros to expend register list macro defined in HW object header file */ 44 45 /* DCN */ 46 #define block HPD 47 #define reg_num 0 48 49 #undef BASE_INNER 50 #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg 51 52 #define BASE(seg) BASE_INNER(seg) 53 54 #undef REG 55 #define REG(reg_name)\ 56 BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name 57 #define SF_HPD(reg_name, field_name, post_fix)\ 58 .field_name = reg_name ## __ ## field_name ## post_fix 59 60 /* macros to expend register list macro defined in HW object header file 61 * end *********************/ 62 63 64 static bool offset_to_id( 65 uint32_t offset, 66 uint32_t mask, 67 enum gpio_id *id, 68 uint32_t *en) 69 { 70 switch (offset) { 71 /* GENERIC */ 72 case REG(DC_GPIO_GENERIC_A): 73 *id = GPIO_ID_GENERIC; 74 switch (mask) { 75 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK: 76 *en = GPIO_GENERIC_A; 77 return true; 78 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK: 79 *en = GPIO_GENERIC_B; 80 return true; 81 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK: 82 *en = GPIO_GENERIC_C; 83 return true; 84 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK: 85 *en = GPIO_GENERIC_D; 86 return true; 87 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK: 88 *en = GPIO_GENERIC_E; 89 return true; 90 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK: 91 *en = GPIO_GENERIC_F; 92 return true; 93 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK: 94 *en = GPIO_GENERIC_G; 95 return true; 96 default: 97 ASSERT_CRITICAL(false); 98 #ifdef PALLADIUM_SUPPORTED 99 *en = GPIO_DDC_LINE_DDC1; 100 return true; 101 #endif 102 return false; 103 } 104 break; 105 /* HPD */ 106 case REG(DC_GPIO_HPD_A): 107 *id = GPIO_ID_HPD; 108 switch (mask) { 109 case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK: 110 *en = GPIO_HPD_1; 111 return true; 112 case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK: 113 *en = GPIO_HPD_2; 114 return true; 115 case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK: 116 *en = GPIO_HPD_3; 117 return true; 118 case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK: 119 *en = GPIO_HPD_4; 120 return true; 121 case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK: 122 *en = GPIO_HPD_5; 123 return true; 124 case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK: 125 *en = GPIO_HPD_6; 126 return true; 127 default: 128 ASSERT_CRITICAL(false); 129 return false; 130 } 131 break; 132 /* REG(DC_GPIO_GENLK_MASK */ 133 case REG(DC_GPIO_GENLK_A): 134 *id = GPIO_ID_GSL; 135 switch (mask) { 136 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK: 137 *en = GPIO_GSL_GENLOCK_CLOCK; 138 return true; 139 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK: 140 *en = GPIO_GSL_GENLOCK_VSYNC; 141 return true; 142 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK: 143 *en = GPIO_GSL_SWAPLOCK_A; 144 return true; 145 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK: 146 *en = GPIO_GSL_SWAPLOCK_B; 147 return true; 148 default: 149 ASSERT_CRITICAL(false); 150 return false; 151 } 152 break; 153 /* DDC */ 154 /* we don't care about the GPIO_ID for DDC 155 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK 156 * directly in the create method 157 */ 158 case REG(DC_GPIO_DDC1_A): 159 *en = GPIO_DDC_LINE_DDC1; 160 return true; 161 case REG(DC_GPIO_DDC2_A): 162 *en = GPIO_DDC_LINE_DDC2; 163 return true; 164 case REG(DC_GPIO_DDC3_A): 165 *en = GPIO_DDC_LINE_DDC3; 166 return true; 167 case REG(DC_GPIO_DDC4_A): 168 *en = GPIO_DDC_LINE_DDC4; 169 return true; 170 case REG(DC_GPIO_DDC5_A): 171 *en = GPIO_DDC_LINE_DDC5; 172 return true; 173 case REG(DC_GPIO_DDCVGA_A): 174 *en = GPIO_DDC_LINE_DDC_VGA; 175 return true; 176 177 /* 178 * case REG(DC_GPIO_I2CPAD_A): not exit 179 * case REG(DC_GPIO_PWRSEQ_A): 180 * case REG(DC_GPIO_PAD_STRENGTH_1): 181 * case REG(DC_GPIO_PAD_STRENGTH_2): 182 * case REG(DC_GPIO_DEBUG): 183 */ 184 /* UNEXPECTED */ 185 default: 186 /* case REG(DC_GPIO_SYNCA_A): not exista */ 187 #ifdef PALLADIUM_SUPPORTED 188 *id = GPIO_ID_HPD; 189 *en = GPIO_DDC_LINE_DDC1; 190 return true; 191 #endif 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_DDC5_A__DC_GPIO_DDC5DATA_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_DDC_CLOCK: 233 info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK; 234 switch (en) { 235 case GPIO_DDC_LINE_DDC1: 236 info->offset = REG(DC_GPIO_DDC1_A); 237 break; 238 case GPIO_DDC_LINE_DDC2: 239 info->offset = REG(DC_GPIO_DDC2_A); 240 break; 241 case GPIO_DDC_LINE_DDC3: 242 info->offset = REG(DC_GPIO_DDC3_A); 243 break; 244 case GPIO_DDC_LINE_DDC4: 245 info->offset = REG(DC_GPIO_DDC4_A); 246 break; 247 case GPIO_DDC_LINE_DDC5: 248 info->offset = REG(DC_GPIO_DDC5_A); 249 break; 250 case GPIO_DDC_LINE_DDC_VGA: 251 info->offset = REG(DC_GPIO_DDCVGA_A); 252 break; 253 case GPIO_DDC_LINE_I2C_PAD: 254 default: 255 ASSERT_CRITICAL(false); 256 result = false; 257 } 258 break; 259 case GPIO_ID_GENERIC: 260 info->offset = REG(DC_GPIO_GENERIC_A); 261 switch (en) { 262 case GPIO_GENERIC_A: 263 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK; 264 break; 265 case GPIO_GENERIC_B: 266 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK; 267 break; 268 case GPIO_GENERIC_C: 269 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK; 270 break; 271 case GPIO_GENERIC_D: 272 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK; 273 break; 274 case GPIO_GENERIC_E: 275 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK; 276 break; 277 case GPIO_GENERIC_F: 278 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK; 279 break; 280 case GPIO_GENERIC_G: 281 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK; 282 break; 283 default: 284 ASSERT_CRITICAL(false); 285 result = false; 286 } 287 break; 288 case GPIO_ID_HPD: 289 info->offset = REG(DC_GPIO_HPD_A); 290 switch (en) { 291 case GPIO_HPD_1: 292 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; 293 break; 294 case GPIO_HPD_2: 295 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK; 296 break; 297 case GPIO_HPD_3: 298 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK; 299 break; 300 case GPIO_HPD_4: 301 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK; 302 break; 303 case GPIO_HPD_5: 304 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK; 305 break; 306 case GPIO_HPD_6: 307 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK; 308 break; 309 default: 310 ASSERT_CRITICAL(false); 311 #ifdef PALLADIUM_SUPPORTED 312 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; 313 result = true; 314 #endif 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_dcn21_init(struct hw_translate *tr) 383 { 384 tr->funcs = &funcs; 385 } 386 387