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