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