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 /** pp_atomfwctrl_get_gpu_pll_dividers_vega10(). 162 * 163 * @param hwmgr input parameter: pointer to HwMgr 164 * @param clock_type input parameter: Clock type: 1 - GFXCLK, 2 - UCLK, 0 - All other clocks 165 * @param clock_value input parameter: Clock 166 * @param dividers output parameter:Clock dividers 167 */ 168 int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr, 169 uint32_t clock_type, uint32_t clock_value, 170 struct pp_atomfwctrl_clock_dividers_soc15 *dividers) 171 { 172 struct amdgpu_device *adev = hwmgr->adev; 173 struct compute_gpu_clock_input_parameter_v1_8 pll_parameters; 174 struct compute_gpu_clock_output_parameter_v1_8 *pll_output; 175 uint32_t idx; 176 177 pll_parameters.gpuclock_10khz = (uint32_t)clock_value; 178 pll_parameters.gpu_clock_type = clock_type; 179 180 idx = GetIndexIntoMasterCmdTable(computegpuclockparam); 181 182 if (amdgpu_atom_execute_table( 183 adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters, sizeof(pll_parameters))) 184 return -EINVAL; 185 186 pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *) 187 &pll_parameters; 188 dividers->ulClock = le32_to_cpu(pll_output->gpuclock_10khz); 189 dividers->ulDid = le32_to_cpu(pll_output->dfs_did); 190 dividers->ulPll_fb_mult = le32_to_cpu(pll_output->pll_fb_mult); 191 dividers->ulPll_ss_fbsmult = le32_to_cpu(pll_output->pll_ss_fbsmult); 192 dividers->usPll_ss_slew_frac = le16_to_cpu(pll_output->pll_ss_slew_frac); 193 dividers->ucPll_ss_enable = pll_output->pll_ss_enable; 194 195 return 0; 196 } 197 198 int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr, 199 struct pp_atomfwctrl_avfs_parameters *param) 200 { 201 uint16_t idx; 202 uint8_t format_revision, content_revision; 203 204 struct atom_asic_profiling_info_v4_1 *profile; 205 struct atom_asic_profiling_info_v4_2 *profile_v4_2; 206 207 idx = GetIndexIntoMasterDataTable(asic_profiling_info); 208 profile = (struct atom_asic_profiling_info_v4_1 *) 209 smu_atom_get_data_table(hwmgr->adev, 210 idx, NULL, NULL, NULL); 211 212 if (!profile) 213 return -1; 214 215 format_revision = ((struct atom_common_table_header *)profile)->format_revision; 216 content_revision = ((struct atom_common_table_header *)profile)->content_revision; 217 218 if (format_revision == 4 && content_revision == 1) { 219 param->ulMaxVddc = le32_to_cpu(profile->maxvddc); 220 param->ulMinVddc = le32_to_cpu(profile->minvddc); 221 param->ulMeanNsigmaAcontant0 = 222 le32_to_cpu(profile->avfs_meannsigma_acontant0); 223 param->ulMeanNsigmaAcontant1 = 224 le32_to_cpu(profile->avfs_meannsigma_acontant1); 225 param->ulMeanNsigmaAcontant2 = 226 le32_to_cpu(profile->avfs_meannsigma_acontant2); 227 param->usMeanNsigmaDcTolSigma = 228 le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma); 229 param->usMeanNsigmaPlatformMean = 230 le16_to_cpu(profile->avfs_meannsigma_platform_mean); 231 param->usMeanNsigmaPlatformSigma = 232 le16_to_cpu(profile->avfs_meannsigma_platform_sigma); 233 param->ulGbVdroopTableCksoffA0 = 234 le32_to_cpu(profile->gb_vdroop_table_cksoff_a0); 235 param->ulGbVdroopTableCksoffA1 = 236 le32_to_cpu(profile->gb_vdroop_table_cksoff_a1); 237 param->ulGbVdroopTableCksoffA2 = 238 le32_to_cpu(profile->gb_vdroop_table_cksoff_a2); 239 param->ulGbVdroopTableCksonA0 = 240 le32_to_cpu(profile->gb_vdroop_table_ckson_a0); 241 param->ulGbVdroopTableCksonA1 = 242 le32_to_cpu(profile->gb_vdroop_table_ckson_a1); 243 param->ulGbVdroopTableCksonA2 = 244 le32_to_cpu(profile->gb_vdroop_table_ckson_a2); 245 param->ulGbFuseTableCksoffM1 = 246 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1); 247 param->ulGbFuseTableCksoffM2 = 248 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2); 249 param->ulGbFuseTableCksoffB = 250 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b); 251 param->ulGbFuseTableCksonM1 = 252 le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1); 253 param->ulGbFuseTableCksonM2 = 254 le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2); 255 param->ulGbFuseTableCksonB = 256 le32_to_cpu(profile->avfsgb_fuse_table_ckson_b); 257 258 param->ucEnableGbVdroopTableCkson = 259 profile->enable_gb_vdroop_table_ckson; 260 param->ucEnableGbFuseTableCkson = 261 profile->enable_gb_fuse_table_ckson; 262 param->usPsmAgeComfactor = 263 le16_to_cpu(profile->psm_age_comfactor); 264 265 param->ulDispclk2GfxclkM1 = 266 le32_to_cpu(profile->dispclk2gfxclk_a); 267 param->ulDispclk2GfxclkM2 = 268 le32_to_cpu(profile->dispclk2gfxclk_b); 269 param->ulDispclk2GfxclkB = 270 le32_to_cpu(profile->dispclk2gfxclk_c); 271 param->ulDcefclk2GfxclkM1 = 272 le32_to_cpu(profile->dcefclk2gfxclk_a); 273 param->ulDcefclk2GfxclkM2 = 274 le32_to_cpu(profile->dcefclk2gfxclk_b); 275 param->ulDcefclk2GfxclkB = 276 le32_to_cpu(profile->dcefclk2gfxclk_c); 277 param->ulPixelclk2GfxclkM1 = 278 le32_to_cpu(profile->pixclk2gfxclk_a); 279 param->ulPixelclk2GfxclkM2 = 280 le32_to_cpu(profile->pixclk2gfxclk_b); 281 param->ulPixelclk2GfxclkB = 282 le32_to_cpu(profile->pixclk2gfxclk_c); 283 param->ulPhyclk2GfxclkM1 = 284 le32_to_cpu(profile->phyclk2gfxclk_a); 285 param->ulPhyclk2GfxclkM2 = 286 le32_to_cpu(profile->phyclk2gfxclk_b); 287 param->ulPhyclk2GfxclkB = 288 le32_to_cpu(profile->phyclk2gfxclk_c); 289 param->ulAcgGbVdroopTableA0 = 0; 290 param->ulAcgGbVdroopTableA1 = 0; 291 param->ulAcgGbVdroopTableA2 = 0; 292 param->ulAcgGbFuseTableM1 = 0; 293 param->ulAcgGbFuseTableM2 = 0; 294 param->ulAcgGbFuseTableB = 0; 295 param->ucAcgEnableGbVdroopTable = 0; 296 param->ucAcgEnableGbFuseTable = 0; 297 } else if (format_revision == 4 && content_revision == 2) { 298 profile_v4_2 = (struct atom_asic_profiling_info_v4_2 *)profile; 299 param->ulMaxVddc = le32_to_cpu(profile_v4_2->maxvddc); 300 param->ulMinVddc = le32_to_cpu(profile_v4_2->minvddc); 301 param->ulMeanNsigmaAcontant0 = 302 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant0); 303 param->ulMeanNsigmaAcontant1 = 304 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant1); 305 param->ulMeanNsigmaAcontant2 = 306 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant2); 307 param->usMeanNsigmaDcTolSigma = 308 le16_to_cpu(profile_v4_2->avfs_meannsigma_dc_tol_sigma); 309 param->usMeanNsigmaPlatformMean = 310 le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_mean); 311 param->usMeanNsigmaPlatformSigma = 312 le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_sigma); 313 param->ulGbVdroopTableCksoffA0 = 314 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a0); 315 param->ulGbVdroopTableCksoffA1 = 316 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a1); 317 param->ulGbVdroopTableCksoffA2 = 318 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a2); 319 param->ulGbVdroopTableCksonA0 = 320 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a0); 321 param->ulGbVdroopTableCksonA1 = 322 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a1); 323 param->ulGbVdroopTableCksonA2 = 324 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a2); 325 param->ulGbFuseTableCksoffM1 = 326 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m1); 327 param->ulGbFuseTableCksoffM2 = 328 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m2); 329 param->ulGbFuseTableCksoffB = 330 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_b); 331 param->ulGbFuseTableCksonM1 = 332 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m1); 333 param->ulGbFuseTableCksonM2 = 334 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m2); 335 param->ulGbFuseTableCksonB = 336 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_b); 337 338 param->ucEnableGbVdroopTableCkson = 339 profile_v4_2->enable_gb_vdroop_table_ckson; 340 param->ucEnableGbFuseTableCkson = 341 profile_v4_2->enable_gb_fuse_table_ckson; 342 param->usPsmAgeComfactor = 343 le16_to_cpu(profile_v4_2->psm_age_comfactor); 344 345 param->ulDispclk2GfxclkM1 = 346 le32_to_cpu(profile_v4_2->dispclk2gfxclk_a); 347 param->ulDispclk2GfxclkM2 = 348 le32_to_cpu(profile_v4_2->dispclk2gfxclk_b); 349 param->ulDispclk2GfxclkB = 350 le32_to_cpu(profile_v4_2->dispclk2gfxclk_c); 351 param->ulDcefclk2GfxclkM1 = 352 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_a); 353 param->ulDcefclk2GfxclkM2 = 354 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_b); 355 param->ulDcefclk2GfxclkB = 356 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_c); 357 param->ulPixelclk2GfxclkM1 = 358 le32_to_cpu(profile_v4_2->pixclk2gfxclk_a); 359 param->ulPixelclk2GfxclkM2 = 360 le32_to_cpu(profile_v4_2->pixclk2gfxclk_b); 361 param->ulPixelclk2GfxclkB = 362 le32_to_cpu(profile_v4_2->pixclk2gfxclk_c); 363 param->ulPhyclk2GfxclkM1 = 364 le32_to_cpu(profile->phyclk2gfxclk_a); 365 param->ulPhyclk2GfxclkM2 = 366 le32_to_cpu(profile_v4_2->phyclk2gfxclk_b); 367 param->ulPhyclk2GfxclkB = 368 le32_to_cpu(profile_v4_2->phyclk2gfxclk_c); 369 param->ulAcgGbVdroopTableA0 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a0); 370 param->ulAcgGbVdroopTableA1 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a1); 371 param->ulAcgGbVdroopTableA2 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a2); 372 param->ulAcgGbFuseTableM1 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m1); 373 param->ulAcgGbFuseTableM2 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m2); 374 param->ulAcgGbFuseTableB = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_b); 375 param->ucAcgEnableGbVdroopTable = le32_to_cpu(profile_v4_2->enable_acg_gb_vdroop_table); 376 param->ucAcgEnableGbFuseTable = le32_to_cpu(profile_v4_2->enable_acg_gb_fuse_table); 377 } else { 378 pr_info("Invalid VBIOS AVFS ProfilingInfo Revision!\n"); 379 return -EINVAL; 380 } 381 382 return 0; 383 } 384 385 int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr, 386 struct pp_atomfwctrl_gpio_parameters *param) 387 { 388 struct atom_smu_info_v3_1 *info; 389 uint16_t idx; 390 391 idx = GetIndexIntoMasterDataTable(smu_info); 392 info = (struct atom_smu_info_v3_1 *) 393 smu_atom_get_data_table(hwmgr->adev, 394 idx, NULL, NULL, NULL); 395 396 if (!info) { 397 pr_info("Error retrieving BIOS smu_info Table Address!"); 398 return -1; 399 } 400 401 param->ucAcDcGpio = info->ac_dc_gpio_bit; 402 param->ucAcDcPolarity = info->ac_dc_polarity; 403 param->ucVR0HotGpio = info->vr0hot_gpio_bit; 404 param->ucVR0HotPolarity = info->vr0hot_polarity; 405 param->ucVR1HotGpio = info->vr1hot_gpio_bit; 406 param->ucVR1HotPolarity = info->vr1hot_polarity; 407 param->ucFwCtfGpio = info->fw_ctf_gpio_bit; 408 param->ucFwCtfPolarity = info->fw_ctf_polarity; 409 410 return 0; 411 } 412 413 int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, 414 uint8_t clk_id, uint8_t syspll_id, 415 uint32_t *frequency) 416 { 417 struct amdgpu_device *adev = hwmgr->adev; 418 struct atom_get_smu_clock_info_parameters_v3_1 parameters; 419 struct atom_get_smu_clock_info_output_parameters_v3_1 *output; 420 uint32_t ix; 421 422 parameters.clk_id = clk_id; 423 parameters.syspll_id = syspll_id; 424 parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ; 425 parameters.dfsdid = 0; 426 427 ix = GetIndexIntoMasterCmdTable(getsmuclockinfo); 428 429 if (amdgpu_atom_execute_table( 430 adev->mode_info.atom_context, ix, (uint32_t *)¶meters, sizeof(parameters))) 431 return -EINVAL; 432 433 output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)¶meters; 434 *frequency = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000; 435 436 return 0; 437 } 438 439 static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr, 440 struct pp_atomfwctrl_bios_boot_up_values *boot_values, 441 struct atom_firmware_info_v3_2 *fw_info) 442 { 443 uint32_t frequency = 0; 444 445 boot_values->ulRevision = fw_info->firmware_revision; 446 boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz; 447 boot_values->ulUClk = fw_info->bootup_mclk_in10khz; 448 boot_values->usVddc = fw_info->bootup_vddc_mv; 449 boot_values->usVddci = fw_info->bootup_vddci_mv; 450 boot_values->usMvddc = fw_info->bootup_mvddc_mv; 451 boot_values->usVddGfx = fw_info->bootup_vddgfx_mv; 452 boot_values->ucCoolingID = fw_info->coolingsolution_id; 453 boot_values->ulSocClk = 0; 454 boot_values->ulDCEFClk = 0; 455 456 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 457 boot_values->ulSocClk = frequency; 458 459 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 460 boot_values->ulDCEFClk = frequency; 461 462 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, SMU11_SYSPLL0_ID, &frequency)) 463 boot_values->ulEClk = frequency; 464 465 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 466 boot_values->ulVClk = frequency; 467 468 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, SMU11_SYSPLL0_ID, &frequency)) 469 boot_values->ulDClk = frequency; 470 471 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL1_0_FCLK_ID, SMU11_SYSPLL1_2_ID, &frequency)) 472 boot_values->ulFClk = frequency; 473 } 474 475 static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr, 476 struct pp_atomfwctrl_bios_boot_up_values *boot_values, 477 struct atom_firmware_info_v3_1 *fw_info) 478 { 479 uint32_t frequency = 0; 480 481 boot_values->ulRevision = fw_info->firmware_revision; 482 boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz; 483 boot_values->ulUClk = fw_info->bootup_mclk_in10khz; 484 boot_values->usVddc = fw_info->bootup_vddc_mv; 485 boot_values->usVddci = fw_info->bootup_vddci_mv; 486 boot_values->usMvddc = fw_info->bootup_mvddc_mv; 487 boot_values->usVddGfx = fw_info->bootup_vddgfx_mv; 488 boot_values->ucCoolingID = fw_info->coolingsolution_id; 489 boot_values->ulSocClk = 0; 490 boot_values->ulDCEFClk = 0; 491 492 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, 0, &frequency)) 493 boot_values->ulSocClk = frequency; 494 495 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, 0, &frequency)) 496 boot_values->ulDCEFClk = frequency; 497 498 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, 0, &frequency)) 499 boot_values->ulEClk = frequency; 500 501 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, 0, &frequency)) 502 boot_values->ulVClk = frequency; 503 504 if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, 0, &frequency)) 505 boot_values->ulDClk = frequency; 506 } 507 508 int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr, 509 struct pp_atomfwctrl_bios_boot_up_values *boot_values) 510 { 511 struct atom_firmware_info_v3_2 *fwinfo_3_2; 512 struct atom_firmware_info_v3_1 *fwinfo_3_1; 513 struct atom_common_table_header *info = NULL; 514 uint16_t ix; 515 516 ix = GetIndexIntoMasterDataTable(firmwareinfo); 517 info = (struct atom_common_table_header *) 518 smu_atom_get_data_table(hwmgr->adev, 519 ix, NULL, NULL, NULL); 520 521 if (!info) { 522 pr_info("Error retrieving BIOS firmwareinfo!"); 523 return -EINVAL; 524 } 525 526 if ((info->format_revision == 3) && (info->content_revision == 2)) { 527 fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info; 528 pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr, 529 boot_values, fwinfo_3_2); 530 } else if ((info->format_revision == 3) && (info->content_revision == 1)) { 531 fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info; 532 pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr, 533 boot_values, fwinfo_3_1); 534 } else { 535 pr_info("Fw info table revision does not match!"); 536 return -EINVAL; 537 } 538 539 return 0; 540 } 541 542 int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr, 543 struct pp_atomfwctrl_smc_dpm_parameters *param) 544 { 545 struct atom_smc_dpm_info_v4_1 *info; 546 uint16_t ix; 547 548 ix = GetIndexIntoMasterDataTable(smc_dpm_info); 549 info = (struct atom_smc_dpm_info_v4_1 *) 550 smu_atom_get_data_table(hwmgr->adev, 551 ix, NULL, NULL, NULL); 552 if (!info) { 553 pr_info("Error retrieving BIOS Table Address!"); 554 return -EINVAL; 555 } 556 557 param->liquid1_i2c_address = info->liquid1_i2c_address; 558 param->liquid2_i2c_address = info->liquid2_i2c_address; 559 param->vr_i2c_address = info->vr_i2c_address; 560 param->plx_i2c_address = info->plx_i2c_address; 561 562 param->liquid_i2c_linescl = info->liquid_i2c_linescl; 563 param->liquid_i2c_linesda = info->liquid_i2c_linesda; 564 param->vr_i2c_linescl = info->vr_i2c_linescl; 565 param->vr_i2c_linesda = info->vr_i2c_linesda; 566 567 param->plx_i2c_linescl = info->plx_i2c_linescl; 568 param->plx_i2c_linesda = info->plx_i2c_linesda; 569 param->vrsensorpresent = info->vrsensorpresent; 570 param->liquidsensorpresent = info->liquidsensorpresent; 571 572 param->maxvoltagestepgfx = info->maxvoltagestepgfx; 573 param->maxvoltagestepsoc = info->maxvoltagestepsoc; 574 575 param->vddgfxvrmapping = info->vddgfxvrmapping; 576 param->vddsocvrmapping = info->vddsocvrmapping; 577 param->vddmem0vrmapping = info->vddmem0vrmapping; 578 param->vddmem1vrmapping = info->vddmem1vrmapping; 579 580 param->gfxulvphasesheddingmask = info->gfxulvphasesheddingmask; 581 param->soculvphasesheddingmask = info->soculvphasesheddingmask; 582 583 param->gfxmaxcurrent = info->gfxmaxcurrent; 584 param->gfxoffset = info->gfxoffset; 585 param->padding_telemetrygfx = info->padding_telemetrygfx; 586 587 param->socmaxcurrent = info->socmaxcurrent; 588 param->socoffset = info->socoffset; 589 param->padding_telemetrysoc = info->padding_telemetrysoc; 590 591 param->mem0maxcurrent = info->mem0maxcurrent; 592 param->mem0offset = info->mem0offset; 593 param->padding_telemetrymem0 = info->padding_telemetrymem0; 594 595 param->mem1maxcurrent = info->mem1maxcurrent; 596 param->mem1offset = info->mem1offset; 597 param->padding_telemetrymem1 = info->padding_telemetrymem1; 598 599 param->acdcgpio = info->acdcgpio; 600 param->acdcpolarity = info->acdcpolarity; 601 param->vr0hotgpio = info->vr0hotgpio; 602 param->vr0hotpolarity = info->vr0hotpolarity; 603 604 param->vr1hotgpio = info->vr1hotgpio; 605 param->vr1hotpolarity = info->vr1hotpolarity; 606 param->padding1 = info->padding1; 607 param->padding2 = info->padding2; 608 609 param->ledpin0 = info->ledpin0; 610 param->ledpin1 = info->ledpin1; 611 param->ledpin2 = info->ledpin2; 612 613 param->pllgfxclkspreadenabled = info->pllgfxclkspreadenabled; 614 param->pllgfxclkspreadpercent = info->pllgfxclkspreadpercent; 615 param->pllgfxclkspreadfreq = info->pllgfxclkspreadfreq; 616 617 param->uclkspreadenabled = info->uclkspreadenabled; 618 param->uclkspreadpercent = info->uclkspreadpercent; 619 param->uclkspreadfreq = info->uclkspreadfreq; 620 621 param->socclkspreadenabled = info->socclkspreadenabled; 622 param->socclkspreadpercent = info->socclkspreadpercent; 623 param->socclkspreadfreq = info->socclkspreadfreq; 624 625 param->acggfxclkspreadenabled = info->acggfxclkspreadenabled; 626 param->acggfxclkspreadpercent = info->acggfxclkspreadpercent; 627 param->acggfxclkspreadfreq = info->acggfxclkspreadfreq; 628 629 param->Vr2_I2C_address = info->Vr2_I2C_address; 630 631 return 0; 632 } 633