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