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