1 /* $NetBSD: amdgpu_ppatomfwctrl.c,v 1.3 2021/12/19 12:21:29 riastradh Exp $ */ 2 3 /* 4 * Copyright 2016 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 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: amdgpu_ppatomfwctrl.c,v 1.3 2021/12/19 12:21:29 riastradh Exp $"); 28 29 #include "ppatomfwctrl.h" 30 #include "atomfirmware.h" 31 #include "atom.h" 32 #include "pp_debug.h" 33 34 static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4( 35 const struct atom_voltage_objects_info_v4_1 *voltage_object_info_table, 36 uint8_t voltage_type, uint8_t voltage_mode) 37 { 38 unsigned int size = le16_to_cpu( 39 voltage_object_info_table->table_header.structuresize); 40 unsigned int offset = 41 offsetof(struct atom_voltage_objects_info_v4_1, voltage_object[0]); 42 unsigned long start = (unsigned long)voltage_object_info_table; 43 44 while (offset < size) { 45 const union atom_voltage_object_v4 *voltage_object = 46 (const union atom_voltage_object_v4 *)(start + offset); 47 48 if (voltage_type == voltage_object->gpio_voltage_obj.header.voltage_type && 49 voltage_mode == voltage_object->gpio_voltage_obj.header.voltage_mode) 50 return voltage_object; 51 52 offset += le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size); 53 54 } 55 56 return NULL; 57 } 58 59 static const struct atom_voltage_objects_info_v4_1 *pp_atomfwctrl_get_voltage_info_table( 60 struct pp_hwmgr *hwmgr) 61 { 62 const void *table_address; 63 uint16_t idx; 64 65 idx = GetIndexIntoMasterDataTable(voltageobject_info); 66 table_address = smu_atom_get_data_table(hwmgr->adev, 67 idx, NULL, NULL, NULL); 68 69 PP_ASSERT_WITH_CODE(table_address, 70 "Error retrieving BIOS Table Address!", 71 return NULL); 72 73 return (const struct atom_voltage_objects_info_v4_1 *)table_address; 74 } 75 76 /** 77 * Returns TRUE if the given voltage type is controlled by GPIO pins. 78 * voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC, SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ. 79 * voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE 80 */ 81 bool pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(struct pp_hwmgr *hwmgr, 82 uint8_t voltage_type, uint8_t voltage_mode) 83 { 84 const struct atom_voltage_objects_info_v4_1 *voltage_info = 85 (const struct atom_voltage_objects_info_v4_1 *) 86 pp_atomfwctrl_get_voltage_info_table(hwmgr); 87 bool ret; 88 89 /* If we cannot find the table do NOT try to control this voltage. */ 90 PP_ASSERT_WITH_CODE(voltage_info, 91 "Could not find Voltage Table in BIOS.", 92 return false); 93 94 ret = (pp_atomfwctrl_lookup_voltage_type_v4(voltage_info, 95 voltage_type, voltage_mode)) ? true : false; 96 97 return ret; 98 } 99 100 int pp_atomfwctrl_get_voltage_table_v4(struct pp_hwmgr *hwmgr, 101 uint8_t voltage_type, uint8_t voltage_mode, 102 struct pp_atomfwctrl_voltage_table *voltage_table) 103 { 104 const struct atom_voltage_objects_info_v4_1 *voltage_info = 105 (const struct atom_voltage_objects_info_v4_1 *) 106 pp_atomfwctrl_get_voltage_info_table(hwmgr); 107 const union atom_voltage_object_v4 *voltage_object; 108 unsigned int i; 109 int result = 0; 110 111 PP_ASSERT_WITH_CODE(voltage_info, 112 "Could not find Voltage Table in BIOS.", 113 return -1); 114 115 voltage_object = pp_atomfwctrl_lookup_voltage_type_v4(voltage_info, 116 voltage_type, voltage_mode); 117 118 if (!voltage_object) 119 return -1; 120 121 voltage_table->count = 0; 122 if (voltage_mode == VOLTAGE_OBJ_GPIO_LUT) { 123 PP_ASSERT_WITH_CODE( 124 (voltage_object->gpio_voltage_obj.gpio_entry_num <= 125 PP_ATOMFWCTRL_MAX_VOLTAGE_ENTRIES), 126 "Too many voltage entries!", 127 result = -1); 128 129 if (!result) { 130 for (i = 0; i < voltage_object->gpio_voltage_obj. 131 gpio_entry_num; i++) { 132 voltage_table->entries[i].value = 133 le16_to_cpu(voltage_object->gpio_voltage_obj. 134 voltage_gpio_lut[i].voltage_level_mv); 135 voltage_table->entries[i].smio_low = 136 le32_to_cpu(voltage_object->gpio_voltage_obj. 137 voltage_gpio_lut[i].voltage_gpio_reg_val); 138 } 139 voltage_table->count = 140 voltage_object->gpio_voltage_obj.gpio_entry_num; 141 voltage_table->mask_low = 142 le32_to_cpu( 143 voltage_object->gpio_voltage_obj.gpio_mask_val); 144 voltage_table->phase_delay = 145 voltage_object->gpio_voltage_obj.phase_delay_us; 146 } 147 } else if (voltage_mode == VOLTAGE_OBJ_SVID2) { 148 voltage_table->psi1_enable = 149 (voltage_object->svid2_voltage_obj.loadline_psi1 & 0x20) >> 5; 150 voltage_table->psi0_enable = 151 voltage_object->svid2_voltage_obj.psi0_enable & 0x1; 152 voltage_table->max_vid_step = 153 voltage_object->svid2_voltage_obj.maxvstep; 154 voltage_table->telemetry_offset = 155 voltage_object->svid2_voltage_obj.telemetry_offset; 156 voltage_table->telemetry_slope = 157 voltage_object->svid2_voltage_obj.telemetry_gain; 158 } else 159 PP_ASSERT_WITH_CODE(false, 160 "Unsupported Voltage Object Mode!", 161 result = -1); 162 163 return result; 164 } 165 166 167 static const struct atom_gpio_pin_lut_v2_1 *pp_atomfwctrl_get_gpio_lookup_table( 168 struct pp_hwmgr *hwmgr) 169 { 170 const void *table_address; 171 uint16_t idx; 172 173 idx = GetIndexIntoMasterDataTable(gpio_pin_lut); 174 table_address = smu_atom_get_data_table(hwmgr->adev, 175 idx, NULL, NULL, NULL); 176 PP_ASSERT_WITH_CODE(table_address, 177 "Error retrieving BIOS Table Address!", 178 return NULL); 179 180 return (const struct atom_gpio_pin_lut_v2_1 *)table_address; 181 } 182 183 static bool pp_atomfwctrl_lookup_gpio_pin( 184 const struct atom_gpio_pin_lut_v2_1 *gpio_lookup_table, 185 const uint32_t pin_id, 186 struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment) 187 { 188 unsigned int size = le16_to_cpu( 189 gpio_lookup_table->table_header.structuresize); 190 unsigned int offset = 191 offsetof(struct atom_gpio_pin_lut_v2_1, gpio_pin[0]); 192 unsigned long start = (unsigned long)gpio_lookup_table; 193 194 while (offset < size) { 195 const struct atom_gpio_pin_assignment *pin_assignment = 196 (const struct atom_gpio_pin_assignment *)(start + offset); 197 198 if (pin_id == pin_assignment->gpio_id) { 199 gpio_pin_assignment->uc_gpio_pin_bit_shift = 200 pin_assignment->gpio_bitshift; 201 gpio_pin_assignment->us_gpio_pin_aindex = 202 le16_to_cpu(pin_assignment->data_a_reg_index); 203 return true; 204 } 205 offset += offsetof(struct atom_gpio_pin_assignment, gpio_id) + 1; 206 } 207 return false; 208 } 209 210 /** 211 * Returns TRUE if the given pin id find in lookup table. 212 */ 213 bool pp_atomfwctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, 214 const uint32_t pin_id, 215 struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment) 216 { 217 bool ret = false; 218 const struct atom_gpio_pin_lut_v2_1 *gpio_lookup_table = 219 pp_atomfwctrl_get_gpio_lookup_table(hwmgr); 220 221 /* If we cannot find the table do NOT try to control this voltage. */ 222 PP_ASSERT_WITH_CODE(gpio_lookup_table, 223 "Could not find GPIO lookup Table in BIOS.", 224 return false); 225 226 ret = pp_atomfwctrl_lookup_gpio_pin(gpio_lookup_table, 227 pin_id, gpio_pin_assignment); 228 229 return ret; 230 } 231 232 /** 233 * Enter to SelfRefresh mode. 234 * @param hwmgr 235 */ 236 int pp_atomfwctrl_enter_self_refresh(struct pp_hwmgr *hwmgr) 237 { 238 /* 0 - no action 239 * 1 - leave power to video memory always on 240 */ 241 return 0; 242 } 243 244 /** pp_atomfwctrl_get_gpu_pll_dividers_vega10(). 245 * 246 * @param hwmgr input parameter: pointer to HwMgr 247 * @param clock_type input parameter: Clock type: 1 - GFXCLK, 2 - UCLK, 0 - All other clocks 248 * @param clock_value input parameter: Clock 249 * @param dividers output parameter:Clock dividers 250 */ 251 int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr, 252 uint32_t clock_type, uint32_t clock_value, 253 struct pp_atomfwctrl_clock_dividers_soc15 *dividers) 254 { 255 struct amdgpu_device *adev = hwmgr->adev; 256 struct compute_gpu_clock_input_parameter_v1_8 pll_parameters; 257 struct compute_gpu_clock_output_parameter_v1_8 *pll_output; 258 uint32_t idx; 259 260 pll_parameters.gpuclock_10khz = (uint32_t)clock_value; 261 pll_parameters.gpu_clock_type = clock_type; 262 263 idx = GetIndexIntoMasterCmdTable(computegpuclockparam); 264 265 if (amdgpu_atom_execute_table( 266 adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters)) 267 return -EINVAL; 268 269 pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *) 270 &pll_parameters; 271 dividers->ulClock = le32_to_cpu(pll_output->gpuclock_10khz); 272 dividers->ulDid = le32_to_cpu(pll_output->dfs_did); 273 dividers->ulPll_fb_mult = le32_to_cpu(pll_output->pll_fb_mult); 274 dividers->ulPll_ss_fbsmult = le32_to_cpu(pll_output->pll_ss_fbsmult); 275 dividers->usPll_ss_slew_frac = le16_to_cpu(pll_output->pll_ss_slew_frac); 276 dividers->ucPll_ss_enable = pll_output->pll_ss_enable; 277 278 return 0; 279 } 280 281 int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr, 282 struct pp_atomfwctrl_avfs_parameters *param) 283 { 284 uint16_t idx; 285 uint8_t format_revision, content_revision; 286 287 struct atom_asic_profiling_info_v4_1 *profile; 288 struct atom_asic_profiling_info_v4_2 *profile_v4_2; 289 290 idx = GetIndexIntoMasterDataTable(asic_profiling_info); 291 profile = (struct atom_asic_profiling_info_v4_1 *) 292 smu_atom_get_data_table(hwmgr->adev, 293 idx, NULL, NULL, NULL); 294 295 if (!profile) 296 return -1; 297 298 format_revision = ((struct atom_common_table_header *)profile)->format_revision; 299 content_revision = ((struct atom_common_table_header *)profile)->content_revision; 300 301 if (format_revision == 4 && content_revision == 1) { 302 param->ulMaxVddc = le32_to_cpu(profile->maxvddc); 303 param->ulMinVddc = le32_to_cpu(profile->minvddc); 304 param->ulMeanNsigmaAcontant0 = 305 le32_to_cpu(profile->avfs_meannsigma_acontant0); 306 param->ulMeanNsigmaAcontant1 = 307 le32_to_cpu(profile->avfs_meannsigma_acontant1); 308 param->ulMeanNsigmaAcontant2 = 309 le32_to_cpu(profile->avfs_meannsigma_acontant2); 310 param->usMeanNsigmaDcTolSigma = 311 le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma); 312 param->usMeanNsigmaPlatformMean = 313 le16_to_cpu(profile->avfs_meannsigma_platform_mean); 314 param->usMeanNsigmaPlatformSigma = 315 le16_to_cpu(profile->avfs_meannsigma_platform_sigma); 316 param->ulGbVdroopTableCksoffA0 = 317 le32_to_cpu(profile->gb_vdroop_table_cksoff_a0); 318 param->ulGbVdroopTableCksoffA1 = 319 le32_to_cpu(profile->gb_vdroop_table_cksoff_a1); 320 param->ulGbVdroopTableCksoffA2 = 321 le32_to_cpu(profile->gb_vdroop_table_cksoff_a2); 322 param->ulGbVdroopTableCksonA0 = 323 le32_to_cpu(profile->gb_vdroop_table_ckson_a0); 324 param->ulGbVdroopTableCksonA1 = 325 le32_to_cpu(profile->gb_vdroop_table_ckson_a1); 326 param->ulGbVdroopTableCksonA2 = 327 le32_to_cpu(profile->gb_vdroop_table_ckson_a2); 328 param->ulGbFuseTableCksoffM1 = 329 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1); 330 param->ulGbFuseTableCksoffM2 = 331 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2); 332 param->ulGbFuseTableCksoffB = 333 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b); 334 param->ulGbFuseTableCksonM1 = 335 le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1); 336 param->ulGbFuseTableCksonM2 = 337 le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2); 338 param->ulGbFuseTableCksonB = 339 le32_to_cpu(profile->avfsgb_fuse_table_ckson_b); 340 341 param->ucEnableGbVdroopTableCkson = 342 profile->enable_gb_vdroop_table_ckson; 343 param->ucEnableGbFuseTableCkson = 344 profile->enable_gb_fuse_table_ckson; 345 param->usPsmAgeComfactor = 346 le16_to_cpu(profile->psm_age_comfactor); 347 348 param->ulDispclk2GfxclkM1 = 349 le32_to_cpu(profile->dispclk2gfxclk_a); 350 param->ulDispclk2GfxclkM2 = 351 le32_to_cpu(profile->dispclk2gfxclk_b); 352 param->ulDispclk2GfxclkB = 353 le32_to_cpu(profile->dispclk2gfxclk_c); 354 param->ulDcefclk2GfxclkM1 = 355 le32_to_cpu(profile->dcefclk2gfxclk_a); 356 param->ulDcefclk2GfxclkM2 = 357 le32_to_cpu(profile->dcefclk2gfxclk_b); 358 param->ulDcefclk2GfxclkB = 359 le32_to_cpu(profile->dcefclk2gfxclk_c); 360 param->ulPixelclk2GfxclkM1 = 361 le32_to_cpu(profile->pixclk2gfxclk_a); 362 param->ulPixelclk2GfxclkM2 = 363 le32_to_cpu(profile->pixclk2gfxclk_b); 364 param->ulPixelclk2GfxclkB = 365 le32_to_cpu(profile->pixclk2gfxclk_c); 366 param->ulPhyclk2GfxclkM1 = 367 le32_to_cpu(profile->phyclk2gfxclk_a); 368 param->ulPhyclk2GfxclkM2 = 369 le32_to_cpu(profile->phyclk2gfxclk_b); 370 param->ulPhyclk2GfxclkB = 371 le32_to_cpu(profile->phyclk2gfxclk_c); 372 param->ulAcgGbVdroopTableA0 = 0; 373 param->ulAcgGbVdroopTableA1 = 0; 374 param->ulAcgGbVdroopTableA2 = 0; 375 param->ulAcgGbFuseTableM1 = 0; 376 param->ulAcgGbFuseTableM2 = 0; 377 param->ulAcgGbFuseTableB = 0; 378 param->ucAcgEnableGbVdroopTable = 0; 379 param->ucAcgEnableGbFuseTable = 0; 380 } else if (format_revision == 4 && content_revision == 2) { 381 profile_v4_2 = (struct atom_asic_profiling_info_v4_2 *)profile; 382 param->ulMaxVddc = le32_to_cpu(profile_v4_2->maxvddc); 383 param->ulMinVddc = le32_to_cpu(profile_v4_2->minvddc); 384 param->ulMeanNsigmaAcontant0 = 385 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant0); 386 param->ulMeanNsigmaAcontant1 = 387 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant1); 388 param->ulMeanNsigmaAcontant2 = 389 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant2); 390 param->usMeanNsigmaDcTolSigma = 391 le16_to_cpu(profile_v4_2->avfs_meannsigma_dc_tol_sigma); 392 param->usMeanNsigmaPlatformMean = 393 le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_mean); 394 param->usMeanNsigmaPlatformSigma = 395 le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_sigma); 396 param->ulGbVdroopTableCksoffA0 = 397 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a0); 398 param->ulGbVdroopTableCksoffA1 = 399 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a1); 400 param->ulGbVdroopTableCksoffA2 = 401 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a2); 402 param->ulGbVdroopTableCksonA0 = 403 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a0); 404 param->ulGbVdroopTableCksonA1 = 405 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a1); 406 param->ulGbVdroopTableCksonA2 = 407 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a2); 408 param->ulGbFuseTableCksoffM1 = 409 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m1); 410 param->ulGbFuseTableCksoffM2 = 411 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m2); 412 param->ulGbFuseTableCksoffB = 413 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_b); 414 param->ulGbFuseTableCksonM1 = 415 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m1); 416 param->ulGbFuseTableCksonM2 = 417 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m2); 418 param->ulGbFuseTableCksonB = 419 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_b); 420 421 param->ucEnableGbVdroopTableCkson = 422 profile_v4_2->enable_gb_vdroop_table_ckson; 423 param->ucEnableGbFuseTableCkson = 424 profile_v4_2->enable_gb_fuse_table_ckson; 425 param->usPsmAgeComfactor = 426 le16_to_cpu(profile_v4_2->psm_age_comfactor); 427 428 param->ulDispclk2GfxclkM1 = 429 le32_to_cpu(profile_v4_2->dispclk2gfxclk_a); 430 param->ulDispclk2GfxclkM2 = 431 le32_to_cpu(profile_v4_2->dispclk2gfxclk_b); 432 param->ulDispclk2GfxclkB = 433 le32_to_cpu(profile_v4_2->dispclk2gfxclk_c); 434 param->ulDcefclk2GfxclkM1 = 435 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_a); 436 param->ulDcefclk2GfxclkM2 = 437 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_b); 438 param->ulDcefclk2GfxclkB = 439 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_c); 440 param->ulPixelclk2GfxclkM1 = 441 le32_to_cpu(profile_v4_2->pixclk2gfxclk_a); 442 param->ulPixelclk2GfxclkM2 = 443 le32_to_cpu(profile_v4_2->pixclk2gfxclk_b); 444 param->ulPixelclk2GfxclkB = 445 le32_to_cpu(profile_v4_2->pixclk2gfxclk_c); 446 param->ulPhyclk2GfxclkM1 = 447 le32_to_cpu(profile->phyclk2gfxclk_a); 448 param->ulPhyclk2GfxclkM2 = 449 le32_to_cpu(profile_v4_2->phyclk2gfxclk_b); 450 param->ulPhyclk2GfxclkB = 451 le32_to_cpu(profile_v4_2->phyclk2gfxclk_c); 452 param->ulAcgGbVdroopTableA0 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a0); 453 param->ulAcgGbVdroopTableA1 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a1); 454 param->ulAcgGbVdroopTableA2 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a2); 455 param->ulAcgGbFuseTableM1 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m1); 456 param->ulAcgGbFuseTableM2 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m2); 457 param->ulAcgGbFuseTableB = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_b); 458 param->ucAcgEnableGbVdroopTable = le32_to_cpu(profile_v4_2->enable_acg_gb_vdroop_table); 459 param->ucAcgEnableGbFuseTable = le32_to_cpu(profile_v4_2->enable_acg_gb_fuse_table); 460 } else { 461 pr_info("Invalid VBIOS AVFS ProfilingInfo Revision!\n"); 462 return -EINVAL; 463 } 464 465 return 0; 466 } 467 468 int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr, 469 struct pp_atomfwctrl_gpio_parameters *param) 470 { 471 struct atom_smu_info_v3_1 *info; 472 uint16_t idx; 473 474 idx = GetIndexIntoMasterDataTable(smu_info); 475 info = (struct atom_smu_info_v3_1 *) 476 smu_atom_get_data_table(hwmgr->adev, 477 idx, NULL, NULL, NULL); 478 479 if (!info) { 480 pr_info("Error retrieving BIOS smu_info Table Address!"); 481 return -1; 482 } 483 484 param->ucAcDcGpio = info->ac_dc_gpio_bit; 485 param->ucAcDcPolarity = info->ac_dc_polarity; 486 param->ucVR0HotGpio = info->vr0hot_gpio_bit; 487 param->ucVR0HotPolarity = info->vr0hot_polarity; 488 param->ucVR1HotGpio = info->vr1hot_gpio_bit; 489 param->ucVR1HotPolarity = info->vr1hot_polarity; 490 param->ucFwCtfGpio = info->fw_ctf_gpio_bit; 491 param->ucFwCtfPolarity = info->fw_ctf_polarity; 492 493 return 0; 494 } 495 496 int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, 497 uint8_t clk_id, uint8_t syspll_id, 498 uint32_t *frequency) 499 { 500 struct amdgpu_device *adev = hwmgr->adev; 501 struct atom_get_smu_clock_info_parameters_v3_1 parameters; 502 struct atom_get_smu_clock_info_output_parameters_v3_1 *output; 503 uint32_t ix; 504 505 parameters.clk_id = clk_id; 506 parameters.syspll_id = syspll_id; 507 parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ; 508 parameters.dfsdid = 0; 509 510 ix = GetIndexIntoMasterCmdTable(getsmuclockinfo); 511 512 if (amdgpu_atom_execute_table( 513 adev->mode_info.atom_context, ix, (uint32_t *)¶meters)) 514 return -EINVAL; 515 516 output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)¶meters; 517 *frequency = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000; 518 519 return 0; 520 } 521 522 static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr, 523 struct pp_atomfwctrl_bios_boot_up_values *boot_values, 524 struct atom_firmware_info_v3_2 *fw_info) 525 { 526 uint32_t frequency = 0; 527 528 boot_values->ulRevision = fw_info->firmware_revision; 529 boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz; 530 boot_values->ulUClk = fw_info->bootup_mclk_in10khz; 531 boot_values->usVddc = fw_info->bootup_vddc_mv; 532 boot_values->usVddci = fw_info->bootup_vddci_mv; 533 boot_values->usMvddc = fw_info->bootup_mvddc_mv; 534 boot_values->usVddGfx = fw_info->bootup_vddgfx_mv; 535 boot_values->ucCoolingID = fw_info->coolingsolution_id; 536 boot_values->ulSocClk = 0; 537 boot_values->ulDCEFClk = 0; 538 539 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 540 boot_values->ulSocClk = frequency; 541 542 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 543 boot_values->ulDCEFClk = frequency; 544 545 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, SMU11_SYSPLL0_ID, &frequency)) 546 boot_values->ulEClk = frequency; 547 548 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 549 boot_values->ulVClk = frequency; 550 551 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 552 boot_values->ulDClk = frequency; 553 554 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL1_0_FCLK_ID, SMU11_SYSPLL1_2_ID, &frequency)) 555 boot_values->ulFClk = frequency; 556 } 557 558 static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr, 559 struct pp_atomfwctrl_bios_boot_up_values *boot_values, 560 struct atom_firmware_info_v3_1 *fw_info) 561 { 562 uint32_t frequency = 0; 563 564 boot_values->ulRevision = fw_info->firmware_revision; 565 boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz; 566 boot_values->ulUClk = fw_info->bootup_mclk_in10khz; 567 boot_values->usVddc = fw_info->bootup_vddc_mv; 568 boot_values->usVddci = fw_info->bootup_vddci_mv; 569 boot_values->usMvddc = fw_info->bootup_mvddc_mv; 570 boot_values->usVddGfx = fw_info->bootup_vddgfx_mv; 571 boot_values->ucCoolingID = fw_info->coolingsolution_id; 572 boot_values->ulSocClk = 0; 573 boot_values->ulDCEFClk = 0; 574 575 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, 0, &frequency)) 576 boot_values->ulSocClk = frequency; 577 578 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, 0, &frequency)) 579 boot_values->ulDCEFClk = frequency; 580 581 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, 0, &frequency)) 582 boot_values->ulEClk = frequency; 583 584 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, 0, &frequency)) 585 boot_values->ulVClk = frequency; 586 587 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, 0, &frequency)) 588 boot_values->ulDClk = frequency; 589 } 590 591 int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr, 592 struct pp_atomfwctrl_bios_boot_up_values *boot_values) 593 { 594 struct atom_firmware_info_v3_2 *fwinfo_3_2; 595 struct atom_firmware_info_v3_1 *fwinfo_3_1; 596 struct atom_common_table_header *info = NULL; 597 uint16_t ix; 598 599 ix = GetIndexIntoMasterDataTable(firmwareinfo); 600 info = (struct atom_common_table_header *) 601 smu_atom_get_data_table(hwmgr->adev, 602 ix, NULL, NULL, NULL); 603 604 if (!info) { 605 pr_info("Error retrieving BIOS firmwareinfo!"); 606 return -EINVAL; 607 } 608 609 if ((info->format_revision == 3) && (info->content_revision == 2)) { 610 fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info; 611 pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr, 612 boot_values, fwinfo_3_2); 613 } else if ((info->format_revision == 3) && (info->content_revision == 1)) { 614 fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info; 615 pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr, 616 boot_values, fwinfo_3_1); 617 } else { 618 pr_info("Fw info table revision does not match!"); 619 return -EINVAL; 620 } 621 622 return 0; 623 } 624 625 int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr, 626 struct pp_atomfwctrl_smc_dpm_parameters *param) 627 { 628 struct atom_smc_dpm_info_v4_1 *info; 629 uint16_t ix; 630 631 ix = GetIndexIntoMasterDataTable(smc_dpm_info); 632 info = (struct atom_smc_dpm_info_v4_1 *) 633 smu_atom_get_data_table(hwmgr->adev, 634 ix, NULL, NULL, NULL); 635 if (!info) { 636 pr_info("Error retrieving BIOS Table Address!"); 637 return -EINVAL; 638 } 639 640 param->liquid1_i2c_address = info->liquid1_i2c_address; 641 param->liquid2_i2c_address = info->liquid2_i2c_address; 642 param->vr_i2c_address = info->vr_i2c_address; 643 param->plx_i2c_address = info->plx_i2c_address; 644 645 param->liquid_i2c_linescl = info->liquid_i2c_linescl; 646 param->liquid_i2c_linesda = info->liquid_i2c_linesda; 647 param->vr_i2c_linescl = info->vr_i2c_linescl; 648 param->vr_i2c_linesda = info->vr_i2c_linesda; 649 650 param->plx_i2c_linescl = info->plx_i2c_linescl; 651 param->plx_i2c_linesda = info->plx_i2c_linesda; 652 param->vrsensorpresent = info->vrsensorpresent; 653 param->liquidsensorpresent = info->liquidsensorpresent; 654 655 param->maxvoltagestepgfx = info->maxvoltagestepgfx; 656 param->maxvoltagestepsoc = info->maxvoltagestepsoc; 657 658 param->vddgfxvrmapping = info->vddgfxvrmapping; 659 param->vddsocvrmapping = info->vddsocvrmapping; 660 param->vddmem0vrmapping = info->vddmem0vrmapping; 661 param->vddmem1vrmapping = info->vddmem1vrmapping; 662 663 param->gfxulvphasesheddingmask = info->gfxulvphasesheddingmask; 664 param->soculvphasesheddingmask = info->soculvphasesheddingmask; 665 666 param->gfxmaxcurrent = info->gfxmaxcurrent; 667 param->gfxoffset = info->gfxoffset; 668 param->padding_telemetrygfx = info->padding_telemetrygfx; 669 670 param->socmaxcurrent = info->socmaxcurrent; 671 param->socoffset = info->socoffset; 672 param->padding_telemetrysoc = info->padding_telemetrysoc; 673 674 param->mem0maxcurrent = info->mem0maxcurrent; 675 param->mem0offset = info->mem0offset; 676 param->padding_telemetrymem0 = info->padding_telemetrymem0; 677 678 param->mem1maxcurrent = info->mem1maxcurrent; 679 param->mem1offset = info->mem1offset; 680 param->padding_telemetrymem1 = info->padding_telemetrymem1; 681 682 param->acdcgpio = info->acdcgpio; 683 param->acdcpolarity = info->acdcpolarity; 684 param->vr0hotgpio = info->vr0hotgpio; 685 param->vr0hotpolarity = info->vr0hotpolarity; 686 687 param->vr1hotgpio = info->vr1hotgpio; 688 param->vr1hotpolarity = info->vr1hotpolarity; 689 param->padding1 = info->padding1; 690 param->padding2 = info->padding2; 691 692 param->ledpin0 = info->ledpin0; 693 param->ledpin1 = info->ledpin1; 694 param->ledpin2 = info->ledpin2; 695 696 param->pllgfxclkspreadenabled = info->pllgfxclkspreadenabled; 697 param->pllgfxclkspreadpercent = info->pllgfxclkspreadpercent; 698 param->pllgfxclkspreadfreq = info->pllgfxclkspreadfreq; 699 700 param->uclkspreadenabled = info->uclkspreadenabled; 701 param->uclkspreadpercent = info->uclkspreadpercent; 702 param->uclkspreadfreq = info->uclkspreadfreq; 703 704 param->socclkspreadenabled = info->socclkspreadenabled; 705 param->socclkspreadpercent = info->socclkspreadpercent; 706 param->socclkspreadfreq = info->socclkspreadfreq; 707 708 param->acggfxclkspreadenabled = info->acggfxclkspreadenabled; 709 param->acggfxclkspreadpercent = info->acggfxclkspreadpercent; 710 param->acggfxclkspreadfreq = info->acggfxclkspreadfreq; 711 712 param->Vr2_I2C_address = info->Vr2_I2C_address; 713 714 return 0; 715 } 716