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