1 /* $NetBSD: amdgpu_hw_translate_dce80.c,v 1.2 2021/12/18 23:45:05 riastradh Exp $ */ 2 3 /* 4 * Copyright 2012-15 Advanced Micro Devices, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: AMD 25 * 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_hw_translate_dce80.c,v 1.2 2021/12/18 23:45:05 riastradh Exp $"); 30 31 #include "dm_services.h" 32 33 /* 34 * Pre-requisites: headers required by header of this unit 35 */ 36 #include "include/gpio_types.h" 37 #include "../hw_translate.h" 38 39 #include "hw_translate_dce80.h" 40 41 #include "dce/dce_8_0_d.h" 42 #include "dce/dce_8_0_sh_mask.h" 43 #include "smu/smu_7_0_1_d.h" 44 45 /* 46 * @brief 47 * Returns index of first bit (starting with LSB) which is set 48 */ 49 static uint32_t index_from_vector( 50 uint32_t vector) 51 { 52 uint32_t result = 0; 53 uint32_t mask = 1; 54 55 do { 56 if (vector == mask) 57 return result; 58 59 ++result; 60 mask <<= 1; 61 } while (mask); 62 63 BREAK_TO_DEBUGGER(); 64 65 return GPIO_ENUM_UNKNOWN; 66 } 67 68 static bool offset_to_id( 69 uint32_t offset, 70 uint32_t mask, 71 enum gpio_id *id, 72 uint32_t *en) 73 { 74 switch (offset) { 75 /* GENERIC */ 76 case mmDC_GPIO_GENERIC_A: 77 *id = GPIO_ID_GENERIC; 78 switch (mask) { 79 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK: 80 *en = GPIO_GENERIC_A; 81 return true; 82 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK: 83 *en = GPIO_GENERIC_B; 84 return true; 85 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK: 86 *en = GPIO_GENERIC_C; 87 return true; 88 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK: 89 *en = GPIO_GENERIC_D; 90 return true; 91 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK: 92 *en = GPIO_GENERIC_E; 93 return true; 94 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK: 95 *en = GPIO_GENERIC_F; 96 return true; 97 case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK: 98 *en = GPIO_GENERIC_G; 99 return true; 100 default: 101 BREAK_TO_DEBUGGER(); 102 return false; 103 } 104 break; 105 /* HPD */ 106 case mmDC_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 BREAK_TO_DEBUGGER(); 129 return false; 130 } 131 break; 132 /* SYNCA */ 133 case mmDC_GPIO_SYNCA_A: 134 *id = GPIO_ID_SYNC; 135 switch (mask) { 136 case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK: 137 *en = GPIO_SYNC_HSYNC_A; 138 return true; 139 case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK: 140 *en = GPIO_SYNC_VSYNC_A; 141 return true; 142 default: 143 BREAK_TO_DEBUGGER(); 144 return false; 145 } 146 break; 147 /* mmDC_GPIO_GENLK_MASK */ 148 case mmDC_GPIO_GENLK_A: 149 *id = GPIO_ID_GSL; 150 switch (mask) { 151 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK: 152 *en = GPIO_GSL_GENLOCK_CLOCK; 153 return true; 154 case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK: 155 *en = GPIO_GSL_GENLOCK_VSYNC; 156 return true; 157 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK: 158 *en = GPIO_GSL_SWAPLOCK_A; 159 return true; 160 case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK: 161 *en = GPIO_GSL_SWAPLOCK_B; 162 return true; 163 default: 164 BREAK_TO_DEBUGGER(); 165 return false; 166 } 167 break; 168 /* GPIOPAD */ 169 case mmGPIOPAD_A: 170 *id = GPIO_ID_GPIO_PAD; 171 *en = index_from_vector(mask); 172 return (*en <= GPIO_GPIO_PAD_MAX); 173 /* DDC */ 174 /* we don't care about the GPIO_ID for DDC 175 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK 176 * directly in the create method */ 177 case mmDC_GPIO_DDC1_A: 178 *en = GPIO_DDC_LINE_DDC1; 179 return true; 180 case mmDC_GPIO_DDC2_A: 181 *en = GPIO_DDC_LINE_DDC2; 182 return true; 183 case mmDC_GPIO_DDC3_A: 184 *en = GPIO_DDC_LINE_DDC3; 185 return true; 186 case mmDC_GPIO_DDC4_A: 187 *en = GPIO_DDC_LINE_DDC4; 188 return true; 189 case mmDC_GPIO_DDC5_A: 190 *en = GPIO_DDC_LINE_DDC5; 191 return true; 192 case mmDC_GPIO_DDC6_A: 193 *en = GPIO_DDC_LINE_DDC6; 194 return true; 195 case mmDC_GPIO_DDCVGA_A: 196 *en = GPIO_DDC_LINE_DDC_VGA; 197 return true; 198 /* GPIO_I2CPAD */ 199 case mmDC_GPIO_I2CPAD_A: 200 *en = GPIO_DDC_LINE_I2C_PAD; 201 return true; 202 /* Not implemented */ 203 case mmDC_GPIO_PWRSEQ_A: 204 case mmDC_GPIO_PAD_STRENGTH_1: 205 case mmDC_GPIO_PAD_STRENGTH_2: 206 case mmDC_GPIO_DEBUG: 207 return false; 208 /* UNEXPECTED */ 209 default: 210 BREAK_TO_DEBUGGER(); 211 return false; 212 } 213 } 214 215 static bool id_to_offset( 216 enum gpio_id id, 217 uint32_t en, 218 struct gpio_pin_info *info) 219 { 220 bool result = true; 221 222 switch (id) { 223 case GPIO_ID_DDC_DATA: 224 info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK; 225 switch (en) { 226 case GPIO_DDC_LINE_DDC1: 227 info->offset = mmDC_GPIO_DDC1_A; 228 break; 229 case GPIO_DDC_LINE_DDC2: 230 info->offset = mmDC_GPIO_DDC2_A; 231 break; 232 case GPIO_DDC_LINE_DDC3: 233 info->offset = mmDC_GPIO_DDC3_A; 234 break; 235 case GPIO_DDC_LINE_DDC4: 236 info->offset = mmDC_GPIO_DDC4_A; 237 break; 238 case GPIO_DDC_LINE_DDC5: 239 info->offset = mmDC_GPIO_DDC5_A; 240 break; 241 case GPIO_DDC_LINE_DDC6: 242 info->offset = mmDC_GPIO_DDC6_A; 243 break; 244 case GPIO_DDC_LINE_DDC_VGA: 245 info->offset = mmDC_GPIO_DDCVGA_A; 246 break; 247 case GPIO_DDC_LINE_I2C_PAD: 248 info->offset = mmDC_GPIO_I2CPAD_A; 249 break; 250 default: 251 BREAK_TO_DEBUGGER(); 252 result = false; 253 } 254 break; 255 case GPIO_ID_DDC_CLOCK: 256 info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK; 257 switch (en) { 258 case GPIO_DDC_LINE_DDC1: 259 info->offset = mmDC_GPIO_DDC1_A; 260 break; 261 case GPIO_DDC_LINE_DDC2: 262 info->offset = mmDC_GPIO_DDC2_A; 263 break; 264 case GPIO_DDC_LINE_DDC3: 265 info->offset = mmDC_GPIO_DDC3_A; 266 break; 267 case GPIO_DDC_LINE_DDC4: 268 info->offset = mmDC_GPIO_DDC4_A; 269 break; 270 case GPIO_DDC_LINE_DDC5: 271 info->offset = mmDC_GPIO_DDC5_A; 272 break; 273 case GPIO_DDC_LINE_DDC6: 274 info->offset = mmDC_GPIO_DDC6_A; 275 break; 276 case GPIO_DDC_LINE_DDC_VGA: 277 info->offset = mmDC_GPIO_DDCVGA_A; 278 break; 279 case GPIO_DDC_LINE_I2C_PAD: 280 info->offset = mmDC_GPIO_I2CPAD_A; 281 break; 282 default: 283 BREAK_TO_DEBUGGER(); 284 result = false; 285 } 286 break; 287 case GPIO_ID_GENERIC: 288 info->offset = mmDC_GPIO_GENERIC_A; 289 switch (en) { 290 case GPIO_GENERIC_A: 291 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK; 292 break; 293 case GPIO_GENERIC_B: 294 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK; 295 break; 296 case GPIO_GENERIC_C: 297 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK; 298 break; 299 case GPIO_GENERIC_D: 300 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK; 301 break; 302 case GPIO_GENERIC_E: 303 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK; 304 break; 305 case GPIO_GENERIC_F: 306 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK; 307 break; 308 case GPIO_GENERIC_G: 309 info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK; 310 break; 311 default: 312 BREAK_TO_DEBUGGER(); 313 result = false; 314 } 315 break; 316 case GPIO_ID_HPD: 317 info->offset = mmDC_GPIO_HPD_A; 318 switch (en) { 319 case GPIO_HPD_1: 320 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; 321 break; 322 case GPIO_HPD_2: 323 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK; 324 break; 325 case GPIO_HPD_3: 326 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK; 327 break; 328 case GPIO_HPD_4: 329 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK; 330 break; 331 case GPIO_HPD_5: 332 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK; 333 break; 334 case GPIO_HPD_6: 335 info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK; 336 break; 337 default: 338 BREAK_TO_DEBUGGER(); 339 result = false; 340 } 341 break; 342 case GPIO_ID_SYNC: 343 switch (en) { 344 case GPIO_SYNC_HSYNC_A: 345 info->offset = mmDC_GPIO_SYNCA_A; 346 info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK; 347 break; 348 case GPIO_SYNC_VSYNC_A: 349 info->offset = mmDC_GPIO_SYNCA_A; 350 info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK; 351 break; 352 case GPIO_SYNC_HSYNC_B: 353 case GPIO_SYNC_VSYNC_B: 354 default: 355 BREAK_TO_DEBUGGER(); 356 result = false; 357 } 358 break; 359 case GPIO_ID_GSL: 360 switch (en) { 361 case GPIO_GSL_GENLOCK_CLOCK: 362 info->offset = mmDC_GPIO_GENLK_A; 363 info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK; 364 break; 365 case GPIO_GSL_GENLOCK_VSYNC: 366 info->offset = mmDC_GPIO_GENLK_A; 367 info->mask = 368 DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK; 369 break; 370 case GPIO_GSL_SWAPLOCK_A: 371 info->offset = mmDC_GPIO_GENLK_A; 372 info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK; 373 break; 374 case GPIO_GSL_SWAPLOCK_B: 375 info->offset = mmDC_GPIO_GENLK_A; 376 info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK; 377 break; 378 default: 379 BREAK_TO_DEBUGGER(); 380 result = false; 381 } 382 break; 383 case GPIO_ID_GPIO_PAD: 384 info->offset = mmGPIOPAD_A; 385 info->mask = (1 << en); 386 result = (info->mask <= GPIO_GPIO_PAD_MAX); 387 break; 388 case GPIO_ID_VIP_PAD: 389 default: 390 BREAK_TO_DEBUGGER(); 391 result = false; 392 } 393 394 if (result) { 395 info->offset_y = info->offset + 2; 396 info->offset_en = info->offset + 1; 397 info->offset_mask = info->offset - 1; 398 399 info->mask_y = info->mask; 400 info->mask_en = info->mask; 401 info->mask_mask = info->mask; 402 } 403 404 return result; 405 } 406 407 static const struct hw_translate_funcs funcs = { 408 .offset_to_id = offset_to_id, 409 .id_to_offset = id_to_offset, 410 }; 411 412 void dal_hw_translate_dce80_init( 413 struct hw_translate *translate) 414 { 415 translate->funcs = &funcs; 416 } 417