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