vega10_processpptables.c (49576B)
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#include <linux/module.h> 24#include <linux/pci.h> 25#include <linux/slab.h> 26#include <linux/fb.h> 27 28#include "vega10_processpptables.h" 29#include "ppatomfwctrl.h" 30#include "atomfirmware.h" 31#include "pp_debug.h" 32#include "cgs_common.h" 33#include "vega10_pptable.h" 34 35#define NUM_DSPCLK_LEVELS 8 36#define VEGA10_ENGINECLOCK_HARDMAX 198000 37 38static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable, 39 enum phm_platform_caps cap) 40{ 41 if (enable) 42 phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap); 43 else 44 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap); 45} 46 47static const void *get_powerplay_table(struct pp_hwmgr *hwmgr) 48{ 49 int index = GetIndexIntoMasterDataTable(powerplayinfo); 50 51 u16 size; 52 u8 frev, crev; 53 const void *table_address = hwmgr->soft_pp_table; 54 55 if (!table_address) { 56 table_address = (ATOM_Vega10_POWERPLAYTABLE *) 57 smu_atom_get_data_table(hwmgr->adev, index, 58 &size, &frev, &crev); 59 60 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/ 61 hwmgr->soft_pp_table_size = size; 62 } 63 64 return table_address; 65} 66 67static int check_powerplay_tables( 68 struct pp_hwmgr *hwmgr, 69 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table) 70{ 71 const ATOM_Vega10_State_Array *state_arrays; 72 73 state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)powerplay_table) + 74 le16_to_cpu(powerplay_table->usStateArrayOffset)); 75 76 PP_ASSERT_WITH_CODE((powerplay_table->sHeader.format_revision >= 77 ATOM_Vega10_TABLE_REVISION_VEGA10), 78 "Unsupported PPTable format!", return -1); 79 PP_ASSERT_WITH_CODE(powerplay_table->usStateArrayOffset, 80 "State table is not set!", return -1); 81 PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0, 82 "Invalid PowerPlay Table!", return -1); 83 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0, 84 "Invalid PowerPlay Table!", return -1); 85 86 return 0; 87} 88 89static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps) 90{ 91 set_hw_cap( 92 hwmgr, 93 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_POWERPLAY), 94 PHM_PlatformCaps_PowerPlaySupport); 95 96 set_hw_cap( 97 hwmgr, 98 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_SBIOSPOWERSOURCE), 99 PHM_PlatformCaps_BiosPowerSourceControl); 100 101 set_hw_cap( 102 hwmgr, 103 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_HARDWAREDC), 104 PHM_PlatformCaps_AutomaticDCTransition); 105 106 set_hw_cap( 107 hwmgr, 108 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_BACO), 109 PHM_PlatformCaps_BACO); 110 111 set_hw_cap( 112 hwmgr, 113 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL), 114 PHM_PlatformCaps_CombinePCCWithThermalSignal); 115 116 return 0; 117} 118 119static int init_thermal_controller( 120 struct pp_hwmgr *hwmgr, 121 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table) 122{ 123 const ATOM_Vega10_Thermal_Controller *thermal_controller; 124 const Vega10_PPTable_Generic_SubTable_Header *header; 125 const ATOM_Vega10_Fan_Table *fan_table_v1; 126 const ATOM_Vega10_Fan_Table_V2 *fan_table_v2; 127 const ATOM_Vega10_Fan_Table_V3 *fan_table_v3; 128 129 thermal_controller = (ATOM_Vega10_Thermal_Controller *) 130 (((unsigned long)powerplay_table) + 131 le16_to_cpu(powerplay_table->usThermalControllerOffset)); 132 133 PP_ASSERT_WITH_CODE((powerplay_table->usThermalControllerOffset != 0), 134 "Thermal controller table not set!", return -EINVAL); 135 136 hwmgr->thermal_controller.ucType = thermal_controller->ucType; 137 hwmgr->thermal_controller.ucI2cLine = thermal_controller->ucI2cLine; 138 hwmgr->thermal_controller.ucI2cAddress = thermal_controller->ucI2cAddress; 139 140 hwmgr->thermal_controller.fanInfo.bNoFan = 141 (0 != (thermal_controller->ucFanParameters & 142 ATOM_VEGA10_PP_FANPARAMETERS_NOFAN)); 143 144 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution = 145 thermal_controller->ucFanParameters & 146 ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK; 147 148 hwmgr->thermal_controller.fanInfo.ulMinRPM = 149 thermal_controller->ucFanMinRPM * 100UL; 150 hwmgr->thermal_controller.fanInfo.ulMaxRPM = 151 thermal_controller->ucFanMaxRPM * 100UL; 152 153 hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay 154 = 100000; 155 156 set_hw_cap( 157 hwmgr, 158 ATOM_VEGA10_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType, 159 PHM_PlatformCaps_ThermalController); 160 161 if (!powerplay_table->usFanTableOffset) 162 return 0; 163 164 header = (const Vega10_PPTable_Generic_SubTable_Header *) 165 (((unsigned long)powerplay_table) + 166 le16_to_cpu(powerplay_table->usFanTableOffset)); 167 168 if (header->ucRevId == 10) { 169 fan_table_v1 = (ATOM_Vega10_Fan_Table *)header; 170 171 PP_ASSERT_WITH_CODE((fan_table_v1->ucRevId >= 8), 172 "Invalid Input Fan Table!", return -EINVAL); 173 174 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 175 PHM_PlatformCaps_MicrocodeFanControl); 176 177 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity = 178 le16_to_cpu(fan_table_v1->usFanOutputSensitivity); 179 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM = 180 le16_to_cpu(fan_table_v1->usFanRPMMax); 181 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit = 182 le16_to_cpu(fan_table_v1->usThrottlingRPM); 183 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit = 184 le16_to_cpu(fan_table_v1->usFanAcousticLimit); 185 hwmgr->thermal_controller.advanceFanControlParameters.usTMax = 186 le16_to_cpu(fan_table_v1->usTargetTemperature); 187 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin = 188 le16_to_cpu(fan_table_v1->usMinimumPWMLimit); 189 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk = 190 le16_to_cpu(fan_table_v1->usTargetGfxClk); 191 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge = 192 le16_to_cpu(fan_table_v1->usFanGainEdge); 193 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot = 194 le16_to_cpu(fan_table_v1->usFanGainHotspot); 195 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid = 196 le16_to_cpu(fan_table_v1->usFanGainLiquid); 197 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc = 198 le16_to_cpu(fan_table_v1->usFanGainVrVddc); 199 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd = 200 le16_to_cpu(fan_table_v1->usFanGainVrMvdd); 201 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx = 202 le16_to_cpu(fan_table_v1->usFanGainPlx); 203 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm = 204 le16_to_cpu(fan_table_v1->usFanGainHbm); 205 206 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM = 207 fan_table_v1->ucEnableZeroRPM; 208 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature = 209 le16_to_cpu(fan_table_v1->usFanStopTemperature); 210 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature = 211 le16_to_cpu(fan_table_v1->usFanStartTemperature); 212 } else if (header->ucRevId == 0xb) { 213 fan_table_v2 = (ATOM_Vega10_Fan_Table_V2 *)header; 214 215 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution = 216 fan_table_v2->ucFanParameters & ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK; 217 hwmgr->thermal_controller.fanInfo.ulMinRPM = fan_table_v2->ucFanMinRPM * 100UL; 218 hwmgr->thermal_controller.fanInfo.ulMaxRPM = fan_table_v2->ucFanMaxRPM * 100UL; 219 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 220 PHM_PlatformCaps_MicrocodeFanControl); 221 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity = 222 le16_to_cpu(fan_table_v2->usFanOutputSensitivity); 223 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM = 224 fan_table_v2->ucFanMaxRPM * 100UL; 225 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit = 226 le16_to_cpu(fan_table_v2->usThrottlingRPM); 227 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit = 228 le16_to_cpu(fan_table_v2->usFanAcousticLimitRpm); 229 hwmgr->thermal_controller.advanceFanControlParameters.usTMax = 230 le16_to_cpu(fan_table_v2->usTargetTemperature); 231 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin = 232 le16_to_cpu(fan_table_v2->usMinimumPWMLimit); 233 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk = 234 le16_to_cpu(fan_table_v2->usTargetGfxClk); 235 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge = 236 le16_to_cpu(fan_table_v2->usFanGainEdge); 237 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot = 238 le16_to_cpu(fan_table_v2->usFanGainHotspot); 239 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid = 240 le16_to_cpu(fan_table_v2->usFanGainLiquid); 241 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc = 242 le16_to_cpu(fan_table_v2->usFanGainVrVddc); 243 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd = 244 le16_to_cpu(fan_table_v2->usFanGainVrMvdd); 245 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx = 246 le16_to_cpu(fan_table_v2->usFanGainPlx); 247 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm = 248 le16_to_cpu(fan_table_v2->usFanGainHbm); 249 250 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM = 251 fan_table_v2->ucEnableZeroRPM; 252 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature = 253 le16_to_cpu(fan_table_v2->usFanStopTemperature); 254 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature = 255 le16_to_cpu(fan_table_v2->usFanStartTemperature); 256 } else if (header->ucRevId > 0xb) { 257 fan_table_v3 = (ATOM_Vega10_Fan_Table_V3 *)header; 258 259 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution = 260 fan_table_v3->ucFanParameters & ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK; 261 hwmgr->thermal_controller.fanInfo.ulMinRPM = fan_table_v3->ucFanMinRPM * 100UL; 262 hwmgr->thermal_controller.fanInfo.ulMaxRPM = fan_table_v3->ucFanMaxRPM * 100UL; 263 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 264 PHM_PlatformCaps_MicrocodeFanControl); 265 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity = 266 le16_to_cpu(fan_table_v3->usFanOutputSensitivity); 267 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM = 268 fan_table_v3->ucFanMaxRPM * 100UL; 269 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit = 270 le16_to_cpu(fan_table_v3->usThrottlingRPM); 271 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit = 272 le16_to_cpu(fan_table_v3->usFanAcousticLimitRpm); 273 hwmgr->thermal_controller.advanceFanControlParameters.usTMax = 274 le16_to_cpu(fan_table_v3->usTargetTemperature); 275 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin = 276 le16_to_cpu(fan_table_v3->usMinimumPWMLimit); 277 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk = 278 le16_to_cpu(fan_table_v3->usTargetGfxClk); 279 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge = 280 le16_to_cpu(fan_table_v3->usFanGainEdge); 281 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot = 282 le16_to_cpu(fan_table_v3->usFanGainHotspot); 283 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid = 284 le16_to_cpu(fan_table_v3->usFanGainLiquid); 285 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc = 286 le16_to_cpu(fan_table_v3->usFanGainVrVddc); 287 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd = 288 le16_to_cpu(fan_table_v3->usFanGainVrMvdd); 289 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx = 290 le16_to_cpu(fan_table_v3->usFanGainPlx); 291 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm = 292 le16_to_cpu(fan_table_v3->usFanGainHbm); 293 294 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM = 295 fan_table_v3->ucEnableZeroRPM; 296 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature = 297 le16_to_cpu(fan_table_v3->usFanStopTemperature); 298 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature = 299 le16_to_cpu(fan_table_v3->usFanStartTemperature); 300 hwmgr->thermal_controller.advanceFanControlParameters.usMGpuThrottlingRPMLimit = 301 le16_to_cpu(fan_table_v3->usMGpuThrottlingRPM); 302 } 303 304 return 0; 305} 306 307static int init_over_drive_limits( 308 struct pp_hwmgr *hwmgr, 309 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table) 310{ 311 const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table = 312 (const ATOM_Vega10_GFXCLK_Dependency_Table *) 313 (((unsigned long) powerplay_table) + 314 le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset)); 315 bool is_acg_enabled = false; 316 ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2; 317 318 if (gfxclk_dep_table->ucRevId == 1) { 319 patom_record_v2 = 320 (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)gfxclk_dep_table->entries; 321 is_acg_enabled = 322 (bool)patom_record_v2[gfxclk_dep_table->ucNumEntries-1].ucACGEnable; 323 } 324 325 if (powerplay_table->ulMaxODEngineClock > VEGA10_ENGINECLOCK_HARDMAX && 326 !is_acg_enabled) 327 hwmgr->platform_descriptor.overdriveLimit.engineClock = 328 VEGA10_ENGINECLOCK_HARDMAX; 329 else 330 hwmgr->platform_descriptor.overdriveLimit.engineClock = 331 le32_to_cpu(powerplay_table->ulMaxODEngineClock); 332 hwmgr->platform_descriptor.overdriveLimit.memoryClock = 333 le32_to_cpu(powerplay_table->ulMaxODMemoryClock); 334 335 hwmgr->platform_descriptor.minOverdriveVDDC = 0; 336 hwmgr->platform_descriptor.maxOverdriveVDDC = 0; 337 hwmgr->platform_descriptor.overdriveVDDCStep = 0; 338 339 return 0; 340} 341 342static int get_mm_clock_voltage_table( 343 struct pp_hwmgr *hwmgr, 344 phm_ppt_v1_mm_clock_voltage_dependency_table **vega10_mm_table, 345 const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table) 346{ 347 uint32_t i; 348 const ATOM_Vega10_MM_Dependency_Record *mm_dependency_record; 349 phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table; 350 351 PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0), 352 "Invalid PowerPlay Table!", return -1); 353 354 mm_table = kzalloc(struct_size(mm_table, entries, mm_dependency_table->ucNumEntries), 355 GFP_KERNEL); 356 if (!mm_table) 357 return -ENOMEM; 358 359 mm_table->count = mm_dependency_table->ucNumEntries; 360 361 for (i = 0; i < mm_dependency_table->ucNumEntries; i++) { 362 mm_dependency_record = &mm_dependency_table->entries[i]; 363 mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd; 364 mm_table->entries[i].samclock = 365 le32_to_cpu(mm_dependency_record->ulPSPClk); 366 mm_table->entries[i].eclk = le32_to_cpu(mm_dependency_record->ulEClk); 367 mm_table->entries[i].vclk = le32_to_cpu(mm_dependency_record->ulVClk); 368 mm_table->entries[i].dclk = le32_to_cpu(mm_dependency_record->ulDClk); 369 } 370 371 *vega10_mm_table = mm_table; 372 373 return 0; 374} 375 376static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda) 377{ 378 switch(line){ 379 case Vega10_I2CLineID_DDC1: 380 *scl = Vega10_I2C_DDC1CLK; 381 *sda = Vega10_I2C_DDC1DATA; 382 break; 383 case Vega10_I2CLineID_DDC2: 384 *scl = Vega10_I2C_DDC2CLK; 385 *sda = Vega10_I2C_DDC2DATA; 386 break; 387 case Vega10_I2CLineID_DDC3: 388 *scl = Vega10_I2C_DDC3CLK; 389 *sda = Vega10_I2C_DDC3DATA; 390 break; 391 case Vega10_I2CLineID_DDC4: 392 *scl = Vega10_I2C_DDC4CLK; 393 *sda = Vega10_I2C_DDC4DATA; 394 break; 395 case Vega10_I2CLineID_DDC5: 396 *scl = Vega10_I2C_DDC5CLK; 397 *sda = Vega10_I2C_DDC5DATA; 398 break; 399 case Vega10_I2CLineID_DDC6: 400 *scl = Vega10_I2C_DDC6CLK; 401 *sda = Vega10_I2C_DDC6DATA; 402 break; 403 case Vega10_I2CLineID_SCLSDA: 404 *scl = Vega10_I2C_SCL; 405 *sda = Vega10_I2C_SDA; 406 break; 407 case Vega10_I2CLineID_DDCVGA: 408 *scl = Vega10_I2C_DDCVGACLK; 409 *sda = Vega10_I2C_DDCVGADATA; 410 break; 411 default: 412 *scl = 0; 413 *sda = 0; 414 break; 415 } 416} 417 418static int get_tdp_table( 419 struct pp_hwmgr *hwmgr, 420 struct phm_tdp_table **info_tdp_table, 421 const Vega10_PPTable_Generic_SubTable_Header *table) 422{ 423 uint32_t table_size; 424 struct phm_tdp_table *tdp_table; 425 uint8_t scl; 426 uint8_t sda; 427 const ATOM_Vega10_PowerTune_Table *power_tune_table; 428 const ATOM_Vega10_PowerTune_Table_V2 *power_tune_table_v2; 429 const ATOM_Vega10_PowerTune_Table_V3 *power_tune_table_v3; 430 431 table_size = sizeof(uint32_t) + sizeof(struct phm_tdp_table); 432 433 tdp_table = kzalloc(table_size, GFP_KERNEL); 434 435 if (!tdp_table) 436 return -ENOMEM; 437 438 if (table->ucRevId == 5) { 439 power_tune_table = (ATOM_Vega10_PowerTune_Table *)table; 440 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table->usSocketPowerLimit); 441 tdp_table->usTDC = le16_to_cpu(power_tune_table->usTdcLimit); 442 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table->usEdcLimit); 443 tdp_table->usSoftwareShutdownTemp = 444 le16_to_cpu(power_tune_table->usSoftwareShutdownTemp); 445 tdp_table->usTemperatureLimitTedge = 446 le16_to_cpu(power_tune_table->usTemperatureLimitTedge); 447 tdp_table->usTemperatureLimitHotspot = 448 le16_to_cpu(power_tune_table->usTemperatureLimitHotSpot); 449 tdp_table->usTemperatureLimitLiquid1 = 450 le16_to_cpu(power_tune_table->usTemperatureLimitLiquid1); 451 tdp_table->usTemperatureLimitLiquid2 = 452 le16_to_cpu(power_tune_table->usTemperatureLimitLiquid2); 453 tdp_table->usTemperatureLimitHBM = 454 le16_to_cpu(power_tune_table->usTemperatureLimitHBM); 455 tdp_table->usTemperatureLimitVrVddc = 456 le16_to_cpu(power_tune_table->usTemperatureLimitVrSoc); 457 tdp_table->usTemperatureLimitVrMvdd = 458 le16_to_cpu(power_tune_table->usTemperatureLimitVrMem); 459 tdp_table->usTemperatureLimitPlx = 460 le16_to_cpu(power_tune_table->usTemperatureLimitPlx); 461 tdp_table->ucLiquid1_I2C_address = power_tune_table->ucLiquid1_I2C_address; 462 tdp_table->ucLiquid2_I2C_address = power_tune_table->ucLiquid2_I2C_address; 463 tdp_table->ucLiquid_I2C_Line = power_tune_table->ucLiquid_I2C_LineSCL; 464 tdp_table->ucLiquid_I2C_LineSDA = power_tune_table->ucLiquid_I2C_LineSDA; 465 tdp_table->ucVr_I2C_address = power_tune_table->ucVr_I2C_address; 466 tdp_table->ucVr_I2C_Line = power_tune_table->ucVr_I2C_LineSCL; 467 tdp_table->ucVr_I2C_LineSDA = power_tune_table->ucVr_I2C_LineSDA; 468 tdp_table->ucPlx_I2C_address = power_tune_table->ucPlx_I2C_address; 469 tdp_table->ucPlx_I2C_Line = power_tune_table->ucPlx_I2C_LineSCL; 470 tdp_table->ucPlx_I2C_LineSDA = power_tune_table->ucPlx_I2C_LineSDA; 471 hwmgr->platform_descriptor.LoadLineSlope = le16_to_cpu(power_tune_table->usLoadLineResistance); 472 } else if (table->ucRevId == 6) { 473 power_tune_table_v2 = (ATOM_Vega10_PowerTune_Table_V2 *)table; 474 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table_v2->usSocketPowerLimit); 475 tdp_table->usTDC = le16_to_cpu(power_tune_table_v2->usTdcLimit); 476 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table_v2->usEdcLimit); 477 tdp_table->usSoftwareShutdownTemp = 478 le16_to_cpu(power_tune_table_v2->usSoftwareShutdownTemp); 479 tdp_table->usTemperatureLimitTedge = 480 le16_to_cpu(power_tune_table_v2->usTemperatureLimitTedge); 481 tdp_table->usTemperatureLimitHotspot = 482 le16_to_cpu(power_tune_table_v2->usTemperatureLimitHotSpot); 483 tdp_table->usTemperatureLimitLiquid1 = 484 le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid1); 485 tdp_table->usTemperatureLimitLiquid2 = 486 le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid2); 487 tdp_table->usTemperatureLimitHBM = 488 le16_to_cpu(power_tune_table_v2->usTemperatureLimitHBM); 489 tdp_table->usTemperatureLimitVrVddc = 490 le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrSoc); 491 tdp_table->usTemperatureLimitVrMvdd = 492 le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrMem); 493 tdp_table->usTemperatureLimitPlx = 494 le16_to_cpu(power_tune_table_v2->usTemperatureLimitPlx); 495 tdp_table->ucLiquid1_I2C_address = power_tune_table_v2->ucLiquid1_I2C_address; 496 tdp_table->ucLiquid2_I2C_address = power_tune_table_v2->ucLiquid2_I2C_address; 497 498 get_scl_sda_value(power_tune_table_v2->ucLiquid_I2C_Line, &scl, &sda); 499 500 tdp_table->ucLiquid_I2C_Line = scl; 501 tdp_table->ucLiquid_I2C_LineSDA = sda; 502 503 tdp_table->ucVr_I2C_address = power_tune_table_v2->ucVr_I2C_address; 504 505 get_scl_sda_value(power_tune_table_v2->ucVr_I2C_Line, &scl, &sda); 506 507 tdp_table->ucVr_I2C_Line = scl; 508 tdp_table->ucVr_I2C_LineSDA = sda; 509 tdp_table->ucPlx_I2C_address = power_tune_table_v2->ucPlx_I2C_address; 510 511 get_scl_sda_value(power_tune_table_v2->ucPlx_I2C_Line, &scl, &sda); 512 513 tdp_table->ucPlx_I2C_Line = scl; 514 tdp_table->ucPlx_I2C_LineSDA = sda; 515 516 hwmgr->platform_descriptor.LoadLineSlope = 517 le16_to_cpu(power_tune_table_v2->usLoadLineResistance); 518 } else { 519 power_tune_table_v3 = (ATOM_Vega10_PowerTune_Table_V3 *)table; 520 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table_v3->usSocketPowerLimit); 521 tdp_table->usTDC = le16_to_cpu(power_tune_table_v3->usTdcLimit); 522 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table_v3->usEdcLimit); 523 tdp_table->usSoftwareShutdownTemp = le16_to_cpu(power_tune_table_v3->usSoftwareShutdownTemp); 524 tdp_table->usTemperatureLimitTedge = le16_to_cpu(power_tune_table_v3->usTemperatureLimitTedge); 525 tdp_table->usTemperatureLimitHotspot = le16_to_cpu(power_tune_table_v3->usTemperatureLimitHotSpot); 526 tdp_table->usTemperatureLimitLiquid1 = le16_to_cpu(power_tune_table_v3->usTemperatureLimitLiquid1); 527 tdp_table->usTemperatureLimitLiquid2 = le16_to_cpu(power_tune_table_v3->usTemperatureLimitLiquid2); 528 tdp_table->usTemperatureLimitHBM = le16_to_cpu(power_tune_table_v3->usTemperatureLimitHBM); 529 tdp_table->usTemperatureLimitVrVddc = le16_to_cpu(power_tune_table_v3->usTemperatureLimitVrSoc); 530 tdp_table->usTemperatureLimitVrMvdd = le16_to_cpu(power_tune_table_v3->usTemperatureLimitVrMem); 531 tdp_table->usTemperatureLimitPlx = le16_to_cpu(power_tune_table_v3->usTemperatureLimitPlx); 532 tdp_table->ucLiquid1_I2C_address = power_tune_table_v3->ucLiquid1_I2C_address; 533 tdp_table->ucLiquid2_I2C_address = power_tune_table_v3->ucLiquid2_I2C_address; 534 tdp_table->usBoostStartTemperature = le16_to_cpu(power_tune_table_v3->usBoostStartTemperature); 535 tdp_table->usBoostStopTemperature = le16_to_cpu(power_tune_table_v3->usBoostStopTemperature); 536 tdp_table->ulBoostClock = le32_to_cpu(power_tune_table_v3->ulBoostClock); 537 538 get_scl_sda_value(power_tune_table_v3->ucLiquid_I2C_Line, &scl, &sda); 539 540 tdp_table->ucLiquid_I2C_Line = scl; 541 tdp_table->ucLiquid_I2C_LineSDA = sda; 542 543 tdp_table->ucVr_I2C_address = power_tune_table_v3->ucVr_I2C_address; 544 545 get_scl_sda_value(power_tune_table_v3->ucVr_I2C_Line, &scl, &sda); 546 547 tdp_table->ucVr_I2C_Line = scl; 548 tdp_table->ucVr_I2C_LineSDA = sda; 549 550 tdp_table->ucPlx_I2C_address = power_tune_table_v3->ucPlx_I2C_address; 551 552 get_scl_sda_value(power_tune_table_v3->ucPlx_I2C_Line, &scl, &sda); 553 554 tdp_table->ucPlx_I2C_Line = scl; 555 tdp_table->ucPlx_I2C_LineSDA = sda; 556 557 hwmgr->platform_descriptor.LoadLineSlope = 558 le16_to_cpu(power_tune_table_v3->usLoadLineResistance); 559 } 560 561 *info_tdp_table = tdp_table; 562 563 return 0; 564} 565 566static int get_socclk_voltage_dependency_table( 567 struct pp_hwmgr *hwmgr, 568 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_clk_dep_table, 569 const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table) 570{ 571 uint32_t i; 572 phm_ppt_v1_clock_voltage_dependency_table *clk_table; 573 574 PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries, 575 "Invalid PowerPlay Table!", return -1); 576 577 clk_table = kzalloc(struct_size(clk_table, entries, clk_dep_table->ucNumEntries), 578 GFP_KERNEL); 579 if (!clk_table) 580 return -ENOMEM; 581 582 clk_table->count = (uint32_t)clk_dep_table->ucNumEntries; 583 584 for (i = 0; i < clk_dep_table->ucNumEntries; i++) { 585 clk_table->entries[i].vddInd = 586 clk_dep_table->entries[i].ucVddInd; 587 clk_table->entries[i].clk = 588 le32_to_cpu(clk_dep_table->entries[i].ulClk); 589 } 590 591 *pp_vega10_clk_dep_table = clk_table; 592 593 return 0; 594} 595 596static int get_mclk_voltage_dependency_table( 597 struct pp_hwmgr *hwmgr, 598 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_mclk_dep_table, 599 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table) 600{ 601 uint32_t i; 602 phm_ppt_v1_clock_voltage_dependency_table *mclk_table; 603 604 PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries, 605 "Invalid PowerPlay Table!", return -1); 606 607 mclk_table = kzalloc(struct_size(mclk_table, entries, mclk_dep_table->ucNumEntries), 608 GFP_KERNEL); 609 if (!mclk_table) 610 return -ENOMEM; 611 612 mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries; 613 614 for (i = 0; i < mclk_dep_table->ucNumEntries; i++) { 615 mclk_table->entries[i].vddInd = 616 mclk_dep_table->entries[i].ucVddInd; 617 mclk_table->entries[i].vddciInd = 618 mclk_dep_table->entries[i].ucVddciInd; 619 mclk_table->entries[i].mvddInd = 620 mclk_dep_table->entries[i].ucVddMemInd; 621 mclk_table->entries[i].clk = 622 le32_to_cpu(mclk_dep_table->entries[i].ulMemClk); 623 } 624 625 *pp_vega10_mclk_dep_table = mclk_table; 626 627 return 0; 628} 629 630static int get_gfxclk_voltage_dependency_table( 631 struct pp_hwmgr *hwmgr, 632 struct phm_ppt_v1_clock_voltage_dependency_table 633 **pp_vega10_clk_dep_table, 634 const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table) 635{ 636 uint32_t i; 637 struct phm_ppt_v1_clock_voltage_dependency_table 638 *clk_table; 639 ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2; 640 641 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0), 642 "Invalid PowerPlay Table!", return -1); 643 644 clk_table = kzalloc(struct_size(clk_table, entries, clk_dep_table->ucNumEntries), 645 GFP_KERNEL); 646 if (!clk_table) 647 return -ENOMEM; 648 649 clk_table->count = clk_dep_table->ucNumEntries; 650 651 if (clk_dep_table->ucRevId == 0) { 652 for (i = 0; i < clk_table->count; i++) { 653 clk_table->entries[i].vddInd = 654 clk_dep_table->entries[i].ucVddInd; 655 clk_table->entries[i].clk = 656 le32_to_cpu(clk_dep_table->entries[i].ulClk); 657 clk_table->entries[i].cks_enable = 658 (((le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x8000) 659 >> 15) == 0) ? 1 : 0; 660 clk_table->entries[i].cks_voffset = 661 le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x7F; 662 clk_table->entries[i].sclk_offset = 663 le16_to_cpu(clk_dep_table->entries[i].usAVFSOffset); 664 } 665 } else if (clk_dep_table->ucRevId == 1) { 666 patom_record_v2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)clk_dep_table->entries; 667 for (i = 0; i < clk_table->count; i++) { 668 clk_table->entries[i].vddInd = 669 patom_record_v2->ucVddInd; 670 clk_table->entries[i].clk = 671 le32_to_cpu(patom_record_v2->ulClk); 672 clk_table->entries[i].cks_enable = 673 (((le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x8000) 674 >> 15) == 0) ? 1 : 0; 675 clk_table->entries[i].cks_voffset = 676 le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x7F; 677 clk_table->entries[i].sclk_offset = 678 le16_to_cpu(patom_record_v2->usAVFSOffset); 679 patom_record_v2++; 680 } 681 } else { 682 kfree(clk_table); 683 PP_ASSERT_WITH_CODE(false, 684 "Unsupported GFXClockDependencyTable Revision!", 685 return -EINVAL); 686 } 687 688 *pp_vega10_clk_dep_table = clk_table; 689 690 return 0; 691} 692 693static int get_pix_clk_voltage_dependency_table( 694 struct pp_hwmgr *hwmgr, 695 struct phm_ppt_v1_clock_voltage_dependency_table 696 **pp_vega10_clk_dep_table, 697 const ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table) 698{ 699 uint32_t i; 700 struct phm_ppt_v1_clock_voltage_dependency_table 701 *clk_table; 702 703 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0), 704 "Invalid PowerPlay Table!", return -1); 705 706 clk_table = kzalloc(struct_size(clk_table, entries, clk_dep_table->ucNumEntries), 707 GFP_KERNEL); 708 if (!clk_table) 709 return -ENOMEM; 710 711 clk_table->count = clk_dep_table->ucNumEntries; 712 713 for (i = 0; i < clk_table->count; i++) { 714 clk_table->entries[i].vddInd = 715 clk_dep_table->entries[i].ucVddInd; 716 clk_table->entries[i].clk = 717 le32_to_cpu(clk_dep_table->entries[i].ulClk); 718 } 719 720 *pp_vega10_clk_dep_table = clk_table; 721 722 return 0; 723} 724 725static int get_dcefclk_voltage_dependency_table( 726 struct pp_hwmgr *hwmgr, 727 struct phm_ppt_v1_clock_voltage_dependency_table 728 **pp_vega10_clk_dep_table, 729 const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table) 730{ 731 uint32_t i; 732 uint8_t num_entries; 733 struct phm_ppt_v1_clock_voltage_dependency_table 734 *clk_table; 735 uint32_t dev_id; 736 uint32_t rev_id; 737 struct amdgpu_device *adev = hwmgr->adev; 738 739 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0), 740 "Invalid PowerPlay Table!", return -1); 741 742/* 743 * workaround needed to add another DPM level for pioneer cards 744 * as VBIOS is locked down. 745 * This DPM level was added to support 3DPM monitors @ 4K120Hz 746 * 747 */ 748 dev_id = adev->pdev->device; 749 rev_id = adev->pdev->revision; 750 751 if (dev_id == 0x6863 && rev_id == 0 && 752 clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk < 90000) 753 num_entries = clk_dep_table->ucNumEntries + 1 > NUM_DSPCLK_LEVELS ? 754 NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries + 1; 755 else 756 num_entries = clk_dep_table->ucNumEntries; 757 758 759 clk_table = kzalloc(struct_size(clk_table, entries, num_entries), 760 GFP_KERNEL); 761 if (!clk_table) 762 return -ENOMEM; 763 764 clk_table->count = (uint32_t)num_entries; 765 766 for (i = 0; i < clk_dep_table->ucNumEntries; i++) { 767 clk_table->entries[i].vddInd = 768 clk_dep_table->entries[i].ucVddInd; 769 clk_table->entries[i].clk = 770 le32_to_cpu(clk_dep_table->entries[i].ulClk); 771 } 772 773 if (i < num_entries) { 774 clk_table->entries[i].vddInd = clk_dep_table->entries[i-1].ucVddInd; 775 clk_table->entries[i].clk = 90000; 776 } 777 778 *pp_vega10_clk_dep_table = clk_table; 779 780 return 0; 781} 782 783static int get_pcie_table(struct pp_hwmgr *hwmgr, 784 struct phm_ppt_v1_pcie_table **vega10_pcie_table, 785 const Vega10_PPTable_Generic_SubTable_Header *table) 786{ 787 uint32_t i, pcie_count; 788 struct phm_ppt_v1_pcie_table *pcie_table; 789 struct phm_ppt_v2_information *table_info = 790 (struct phm_ppt_v2_information *)(hwmgr->pptable); 791 const ATOM_Vega10_PCIE_Table *atom_pcie_table = 792 (ATOM_Vega10_PCIE_Table *)table; 793 794 PP_ASSERT_WITH_CODE(atom_pcie_table->ucNumEntries, 795 "Invalid PowerPlay Table!", 796 return 0); 797 798 pcie_table = kzalloc(struct_size(pcie_table, entries, atom_pcie_table->ucNumEntries), 799 GFP_KERNEL); 800 if (!pcie_table) 801 return -ENOMEM; 802 803 pcie_count = table_info->vdd_dep_on_sclk->count; 804 if (atom_pcie_table->ucNumEntries <= pcie_count) 805 pcie_count = atom_pcie_table->ucNumEntries; 806 else 807 pr_info("Number of Pcie Entries exceed the number of" 808 " GFXCLK Dpm Levels!" 809 " Disregarding the excess entries...\n"); 810 811 pcie_table->count = pcie_count; 812 813 for (i = 0; i < pcie_count; i++) { 814 pcie_table->entries[i].gen_speed = 815 atom_pcie_table->entries[i].ucPCIEGenSpeed; 816 pcie_table->entries[i].lane_width = 817 atom_pcie_table->entries[i].ucPCIELaneWidth; 818 pcie_table->entries[i].pcie_sclk = 819 atom_pcie_table->entries[i].ulLCLK; 820 } 821 822 *vega10_pcie_table = pcie_table; 823 824 return 0; 825} 826 827static int get_hard_limits( 828 struct pp_hwmgr *hwmgr, 829 struct phm_clock_and_voltage_limits *limits, 830 const ATOM_Vega10_Hard_Limit_Table *limit_table) 831{ 832 PP_ASSERT_WITH_CODE(limit_table->ucNumEntries, 833 "Invalid PowerPlay Table!", return -1); 834 835 /* currently we always take entries[0] parameters */ 836 limits->sclk = le32_to_cpu(limit_table->entries[0].ulSOCCLKLimit); 837 limits->mclk = le32_to_cpu(limit_table->entries[0].ulMCLKLimit); 838 limits->gfxclk = le32_to_cpu(limit_table->entries[0].ulGFXCLKLimit); 839 limits->vddc = le16_to_cpu(limit_table->entries[0].usVddcLimit); 840 limits->vddci = le16_to_cpu(limit_table->entries[0].usVddciLimit); 841 limits->vddmem = le16_to_cpu(limit_table->entries[0].usVddMemLimit); 842 843 return 0; 844} 845 846static int get_valid_clk( 847 struct pp_hwmgr *hwmgr, 848 struct phm_clock_array **clk_table, 849 const phm_ppt_v1_clock_voltage_dependency_table *clk_volt_pp_table) 850{ 851 uint32_t i; 852 struct phm_clock_array *table; 853 854 PP_ASSERT_WITH_CODE(clk_volt_pp_table->count, 855 "Invalid PowerPlay Table!", return -1); 856 857 table = kzalloc(struct_size(table, values, clk_volt_pp_table->count), 858 GFP_KERNEL); 859 if (!table) 860 return -ENOMEM; 861 862 table->count = (uint32_t)clk_volt_pp_table->count; 863 864 for (i = 0; i < table->count; i++) 865 table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk; 866 867 *clk_table = table; 868 869 return 0; 870} 871 872static int init_powerplay_extended_tables( 873 struct pp_hwmgr *hwmgr, 874 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table) 875{ 876 int result = 0; 877 struct phm_ppt_v2_information *pp_table_info = 878 (struct phm_ppt_v2_information *)(hwmgr->pptable); 879 880 const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table = 881 (const ATOM_Vega10_MM_Dependency_Table *) 882 (((unsigned long) powerplay_table) + 883 le16_to_cpu(powerplay_table->usMMDependencyTableOffset)); 884 const Vega10_PPTable_Generic_SubTable_Header *power_tune_table = 885 (const Vega10_PPTable_Generic_SubTable_Header *) 886 (((unsigned long) powerplay_table) + 887 le16_to_cpu(powerplay_table->usPowerTuneTableOffset)); 888 const ATOM_Vega10_SOCCLK_Dependency_Table *socclk_dep_table = 889 (const ATOM_Vega10_SOCCLK_Dependency_Table *) 890 (((unsigned long) powerplay_table) + 891 le16_to_cpu(powerplay_table->usSocclkDependencyTableOffset)); 892 const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table = 893 (const ATOM_Vega10_GFXCLK_Dependency_Table *) 894 (((unsigned long) powerplay_table) + 895 le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset)); 896 const ATOM_Vega10_DCEFCLK_Dependency_Table *dcefclk_dep_table = 897 (const ATOM_Vega10_DCEFCLK_Dependency_Table *) 898 (((unsigned long) powerplay_table) + 899 le16_to_cpu(powerplay_table->usDcefclkDependencyTableOffset)); 900 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table = 901 (const ATOM_Vega10_MCLK_Dependency_Table *) 902 (((unsigned long) powerplay_table) + 903 le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); 904 const ATOM_Vega10_Hard_Limit_Table *hard_limits = 905 (const ATOM_Vega10_Hard_Limit_Table *) 906 (((unsigned long) powerplay_table) + 907 le16_to_cpu(powerplay_table->usHardLimitTableOffset)); 908 const Vega10_PPTable_Generic_SubTable_Header *pcie_table = 909 (const Vega10_PPTable_Generic_SubTable_Header *) 910 (((unsigned long) powerplay_table) + 911 le16_to_cpu(powerplay_table->usPCIETableOffset)); 912 const ATOM_Vega10_PIXCLK_Dependency_Table *pixclk_dep_table = 913 (const ATOM_Vega10_PIXCLK_Dependency_Table *) 914 (((unsigned long) powerplay_table) + 915 le16_to_cpu(powerplay_table->usPixclkDependencyTableOffset)); 916 const ATOM_Vega10_PHYCLK_Dependency_Table *phyclk_dep_table = 917 (const ATOM_Vega10_PHYCLK_Dependency_Table *) 918 (((unsigned long) powerplay_table) + 919 le16_to_cpu(powerplay_table->usPhyClkDependencyTableOffset)); 920 const ATOM_Vega10_DISPCLK_Dependency_Table *dispclk_dep_table = 921 (const ATOM_Vega10_DISPCLK_Dependency_Table *) 922 (((unsigned long) powerplay_table) + 923 le16_to_cpu(powerplay_table->usDispClkDependencyTableOffset)); 924 925 pp_table_info->vdd_dep_on_socclk = NULL; 926 pp_table_info->vdd_dep_on_sclk = NULL; 927 pp_table_info->vdd_dep_on_mclk = NULL; 928 pp_table_info->vdd_dep_on_dcefclk = NULL; 929 pp_table_info->mm_dep_table = NULL; 930 pp_table_info->tdp_table = NULL; 931 pp_table_info->vdd_dep_on_pixclk = NULL; 932 pp_table_info->vdd_dep_on_phyclk = NULL; 933 pp_table_info->vdd_dep_on_dispclk = NULL; 934 935 if (powerplay_table->usMMDependencyTableOffset) 936 result = get_mm_clock_voltage_table(hwmgr, 937 &pp_table_info->mm_dep_table, 938 mm_dependency_table); 939 940 if (!result && powerplay_table->usPowerTuneTableOffset) 941 result = get_tdp_table(hwmgr, 942 &pp_table_info->tdp_table, 943 power_tune_table); 944 945 if (!result && powerplay_table->usSocclkDependencyTableOffset) 946 result = get_socclk_voltage_dependency_table(hwmgr, 947 &pp_table_info->vdd_dep_on_socclk, 948 socclk_dep_table); 949 950 if (!result && powerplay_table->usGfxclkDependencyTableOffset) 951 result = get_gfxclk_voltage_dependency_table(hwmgr, 952 &pp_table_info->vdd_dep_on_sclk, 953 gfxclk_dep_table); 954 955 if (!result && powerplay_table->usPixclkDependencyTableOffset) 956 result = get_pix_clk_voltage_dependency_table(hwmgr, 957 &pp_table_info->vdd_dep_on_pixclk, 958 (const ATOM_Vega10_PIXCLK_Dependency_Table*) 959 pixclk_dep_table); 960 961 if (!result && powerplay_table->usPhyClkDependencyTableOffset) 962 result = get_pix_clk_voltage_dependency_table(hwmgr, 963 &pp_table_info->vdd_dep_on_phyclk, 964 (const ATOM_Vega10_PIXCLK_Dependency_Table *) 965 phyclk_dep_table); 966 967 if (!result && powerplay_table->usDispClkDependencyTableOffset) 968 result = get_pix_clk_voltage_dependency_table(hwmgr, 969 &pp_table_info->vdd_dep_on_dispclk, 970 (const ATOM_Vega10_PIXCLK_Dependency_Table *) 971 dispclk_dep_table); 972 973 if (!result && powerplay_table->usDcefclkDependencyTableOffset) 974 result = get_dcefclk_voltage_dependency_table(hwmgr, 975 &pp_table_info->vdd_dep_on_dcefclk, 976 dcefclk_dep_table); 977 978 if (!result && powerplay_table->usMclkDependencyTableOffset) 979 result = get_mclk_voltage_dependency_table(hwmgr, 980 &pp_table_info->vdd_dep_on_mclk, 981 mclk_dep_table); 982 983 if (!result && powerplay_table->usPCIETableOffset) 984 result = get_pcie_table(hwmgr, 985 &pp_table_info->pcie_table, 986 pcie_table); 987 988 if (!result && powerplay_table->usHardLimitTableOffset) 989 result = get_hard_limits(hwmgr, 990 &pp_table_info->max_clock_voltage_on_dc, 991 hard_limits); 992 993 hwmgr->dyn_state.max_clock_voltage_on_dc.sclk = 994 pp_table_info->max_clock_voltage_on_dc.sclk; 995 hwmgr->dyn_state.max_clock_voltage_on_dc.mclk = 996 pp_table_info->max_clock_voltage_on_dc.mclk; 997 hwmgr->dyn_state.max_clock_voltage_on_dc.vddc = 998 pp_table_info->max_clock_voltage_on_dc.vddc; 999 hwmgr->dyn_state.max_clock_voltage_on_dc.vddci = 1000 pp_table_info->max_clock_voltage_on_dc.vddci; 1001 1002 if (!result && 1003 pp_table_info->vdd_dep_on_socclk && 1004 pp_table_info->vdd_dep_on_socclk->count) 1005 result = get_valid_clk(hwmgr, 1006 &pp_table_info->valid_socclk_values, 1007 pp_table_info->vdd_dep_on_socclk); 1008 1009 if (!result && 1010 pp_table_info->vdd_dep_on_sclk && 1011 pp_table_info->vdd_dep_on_sclk->count) 1012 result = get_valid_clk(hwmgr, 1013 &pp_table_info->valid_sclk_values, 1014 pp_table_info->vdd_dep_on_sclk); 1015 1016 if (!result && 1017 pp_table_info->vdd_dep_on_dcefclk && 1018 pp_table_info->vdd_dep_on_dcefclk->count) 1019 result = get_valid_clk(hwmgr, 1020 &pp_table_info->valid_dcefclk_values, 1021 pp_table_info->vdd_dep_on_dcefclk); 1022 1023 if (!result && 1024 pp_table_info->vdd_dep_on_mclk && 1025 pp_table_info->vdd_dep_on_mclk->count) 1026 result = get_valid_clk(hwmgr, 1027 &pp_table_info->valid_mclk_values, 1028 pp_table_info->vdd_dep_on_mclk); 1029 1030 return result; 1031} 1032 1033static int get_vddc_lookup_table( 1034 struct pp_hwmgr *hwmgr, 1035 phm_ppt_v1_voltage_lookup_table **lookup_table, 1036 const ATOM_Vega10_Voltage_Lookup_Table *vddc_lookup_pp_tables, 1037 uint32_t max_levels) 1038{ 1039 uint32_t i; 1040 phm_ppt_v1_voltage_lookup_table *table; 1041 1042 PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0), 1043 "Invalid SOC_VDDD Lookup Table!", return 1); 1044 1045 table = kzalloc(struct_size(table, entries, max_levels), GFP_KERNEL); 1046 if (!table) 1047 return -ENOMEM; 1048 1049 table->count = vddc_lookup_pp_tables->ucNumEntries; 1050 1051 for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++) 1052 table->entries[i].us_vdd = 1053 le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd); 1054 1055 *lookup_table = table; 1056 1057 return 0; 1058} 1059 1060static int init_dpm_2_parameters( 1061 struct pp_hwmgr *hwmgr, 1062 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table) 1063{ 1064 int result = 0; 1065 struct phm_ppt_v2_information *pp_table_info = 1066 (struct phm_ppt_v2_information *)(hwmgr->pptable); 1067 uint32_t disable_power_control = 0; 1068 1069 pp_table_info->us_ulv_voltage_offset = 1070 le16_to_cpu(powerplay_table->usUlvVoltageOffset); 1071 1072 pp_table_info->us_ulv_smnclk_did = 1073 le16_to_cpu(powerplay_table->usUlvSmnclkDid); 1074 pp_table_info->us_ulv_mp1clk_did = 1075 le16_to_cpu(powerplay_table->usUlvMp1clkDid); 1076 pp_table_info->us_ulv_gfxclk_bypass = 1077 le16_to_cpu(powerplay_table->usUlvGfxclkBypass); 1078 pp_table_info->us_gfxclk_slew_rate = 1079 le16_to_cpu(powerplay_table->usGfxclkSlewRate); 1080 pp_table_info->uc_gfx_dpm_voltage_mode = 1081 le16_to_cpu(powerplay_table->ucGfxVoltageMode); 1082 pp_table_info->uc_soc_dpm_voltage_mode = 1083 le16_to_cpu(powerplay_table->ucSocVoltageMode); 1084 pp_table_info->uc_uclk_dpm_voltage_mode = 1085 le16_to_cpu(powerplay_table->ucUclkVoltageMode); 1086 pp_table_info->uc_uvd_dpm_voltage_mode = 1087 le16_to_cpu(powerplay_table->ucUvdVoltageMode); 1088 pp_table_info->uc_vce_dpm_voltage_mode = 1089 le16_to_cpu(powerplay_table->ucVceVoltageMode); 1090 pp_table_info->uc_mp0_dpm_voltage_mode = 1091 le16_to_cpu(powerplay_table->ucMp0VoltageMode); 1092 pp_table_info->uc_dcef_dpm_voltage_mode = 1093 le16_to_cpu(powerplay_table->ucDcefVoltageMode); 1094 1095 pp_table_info->ppm_parameter_table = NULL; 1096 pp_table_info->vddc_lookup_table = NULL; 1097 pp_table_info->vddmem_lookup_table = NULL; 1098 pp_table_info->vddci_lookup_table = NULL; 1099 1100 /* TDP limits */ 1101 hwmgr->platform_descriptor.TDPODLimit = 1102 le16_to_cpu(powerplay_table->usPowerControlLimit); 1103 hwmgr->platform_descriptor.TDPAdjustment = 0; 1104 hwmgr->platform_descriptor.VidAdjustment = 0; 1105 hwmgr->platform_descriptor.VidAdjustmentPolarity = 0; 1106 hwmgr->platform_descriptor.VidMinLimit = 0; 1107 hwmgr->platform_descriptor.VidMaxLimit = 1500000; 1108 hwmgr->platform_descriptor.VidStep = 6250; 1109 1110 disable_power_control = 0; 1111 if (!disable_power_control) { 1112 /* enable TDP overdrive (PowerControl) feature as well if supported */ 1113 if (hwmgr->platform_descriptor.TDPODLimit) 1114 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 1115 PHM_PlatformCaps_PowerControl); 1116 } 1117 1118 if (powerplay_table->usVddcLookupTableOffset) { 1119 const ATOM_Vega10_Voltage_Lookup_Table *vddc_table = 1120 (ATOM_Vega10_Voltage_Lookup_Table *) 1121 (((unsigned long)powerplay_table) + 1122 le16_to_cpu(powerplay_table->usVddcLookupTableOffset)); 1123 result = get_vddc_lookup_table(hwmgr, 1124 &pp_table_info->vddc_lookup_table, vddc_table, 8); 1125 } 1126 1127 if (powerplay_table->usVddmemLookupTableOffset) { 1128 const ATOM_Vega10_Voltage_Lookup_Table *vdd_mem_table = 1129 (ATOM_Vega10_Voltage_Lookup_Table *) 1130 (((unsigned long)powerplay_table) + 1131 le16_to_cpu(powerplay_table->usVddmemLookupTableOffset)); 1132 result = get_vddc_lookup_table(hwmgr, 1133 &pp_table_info->vddmem_lookup_table, vdd_mem_table, 4); 1134 } 1135 1136 if (powerplay_table->usVddciLookupTableOffset) { 1137 const ATOM_Vega10_Voltage_Lookup_Table *vddci_table = 1138 (ATOM_Vega10_Voltage_Lookup_Table *) 1139 (((unsigned long)powerplay_table) + 1140 le16_to_cpu(powerplay_table->usVddciLookupTableOffset)); 1141 result = get_vddc_lookup_table(hwmgr, 1142 &pp_table_info->vddci_lookup_table, vddci_table, 4); 1143 } 1144 1145 return result; 1146} 1147 1148static int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr) 1149{ 1150 int result = 0; 1151 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table; 1152 1153 hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL); 1154 1155 PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL), 1156 "Failed to allocate hwmgr->pptable!", return -ENOMEM); 1157 1158 powerplay_table = get_powerplay_table(hwmgr); 1159 1160 PP_ASSERT_WITH_CODE((powerplay_table != NULL), 1161 "Missing PowerPlay Table!", return -1); 1162 1163 result = check_powerplay_tables(hwmgr, powerplay_table); 1164 1165 PP_ASSERT_WITH_CODE((result == 0), 1166 "check_powerplay_tables failed", return result); 1167 1168 result = set_platform_caps(hwmgr, 1169 le32_to_cpu(powerplay_table->ulPlatformCaps)); 1170 1171 PP_ASSERT_WITH_CODE((result == 0), 1172 "set_platform_caps failed", return result); 1173 1174 result = init_thermal_controller(hwmgr, powerplay_table); 1175 1176 PP_ASSERT_WITH_CODE((result == 0), 1177 "init_thermal_controller failed", return result); 1178 1179 result = init_over_drive_limits(hwmgr, powerplay_table); 1180 1181 PP_ASSERT_WITH_CODE((result == 0), 1182 "init_over_drive_limits failed", return result); 1183 1184 result = init_powerplay_extended_tables(hwmgr, powerplay_table); 1185 1186 PP_ASSERT_WITH_CODE((result == 0), 1187 "init_powerplay_extended_tables failed", return result); 1188 1189 result = init_dpm_2_parameters(hwmgr, powerplay_table); 1190 1191 PP_ASSERT_WITH_CODE((result == 0), 1192 "init_dpm_2_parameters failed", return result); 1193 1194 return result; 1195} 1196 1197static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) 1198{ 1199 struct phm_ppt_v2_information *pp_table_info = 1200 (struct phm_ppt_v2_information *)(hwmgr->pptable); 1201 1202 kfree(pp_table_info->vdd_dep_on_sclk); 1203 pp_table_info->vdd_dep_on_sclk = NULL; 1204 1205 kfree(pp_table_info->vdd_dep_on_mclk); 1206 pp_table_info->vdd_dep_on_mclk = NULL; 1207 1208 kfree(pp_table_info->valid_mclk_values); 1209 pp_table_info->valid_mclk_values = NULL; 1210 1211 kfree(pp_table_info->valid_sclk_values); 1212 pp_table_info->valid_sclk_values = NULL; 1213 1214 kfree(pp_table_info->vddc_lookup_table); 1215 pp_table_info->vddc_lookup_table = NULL; 1216 1217 kfree(pp_table_info->vddmem_lookup_table); 1218 pp_table_info->vddmem_lookup_table = NULL; 1219 1220 kfree(pp_table_info->vddci_lookup_table); 1221 pp_table_info->vddci_lookup_table = NULL; 1222 1223 kfree(pp_table_info->ppm_parameter_table); 1224 pp_table_info->ppm_parameter_table = NULL; 1225 1226 kfree(pp_table_info->mm_dep_table); 1227 pp_table_info->mm_dep_table = NULL; 1228 1229 kfree(pp_table_info->cac_dtp_table); 1230 pp_table_info->cac_dtp_table = NULL; 1231 1232 kfree(hwmgr->dyn_state.cac_dtp_table); 1233 hwmgr->dyn_state.cac_dtp_table = NULL; 1234 1235 kfree(pp_table_info->tdp_table); 1236 pp_table_info->tdp_table = NULL; 1237 1238 kfree(hwmgr->pptable); 1239 hwmgr->pptable = NULL; 1240 1241 return 0; 1242} 1243 1244const struct pp_table_func vega10_pptable_funcs = { 1245 .pptable_init = vega10_pp_tables_initialize, 1246 .pptable_fini = vega10_pp_tables_uninitialize, 1247}; 1248 1249int vega10_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr) 1250{ 1251 const ATOM_Vega10_State_Array *state_arrays; 1252 const ATOM_Vega10_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr); 1253 1254 PP_ASSERT_WITH_CODE((pp_table != NULL), 1255 "Missing PowerPlay Table!", return -1); 1256 PP_ASSERT_WITH_CODE((pp_table->sHeader.format_revision >= 1257 ATOM_Vega10_TABLE_REVISION_VEGA10), 1258 "Incorrect PowerPlay table revision!", return -1); 1259 1260 state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)pp_table) + 1261 le16_to_cpu(pp_table->usStateArrayOffset)); 1262 1263 return (uint32_t)(state_arrays->ucNumEntries); 1264} 1265 1266static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr, 1267 uint16_t classification, uint16_t classification2) 1268{ 1269 uint32_t result = 0; 1270 1271 if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT) 1272 result |= PP_StateClassificationFlag_Boot; 1273 1274 if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL) 1275 result |= PP_StateClassificationFlag_Thermal; 1276 1277 if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE) 1278 result |= PP_StateClassificationFlag_LimitedPowerSource; 1279 1280 if (classification & ATOM_PPLIB_CLASSIFICATION_REST) 1281 result |= PP_StateClassificationFlag_Rest; 1282 1283 if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED) 1284 result |= PP_StateClassificationFlag_Forced; 1285 1286 if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI) 1287 result |= PP_StateClassificationFlag_ACPI; 1288 1289 if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2) 1290 result |= PP_StateClassificationFlag_LimitedPowerSource_2; 1291 1292 return result; 1293} 1294 1295int vega10_get_powerplay_table_entry(struct pp_hwmgr *hwmgr, 1296 uint32_t entry_index, struct pp_power_state *power_state, 1297 int (*call_back_func)(struct pp_hwmgr *, void *, 1298 struct pp_power_state *, void *, uint32_t)) 1299{ 1300 int result = 0; 1301 const ATOM_Vega10_State_Array *state_arrays; 1302 const ATOM_Vega10_State *state_entry; 1303 const ATOM_Vega10_POWERPLAYTABLE *pp_table = 1304 get_powerplay_table(hwmgr); 1305 1306 PP_ASSERT_WITH_CODE(pp_table, "Missing PowerPlay Table!", 1307 return -1;); 1308 power_state->classification.bios_index = entry_index; 1309 1310 if (pp_table->sHeader.format_revision >= 1311 ATOM_Vega10_TABLE_REVISION_VEGA10) { 1312 state_arrays = (ATOM_Vega10_State_Array *) 1313 (((unsigned long)pp_table) + 1314 le16_to_cpu(pp_table->usStateArrayOffset)); 1315 1316 PP_ASSERT_WITH_CODE(pp_table->usStateArrayOffset > 0, 1317 "Invalid PowerPlay Table State Array Offset.", 1318 return -1); 1319 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0, 1320 "Invalid PowerPlay Table State Array.", 1321 return -1); 1322 PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries), 1323 "Invalid PowerPlay Table State Array Entry.", 1324 return -1); 1325 1326 state_entry = &(state_arrays->states[entry_index]); 1327 1328 result = call_back_func(hwmgr, (void *)state_entry, power_state, 1329 (void *)pp_table, 1330 make_classification_flags(hwmgr, 1331 le16_to_cpu(state_entry->usClassification), 1332 le16_to_cpu(state_entry->usClassification2))); 1333 } 1334 1335 if (!result && (power_state->classification.flags & 1336 PP_StateClassificationFlag_Boot)) 1337 result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware)); 1338 1339 return result; 1340} 1341 1342int vega10_baco_set_cap(struct pp_hwmgr *hwmgr) 1343{ 1344 int result = 0; 1345 1346 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table; 1347 1348 powerplay_table = get_powerplay_table(hwmgr); 1349 1350 PP_ASSERT_WITH_CODE((powerplay_table != NULL), 1351 "Missing PowerPlay Table!", return -1); 1352 1353 result = check_powerplay_tables(hwmgr, powerplay_table); 1354 1355 PP_ASSERT_WITH_CODE((result == 0), 1356 "check_powerplay_tables failed", return result); 1357 1358 set_hw_cap( 1359 hwmgr, 1360 0 != (le32_to_cpu(powerplay_table->ulPlatformCaps) & ATOM_VEGA10_PP_PLATFORM_CAP_BACO), 1361 PHM_PlatformCaps_BACO); 1362 return result; 1363} 1364