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