2 * Copyright 2016 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
23 #include <linux/module.h>
24 #include <linux/slab.h>
27 #include "vega10_processpptables.h"
28 #include "ppatomfwctrl.h"
29 #include "atomfirmware.h"
31 #include "cgs_common.h"
32 #include "vega10_pptable.h"
34 static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
35 enum phm_platform_caps cap)
38 phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
40 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
43 static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
45 int index = GetIndexIntoMasterDataTable(powerplayinfo);
49 const void *table_address = hwmgr->soft_pp_table;
52 table_address = (ATOM_Vega10_POWERPLAYTABLE *)
53 cgs_atom_get_data_table(hwmgr->device, index,
56 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/
62 static int check_powerplay_tables(
63 struct pp_hwmgr *hwmgr,
64 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
66 const ATOM_Vega10_State_Array *state_arrays;
68 state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)powerplay_table) +
69 le16_to_cpu(powerplay_table->usStateArrayOffset));
71 PP_ASSERT_WITH_CODE((powerplay_table->sHeader.format_revision >=
72 ATOM_Vega10_TABLE_REVISION_VEGA10),
73 "Unsupported PPTable format!", return -1);
74 PP_ASSERT_WITH_CODE(powerplay_table->usStateArrayOffset,
75 "State table is not set!", return -1);
76 PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
77 "Invalid PowerPlay Table!", return -1);
78 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
79 "Invalid PowerPlay Table!", return -1);
84 static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
88 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_POWERPLAY),
89 PHM_PlatformCaps_PowerPlaySupport);
93 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
94 PHM_PlatformCaps_BiosPowerSourceControl);
98 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_HARDWAREDC),
99 PHM_PlatformCaps_AutomaticDCTransition);
103 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_BACO),
104 PHM_PlatformCaps_BACO);
108 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL),
109 PHM_PlatformCaps_CombinePCCWithThermalSignal);
114 static int init_thermal_controller(
115 struct pp_hwmgr *hwmgr,
116 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
118 const ATOM_Vega10_Thermal_Controller *thermal_controller;
119 const Vega10_PPTable_Generic_SubTable_Header *header;
120 const ATOM_Vega10_Fan_Table *fan_table_v1;
121 const ATOM_Vega10_Fan_Table_V2 *fan_table_v2;
123 thermal_controller = (ATOM_Vega10_Thermal_Controller *)
124 (((unsigned long)powerplay_table) +
125 le16_to_cpu(powerplay_table->usThermalControllerOffset));
127 PP_ASSERT_WITH_CODE((powerplay_table->usThermalControllerOffset != 0),
128 "Thermal controller table not set!", return -EINVAL);
130 hwmgr->thermal_controller.ucType = thermal_controller->ucType;
131 hwmgr->thermal_controller.ucI2cLine = thermal_controller->ucI2cLine;
132 hwmgr->thermal_controller.ucI2cAddress = thermal_controller->ucI2cAddress;
134 hwmgr->thermal_controller.fanInfo.bNoFan =
135 (0 != (thermal_controller->ucFanParameters &
136 ATOM_VEGA10_PP_FANPARAMETERS_NOFAN));
138 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
139 thermal_controller->ucFanParameters &
140 ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
142 hwmgr->thermal_controller.fanInfo.ulMinRPM =
143 thermal_controller->ucFanMinRPM * 100UL;
144 hwmgr->thermal_controller.fanInfo.ulMaxRPM =
145 thermal_controller->ucFanMaxRPM * 100UL;
147 hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay
152 ATOM_VEGA10_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
153 PHM_PlatformCaps_ThermalController);
155 if (!powerplay_table->usFanTableOffset)
158 header = (const Vega10_PPTable_Generic_SubTable_Header *)
159 (((unsigned long)powerplay_table) +
160 le16_to_cpu(powerplay_table->usFanTableOffset));
162 if (header->ucRevId == 10) {
163 fan_table_v1 = (ATOM_Vega10_Fan_Table *)header;
165 PP_ASSERT_WITH_CODE((fan_table_v1->ucRevId >= 8),
166 "Invalid Input Fan Table!", return -EINVAL);
168 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
169 PHM_PlatformCaps_MicrocodeFanControl);
171 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
172 le16_to_cpu(fan_table_v1->usFanOutputSensitivity);
173 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
174 le16_to_cpu(fan_table_v1->usFanRPMMax);
175 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit =
176 le16_to_cpu(fan_table_v1->usThrottlingRPM);
177 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit =
178 le16_to_cpu(fan_table_v1->usFanAcousticLimit);
179 hwmgr->thermal_controller.advanceFanControlParameters.usTMax =
180 le16_to_cpu(fan_table_v1->usTargetTemperature);
181 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin =
182 le16_to_cpu(fan_table_v1->usMinimumPWMLimit);
183 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk =
184 le16_to_cpu(fan_table_v1->usTargetGfxClk);
185 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge =
186 le16_to_cpu(fan_table_v1->usFanGainEdge);
187 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot =
188 le16_to_cpu(fan_table_v1->usFanGainHotspot);
189 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid =
190 le16_to_cpu(fan_table_v1->usFanGainLiquid);
191 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc =
192 le16_to_cpu(fan_table_v1->usFanGainVrVddc);
193 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd =
194 le16_to_cpu(fan_table_v1->usFanGainVrMvdd);
195 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx =
196 le16_to_cpu(fan_table_v1->usFanGainPlx);
197 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm =
198 le16_to_cpu(fan_table_v1->usFanGainHbm);
200 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM =
201 fan_table_v1->ucEnableZeroRPM;
202 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature =
203 le16_to_cpu(fan_table_v1->usFanStopTemperature);
204 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature =
205 le16_to_cpu(fan_table_v1->usFanStartTemperature);
206 } else if (header->ucRevId > 10) {
207 fan_table_v2 = (ATOM_Vega10_Fan_Table_V2 *)header;
209 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
210 fan_table_v2->ucFanParameters & ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
211 hwmgr->thermal_controller.fanInfo.ulMinRPM = fan_table_v2->ucFanMinRPM * 100UL;
212 hwmgr->thermal_controller.fanInfo.ulMaxRPM = fan_table_v2->ucFanMaxRPM * 100UL;
214 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
215 PHM_PlatformCaps_MicrocodeFanControl);
217 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
218 le16_to_cpu(fan_table_v2->usFanOutputSensitivity);
219 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
220 fan_table_v2->ucFanMaxRPM * 100UL;
221 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit =
222 le16_to_cpu(fan_table_v2->usThrottlingRPM);
223 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit =
224 le16_to_cpu(fan_table_v2->usFanAcousticLimitRpm);
225 hwmgr->thermal_controller.advanceFanControlParameters.usTMax =
226 le16_to_cpu(fan_table_v2->usTargetTemperature);
227 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin =
228 le16_to_cpu(fan_table_v2->usMinimumPWMLimit);
229 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk =
230 le16_to_cpu(fan_table_v2->usTargetGfxClk);
231 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge =
232 le16_to_cpu(fan_table_v2->usFanGainEdge);
233 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot =
234 le16_to_cpu(fan_table_v2->usFanGainHotspot);
235 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid =
236 le16_to_cpu(fan_table_v2->usFanGainLiquid);
237 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc =
238 le16_to_cpu(fan_table_v2->usFanGainVrVddc);
239 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd =
240 le16_to_cpu(fan_table_v2->usFanGainVrMvdd);
241 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx =
242 le16_to_cpu(fan_table_v2->usFanGainPlx);
243 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm =
244 le16_to_cpu(fan_table_v2->usFanGainHbm);
246 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM =
247 fan_table_v2->ucEnableZeroRPM;
248 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature =
249 le16_to_cpu(fan_table_v2->usFanStopTemperature);
250 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature =
251 le16_to_cpu(fan_table_v2->usFanStartTemperature);
256 static int init_over_drive_limits(
257 struct pp_hwmgr *hwmgr,
258 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
260 hwmgr->platform_descriptor.overdriveLimit.engineClock =
261 le32_to_cpu(powerplay_table->ulMaxODEngineClock);
262 hwmgr->platform_descriptor.overdriveLimit.memoryClock =
263 le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
265 hwmgr->platform_descriptor.minOverdriveVDDC = 0;
266 hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
267 hwmgr->platform_descriptor.overdriveVDDCStep = 0;
269 if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0 &&
270 hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0) {
271 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
272 PHM_PlatformCaps_ACOverdriveSupport);
278 static int get_mm_clock_voltage_table(
279 struct pp_hwmgr *hwmgr,
280 phm_ppt_v1_mm_clock_voltage_dependency_table **vega10_mm_table,
281 const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table)
283 uint32_t table_size, i;
284 const ATOM_Vega10_MM_Dependency_Record *mm_dependency_record;
285 phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
287 PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0),
288 "Invalid PowerPlay Table!", return -1);
290 table_size = sizeof(uint32_t) +
291 sizeof(phm_ppt_v1_mm_clock_voltage_dependency_record) *
292 mm_dependency_table->ucNumEntries;
293 mm_table = (phm_ppt_v1_mm_clock_voltage_dependency_table *)
294 kzalloc(table_size, GFP_KERNEL);
299 mm_table->count = mm_dependency_table->ucNumEntries;
301 for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
302 mm_dependency_record = &mm_dependency_table->entries[i];
303 mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
304 mm_table->entries[i].samclock =
305 le32_to_cpu(mm_dependency_record->ulPSPClk);
306 mm_table->entries[i].eclk = le32_to_cpu(mm_dependency_record->ulEClk);
307 mm_table->entries[i].vclk = le32_to_cpu(mm_dependency_record->ulVClk);
308 mm_table->entries[i].dclk = le32_to_cpu(mm_dependency_record->ulDClk);
311 *vega10_mm_table = mm_table;
316 static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda)
319 case Vega10_I2CLineID_DDC1:
320 *scl = Vega10_I2C_DDC1CLK;
321 *sda = Vega10_I2C_DDC1DATA;
323 case Vega10_I2CLineID_DDC2:
324 *scl = Vega10_I2C_DDC2CLK;
325 *sda = Vega10_I2C_DDC2DATA;
327 case Vega10_I2CLineID_DDC3:
328 *scl = Vega10_I2C_DDC3CLK;
329 *sda = Vega10_I2C_DDC3DATA;
331 case Vega10_I2CLineID_DDC4:
332 *scl = Vega10_I2C_DDC4CLK;
333 *sda = Vega10_I2C_DDC4DATA;
335 case Vega10_I2CLineID_DDC5:
336 *scl = Vega10_I2C_DDC5CLK;
337 *sda = Vega10_I2C_DDC5DATA;
339 case Vega10_I2CLineID_DDC6:
340 *scl = Vega10_I2C_DDC6CLK;
341 *sda = Vega10_I2C_DDC6DATA;
343 case Vega10_I2CLineID_SCLSDA:
344 *scl = Vega10_I2C_SCL;
345 *sda = Vega10_I2C_SDA;
347 case Vega10_I2CLineID_DDCVGA:
348 *scl = Vega10_I2C_DDCVGACLK;
349 *sda = Vega10_I2C_DDCVGADATA;
358 static int get_tdp_table(
359 struct pp_hwmgr *hwmgr,
360 struct phm_tdp_table **info_tdp_table,
361 const Vega10_PPTable_Generic_SubTable_Header *table)
364 struct phm_tdp_table *tdp_table;
367 const ATOM_Vega10_PowerTune_Table *power_tune_table;
368 const ATOM_Vega10_PowerTune_Table_V2 *power_tune_table_v2;
370 table_size = sizeof(uint32_t) + sizeof(struct phm_tdp_table);
372 tdp_table = kzalloc(table_size, GFP_KERNEL);
377 if (table->ucRevId == 5) {
378 power_tune_table = (ATOM_Vega10_PowerTune_Table *)table;
379 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table->usSocketPowerLimit);
380 tdp_table->usTDC = le16_to_cpu(power_tune_table->usTdcLimit);
381 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table->usEdcLimit);
382 tdp_table->usSoftwareShutdownTemp =
383 le16_to_cpu(power_tune_table->usSoftwareShutdownTemp);
384 tdp_table->usTemperatureLimitTedge =
385 le16_to_cpu(power_tune_table->usTemperatureLimitTedge);
386 tdp_table->usTemperatureLimitHotspot =
387 le16_to_cpu(power_tune_table->usTemperatureLimitHotSpot);
388 tdp_table->usTemperatureLimitLiquid1 =
389 le16_to_cpu(power_tune_table->usTemperatureLimitLiquid1);
390 tdp_table->usTemperatureLimitLiquid2 =
391 le16_to_cpu(power_tune_table->usTemperatureLimitLiquid2);
392 tdp_table->usTemperatureLimitHBM =
393 le16_to_cpu(power_tune_table->usTemperatureLimitHBM);
394 tdp_table->usTemperatureLimitVrVddc =
395 le16_to_cpu(power_tune_table->usTemperatureLimitVrSoc);
396 tdp_table->usTemperatureLimitVrMvdd =
397 le16_to_cpu(power_tune_table->usTemperatureLimitVrMem);
398 tdp_table->usTemperatureLimitPlx =
399 le16_to_cpu(power_tune_table->usTemperatureLimitPlx);
400 tdp_table->ucLiquid1_I2C_address = power_tune_table->ucLiquid1_I2C_address;
401 tdp_table->ucLiquid2_I2C_address = power_tune_table->ucLiquid2_I2C_address;
402 tdp_table->ucLiquid_I2C_Line = power_tune_table->ucLiquid_I2C_LineSCL;
403 tdp_table->ucLiquid_I2C_LineSDA = power_tune_table->ucLiquid_I2C_LineSDA;
404 tdp_table->ucVr_I2C_address = power_tune_table->ucVr_I2C_address;
405 tdp_table->ucVr_I2C_Line = power_tune_table->ucVr_I2C_LineSCL;
406 tdp_table->ucVr_I2C_LineSDA = power_tune_table->ucVr_I2C_LineSDA;
407 tdp_table->ucPlx_I2C_address = power_tune_table->ucPlx_I2C_address;
408 tdp_table->ucPlx_I2C_Line = power_tune_table->ucPlx_I2C_LineSCL;
409 tdp_table->ucPlx_I2C_LineSDA = power_tune_table->ucPlx_I2C_LineSDA;
410 hwmgr->platform_descriptor.LoadLineSlope = le16_to_cpu(power_tune_table->usLoadLineResistance);
412 power_tune_table_v2 = (ATOM_Vega10_PowerTune_Table_V2 *)table;
413 tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table_v2->usSocketPowerLimit);
414 tdp_table->usTDC = le16_to_cpu(power_tune_table_v2->usTdcLimit);
415 tdp_table->usEDCLimit = le16_to_cpu(power_tune_table_v2->usEdcLimit);
416 tdp_table->usSoftwareShutdownTemp =
417 le16_to_cpu(power_tune_table_v2->usSoftwareShutdownTemp);
418 tdp_table->usTemperatureLimitTedge =
419 le16_to_cpu(power_tune_table_v2->usTemperatureLimitTedge);
420 tdp_table->usTemperatureLimitHotspot =
421 le16_to_cpu(power_tune_table_v2->usTemperatureLimitHotSpot);
422 tdp_table->usTemperatureLimitLiquid1 =
423 le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid1);
424 tdp_table->usTemperatureLimitLiquid2 =
425 le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid2);
426 tdp_table->usTemperatureLimitHBM =
427 le16_to_cpu(power_tune_table_v2->usTemperatureLimitHBM);
428 tdp_table->usTemperatureLimitVrVddc =
429 le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrSoc);
430 tdp_table->usTemperatureLimitVrMvdd =
431 le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrMem);
432 tdp_table->usTemperatureLimitPlx =
433 le16_to_cpu(power_tune_table_v2->usTemperatureLimitPlx);
434 tdp_table->ucLiquid1_I2C_address = power_tune_table_v2->ucLiquid1_I2C_address;
435 tdp_table->ucLiquid2_I2C_address = power_tune_table_v2->ucLiquid2_I2C_address;
437 get_scl_sda_value(power_tune_table_v2->ucLiquid_I2C_Line, &scl, &sda);
439 tdp_table->ucLiquid_I2C_Line = scl;
440 tdp_table->ucLiquid_I2C_LineSDA = sda;
442 tdp_table->ucVr_I2C_address = power_tune_table_v2->ucVr_I2C_address;
444 get_scl_sda_value(power_tune_table_v2->ucVr_I2C_Line, &scl, &sda);
446 tdp_table->ucVr_I2C_Line = scl;
447 tdp_table->ucVr_I2C_LineSDA = sda;
448 tdp_table->ucPlx_I2C_address = power_tune_table_v2->ucPlx_I2C_address;
450 get_scl_sda_value(power_tune_table_v2->ucPlx_I2C_Line, &scl, &sda);
452 tdp_table->ucPlx_I2C_Line = scl;
453 tdp_table->ucPlx_I2C_LineSDA = sda;
455 hwmgr->platform_descriptor.LoadLineSlope =
456 le16_to_cpu(power_tune_table_v2->usLoadLineResistance);
459 *info_tdp_table = tdp_table;
464 static int get_socclk_voltage_dependency_table(
465 struct pp_hwmgr *hwmgr,
466 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_clk_dep_table,
467 const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table)
469 uint32_t table_size, i;
470 phm_ppt_v1_clock_voltage_dependency_table *clk_table;
472 PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries,
473 "Invalid PowerPlay Table!", return -1);
475 table_size = sizeof(uint32_t) +
476 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
477 clk_dep_table->ucNumEntries;
479 clk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
480 kzalloc(table_size, GFP_KERNEL);
485 clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;
487 for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
488 clk_table->entries[i].vddInd =
489 clk_dep_table->entries[i].ucVddInd;
490 clk_table->entries[i].clk =
491 le32_to_cpu(clk_dep_table->entries[i].ulClk);
494 *pp_vega10_clk_dep_table = clk_table;
499 static int get_mclk_voltage_dependency_table(
500 struct pp_hwmgr *hwmgr,
501 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_mclk_dep_table,
502 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table)
504 uint32_t table_size, i;
505 phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
507 PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries,
508 "Invalid PowerPlay Table!", return -1);
510 table_size = sizeof(uint32_t) +
511 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
512 mclk_dep_table->ucNumEntries;
514 mclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
515 kzalloc(table_size, GFP_KERNEL);
520 mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
522 for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
523 mclk_table->entries[i].vddInd =
524 mclk_dep_table->entries[i].ucVddInd;
525 mclk_table->entries[i].vddciInd =
526 mclk_dep_table->entries[i].ucVddciInd;
527 mclk_table->entries[i].mvddInd =
528 mclk_dep_table->entries[i].ucVddMemInd;
529 mclk_table->entries[i].clk =
530 le32_to_cpu(mclk_dep_table->entries[i].ulMemClk);
533 *pp_vega10_mclk_dep_table = mclk_table;
538 static int get_gfxclk_voltage_dependency_table(
539 struct pp_hwmgr *hwmgr,
540 struct phm_ppt_v1_clock_voltage_dependency_table
541 **pp_vega10_clk_dep_table,
542 const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table)
544 uint32_t table_size, i;
545 struct phm_ppt_v1_clock_voltage_dependency_table
548 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
549 "Invalid PowerPlay Table!", return -1);
551 table_size = sizeof(uint32_t) +
552 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
553 clk_dep_table->ucNumEntries;
555 clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)
556 kzalloc(table_size, GFP_KERNEL);
561 clk_table->count = clk_dep_table->ucNumEntries;
563 for (i = 0; i < clk_table->count; i++) {
564 clk_table->entries[i].vddInd =
565 clk_dep_table->entries[i].ucVddInd;
566 clk_table->entries[i].clk =
567 le32_to_cpu(clk_dep_table->entries[i].ulClk);
568 clk_table->entries[i].cks_enable =
569 (((clk_dep_table->entries[i].usCKSVOffsetandDisable & 0x80)
570 >> 15) == 0) ? 1 : 0;
571 clk_table->entries[i].cks_voffset =
572 (clk_dep_table->entries[i].usCKSVOffsetandDisable & 0x7F);
573 clk_table->entries[i].sclk_offset =
574 clk_dep_table->entries[i].usAVFSOffset;
577 *pp_vega10_clk_dep_table = clk_table;
582 static int get_dcefclk_voltage_dependency_table(
583 struct pp_hwmgr *hwmgr,
584 struct phm_ppt_v1_clock_voltage_dependency_table
585 **pp_vega10_clk_dep_table,
586 const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
588 uint32_t table_size, i;
589 struct phm_ppt_v1_clock_voltage_dependency_table
592 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
593 "Invalid PowerPlay Table!", return -1);
595 table_size = sizeof(uint32_t) +
596 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
597 clk_dep_table->ucNumEntries;
599 clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)
600 kzalloc(table_size, GFP_KERNEL);
605 clk_table->count = clk_dep_table->ucNumEntries;
607 for (i = 0; i < clk_table->count; i++) {
608 clk_table->entries[i].vddInd =
609 clk_dep_table->entries[i].ucVddInd;
610 clk_table->entries[i].clk =
611 le32_to_cpu(clk_dep_table->entries[i].ulClk);
614 *pp_vega10_clk_dep_table = clk_table;
619 static int get_pcie_table(struct pp_hwmgr *hwmgr,
620 struct phm_ppt_v1_pcie_table **vega10_pcie_table,
621 const Vega10_PPTable_Generic_SubTable_Header *table)
623 uint32_t table_size, i, pcie_count;
624 struct phm_ppt_v1_pcie_table *pcie_table;
625 struct phm_ppt_v2_information *table_info =
626 (struct phm_ppt_v2_information *)(hwmgr->pptable);
627 const ATOM_Vega10_PCIE_Table *atom_pcie_table =
628 (ATOM_Vega10_PCIE_Table *)table;
630 PP_ASSERT_WITH_CODE(atom_pcie_table->ucNumEntries,
631 "Invalid PowerPlay Table!",
634 table_size = sizeof(uint32_t) +
635 sizeof(struct phm_ppt_v1_pcie_record) *
636 atom_pcie_table->ucNumEntries;
638 pcie_table = (struct phm_ppt_v1_pcie_table *)
639 kzalloc(table_size, GFP_KERNEL);
644 pcie_count = table_info->vdd_dep_on_sclk->count;
645 if (atom_pcie_table->ucNumEntries <= pcie_count)
646 pcie_count = atom_pcie_table->ucNumEntries;
648 pr_info("Number of Pcie Entries exceed the number of"
649 " GFXCLK Dpm Levels!"
650 " Disregarding the excess entries...\n");
652 pcie_table->count = pcie_count;
654 for (i = 0; i < pcie_count; i++) {
655 pcie_table->entries[i].gen_speed =
656 atom_pcie_table->entries[i].ucPCIEGenSpeed;
657 pcie_table->entries[i].lane_width =
658 atom_pcie_table->entries[i].ucPCIELaneWidth;
659 pcie_table->entries[i].pcie_sclk =
660 atom_pcie_table->entries[i].ulLCLK;
663 *vega10_pcie_table = pcie_table;
668 static int get_hard_limits(
669 struct pp_hwmgr *hwmgr,
670 struct phm_clock_and_voltage_limits *limits,
671 const ATOM_Vega10_Hard_Limit_Table *limit_table)
673 PP_ASSERT_WITH_CODE(limit_table->ucNumEntries,
674 "Invalid PowerPlay Table!", return -1);
676 /* currently we always take entries[0] parameters */
677 limits->sclk = le32_to_cpu(limit_table->entries[0].ulSOCCLKLimit);
678 limits->mclk = le32_to_cpu(limit_table->entries[0].ulMCLKLimit);
679 limits->gfxclk = le32_to_cpu(limit_table->entries[0].ulGFXCLKLimit);
680 limits->vddc = le16_to_cpu(limit_table->entries[0].usVddcLimit);
681 limits->vddci = le16_to_cpu(limit_table->entries[0].usVddciLimit);
682 limits->vddmem = le16_to_cpu(limit_table->entries[0].usVddMemLimit);
687 static int get_valid_clk(
688 struct pp_hwmgr *hwmgr,
689 struct phm_clock_array **clk_table,
690 const phm_ppt_v1_clock_voltage_dependency_table *clk_volt_pp_table)
692 uint32_t table_size, i;
693 struct phm_clock_array *table;
695 PP_ASSERT_WITH_CODE(clk_volt_pp_table->count,
696 "Invalid PowerPlay Table!", return -1);
698 table_size = sizeof(uint32_t) +
699 sizeof(uint32_t) * clk_volt_pp_table->count;
701 table = kzalloc(table_size, GFP_KERNEL);
706 table->count = (uint32_t)clk_volt_pp_table->count;
708 for (i = 0; i < table->count; i++)
709 table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk;
716 static int init_powerplay_extended_tables(
717 struct pp_hwmgr *hwmgr,
718 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
721 struct phm_ppt_v2_information *pp_table_info =
722 (struct phm_ppt_v2_information *)(hwmgr->pptable);
724 const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table =
725 (const ATOM_Vega10_MM_Dependency_Table *)
726 (((unsigned long) powerplay_table) +
727 le16_to_cpu(powerplay_table->usMMDependencyTableOffset));
728 const Vega10_PPTable_Generic_SubTable_Header *power_tune_table =
729 (const Vega10_PPTable_Generic_SubTable_Header *)
730 (((unsigned long) powerplay_table) +
731 le16_to_cpu(powerplay_table->usPowerTuneTableOffset));
732 const ATOM_Vega10_SOCCLK_Dependency_Table *socclk_dep_table =
733 (const ATOM_Vega10_SOCCLK_Dependency_Table *)
734 (((unsigned long) powerplay_table) +
735 le16_to_cpu(powerplay_table->usSocclkDependencyTableOffset));
736 const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
737 (const ATOM_Vega10_GFXCLK_Dependency_Table *)
738 (((unsigned long) powerplay_table) +
739 le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
740 const ATOM_Vega10_DCEFCLK_Dependency_Table *dcefclk_dep_table =
741 (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
742 (((unsigned long) powerplay_table) +
743 le16_to_cpu(powerplay_table->usDcefclkDependencyTableOffset));
744 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table =
745 (const ATOM_Vega10_MCLK_Dependency_Table *)
746 (((unsigned long) powerplay_table) +
747 le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
748 const ATOM_Vega10_Hard_Limit_Table *hard_limits =
749 (const ATOM_Vega10_Hard_Limit_Table *)
750 (((unsigned long) powerplay_table) +
751 le16_to_cpu(powerplay_table->usHardLimitTableOffset));
752 const Vega10_PPTable_Generic_SubTable_Header *pcie_table =
753 (const Vega10_PPTable_Generic_SubTable_Header *)
754 (((unsigned long) powerplay_table) +
755 le16_to_cpu(powerplay_table->usPCIETableOffset));
756 const ATOM_Vega10_PIXCLK_Dependency_Table *pixclk_dep_table =
757 (const ATOM_Vega10_PIXCLK_Dependency_Table *)
758 (((unsigned long) powerplay_table) +
759 le16_to_cpu(powerplay_table->usPixclkDependencyTableOffset));
760 const ATOM_Vega10_PHYCLK_Dependency_Table *phyclk_dep_table =
761 (const ATOM_Vega10_PHYCLK_Dependency_Table *)
762 (((unsigned long) powerplay_table) +
763 le16_to_cpu(powerplay_table->usPhyClkDependencyTableOffset));
764 const ATOM_Vega10_DISPCLK_Dependency_Table *dispclk_dep_table =
765 (const ATOM_Vega10_DISPCLK_Dependency_Table *)
766 (((unsigned long) powerplay_table) +
767 le16_to_cpu(powerplay_table->usDispClkDependencyTableOffset));
769 pp_table_info->vdd_dep_on_socclk = NULL;
770 pp_table_info->vdd_dep_on_sclk = NULL;
771 pp_table_info->vdd_dep_on_mclk = NULL;
772 pp_table_info->vdd_dep_on_dcefclk = NULL;
773 pp_table_info->mm_dep_table = NULL;
774 pp_table_info->tdp_table = NULL;
775 pp_table_info->vdd_dep_on_pixclk = NULL;
776 pp_table_info->vdd_dep_on_phyclk = NULL;
777 pp_table_info->vdd_dep_on_dispclk = NULL;
779 if (powerplay_table->usMMDependencyTableOffset)
780 result = get_mm_clock_voltage_table(hwmgr,
781 &pp_table_info->mm_dep_table,
782 mm_dependency_table);
784 if (!result && powerplay_table->usPowerTuneTableOffset)
785 result = get_tdp_table(hwmgr,
786 &pp_table_info->tdp_table,
789 if (!result && powerplay_table->usSocclkDependencyTableOffset)
790 result = get_socclk_voltage_dependency_table(hwmgr,
791 &pp_table_info->vdd_dep_on_socclk,
794 if (!result && powerplay_table->usGfxclkDependencyTableOffset)
795 result = get_gfxclk_voltage_dependency_table(hwmgr,
796 &pp_table_info->vdd_dep_on_sclk,
799 if (!result && powerplay_table->usPixclkDependencyTableOffset)
800 result = get_dcefclk_voltage_dependency_table(hwmgr,
801 &pp_table_info->vdd_dep_on_pixclk,
802 (const ATOM_Vega10_DCEFCLK_Dependency_Table*)
805 if (!result && powerplay_table->usPhyClkDependencyTableOffset)
806 result = get_dcefclk_voltage_dependency_table(hwmgr,
807 &pp_table_info->vdd_dep_on_phyclk,
808 (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
811 if (!result && powerplay_table->usDispClkDependencyTableOffset)
812 result = get_dcefclk_voltage_dependency_table(hwmgr,
813 &pp_table_info->vdd_dep_on_dispclk,
814 (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
817 if (!result && powerplay_table->usDcefclkDependencyTableOffset)
818 result = get_dcefclk_voltage_dependency_table(hwmgr,
819 &pp_table_info->vdd_dep_on_dcefclk,
822 if (!result && powerplay_table->usMclkDependencyTableOffset)
823 result = get_mclk_voltage_dependency_table(hwmgr,
824 &pp_table_info->vdd_dep_on_mclk,
827 if (!result && powerplay_table->usPCIETableOffset)
828 result = get_pcie_table(hwmgr,
829 &pp_table_info->pcie_table,
832 if (!result && powerplay_table->usHardLimitTableOffset)
833 result = get_hard_limits(hwmgr,
834 &pp_table_info->max_clock_voltage_on_dc,
837 hwmgr->dyn_state.max_clock_voltage_on_dc.sclk =
838 pp_table_info->max_clock_voltage_on_dc.sclk;
839 hwmgr->dyn_state.max_clock_voltage_on_dc.mclk =
840 pp_table_info->max_clock_voltage_on_dc.mclk;
841 hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
842 pp_table_info->max_clock_voltage_on_dc.vddc;
843 hwmgr->dyn_state.max_clock_voltage_on_dc.vddci =
844 pp_table_info->max_clock_voltage_on_dc.vddci;
847 pp_table_info->vdd_dep_on_socclk &&
848 pp_table_info->vdd_dep_on_socclk->count)
849 result = get_valid_clk(hwmgr,
850 &pp_table_info->valid_socclk_values,
851 pp_table_info->vdd_dep_on_socclk);
854 pp_table_info->vdd_dep_on_sclk &&
855 pp_table_info->vdd_dep_on_sclk->count)
856 result = get_valid_clk(hwmgr,
857 &pp_table_info->valid_sclk_values,
858 pp_table_info->vdd_dep_on_sclk);
861 pp_table_info->vdd_dep_on_dcefclk &&
862 pp_table_info->vdd_dep_on_dcefclk->count)
863 result = get_valid_clk(hwmgr,
864 &pp_table_info->valid_dcefclk_values,
865 pp_table_info->vdd_dep_on_dcefclk);
868 pp_table_info->vdd_dep_on_mclk &&
869 pp_table_info->vdd_dep_on_mclk->count)
870 result = get_valid_clk(hwmgr,
871 &pp_table_info->valid_mclk_values,
872 pp_table_info->vdd_dep_on_mclk);
877 static int get_vddc_lookup_table(
878 struct pp_hwmgr *hwmgr,
879 phm_ppt_v1_voltage_lookup_table **lookup_table,
880 const ATOM_Vega10_Voltage_Lookup_Table *vddc_lookup_pp_tables,
883 uint32_t table_size, i;
884 phm_ppt_v1_voltage_lookup_table *table;
886 PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0),
887 "Invalid SOC_VDDD Lookup Table!", return 1);
889 table_size = sizeof(uint32_t) +
890 sizeof(phm_ppt_v1_voltage_lookup_record) * max_levels;
892 table = (phm_ppt_v1_voltage_lookup_table *)
893 kzalloc(table_size, GFP_KERNEL);
898 table->count = vddc_lookup_pp_tables->ucNumEntries;
900 for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++)
901 table->entries[i].us_vdd =
902 le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd);
904 *lookup_table = table;
909 static int init_dpm_2_parameters(
910 struct pp_hwmgr *hwmgr,
911 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
914 struct phm_ppt_v2_information *pp_table_info =
915 (struct phm_ppt_v2_information *)(hwmgr->pptable);
916 uint32_t disable_power_control = 0;
918 pp_table_info->us_ulv_voltage_offset =
919 le16_to_cpu(powerplay_table->usUlvVoltageOffset);
921 pp_table_info->us_ulv_smnclk_did =
922 le16_to_cpu(powerplay_table->usUlvSmnclkDid);
923 pp_table_info->us_ulv_mp1clk_did =
924 le16_to_cpu(powerplay_table->usUlvMp1clkDid);
925 pp_table_info->us_ulv_gfxclk_bypass =
926 le16_to_cpu(powerplay_table->usUlvGfxclkBypass);
927 pp_table_info->us_gfxclk_slew_rate =
928 le16_to_cpu(powerplay_table->usGfxclkSlewRate);
929 pp_table_info->uc_gfx_dpm_voltage_mode =
930 le16_to_cpu(powerplay_table->ucGfxVoltageMode);
931 pp_table_info->uc_soc_dpm_voltage_mode =
932 le16_to_cpu(powerplay_table->ucSocVoltageMode);
933 pp_table_info->uc_uclk_dpm_voltage_mode =
934 le16_to_cpu(powerplay_table->ucUclkVoltageMode);
935 pp_table_info->uc_uvd_dpm_voltage_mode =
936 le16_to_cpu(powerplay_table->ucUvdVoltageMode);
937 pp_table_info->uc_vce_dpm_voltage_mode =
938 le16_to_cpu(powerplay_table->ucVceVoltageMode);
939 pp_table_info->uc_mp0_dpm_voltage_mode =
940 le16_to_cpu(powerplay_table->ucMp0VoltageMode);
941 pp_table_info->uc_dcef_dpm_voltage_mode =
942 le16_to_cpu(powerplay_table->ucDcefVoltageMode);
944 pp_table_info->ppm_parameter_table = NULL;
945 pp_table_info->vddc_lookup_table = NULL;
946 pp_table_info->vddmem_lookup_table = NULL;
947 pp_table_info->vddci_lookup_table = NULL;
950 hwmgr->platform_descriptor.TDPODLimit =
951 le16_to_cpu(powerplay_table->usPowerControlLimit);
952 hwmgr->platform_descriptor.TDPAdjustment = 0;
953 hwmgr->platform_descriptor.VidAdjustment = 0;
954 hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
955 hwmgr->platform_descriptor.VidMinLimit = 0;
956 hwmgr->platform_descriptor.VidMaxLimit = 1500000;
957 hwmgr->platform_descriptor.VidStep = 6250;
959 disable_power_control = 0;
960 if (!disable_power_control) {
961 /* enable TDP overdrive (PowerControl) feature as well if supported */
962 if (hwmgr->platform_descriptor.TDPODLimit)
963 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
964 PHM_PlatformCaps_PowerControl);
967 if (powerplay_table->usVddcLookupTableOffset) {
968 const ATOM_Vega10_Voltage_Lookup_Table *vddc_table =
969 (ATOM_Vega10_Voltage_Lookup_Table *)
970 (((unsigned long)powerplay_table) +
971 le16_to_cpu(powerplay_table->usVddcLookupTableOffset));
972 result = get_vddc_lookup_table(hwmgr,
973 &pp_table_info->vddc_lookup_table, vddc_table, 8);
976 if (powerplay_table->usVddmemLookupTableOffset) {
977 const ATOM_Vega10_Voltage_Lookup_Table *vdd_mem_table =
978 (ATOM_Vega10_Voltage_Lookup_Table *)
979 (((unsigned long)powerplay_table) +
980 le16_to_cpu(powerplay_table->usVddmemLookupTableOffset));
981 result = get_vddc_lookup_table(hwmgr,
982 &pp_table_info->vddmem_lookup_table, vdd_mem_table, 4);
985 if (powerplay_table->usVddciLookupTableOffset) {
986 const ATOM_Vega10_Voltage_Lookup_Table *vddci_table =
987 (ATOM_Vega10_Voltage_Lookup_Table *)
988 (((unsigned long)powerplay_table) +
989 le16_to_cpu(powerplay_table->usVddciLookupTableOffset));
990 result = get_vddc_lookup_table(hwmgr,
991 &pp_table_info->vddci_lookup_table, vddci_table, 4);
997 int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr)
1000 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table;
1002 hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL);
1004 PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable),
1005 "Failed to allocate hwmgr->pptable!", return -ENOMEM);
1007 powerplay_table = get_powerplay_table(hwmgr);
1009 PP_ASSERT_WITH_CODE((NULL != powerplay_table),
1010 "Missing PowerPlay Table!", return -1);
1012 result = check_powerplay_tables(hwmgr, powerplay_table);
1014 PP_ASSERT_WITH_CODE((result == 0),
1015 "check_powerplay_tables failed", return result);
1017 result = set_platform_caps(hwmgr,
1018 le32_to_cpu(powerplay_table->ulPlatformCaps));
1020 PP_ASSERT_WITH_CODE((result == 0),
1021 "set_platform_caps failed", return result);
1023 result = init_thermal_controller(hwmgr, powerplay_table);
1025 PP_ASSERT_WITH_CODE((result == 0),
1026 "init_thermal_controller failed", return result);
1028 result = init_over_drive_limits(hwmgr, powerplay_table);
1030 PP_ASSERT_WITH_CODE((result == 0),
1031 "init_over_drive_limits failed", return result);
1033 result = init_powerplay_extended_tables(hwmgr, powerplay_table);
1035 PP_ASSERT_WITH_CODE((result == 0),
1036 "init_powerplay_extended_tables failed", return result);
1038 result = init_dpm_2_parameters(hwmgr, powerplay_table);
1040 PP_ASSERT_WITH_CODE((result == 0),
1041 "init_dpm_2_parameters failed", return result);
1046 static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
1049 struct phm_ppt_v2_information *pp_table_info =
1050 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1052 kfree(pp_table_info->vdd_dep_on_sclk);
1053 pp_table_info->vdd_dep_on_sclk = NULL;
1055 kfree(pp_table_info->vdd_dep_on_mclk);
1056 pp_table_info->vdd_dep_on_mclk = NULL;
1058 kfree(pp_table_info->valid_mclk_values);
1059 pp_table_info->valid_mclk_values = NULL;
1061 kfree(pp_table_info->valid_sclk_values);
1062 pp_table_info->valid_sclk_values = NULL;
1064 kfree(pp_table_info->vddc_lookup_table);
1065 pp_table_info->vddc_lookup_table = NULL;
1067 kfree(pp_table_info->vddmem_lookup_table);
1068 pp_table_info->vddmem_lookup_table = NULL;
1070 kfree(pp_table_info->vddci_lookup_table);
1071 pp_table_info->vddci_lookup_table = NULL;
1073 kfree(pp_table_info->ppm_parameter_table);
1074 pp_table_info->ppm_parameter_table = NULL;
1076 kfree(pp_table_info->mm_dep_table);
1077 pp_table_info->mm_dep_table = NULL;
1079 kfree(pp_table_info->cac_dtp_table);
1080 pp_table_info->cac_dtp_table = NULL;
1082 kfree(hwmgr->dyn_state.cac_dtp_table);
1083 hwmgr->dyn_state.cac_dtp_table = NULL;
1085 kfree(pp_table_info->tdp_table);
1086 pp_table_info->tdp_table = NULL;
1088 kfree(hwmgr->pptable);
1089 hwmgr->pptable = NULL;
1094 const struct pp_table_func vega10_pptable_funcs = {
1095 .pptable_init = vega10_pp_tables_initialize,
1096 .pptable_fini = vega10_pp_tables_uninitialize,
1099 int vega10_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr)
1101 const ATOM_Vega10_State_Array *state_arrays;
1102 const ATOM_Vega10_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
1104 PP_ASSERT_WITH_CODE((NULL != pp_table),
1105 "Missing PowerPlay Table!", return -1);
1106 PP_ASSERT_WITH_CODE((pp_table->sHeader.format_revision >=
1107 ATOM_Vega10_TABLE_REVISION_VEGA10),
1108 "Incorrect PowerPlay table revision!", return -1);
1110 state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)pp_table) +
1111 le16_to_cpu(pp_table->usStateArrayOffset));
1113 return (uint32_t)(state_arrays->ucNumEntries);
1116 static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
1117 uint16_t classification, uint16_t classification2)
1119 uint32_t result = 0;
1121 if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
1122 result |= PP_StateClassificationFlag_Boot;
1124 if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1125 result |= PP_StateClassificationFlag_Thermal;
1127 if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
1128 result |= PP_StateClassificationFlag_LimitedPowerSource;
1130 if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
1131 result |= PP_StateClassificationFlag_Rest;
1133 if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
1134 result |= PP_StateClassificationFlag_Forced;
1136 if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
1137 result |= PP_StateClassificationFlag_ACPI;
1139 if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
1140 result |= PP_StateClassificationFlag_LimitedPowerSource_2;
1145 int vega10_get_powerplay_table_entry(struct pp_hwmgr *hwmgr,
1146 uint32_t entry_index, struct pp_power_state *power_state,
1147 int (*call_back_func)(struct pp_hwmgr *, void *,
1148 struct pp_power_state *, void *, uint32_t))
1151 const ATOM_Vega10_State_Array *state_arrays;
1152 const ATOM_Vega10_State *state_entry;
1153 const ATOM_Vega10_POWERPLAYTABLE *pp_table =
1154 get_powerplay_table(hwmgr);
1156 PP_ASSERT_WITH_CODE(pp_table, "Missing PowerPlay Table!",
1158 power_state->classification.bios_index = entry_index;
1160 if (pp_table->sHeader.format_revision >=
1161 ATOM_Vega10_TABLE_REVISION_VEGA10) {
1162 state_arrays = (ATOM_Vega10_State_Array *)
1163 (((unsigned long)pp_table) +
1164 le16_to_cpu(pp_table->usStateArrayOffset));
1166 PP_ASSERT_WITH_CODE(pp_table->usStateArrayOffset > 0,
1167 "Invalid PowerPlay Table State Array Offset.",
1169 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
1170 "Invalid PowerPlay Table State Array.",
1172 PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
1173 "Invalid PowerPlay Table State Array Entry.",
1176 state_entry = &(state_arrays->states[entry_index]);
1178 result = call_back_func(hwmgr, (void *)state_entry, power_state,
1180 make_classification_flags(hwmgr,
1181 le16_to_cpu(state_entry->usClassification),
1182 le16_to_cpu(state_entry->usClassification2)));
1185 if (!result && (power_state->classification.flags &
1186 PP_StateClassificationFlag_Boot))
1187 result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));