root/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_hw_cap
  2. get_powerplay_table
  3. check_powerplay_tables
  4. set_platform_caps
  5. init_thermal_controller
  6. init_over_drive_limits
  7. get_mm_clock_voltage_table
  8. get_scl_sda_value
  9. get_tdp_table
  10. get_socclk_voltage_dependency_table
  11. get_mclk_voltage_dependency_table
  12. get_gfxclk_voltage_dependency_table
  13. get_pix_clk_voltage_dependency_table
  14. get_dcefclk_voltage_dependency_table
  15. get_pcie_table
  16. get_hard_limits
  17. get_valid_clk
  18. init_powerplay_extended_tables
  19. get_vddc_lookup_table
  20. init_dpm_2_parameters
  21. vega10_pp_tables_initialize
  22. vega10_pp_tables_uninitialize
  23. vega10_get_number_of_powerplay_table_entries
  24. make_classification_flags
  25. vega10_get_powerplay_table_entry
  26. vega10_baco_set_cap

   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 
  38 static 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 
  47 static 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 
  67 static 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 
  89 static 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 
 119 static 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 
 307 static 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 
 342 static 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 table_size, 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         table_size = sizeof(uint32_t) +
 355                         sizeof(phm_ppt_v1_mm_clock_voltage_dependency_record) *
 356                         mm_dependency_table->ucNumEntries;
 357         mm_table = kzalloc(table_size, GFP_KERNEL);
 358 
 359         if (!mm_table)
 360                 return -ENOMEM;
 361 
 362         mm_table->count = mm_dependency_table->ucNumEntries;
 363 
 364         for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
 365                 mm_dependency_record = &mm_dependency_table->entries[i];
 366                 mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
 367                 mm_table->entries[i].samclock =
 368                                 le32_to_cpu(mm_dependency_record->ulPSPClk);
 369                 mm_table->entries[i].eclk = le32_to_cpu(mm_dependency_record->ulEClk);
 370                 mm_table->entries[i].vclk = le32_to_cpu(mm_dependency_record->ulVClk);
 371                 mm_table->entries[i].dclk = le32_to_cpu(mm_dependency_record->ulDClk);
 372         }
 373 
 374         *vega10_mm_table = mm_table;
 375 
 376         return 0;
 377 }
 378 
 379 static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda)
 380 {
 381         switch(line){
 382         case Vega10_I2CLineID_DDC1:
 383                 *scl = Vega10_I2C_DDC1CLK;
 384                 *sda = Vega10_I2C_DDC1DATA;
 385                 break;
 386         case Vega10_I2CLineID_DDC2:
 387                 *scl = Vega10_I2C_DDC2CLK;
 388                 *sda = Vega10_I2C_DDC2DATA;
 389                 break;
 390         case Vega10_I2CLineID_DDC3:
 391                 *scl = Vega10_I2C_DDC3CLK;
 392                 *sda = Vega10_I2C_DDC3DATA;
 393                 break;
 394         case Vega10_I2CLineID_DDC4:
 395                 *scl = Vega10_I2C_DDC4CLK;
 396                 *sda = Vega10_I2C_DDC4DATA;
 397                 break;
 398         case Vega10_I2CLineID_DDC5:
 399                 *scl = Vega10_I2C_DDC5CLK;
 400                 *sda = Vega10_I2C_DDC5DATA;
 401                 break;
 402         case Vega10_I2CLineID_DDC6:
 403                 *scl = Vega10_I2C_DDC6CLK;
 404                 *sda = Vega10_I2C_DDC6DATA;
 405                 break;
 406         case Vega10_I2CLineID_SCLSDA:
 407                 *scl = Vega10_I2C_SCL;
 408                 *sda = Vega10_I2C_SDA;
 409                 break;
 410         case Vega10_I2CLineID_DDCVGA:
 411                 *scl = Vega10_I2C_DDCVGACLK;
 412                 *sda = Vega10_I2C_DDCVGADATA;
 413                 break;
 414         default:
 415                 *scl = 0;
 416                 *sda = 0;
 417                 break;
 418         }
 419 }
 420 
 421 static int get_tdp_table(
 422                 struct pp_hwmgr *hwmgr,
 423                 struct phm_tdp_table **info_tdp_table,
 424                 const Vega10_PPTable_Generic_SubTable_Header *table)
 425 {
 426         uint32_t table_size;
 427         struct phm_tdp_table *tdp_table;
 428         uint8_t scl;
 429         uint8_t sda;
 430         const ATOM_Vega10_PowerTune_Table *power_tune_table;
 431         const ATOM_Vega10_PowerTune_Table_V2 *power_tune_table_v2;
 432         const ATOM_Vega10_PowerTune_Table_V3 *power_tune_table_v3;
 433 
 434         table_size = sizeof(uint32_t) + sizeof(struct phm_tdp_table);
 435 
 436         tdp_table = kzalloc(table_size, GFP_KERNEL);
 437 
 438         if (!tdp_table)
 439                 return -ENOMEM;
 440 
 441         if (table->ucRevId == 5) {
 442                 power_tune_table = (ATOM_Vega10_PowerTune_Table *)table;
 443                 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table->usSocketPowerLimit);
 444                 tdp_table->usTDC = le16_to_cpu(power_tune_table->usTdcLimit);
 445                 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table->usEdcLimit);
 446                 tdp_table->usSoftwareShutdownTemp =
 447                                 le16_to_cpu(power_tune_table->usSoftwareShutdownTemp);
 448                 tdp_table->usTemperatureLimitTedge =
 449                                 le16_to_cpu(power_tune_table->usTemperatureLimitTedge);
 450                 tdp_table->usTemperatureLimitHotspot =
 451                                 le16_to_cpu(power_tune_table->usTemperatureLimitHotSpot);
 452                 tdp_table->usTemperatureLimitLiquid1 =
 453                                 le16_to_cpu(power_tune_table->usTemperatureLimitLiquid1);
 454                 tdp_table->usTemperatureLimitLiquid2 =
 455                                 le16_to_cpu(power_tune_table->usTemperatureLimitLiquid2);
 456                 tdp_table->usTemperatureLimitHBM =
 457                                 le16_to_cpu(power_tune_table->usTemperatureLimitHBM);
 458                 tdp_table->usTemperatureLimitVrVddc =
 459                                 le16_to_cpu(power_tune_table->usTemperatureLimitVrSoc);
 460                 tdp_table->usTemperatureLimitVrMvdd =
 461                                 le16_to_cpu(power_tune_table->usTemperatureLimitVrMem);
 462                 tdp_table->usTemperatureLimitPlx =
 463                                 le16_to_cpu(power_tune_table->usTemperatureLimitPlx);
 464                 tdp_table->ucLiquid1_I2C_address = power_tune_table->ucLiquid1_I2C_address;
 465                 tdp_table->ucLiquid2_I2C_address = power_tune_table->ucLiquid2_I2C_address;
 466                 tdp_table->ucLiquid_I2C_Line = power_tune_table->ucLiquid_I2C_LineSCL;
 467                 tdp_table->ucLiquid_I2C_LineSDA = power_tune_table->ucLiquid_I2C_LineSDA;
 468                 tdp_table->ucVr_I2C_address = power_tune_table->ucVr_I2C_address;
 469                 tdp_table->ucVr_I2C_Line = power_tune_table->ucVr_I2C_LineSCL;
 470                 tdp_table->ucVr_I2C_LineSDA = power_tune_table->ucVr_I2C_LineSDA;
 471                 tdp_table->ucPlx_I2C_address = power_tune_table->ucPlx_I2C_address;
 472                 tdp_table->ucPlx_I2C_Line = power_tune_table->ucPlx_I2C_LineSCL;
 473                 tdp_table->ucPlx_I2C_LineSDA = power_tune_table->ucPlx_I2C_LineSDA;
 474                 hwmgr->platform_descriptor.LoadLineSlope = le16_to_cpu(power_tune_table->usLoadLineResistance);
 475         } else if (table->ucRevId == 6) {
 476                 power_tune_table_v2 = (ATOM_Vega10_PowerTune_Table_V2 *)table;
 477                 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table_v2->usSocketPowerLimit);
 478                 tdp_table->usTDC = le16_to_cpu(power_tune_table_v2->usTdcLimit);
 479                 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table_v2->usEdcLimit);
 480                 tdp_table->usSoftwareShutdownTemp =
 481                                 le16_to_cpu(power_tune_table_v2->usSoftwareShutdownTemp);
 482                 tdp_table->usTemperatureLimitTedge =
 483                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitTedge);
 484                 tdp_table->usTemperatureLimitHotspot =
 485                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitHotSpot);
 486                 tdp_table->usTemperatureLimitLiquid1 =
 487                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid1);
 488                 tdp_table->usTemperatureLimitLiquid2 =
 489                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid2);
 490                 tdp_table->usTemperatureLimitHBM =
 491                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitHBM);
 492                 tdp_table->usTemperatureLimitVrVddc =
 493                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrSoc);
 494                 tdp_table->usTemperatureLimitVrMvdd =
 495                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrMem);
 496                 tdp_table->usTemperatureLimitPlx =
 497                                 le16_to_cpu(power_tune_table_v2->usTemperatureLimitPlx);
 498                 tdp_table->ucLiquid1_I2C_address = power_tune_table_v2->ucLiquid1_I2C_address;
 499                 tdp_table->ucLiquid2_I2C_address = power_tune_table_v2->ucLiquid2_I2C_address;
 500 
 501                 get_scl_sda_value(power_tune_table_v2->ucLiquid_I2C_Line, &scl, &sda);
 502 
 503                 tdp_table->ucLiquid_I2C_Line = scl;
 504                 tdp_table->ucLiquid_I2C_LineSDA = sda;
 505 
 506                 tdp_table->ucVr_I2C_address = power_tune_table_v2->ucVr_I2C_address;
 507 
 508                 get_scl_sda_value(power_tune_table_v2->ucVr_I2C_Line, &scl, &sda);
 509 
 510                 tdp_table->ucVr_I2C_Line = scl;
 511                 tdp_table->ucVr_I2C_LineSDA = sda;
 512                 tdp_table->ucPlx_I2C_address = power_tune_table_v2->ucPlx_I2C_address;
 513 
 514                 get_scl_sda_value(power_tune_table_v2->ucPlx_I2C_Line, &scl, &sda);
 515 
 516                 tdp_table->ucPlx_I2C_Line = scl;
 517                 tdp_table->ucPlx_I2C_LineSDA = sda;
 518 
 519                 hwmgr->platform_descriptor.LoadLineSlope =
 520                                         le16_to_cpu(power_tune_table_v2->usLoadLineResistance);
 521         } else {
 522                 power_tune_table_v3 = (ATOM_Vega10_PowerTune_Table_V3 *)table;
 523                 tdp_table->usMaximumPowerDeliveryLimit   = le16_to_cpu(power_tune_table_v3->usSocketPowerLimit);
 524                 tdp_table->usTDC                         = le16_to_cpu(power_tune_table_v3->usTdcLimit);
 525                 tdp_table->usEDCLimit                    = le16_to_cpu(power_tune_table_v3->usEdcLimit);
 526                 tdp_table->usSoftwareShutdownTemp        = le16_to_cpu(power_tune_table_v3->usSoftwareShutdownTemp);
 527                 tdp_table->usTemperatureLimitTedge       = le16_to_cpu(power_tune_table_v3->usTemperatureLimitTedge);
 528                 tdp_table->usTemperatureLimitHotspot     = le16_to_cpu(power_tune_table_v3->usTemperatureLimitHotSpot);
 529                 tdp_table->usTemperatureLimitLiquid1     = le16_to_cpu(power_tune_table_v3->usTemperatureLimitLiquid1);
 530                 tdp_table->usTemperatureLimitLiquid2     = le16_to_cpu(power_tune_table_v3->usTemperatureLimitLiquid2);
 531                 tdp_table->usTemperatureLimitHBM         = le16_to_cpu(power_tune_table_v3->usTemperatureLimitHBM);
 532                 tdp_table->usTemperatureLimitVrVddc      = le16_to_cpu(power_tune_table_v3->usTemperatureLimitVrSoc);
 533                 tdp_table->usTemperatureLimitVrMvdd      = le16_to_cpu(power_tune_table_v3->usTemperatureLimitVrMem);
 534                 tdp_table->usTemperatureLimitPlx         = le16_to_cpu(power_tune_table_v3->usTemperatureLimitPlx);
 535                 tdp_table->ucLiquid1_I2C_address         = power_tune_table_v3->ucLiquid1_I2C_address;
 536                 tdp_table->ucLiquid2_I2C_address         = power_tune_table_v3->ucLiquid2_I2C_address;
 537                 tdp_table->usBoostStartTemperature       = le16_to_cpu(power_tune_table_v3->usBoostStartTemperature);
 538                 tdp_table->usBoostStopTemperature        = le16_to_cpu(power_tune_table_v3->usBoostStopTemperature);
 539                 tdp_table->ulBoostClock                  = le32_to_cpu(power_tune_table_v3->ulBoostClock);
 540 
 541                 get_scl_sda_value(power_tune_table_v3->ucLiquid_I2C_Line, &scl, &sda);
 542 
 543                 tdp_table->ucLiquid_I2C_Line             = scl;
 544                 tdp_table->ucLiquid_I2C_LineSDA          = sda;
 545 
 546                 tdp_table->ucVr_I2C_address              = power_tune_table_v3->ucVr_I2C_address;
 547 
 548                 get_scl_sda_value(power_tune_table_v3->ucVr_I2C_Line, &scl, &sda);
 549 
 550                 tdp_table->ucVr_I2C_Line                 = scl;
 551                 tdp_table->ucVr_I2C_LineSDA              = sda;
 552 
 553                 tdp_table->ucPlx_I2C_address             = power_tune_table_v3->ucPlx_I2C_address;
 554 
 555                 get_scl_sda_value(power_tune_table_v3->ucPlx_I2C_Line, &scl, &sda);
 556 
 557                 tdp_table->ucPlx_I2C_Line                = scl;
 558                 tdp_table->ucPlx_I2C_LineSDA             = sda;
 559 
 560                 hwmgr->platform_descriptor.LoadLineSlope =
 561                                         le16_to_cpu(power_tune_table_v3->usLoadLineResistance);
 562         }
 563 
 564         *info_tdp_table = tdp_table;
 565 
 566         return 0;
 567 }
 568 
 569 static int get_socclk_voltage_dependency_table(
 570                 struct pp_hwmgr *hwmgr,
 571                 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_clk_dep_table,
 572                 const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table)
 573 {
 574         uint32_t table_size, i;
 575         phm_ppt_v1_clock_voltage_dependency_table *clk_table;
 576 
 577         PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries,
 578                 "Invalid PowerPlay Table!", return -1);
 579 
 580         table_size = sizeof(uint32_t) +
 581                         sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
 582                         clk_dep_table->ucNumEntries;
 583 
 584         clk_table = kzalloc(table_size, GFP_KERNEL);
 585 
 586         if (!clk_table)
 587                 return -ENOMEM;
 588 
 589         clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;
 590 
 591         for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
 592                 clk_table->entries[i].vddInd =
 593                                 clk_dep_table->entries[i].ucVddInd;
 594                 clk_table->entries[i].clk =
 595                                 le32_to_cpu(clk_dep_table->entries[i].ulClk);
 596         }
 597 
 598         *pp_vega10_clk_dep_table = clk_table;
 599 
 600         return 0;
 601 }
 602 
 603 static int get_mclk_voltage_dependency_table(
 604                 struct pp_hwmgr *hwmgr,
 605                 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_mclk_dep_table,
 606                 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table)
 607 {
 608         uint32_t table_size, i;
 609         phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
 610 
 611         PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries,
 612                 "Invalid PowerPlay Table!", return -1);
 613 
 614         table_size = sizeof(uint32_t) +
 615                         sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
 616                         mclk_dep_table->ucNumEntries;
 617 
 618         mclk_table = kzalloc(table_size, GFP_KERNEL);
 619 
 620         if (!mclk_table)
 621                 return -ENOMEM;
 622 
 623         mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
 624 
 625         for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
 626                 mclk_table->entries[i].vddInd =
 627                                 mclk_dep_table->entries[i].ucVddInd;
 628                 mclk_table->entries[i].vddciInd =
 629                                 mclk_dep_table->entries[i].ucVddciInd;
 630                 mclk_table->entries[i].mvddInd =
 631                                 mclk_dep_table->entries[i].ucVddMemInd;
 632                 mclk_table->entries[i].clk =
 633                                 le32_to_cpu(mclk_dep_table->entries[i].ulMemClk);
 634         }
 635 
 636         *pp_vega10_mclk_dep_table = mclk_table;
 637 
 638         return 0;
 639 }
 640 
 641 static int get_gfxclk_voltage_dependency_table(
 642                 struct pp_hwmgr *hwmgr,
 643                 struct phm_ppt_v1_clock_voltage_dependency_table
 644                         **pp_vega10_clk_dep_table,
 645                 const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table)
 646 {
 647         uint32_t table_size, i;
 648         struct phm_ppt_v1_clock_voltage_dependency_table
 649                                 *clk_table;
 650         ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
 651 
 652         PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
 653                         "Invalid PowerPlay Table!", return -1);
 654 
 655         table_size = sizeof(uint32_t) +
 656                         sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
 657                         clk_dep_table->ucNumEntries;
 658 
 659         clk_table = kzalloc(table_size, GFP_KERNEL);
 660 
 661         if (!clk_table)
 662                 return -ENOMEM;
 663 
 664         clk_table->count = clk_dep_table->ucNumEntries;
 665 
 666         if (clk_dep_table->ucRevId == 0) {
 667                 for (i = 0; i < clk_table->count; i++) {
 668                         clk_table->entries[i].vddInd =
 669                                 clk_dep_table->entries[i].ucVddInd;
 670                         clk_table->entries[i].clk =
 671                                 le32_to_cpu(clk_dep_table->entries[i].ulClk);
 672                         clk_table->entries[i].cks_enable =
 673                                 (((le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x8000)
 674                                                 >> 15) == 0) ? 1 : 0;
 675                         clk_table->entries[i].cks_voffset =
 676                                 le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x7F;
 677                         clk_table->entries[i].sclk_offset =
 678                                 le16_to_cpu(clk_dep_table->entries[i].usAVFSOffset);
 679                 }
 680         } else if (clk_dep_table->ucRevId == 1) {
 681                 patom_record_v2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)clk_dep_table->entries;
 682                 for (i = 0; i < clk_table->count; i++) {
 683                         clk_table->entries[i].vddInd =
 684                                         patom_record_v2->ucVddInd;
 685                         clk_table->entries[i].clk =
 686                                         le32_to_cpu(patom_record_v2->ulClk);
 687                         clk_table->entries[i].cks_enable =
 688                                         (((le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x8000)
 689                                                         >> 15) == 0) ? 1 : 0;
 690                         clk_table->entries[i].cks_voffset =
 691                                         le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x7F;
 692                         clk_table->entries[i].sclk_offset =
 693                                         le16_to_cpu(patom_record_v2->usAVFSOffset);
 694                         patom_record_v2++;
 695                 }
 696         } else {
 697                 kfree(clk_table);
 698                 PP_ASSERT_WITH_CODE(false,
 699                         "Unsupported GFXClockDependencyTable Revision!",
 700                         return -EINVAL);
 701         }
 702 
 703         *pp_vega10_clk_dep_table = clk_table;
 704 
 705         return 0;
 706 }
 707 
 708 static int get_pix_clk_voltage_dependency_table(
 709                 struct pp_hwmgr *hwmgr,
 710                 struct phm_ppt_v1_clock_voltage_dependency_table
 711                         **pp_vega10_clk_dep_table,
 712                 const  ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table)
 713 {
 714         uint32_t table_size, i;
 715         struct phm_ppt_v1_clock_voltage_dependency_table
 716                                 *clk_table;
 717 
 718         PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
 719                         "Invalid PowerPlay Table!", return -1);
 720 
 721         table_size = sizeof(uint32_t) +
 722                         sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
 723                         clk_dep_table->ucNumEntries;
 724 
 725         clk_table = kzalloc(table_size, GFP_KERNEL);
 726 
 727         if (!clk_table)
 728                 return -ENOMEM;
 729 
 730         clk_table->count = clk_dep_table->ucNumEntries;
 731 
 732         for (i = 0; i < clk_table->count; i++) {
 733                 clk_table->entries[i].vddInd =
 734                                 clk_dep_table->entries[i].ucVddInd;
 735                 clk_table->entries[i].clk =
 736                                 le32_to_cpu(clk_dep_table->entries[i].ulClk);
 737         }
 738 
 739         *pp_vega10_clk_dep_table = clk_table;
 740 
 741         return 0;
 742 }
 743 
 744 static int get_dcefclk_voltage_dependency_table(
 745                 struct pp_hwmgr *hwmgr,
 746                 struct phm_ppt_v1_clock_voltage_dependency_table
 747                         **pp_vega10_clk_dep_table,
 748                 const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
 749 {
 750         uint32_t table_size, i;
 751         uint8_t num_entries;
 752         struct phm_ppt_v1_clock_voltage_dependency_table
 753                                 *clk_table;
 754         uint32_t dev_id;
 755         uint32_t rev_id;
 756         struct amdgpu_device *adev = hwmgr->adev;
 757 
 758         PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
 759                         "Invalid PowerPlay Table!", return -1);
 760 
 761 /*
 762  * workaround needed to add another DPM level for pioneer cards
 763  * as VBIOS is locked down.
 764  * This DPM level was added to support 3DPM monitors @ 4K120Hz
 765  *
 766  */
 767         dev_id = adev->pdev->device;
 768         rev_id = adev->pdev->revision;
 769 
 770         if (dev_id == 0x6863 && rev_id == 0 &&
 771                 clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk < 90000)
 772                 num_entries = clk_dep_table->ucNumEntries + 1 > NUM_DSPCLK_LEVELS ?
 773                                 NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries + 1;
 774         else
 775                 num_entries = clk_dep_table->ucNumEntries;
 776 
 777 
 778         table_size = sizeof(uint32_t) +
 779                         sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
 780                         num_entries;
 781 
 782         clk_table = kzalloc(table_size, GFP_KERNEL);
 783 
 784         if (!clk_table)
 785                 return -ENOMEM;
 786 
 787         clk_table->count = (uint32_t)num_entries;
 788 
 789         for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
 790                 clk_table->entries[i].vddInd =
 791                                 clk_dep_table->entries[i].ucVddInd;
 792                 clk_table->entries[i].clk =
 793                                 le32_to_cpu(clk_dep_table->entries[i].ulClk);
 794         }
 795 
 796         if (i < num_entries) {
 797                 clk_table->entries[i].vddInd = clk_dep_table->entries[i-1].ucVddInd;
 798                 clk_table->entries[i].clk = 90000;
 799         }
 800 
 801         *pp_vega10_clk_dep_table = clk_table;
 802 
 803         return 0;
 804 }
 805 
 806 static int get_pcie_table(struct pp_hwmgr *hwmgr,
 807                 struct phm_ppt_v1_pcie_table **vega10_pcie_table,
 808                 const Vega10_PPTable_Generic_SubTable_Header *table)
 809 {
 810         uint32_t table_size, i, pcie_count;
 811         struct phm_ppt_v1_pcie_table *pcie_table;
 812         struct phm_ppt_v2_information *table_info =
 813                         (struct phm_ppt_v2_information *)(hwmgr->pptable);
 814         const ATOM_Vega10_PCIE_Table *atom_pcie_table =
 815                         (ATOM_Vega10_PCIE_Table *)table;
 816 
 817         PP_ASSERT_WITH_CODE(atom_pcie_table->ucNumEntries,
 818                         "Invalid PowerPlay Table!",
 819                         return 0);
 820 
 821         table_size = sizeof(uint32_t) +
 822                         sizeof(struct phm_ppt_v1_pcie_record) *
 823                         atom_pcie_table->ucNumEntries;
 824 
 825         pcie_table = kzalloc(table_size, GFP_KERNEL);
 826 
 827         if (!pcie_table)
 828                 return -ENOMEM;
 829 
 830         pcie_count = table_info->vdd_dep_on_sclk->count;
 831         if (atom_pcie_table->ucNumEntries <= pcie_count)
 832                 pcie_count = atom_pcie_table->ucNumEntries;
 833         else
 834                 pr_info("Number of Pcie Entries exceed the number of"
 835                                 " GFXCLK Dpm Levels!"
 836                                 " Disregarding the excess entries...\n");
 837 
 838         pcie_table->count = pcie_count;
 839 
 840         for (i = 0; i < pcie_count; i++) {
 841                 pcie_table->entries[i].gen_speed =
 842                                 atom_pcie_table->entries[i].ucPCIEGenSpeed;
 843                 pcie_table->entries[i].lane_width =
 844                                 atom_pcie_table->entries[i].ucPCIELaneWidth;
 845                 pcie_table->entries[i].pcie_sclk =
 846                                 atom_pcie_table->entries[i].ulLCLK;
 847         }
 848 
 849         *vega10_pcie_table = pcie_table;
 850 
 851         return 0;
 852 }
 853 
 854 static int get_hard_limits(
 855                 struct pp_hwmgr *hwmgr,
 856                 struct phm_clock_and_voltage_limits *limits,
 857                 const ATOM_Vega10_Hard_Limit_Table *limit_table)
 858 {
 859         PP_ASSERT_WITH_CODE(limit_table->ucNumEntries,
 860                         "Invalid PowerPlay Table!", return -1);
 861 
 862         /* currently we always take entries[0] parameters */
 863         limits->sclk = le32_to_cpu(limit_table->entries[0].ulSOCCLKLimit);
 864         limits->mclk = le32_to_cpu(limit_table->entries[0].ulMCLKLimit);
 865         limits->gfxclk = le32_to_cpu(limit_table->entries[0].ulGFXCLKLimit);
 866         limits->vddc = le16_to_cpu(limit_table->entries[0].usVddcLimit);
 867         limits->vddci = le16_to_cpu(limit_table->entries[0].usVddciLimit);
 868         limits->vddmem = le16_to_cpu(limit_table->entries[0].usVddMemLimit);
 869 
 870         return 0;
 871 }
 872 
 873 static int get_valid_clk(
 874                 struct pp_hwmgr *hwmgr,
 875                 struct phm_clock_array **clk_table,
 876                 const phm_ppt_v1_clock_voltage_dependency_table *clk_volt_pp_table)
 877 {
 878         uint32_t table_size, i;
 879         struct phm_clock_array *table;
 880 
 881         PP_ASSERT_WITH_CODE(clk_volt_pp_table->count,
 882                         "Invalid PowerPlay Table!", return -1);
 883 
 884         table_size = sizeof(uint32_t) +
 885                         sizeof(uint32_t) * clk_volt_pp_table->count;
 886 
 887         table = kzalloc(table_size, GFP_KERNEL);
 888 
 889         if (!table)
 890                 return -ENOMEM;
 891 
 892         table->count = (uint32_t)clk_volt_pp_table->count;
 893 
 894         for (i = 0; i < table->count; i++)
 895                 table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk;
 896 
 897         *clk_table = table;
 898 
 899         return 0;
 900 }
 901 
 902 static int init_powerplay_extended_tables(
 903                 struct pp_hwmgr *hwmgr,
 904                 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
 905 {
 906         int result = 0;
 907         struct phm_ppt_v2_information *pp_table_info =
 908                 (struct phm_ppt_v2_information *)(hwmgr->pptable);
 909 
 910         const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table =
 911                         (const ATOM_Vega10_MM_Dependency_Table *)
 912                         (((unsigned long) powerplay_table) +
 913                         le16_to_cpu(powerplay_table->usMMDependencyTableOffset));
 914         const Vega10_PPTable_Generic_SubTable_Header *power_tune_table =
 915                         (const Vega10_PPTable_Generic_SubTable_Header *)
 916                         (((unsigned long) powerplay_table) +
 917                         le16_to_cpu(powerplay_table->usPowerTuneTableOffset));
 918         const ATOM_Vega10_SOCCLK_Dependency_Table *socclk_dep_table =
 919                         (const ATOM_Vega10_SOCCLK_Dependency_Table *)
 920                         (((unsigned long) powerplay_table) +
 921                         le16_to_cpu(powerplay_table->usSocclkDependencyTableOffset));
 922         const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
 923                         (const ATOM_Vega10_GFXCLK_Dependency_Table *)
 924                         (((unsigned long) powerplay_table) +
 925                         le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
 926         const ATOM_Vega10_DCEFCLK_Dependency_Table *dcefclk_dep_table =
 927                         (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
 928                         (((unsigned long) powerplay_table) +
 929                         le16_to_cpu(powerplay_table->usDcefclkDependencyTableOffset));
 930         const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table =
 931                         (const ATOM_Vega10_MCLK_Dependency_Table *)
 932                         (((unsigned long) powerplay_table) +
 933                         le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
 934         const ATOM_Vega10_Hard_Limit_Table *hard_limits =
 935                         (const ATOM_Vega10_Hard_Limit_Table *)
 936                         (((unsigned long) powerplay_table) +
 937                         le16_to_cpu(powerplay_table->usHardLimitTableOffset));
 938         const Vega10_PPTable_Generic_SubTable_Header *pcie_table =
 939                         (const Vega10_PPTable_Generic_SubTable_Header *)
 940                         (((unsigned long) powerplay_table) +
 941                         le16_to_cpu(powerplay_table->usPCIETableOffset));
 942         const ATOM_Vega10_PIXCLK_Dependency_Table *pixclk_dep_table =
 943                         (const ATOM_Vega10_PIXCLK_Dependency_Table *)
 944                         (((unsigned long) powerplay_table) +
 945                         le16_to_cpu(powerplay_table->usPixclkDependencyTableOffset));
 946         const ATOM_Vega10_PHYCLK_Dependency_Table *phyclk_dep_table =
 947                         (const ATOM_Vega10_PHYCLK_Dependency_Table *)
 948                         (((unsigned long) powerplay_table) +
 949                         le16_to_cpu(powerplay_table->usPhyClkDependencyTableOffset));
 950         const ATOM_Vega10_DISPCLK_Dependency_Table *dispclk_dep_table =
 951                         (const ATOM_Vega10_DISPCLK_Dependency_Table *)
 952                         (((unsigned long) powerplay_table) +
 953                         le16_to_cpu(powerplay_table->usDispClkDependencyTableOffset));
 954 
 955         pp_table_info->vdd_dep_on_socclk = NULL;
 956         pp_table_info->vdd_dep_on_sclk = NULL;
 957         pp_table_info->vdd_dep_on_mclk = NULL;
 958         pp_table_info->vdd_dep_on_dcefclk = NULL;
 959         pp_table_info->mm_dep_table = NULL;
 960         pp_table_info->tdp_table = NULL;
 961         pp_table_info->vdd_dep_on_pixclk = NULL;
 962         pp_table_info->vdd_dep_on_phyclk = NULL;
 963         pp_table_info->vdd_dep_on_dispclk = NULL;
 964 
 965         if (powerplay_table->usMMDependencyTableOffset)
 966                 result = get_mm_clock_voltage_table(hwmgr,
 967                                 &pp_table_info->mm_dep_table,
 968                                 mm_dependency_table);
 969 
 970         if (!result && powerplay_table->usPowerTuneTableOffset)
 971                 result = get_tdp_table(hwmgr,
 972                                 &pp_table_info->tdp_table,
 973                                 power_tune_table);
 974 
 975         if (!result && powerplay_table->usSocclkDependencyTableOffset)
 976                 result = get_socclk_voltage_dependency_table(hwmgr,
 977                                 &pp_table_info->vdd_dep_on_socclk,
 978                                 socclk_dep_table);
 979 
 980         if (!result && powerplay_table->usGfxclkDependencyTableOffset)
 981                 result = get_gfxclk_voltage_dependency_table(hwmgr,
 982                                 &pp_table_info->vdd_dep_on_sclk,
 983                                 gfxclk_dep_table);
 984 
 985         if (!result && powerplay_table->usPixclkDependencyTableOffset)
 986                 result = get_pix_clk_voltage_dependency_table(hwmgr,
 987                                 &pp_table_info->vdd_dep_on_pixclk,
 988                                 (const ATOM_Vega10_PIXCLK_Dependency_Table*)
 989                                 pixclk_dep_table);
 990 
 991         if (!result && powerplay_table->usPhyClkDependencyTableOffset)
 992                 result = get_pix_clk_voltage_dependency_table(hwmgr,
 993                                 &pp_table_info->vdd_dep_on_phyclk,
 994                                 (const ATOM_Vega10_PIXCLK_Dependency_Table *)
 995                                 phyclk_dep_table);
 996 
 997         if (!result && powerplay_table->usDispClkDependencyTableOffset)
 998                 result = get_pix_clk_voltage_dependency_table(hwmgr,
 999                                 &pp_table_info->vdd_dep_on_dispclk,
1000                                 (const ATOM_Vega10_PIXCLK_Dependency_Table *)
1001                                 dispclk_dep_table);
1002 
1003         if (!result && powerplay_table->usDcefclkDependencyTableOffset)
1004                 result = get_dcefclk_voltage_dependency_table(hwmgr,
1005                                 &pp_table_info->vdd_dep_on_dcefclk,
1006                                 dcefclk_dep_table);
1007 
1008         if (!result && powerplay_table->usMclkDependencyTableOffset)
1009                 result = get_mclk_voltage_dependency_table(hwmgr,
1010                                 &pp_table_info->vdd_dep_on_mclk,
1011                                 mclk_dep_table);
1012 
1013         if (!result && powerplay_table->usPCIETableOffset)
1014                 result = get_pcie_table(hwmgr,
1015                                 &pp_table_info->pcie_table,
1016                                 pcie_table);
1017 
1018         if (!result && powerplay_table->usHardLimitTableOffset)
1019                 result = get_hard_limits(hwmgr,
1020                                 &pp_table_info->max_clock_voltage_on_dc,
1021                                 hard_limits);
1022 
1023         hwmgr->dyn_state.max_clock_voltage_on_dc.sclk =
1024                         pp_table_info->max_clock_voltage_on_dc.sclk;
1025         hwmgr->dyn_state.max_clock_voltage_on_dc.mclk =
1026                         pp_table_info->max_clock_voltage_on_dc.mclk;
1027         hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
1028                         pp_table_info->max_clock_voltage_on_dc.vddc;
1029         hwmgr->dyn_state.max_clock_voltage_on_dc.vddci =
1030                         pp_table_info->max_clock_voltage_on_dc.vddci;
1031 
1032         if (!result &&
1033                 pp_table_info->vdd_dep_on_socclk &&
1034                 pp_table_info->vdd_dep_on_socclk->count)
1035                 result = get_valid_clk(hwmgr,
1036                                 &pp_table_info->valid_socclk_values,
1037                                 pp_table_info->vdd_dep_on_socclk);
1038 
1039         if (!result &&
1040                 pp_table_info->vdd_dep_on_sclk &&
1041                 pp_table_info->vdd_dep_on_sclk->count)
1042                 result = get_valid_clk(hwmgr,
1043                                 &pp_table_info->valid_sclk_values,
1044                                 pp_table_info->vdd_dep_on_sclk);
1045 
1046         if (!result &&
1047                 pp_table_info->vdd_dep_on_dcefclk &&
1048                 pp_table_info->vdd_dep_on_dcefclk->count)
1049                 result = get_valid_clk(hwmgr,
1050                                 &pp_table_info->valid_dcefclk_values,
1051                                 pp_table_info->vdd_dep_on_dcefclk);
1052 
1053         if (!result &&
1054                 pp_table_info->vdd_dep_on_mclk &&
1055                 pp_table_info->vdd_dep_on_mclk->count)
1056                 result = get_valid_clk(hwmgr,
1057                                 &pp_table_info->valid_mclk_values,
1058                                 pp_table_info->vdd_dep_on_mclk);
1059 
1060         return result;
1061 }
1062 
1063 static int get_vddc_lookup_table(
1064                 struct pp_hwmgr *hwmgr,
1065                 phm_ppt_v1_voltage_lookup_table **lookup_table,
1066                 const ATOM_Vega10_Voltage_Lookup_Table *vddc_lookup_pp_tables,
1067                 uint32_t max_levels)
1068 {
1069         uint32_t table_size, i;
1070         phm_ppt_v1_voltage_lookup_table *table;
1071 
1072         PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0),
1073                         "Invalid SOC_VDDD Lookup Table!", return 1);
1074 
1075         table_size = sizeof(uint32_t) +
1076                         sizeof(phm_ppt_v1_voltage_lookup_record) * max_levels;
1077 
1078         table = kzalloc(table_size, GFP_KERNEL);
1079 
1080         if (table == NULL)
1081                 return -ENOMEM;
1082 
1083         table->count = vddc_lookup_pp_tables->ucNumEntries;
1084 
1085         for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++)
1086                 table->entries[i].us_vdd =
1087                                 le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd);
1088 
1089         *lookup_table = table;
1090 
1091         return 0;
1092 }
1093 
1094 static int init_dpm_2_parameters(
1095                 struct pp_hwmgr *hwmgr,
1096                 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
1097 {
1098         int result = 0;
1099         struct phm_ppt_v2_information *pp_table_info =
1100                         (struct phm_ppt_v2_information *)(hwmgr->pptable);
1101         uint32_t disable_power_control = 0;
1102 
1103         pp_table_info->us_ulv_voltage_offset =
1104                 le16_to_cpu(powerplay_table->usUlvVoltageOffset);
1105 
1106         pp_table_info->us_ulv_smnclk_did =
1107                         le16_to_cpu(powerplay_table->usUlvSmnclkDid);
1108         pp_table_info->us_ulv_mp1clk_did =
1109                         le16_to_cpu(powerplay_table->usUlvMp1clkDid);
1110         pp_table_info->us_ulv_gfxclk_bypass =
1111                         le16_to_cpu(powerplay_table->usUlvGfxclkBypass);
1112         pp_table_info->us_gfxclk_slew_rate =
1113                         le16_to_cpu(powerplay_table->usGfxclkSlewRate);
1114         pp_table_info->uc_gfx_dpm_voltage_mode  =
1115                         le16_to_cpu(powerplay_table->ucGfxVoltageMode);
1116         pp_table_info->uc_soc_dpm_voltage_mode  =
1117                         le16_to_cpu(powerplay_table->ucSocVoltageMode);
1118         pp_table_info->uc_uclk_dpm_voltage_mode =
1119                         le16_to_cpu(powerplay_table->ucUclkVoltageMode);
1120         pp_table_info->uc_uvd_dpm_voltage_mode  =
1121                         le16_to_cpu(powerplay_table->ucUvdVoltageMode);
1122         pp_table_info->uc_vce_dpm_voltage_mode  =
1123                         le16_to_cpu(powerplay_table->ucVceVoltageMode);
1124         pp_table_info->uc_mp0_dpm_voltage_mode  =
1125                         le16_to_cpu(powerplay_table->ucMp0VoltageMode);
1126         pp_table_info->uc_dcef_dpm_voltage_mode =
1127                         le16_to_cpu(powerplay_table->ucDcefVoltageMode);
1128 
1129         pp_table_info->ppm_parameter_table = NULL;
1130         pp_table_info->vddc_lookup_table = NULL;
1131         pp_table_info->vddmem_lookup_table = NULL;
1132         pp_table_info->vddci_lookup_table = NULL;
1133 
1134         /* TDP limits */
1135         hwmgr->platform_descriptor.TDPODLimit =
1136                 le16_to_cpu(powerplay_table->usPowerControlLimit);
1137         hwmgr->platform_descriptor.TDPAdjustment = 0;
1138         hwmgr->platform_descriptor.VidAdjustment = 0;
1139         hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
1140         hwmgr->platform_descriptor.VidMinLimit = 0;
1141         hwmgr->platform_descriptor.VidMaxLimit = 1500000;
1142         hwmgr->platform_descriptor.VidStep = 6250;
1143 
1144         disable_power_control = 0;
1145         if (!disable_power_control) {
1146                 /* enable TDP overdrive (PowerControl) feature as well if supported */
1147                 if (hwmgr->platform_descriptor.TDPODLimit)
1148                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
1149                         PHM_PlatformCaps_PowerControl);
1150         }
1151 
1152         if (powerplay_table->usVddcLookupTableOffset) {
1153                 const ATOM_Vega10_Voltage_Lookup_Table *vddc_table =
1154                                 (ATOM_Vega10_Voltage_Lookup_Table *)
1155                                 (((unsigned long)powerplay_table) +
1156                                 le16_to_cpu(powerplay_table->usVddcLookupTableOffset));
1157                 result = get_vddc_lookup_table(hwmgr,
1158                                 &pp_table_info->vddc_lookup_table, vddc_table, 8);
1159         }
1160 
1161         if (powerplay_table->usVddmemLookupTableOffset) {
1162                 const ATOM_Vega10_Voltage_Lookup_Table *vdd_mem_table =
1163                                 (ATOM_Vega10_Voltage_Lookup_Table *)
1164                                 (((unsigned long)powerplay_table) +
1165                                 le16_to_cpu(powerplay_table->usVddmemLookupTableOffset));
1166                 result = get_vddc_lookup_table(hwmgr,
1167                                 &pp_table_info->vddmem_lookup_table, vdd_mem_table, 4);
1168         }
1169 
1170         if (powerplay_table->usVddciLookupTableOffset) {
1171                 const ATOM_Vega10_Voltage_Lookup_Table *vddci_table =
1172                                 (ATOM_Vega10_Voltage_Lookup_Table *)
1173                                 (((unsigned long)powerplay_table) +
1174                                 le16_to_cpu(powerplay_table->usVddciLookupTableOffset));
1175                 result = get_vddc_lookup_table(hwmgr,
1176                                 &pp_table_info->vddci_lookup_table, vddci_table, 4);
1177         }
1178 
1179         return result;
1180 }
1181 
1182 int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr)
1183 {
1184         int result = 0;
1185         const ATOM_Vega10_POWERPLAYTABLE *powerplay_table;
1186 
1187         hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL);
1188 
1189         PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL),
1190                             "Failed to allocate hwmgr->pptable!", return -ENOMEM);
1191 
1192         powerplay_table = get_powerplay_table(hwmgr);
1193 
1194         PP_ASSERT_WITH_CODE((powerplay_table != NULL),
1195                 "Missing PowerPlay Table!", return -1);
1196 
1197         result = check_powerplay_tables(hwmgr, powerplay_table);
1198 
1199         PP_ASSERT_WITH_CODE((result == 0),
1200                             "check_powerplay_tables failed", return result);
1201 
1202         result = set_platform_caps(hwmgr,
1203                                    le32_to_cpu(powerplay_table->ulPlatformCaps));
1204 
1205         PP_ASSERT_WITH_CODE((result == 0),
1206                             "set_platform_caps failed", return result);
1207 
1208         result = init_thermal_controller(hwmgr, powerplay_table);
1209 
1210         PP_ASSERT_WITH_CODE((result == 0),
1211                             "init_thermal_controller failed", return result);
1212 
1213         result = init_over_drive_limits(hwmgr, powerplay_table);
1214 
1215         PP_ASSERT_WITH_CODE((result == 0),
1216                             "init_over_drive_limits failed", return result);
1217 
1218         result = init_powerplay_extended_tables(hwmgr, powerplay_table);
1219 
1220         PP_ASSERT_WITH_CODE((result == 0),
1221                             "init_powerplay_extended_tables failed", return result);
1222 
1223         result = init_dpm_2_parameters(hwmgr, powerplay_table);
1224 
1225         PP_ASSERT_WITH_CODE((result == 0),
1226                             "init_dpm_2_parameters failed", return result);
1227 
1228         return result;
1229 }
1230 
1231 static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
1232 {
1233         struct phm_ppt_v2_information *pp_table_info =
1234                         (struct phm_ppt_v2_information *)(hwmgr->pptable);
1235 
1236         kfree(pp_table_info->vdd_dep_on_sclk);
1237         pp_table_info->vdd_dep_on_sclk = NULL;
1238 
1239         kfree(pp_table_info->vdd_dep_on_mclk);
1240         pp_table_info->vdd_dep_on_mclk = NULL;
1241 
1242         kfree(pp_table_info->valid_mclk_values);
1243         pp_table_info->valid_mclk_values = NULL;
1244 
1245         kfree(pp_table_info->valid_sclk_values);
1246         pp_table_info->valid_sclk_values = NULL;
1247 
1248         kfree(pp_table_info->vddc_lookup_table);
1249         pp_table_info->vddc_lookup_table = NULL;
1250 
1251         kfree(pp_table_info->vddmem_lookup_table);
1252         pp_table_info->vddmem_lookup_table = NULL;
1253 
1254         kfree(pp_table_info->vddci_lookup_table);
1255         pp_table_info->vddci_lookup_table = NULL;
1256 
1257         kfree(pp_table_info->ppm_parameter_table);
1258         pp_table_info->ppm_parameter_table = NULL;
1259 
1260         kfree(pp_table_info->mm_dep_table);
1261         pp_table_info->mm_dep_table = NULL;
1262 
1263         kfree(pp_table_info->cac_dtp_table);
1264         pp_table_info->cac_dtp_table = NULL;
1265 
1266         kfree(hwmgr->dyn_state.cac_dtp_table);
1267         hwmgr->dyn_state.cac_dtp_table = NULL;
1268 
1269         kfree(pp_table_info->tdp_table);
1270         pp_table_info->tdp_table = NULL;
1271 
1272         kfree(hwmgr->pptable);
1273         hwmgr->pptable = NULL;
1274 
1275         return 0;
1276 }
1277 
1278 const struct pp_table_func vega10_pptable_funcs = {
1279         .pptable_init = vega10_pp_tables_initialize,
1280         .pptable_fini = vega10_pp_tables_uninitialize,
1281 };
1282 
1283 int vega10_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr)
1284 {
1285         const ATOM_Vega10_State_Array *state_arrays;
1286         const ATOM_Vega10_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
1287 
1288         PP_ASSERT_WITH_CODE((pp_table != NULL),
1289                         "Missing PowerPlay Table!", return -1);
1290         PP_ASSERT_WITH_CODE((pp_table->sHeader.format_revision >=
1291                         ATOM_Vega10_TABLE_REVISION_VEGA10),
1292                         "Incorrect PowerPlay table revision!", return -1);
1293 
1294         state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)pp_table) +
1295                         le16_to_cpu(pp_table->usStateArrayOffset));
1296 
1297         return (uint32_t)(state_arrays->ucNumEntries);
1298 }
1299 
1300 static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
1301                 uint16_t classification, uint16_t classification2)
1302 {
1303         uint32_t result = 0;
1304 
1305         if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
1306                 result |= PP_StateClassificationFlag_Boot;
1307 
1308         if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1309                 result |= PP_StateClassificationFlag_Thermal;
1310 
1311         if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
1312                 result |= PP_StateClassificationFlag_LimitedPowerSource;
1313 
1314         if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
1315                 result |= PP_StateClassificationFlag_Rest;
1316 
1317         if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
1318                 result |= PP_StateClassificationFlag_Forced;
1319 
1320         if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
1321                 result |= PP_StateClassificationFlag_ACPI;
1322 
1323         if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
1324                 result |= PP_StateClassificationFlag_LimitedPowerSource_2;
1325 
1326         return result;
1327 }
1328 
1329 int vega10_get_powerplay_table_entry(struct pp_hwmgr *hwmgr,
1330                 uint32_t entry_index, struct pp_power_state *power_state,
1331                 int (*call_back_func)(struct pp_hwmgr *, void *,
1332                                 struct pp_power_state *, void *, uint32_t))
1333 {
1334         int result = 0;
1335         const ATOM_Vega10_State_Array *state_arrays;
1336         const ATOM_Vega10_State *state_entry;
1337         const ATOM_Vega10_POWERPLAYTABLE *pp_table =
1338                         get_powerplay_table(hwmgr);
1339 
1340         PP_ASSERT_WITH_CODE(pp_table, "Missing PowerPlay Table!",
1341                         return -1;);
1342         power_state->classification.bios_index = entry_index;
1343 
1344         if (pp_table->sHeader.format_revision >=
1345                         ATOM_Vega10_TABLE_REVISION_VEGA10) {
1346                 state_arrays = (ATOM_Vega10_State_Array *)
1347                                 (((unsigned long)pp_table) +
1348                                 le16_to_cpu(pp_table->usStateArrayOffset));
1349 
1350                 PP_ASSERT_WITH_CODE(pp_table->usStateArrayOffset > 0,
1351                                 "Invalid PowerPlay Table State Array Offset.",
1352                                 return -1);
1353                 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
1354                                 "Invalid PowerPlay Table State Array.",
1355                                 return -1);
1356                 PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
1357                                 "Invalid PowerPlay Table State Array Entry.",
1358                                 return -1);
1359 
1360                 state_entry = &(state_arrays->states[entry_index]);
1361 
1362                 result = call_back_func(hwmgr, (void *)state_entry, power_state,
1363                                 (void *)pp_table,
1364                                 make_classification_flags(hwmgr,
1365                                         le16_to_cpu(state_entry->usClassification),
1366                                         le16_to_cpu(state_entry->usClassification2)));
1367         }
1368 
1369         if (!result && (power_state->classification.flags &
1370                         PP_StateClassificationFlag_Boot))
1371                 result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));
1372 
1373         return result;
1374 }
1375 
1376 int vega10_baco_set_cap(struct pp_hwmgr *hwmgr)
1377 {
1378         int result = 0;
1379 
1380         const ATOM_Vega10_POWERPLAYTABLE *powerplay_table;
1381 
1382         powerplay_table = get_powerplay_table(hwmgr);
1383 
1384         PP_ASSERT_WITH_CODE((powerplay_table != NULL),
1385                 "Missing PowerPlay Table!", return -1);
1386 
1387         result = check_powerplay_tables(hwmgr, powerplay_table);
1388 
1389         PP_ASSERT_WITH_CODE((result == 0),
1390                             "check_powerplay_tables failed", return result);
1391 
1392         set_hw_cap(
1393                         hwmgr,
1394                         0 != (le32_to_cpu(powerplay_table->ulPlatformCaps) & ATOM_VEGA10_PP_PLATFORM_CAP_BACO),
1395                         PHM_PlatformCaps_BACO);
1396         return result;
1397 }
1398 

/* [<][>][^][v][top][bottom][index][help] */