Line data Source code
1 : /* 2 : * Copyright 2012-15 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 : #include "dm_services.h" 27 : 28 : /* 29 : * Pre-requisites: headers required by header of this unit 30 : */ 31 : #include "include/gpio_types.h" 32 : #include "../hw_translate.h" 33 : 34 : #include "hw_translate_dce80.h" 35 : 36 : #include "dce/dce_8_0_d.h" 37 : #include "dce/dce_8_0_sh_mask.h" 38 : #include "smu/smu_7_0_1_d.h" 39 : 40 : /* 41 : * @brief 42 : * Returns index of first bit (starting with LSB) which is set 43 : */ 44 0 : static uint32_t index_from_vector( 45 : uint32_t vector) 46 : { 47 0 : uint32_t result = 0; 48 0 : uint32_t mask = 1; 49 : 50 : do { 51 0 : if (vector == mask) 52 : return result; 53 : 54 0 : ++result; 55 0 : mask <<= 1; 56 0 : } while (mask); 57 : 58 0 : BREAK_TO_DEBUGGER(); 59 : 60 0 : return GPIO_ENUM_UNKNOWN; 61 : } 62 : 63 0 : static bool offset_to_id( 64 : uint32_t offset, 65 : uint32_t mask, 66 : enum gpio_id *id, 67 : uint32_t *en) 68 : { 69 0 : switch (offset) { 70 : /* GENERIC */ 71 : case mmDC_GPIO_GENERIC_A: 72 0 : *id = GPIO_ID_GENERIC; 73 0 : switch (mask) { 74 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK: 75 0 : *en = GPIO_GENERIC_A; 76 0 : return true; 77 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK: 78 0 : *en = GPIO_GENERIC_B; 79 0 : return true; 80 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK: 81 0 : *en = GPIO_GENERIC_C; 82 0 : return true; 83 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK: 84 0 : *en = GPIO_GENERIC_D; 85 0 : return true; 86 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK: 87 0 : *en = GPIO_GENERIC_E; 88 0 : return true; 89 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK: 90 0 : *en = GPIO_GENERIC_F; 91 0 : return true; 92 : case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK: 93 0 : *en = GPIO_GENERIC_G; 94 0 : return true; 95 : default: 96 0 : BREAK_TO_DEBUGGER(); 97 0 : return false; 98 : } 99 : break; 100 : /* HPD */ 101 : case mmDC_GPIO_HPD_A: 102 0 : *id = GPIO_ID_HPD; 103 0 : switch (mask) { 104 : case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK: 105 0 : *en = GPIO_HPD_1; 106 0 : return true; 107 : case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK: 108 0 : *en = GPIO_HPD_2; 109 0 : return true; 110 : case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK: 111 0 : *en = GPIO_HPD_3; 112 0 : return true; 113 : case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK: 114 0 : *en = GPIO_HPD_4; 115 0 : return true; 116 : case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK: 117 0 : *en = GPIO_HPD_5; 118 0 : return true; 119 : case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK: 120 0 : *en = GPIO_HPD_6; 121 0 : return true; 122 : default: 123 0 : BREAK_TO_DEBUGGER(); 124 0 : return false; 125 : } 126 : break; 127 : /* SYNCA */ 128 : case mmDC_GPIO_SYNCA_A: 129 0 : *id = GPIO_ID_SYNC; 130 0 : switch (mask) { 131 : case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK: 132 0 : *en = GPIO_SYNC_HSYNC_A; 133 0 : return true; 134 : case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK: 135 0 : *en = GPIO_SYNC_VSYNC_A; 136 0 : return true; 137 : default: 138 0 : BREAK_TO_DEBUGGER(); 139 0 : return false; 140 : } 141 : break; 142 : /* mmDC_GPIO_GENLK_MASK */ 143 : case mmDC_GPIO_GENLK_A: 144 0 : *id = GPIO_ID_GSL; 145 0 : switch (mask) { 146 : case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK: 147 0 : *en = GPIO_GSL_GENLOCK_CLOCK; 148 0 : return true; 149 : case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK: 150 0 : *en = GPIO_GSL_GENLOCK_VSYNC; 151 0 : return true; 152 : case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK: 153 0 : *en = GPIO_GSL_SWAPLOCK_A; 154 0 : return true; 155 : case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK: 156 0 : *en = GPIO_GSL_SWAPLOCK_B; 157 0 : return true; 158 : default: 159 0 : BREAK_TO_DEBUGGER(); 160 0 : return false; 161 : } 162 : break; 163 : /* GPIOPAD */ 164 : case mmGPIOPAD_A: 165 0 : *id = GPIO_ID_GPIO_PAD; 166 0 : *en = index_from_vector(mask); 167 0 : return (*en <= GPIO_GPIO_PAD_MAX); 168 : /* DDC */ 169 : /* we don't care about the GPIO_ID for DDC 170 : * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK 171 : * directly in the create method */ 172 : case mmDC_GPIO_DDC1_A: 173 0 : *en = GPIO_DDC_LINE_DDC1; 174 0 : return true; 175 : case mmDC_GPIO_DDC2_A: 176 0 : *en = GPIO_DDC_LINE_DDC2; 177 0 : return true; 178 : case mmDC_GPIO_DDC3_A: 179 0 : *en = GPIO_DDC_LINE_DDC3; 180 0 : return true; 181 : case mmDC_GPIO_DDC4_A: 182 0 : *en = GPIO_DDC_LINE_DDC4; 183 0 : return true; 184 : case mmDC_GPIO_DDC5_A: 185 0 : *en = GPIO_DDC_LINE_DDC5; 186 0 : return true; 187 : case mmDC_GPIO_DDC6_A: 188 0 : *en = GPIO_DDC_LINE_DDC6; 189 0 : return true; 190 : case mmDC_GPIO_DDCVGA_A: 191 0 : *en = GPIO_DDC_LINE_DDC_VGA; 192 0 : return true; 193 : /* GPIO_I2CPAD */ 194 : case mmDC_GPIO_I2CPAD_A: 195 0 : *en = GPIO_DDC_LINE_I2C_PAD; 196 0 : return true; 197 : /* Not implemented */ 198 : case mmDC_GPIO_PWRSEQ_A: 199 : case mmDC_GPIO_PAD_STRENGTH_1: 200 : case mmDC_GPIO_PAD_STRENGTH_2: 201 : case mmDC_GPIO_DEBUG: 202 : return false; 203 : /* UNEXPECTED */ 204 : default: 205 0 : BREAK_TO_DEBUGGER(); 206 0 : return false; 207 : } 208 : } 209 : 210 0 : static bool id_to_offset( 211 : enum gpio_id id, 212 : uint32_t en, 213 : struct gpio_pin_info *info) 214 : { 215 0 : bool result = true; 216 : 217 0 : switch (id) { 218 : case GPIO_ID_DDC_DATA: 219 0 : info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK; 220 0 : switch (en) { 221 : case GPIO_DDC_LINE_DDC1: 222 0 : info->offset = mmDC_GPIO_DDC1_A; 223 0 : break; 224 : case GPIO_DDC_LINE_DDC2: 225 0 : info->offset = mmDC_GPIO_DDC2_A; 226 0 : break; 227 : case GPIO_DDC_LINE_DDC3: 228 0 : info->offset = mmDC_GPIO_DDC3_A; 229 0 : break; 230 : case GPIO_DDC_LINE_DDC4: 231 0 : info->offset = mmDC_GPIO_DDC4_A; 232 0 : break; 233 : case GPIO_DDC_LINE_DDC5: 234 0 : info->offset = mmDC_GPIO_DDC5_A; 235 0 : break; 236 : case GPIO_DDC_LINE_DDC6: 237 0 : info->offset = mmDC_GPIO_DDC6_A; 238 0 : break; 239 : case GPIO_DDC_LINE_DDC_VGA: 240 0 : info->offset = mmDC_GPIO_DDCVGA_A; 241 0 : break; 242 : case GPIO_DDC_LINE_I2C_PAD: 243 0 : info->offset = mmDC_GPIO_I2CPAD_A; 244 0 : break; 245 : default: 246 0 : BREAK_TO_DEBUGGER(); 247 0 : result = false; 248 : } 249 : break; 250 : case GPIO_ID_DDC_CLOCK: 251 0 : info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK; 252 0 : switch (en) { 253 : case GPIO_DDC_LINE_DDC1: 254 0 : info->offset = mmDC_GPIO_DDC1_A; 255 0 : break; 256 : case GPIO_DDC_LINE_DDC2: 257 0 : info->offset = mmDC_GPIO_DDC2_A; 258 0 : break; 259 : case GPIO_DDC_LINE_DDC3: 260 0 : info->offset = mmDC_GPIO_DDC3_A; 261 0 : break; 262 : case GPIO_DDC_LINE_DDC4: 263 0 : info->offset = mmDC_GPIO_DDC4_A; 264 0 : break; 265 : case GPIO_DDC_LINE_DDC5: 266 0 : info->offset = mmDC_GPIO_DDC5_A; 267 0 : break; 268 : case GPIO_DDC_LINE_DDC6: 269 0 : info->offset = mmDC_GPIO_DDC6_A; 270 0 : break; 271 : case GPIO_DDC_LINE_DDC_VGA: 272 0 : info->offset = mmDC_GPIO_DDCVGA_A; 273 0 : break; 274 : case GPIO_DDC_LINE_I2C_PAD: 275 0 : info->offset = mmDC_GPIO_I2CPAD_A; 276 0 : break; 277 : default: 278 0 : BREAK_TO_DEBUGGER(); 279 0 : result = false; 280 : } 281 : break; 282 : case GPIO_ID_GENERIC: 283 0 : info->offset = mmDC_GPIO_GENERIC_A; 284 0 : switch (en) { 285 : case GPIO_GENERIC_A: 286 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK; 287 0 : break; 288 : case GPIO_GENERIC_B: 289 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK; 290 0 : break; 291 : case GPIO_GENERIC_C: 292 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK; 293 0 : break; 294 : case GPIO_GENERIC_D: 295 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK; 296 0 : break; 297 : case GPIO_GENERIC_E: 298 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK; 299 0 : break; 300 : case GPIO_GENERIC_F: 301 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK; 302 0 : break; 303 : case GPIO_GENERIC_G: 304 0 : info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK; 305 0 : break; 306 : default: 307 0 : BREAK_TO_DEBUGGER(); 308 0 : result = false; 309 : } 310 : break; 311 : case GPIO_ID_HPD: 312 0 : info->offset = mmDC_GPIO_HPD_A; 313 0 : switch (en) { 314 : case GPIO_HPD_1: 315 0 : info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; 316 0 : break; 317 : case GPIO_HPD_2: 318 0 : info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK; 319 0 : break; 320 : case GPIO_HPD_3: 321 0 : info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK; 322 0 : break; 323 : case GPIO_HPD_4: 324 0 : info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK; 325 0 : break; 326 : case GPIO_HPD_5: 327 0 : info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK; 328 0 : break; 329 : case GPIO_HPD_6: 330 0 : info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK; 331 0 : break; 332 : default: 333 0 : BREAK_TO_DEBUGGER(); 334 0 : result = false; 335 : } 336 : break; 337 : case GPIO_ID_SYNC: 338 0 : switch (en) { 339 : case GPIO_SYNC_HSYNC_A: 340 0 : info->offset = mmDC_GPIO_SYNCA_A; 341 0 : info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK; 342 0 : break; 343 : case GPIO_SYNC_VSYNC_A: 344 0 : info->offset = mmDC_GPIO_SYNCA_A; 345 0 : info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK; 346 0 : break; 347 : case GPIO_SYNC_HSYNC_B: 348 : case GPIO_SYNC_VSYNC_B: 349 : default: 350 0 : BREAK_TO_DEBUGGER(); 351 0 : result = false; 352 : } 353 : break; 354 : case GPIO_ID_GSL: 355 0 : switch (en) { 356 : case GPIO_GSL_GENLOCK_CLOCK: 357 0 : info->offset = mmDC_GPIO_GENLK_A; 358 0 : info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK; 359 0 : break; 360 : case GPIO_GSL_GENLOCK_VSYNC: 361 0 : info->offset = mmDC_GPIO_GENLK_A; 362 0 : info->mask = 363 : DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK; 364 0 : break; 365 : case GPIO_GSL_SWAPLOCK_A: 366 0 : info->offset = mmDC_GPIO_GENLK_A; 367 0 : info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK; 368 0 : break; 369 : case GPIO_GSL_SWAPLOCK_B: 370 0 : info->offset = mmDC_GPIO_GENLK_A; 371 0 : info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK; 372 0 : break; 373 : default: 374 0 : BREAK_TO_DEBUGGER(); 375 0 : result = false; 376 : } 377 : break; 378 : case GPIO_ID_GPIO_PAD: 379 0 : info->offset = mmGPIOPAD_A; 380 0 : info->mask = (1 << en); 381 0 : result = (info->mask <= GPIO_GPIO_PAD_MAX); 382 0 : break; 383 : case GPIO_ID_VIP_PAD: 384 : default: 385 0 : BREAK_TO_DEBUGGER(); 386 0 : result = false; 387 : } 388 : 389 0 : if (result) { 390 0 : info->offset_y = info->offset + 2; 391 0 : info->offset_en = info->offset + 1; 392 0 : info->offset_mask = info->offset - 1; 393 : 394 0 : info->mask_y = info->mask; 395 0 : info->mask_en = info->mask; 396 0 : info->mask_mask = info->mask; 397 : } 398 : 399 0 : return result; 400 : } 401 : 402 : static const struct hw_translate_funcs funcs = { 403 : .offset_to_id = offset_to_id, 404 : .id_to_offset = id_to_offset, 405 : }; 406 : 407 0 : void dal_hw_translate_dce80_init( 408 : struct hw_translate *translate) 409 : { 410 0 : translate->funcs = &funcs; 411 0 : }