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.*/
57 hwmgr->soft_pp_table_size = size;
63 static int check_powerplay_tables(
64 struct pp_hwmgr *hwmgr,
65 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
67 const ATOM_Vega10_State_Array *state_arrays;
69 state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)powerplay_table) +
70 le16_to_cpu(powerplay_table->usStateArrayOffset));
72 PP_ASSERT_WITH_CODE((powerplay_table->sHeader.format_revision >=
73 ATOM_Vega10_TABLE_REVISION_VEGA10),
74 "Unsupported PPTable format!", return -1);
75 PP_ASSERT_WITH_CODE(powerplay_table->usStateArrayOffset,
76 "State table is not set!", return -1);
77 PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
78 "Invalid PowerPlay Table!", return -1);
79 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
80 "Invalid PowerPlay Table!", return -1);
85 static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
89 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_POWERPLAY),
90 PHM_PlatformCaps_PowerPlaySupport);
94 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
95 PHM_PlatformCaps_BiosPowerSourceControl);
99 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_HARDWAREDC),
100 PHM_PlatformCaps_AutomaticDCTransition);
104 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_BACO),
105 PHM_PlatformCaps_BACO);
109 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL),
110 PHM_PlatformCaps_CombinePCCWithThermalSignal);
115 static int init_thermal_controller(
116 struct pp_hwmgr *hwmgr,
117 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
119 const ATOM_Vega10_Thermal_Controller *thermal_controller;
120 const Vega10_PPTable_Generic_SubTable_Header *header;
121 const ATOM_Vega10_Fan_Table *fan_table_v1;
122 const ATOM_Vega10_Fan_Table_V2 *fan_table_v2;
124 thermal_controller = (ATOM_Vega10_Thermal_Controller *)
125 (((unsigned long)powerplay_table) +
126 le16_to_cpu(powerplay_table->usThermalControllerOffset));
128 PP_ASSERT_WITH_CODE((powerplay_table->usThermalControllerOffset != 0),
129 "Thermal controller table not set!", return -EINVAL);
131 hwmgr->thermal_controller.ucType = thermal_controller->ucType;
132 hwmgr->thermal_controller.ucI2cLine = thermal_controller->ucI2cLine;
133 hwmgr->thermal_controller.ucI2cAddress = thermal_controller->ucI2cAddress;
135 hwmgr->thermal_controller.fanInfo.bNoFan =
136 (0 != (thermal_controller->ucFanParameters &
137 ATOM_VEGA10_PP_FANPARAMETERS_NOFAN));
139 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
140 thermal_controller->ucFanParameters &
141 ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
143 hwmgr->thermal_controller.fanInfo.ulMinRPM =
144 thermal_controller->ucFanMinRPM * 100UL;
145 hwmgr->thermal_controller.fanInfo.ulMaxRPM =
146 thermal_controller->ucFanMaxRPM * 100UL;
148 hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay
153 ATOM_VEGA10_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
154 PHM_PlatformCaps_ThermalController);
156 if (!powerplay_table->usFanTableOffset)
159 header = (const Vega10_PPTable_Generic_SubTable_Header *)
160 (((unsigned long)powerplay_table) +
161 le16_to_cpu(powerplay_table->usFanTableOffset));
163 if (header->ucRevId == 10) {
164 fan_table_v1 = (ATOM_Vega10_Fan_Table *)header;
166 PP_ASSERT_WITH_CODE((fan_table_v1->ucRevId >= 8),
167 "Invalid Input Fan Table!", return -EINVAL);
169 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
170 PHM_PlatformCaps_MicrocodeFanControl);
172 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
173 le16_to_cpu(fan_table_v1->usFanOutputSensitivity);
174 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
175 le16_to_cpu(fan_table_v1->usFanRPMMax);
176 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit =
177 le16_to_cpu(fan_table_v1->usThrottlingRPM);
178 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit =
179 le16_to_cpu(fan_table_v1->usFanAcousticLimit);
180 hwmgr->thermal_controller.advanceFanControlParameters.usTMax =
181 le16_to_cpu(fan_table_v1->usTargetTemperature);
182 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin =
183 le16_to_cpu(fan_table_v1->usMinimumPWMLimit);
184 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk =
185 le16_to_cpu(fan_table_v1->usTargetGfxClk);
186 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge =
187 le16_to_cpu(fan_table_v1->usFanGainEdge);
188 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot =
189 le16_to_cpu(fan_table_v1->usFanGainHotspot);
190 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid =
191 le16_to_cpu(fan_table_v1->usFanGainLiquid);
192 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc =
193 le16_to_cpu(fan_table_v1->usFanGainVrVddc);
194 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd =
195 le16_to_cpu(fan_table_v1->usFanGainVrMvdd);
196 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx =
197 le16_to_cpu(fan_table_v1->usFanGainPlx);
198 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm =
199 le16_to_cpu(fan_table_v1->usFanGainHbm);
201 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM =
202 fan_table_v1->ucEnableZeroRPM;
203 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature =
204 le16_to_cpu(fan_table_v1->usFanStopTemperature);
205 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature =
206 le16_to_cpu(fan_table_v1->usFanStartTemperature);
207 } else if (header->ucRevId > 10) {
208 fan_table_v2 = (ATOM_Vega10_Fan_Table_V2 *)header;
210 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
211 fan_table_v2->ucFanParameters & ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
212 hwmgr->thermal_controller.fanInfo.ulMinRPM = fan_table_v2->ucFanMinRPM * 100UL;
213 hwmgr->thermal_controller.fanInfo.ulMaxRPM = fan_table_v2->ucFanMaxRPM * 100UL;
214 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
215 PHM_PlatformCaps_MicrocodeFanControl);
216 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
217 le16_to_cpu(fan_table_v2->usFanOutputSensitivity);
218 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
219 fan_table_v2->ucFanMaxRPM * 100UL;
220 hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit =
221 le16_to_cpu(fan_table_v2->usThrottlingRPM);
222 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit =
223 le16_to_cpu(fan_table_v2->usFanAcousticLimitRpm);
224 hwmgr->thermal_controller.advanceFanControlParameters.usTMax =
225 le16_to_cpu(fan_table_v2->usTargetTemperature);
226 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin =
227 le16_to_cpu(fan_table_v2->usMinimumPWMLimit);
228 hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk =
229 le16_to_cpu(fan_table_v2->usTargetGfxClk);
230 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge =
231 le16_to_cpu(fan_table_v2->usFanGainEdge);
232 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot =
233 le16_to_cpu(fan_table_v2->usFanGainHotspot);
234 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid =
235 le16_to_cpu(fan_table_v2->usFanGainLiquid);
236 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc =
237 le16_to_cpu(fan_table_v2->usFanGainVrVddc);
238 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd =
239 le16_to_cpu(fan_table_v2->usFanGainVrMvdd);
240 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx =
241 le16_to_cpu(fan_table_v2->usFanGainPlx);
242 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm =
243 le16_to_cpu(fan_table_v2->usFanGainHbm);
245 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM =
246 fan_table_v2->ucEnableZeroRPM;
247 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature =
248 le16_to_cpu(fan_table_v2->usFanStopTemperature);
249 hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature =
250 le16_to_cpu(fan_table_v2->usFanStartTemperature);
255 static int init_over_drive_limits(
256 struct pp_hwmgr *hwmgr,
257 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
259 hwmgr->platform_descriptor.overdriveLimit.engineClock =
260 le32_to_cpu(powerplay_table->ulMaxODEngineClock);
261 hwmgr->platform_descriptor.overdriveLimit.memoryClock =
262 le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
264 hwmgr->platform_descriptor.minOverdriveVDDC = 0;
265 hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
266 hwmgr->platform_descriptor.overdriveVDDCStep = 0;
268 if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0 &&
269 hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0) {
270 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
271 PHM_PlatformCaps_ACOverdriveSupport);
277 static int get_mm_clock_voltage_table(
278 struct pp_hwmgr *hwmgr,
279 phm_ppt_v1_mm_clock_voltage_dependency_table **vega10_mm_table,
280 const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table)
282 uint32_t table_size, i;
283 const ATOM_Vega10_MM_Dependency_Record *mm_dependency_record;
284 phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
286 PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0),
287 "Invalid PowerPlay Table!", return -1);
289 table_size = sizeof(uint32_t) +
290 sizeof(phm_ppt_v1_mm_clock_voltage_dependency_record) *
291 mm_dependency_table->ucNumEntries;
292 mm_table = (phm_ppt_v1_mm_clock_voltage_dependency_table *)
293 kzalloc(table_size, GFP_KERNEL);
298 mm_table->count = mm_dependency_table->ucNumEntries;
300 for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
301 mm_dependency_record = &mm_dependency_table->entries[i];
302 mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
303 mm_table->entries[i].samclock =
304 le32_to_cpu(mm_dependency_record->ulPSPClk);
305 mm_table->entries[i].eclk = le32_to_cpu(mm_dependency_record->ulEClk);
306 mm_table->entries[i].vclk = le32_to_cpu(mm_dependency_record->ulVClk);
307 mm_table->entries[i].dclk = le32_to_cpu(mm_dependency_record->ulDClk);
310 *vega10_mm_table = mm_table;
315 static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda)
318 case Vega10_I2CLineID_DDC1:
319 *scl = Vega10_I2C_DDC1CLK;
320 *sda = Vega10_I2C_DDC1DATA;
322 case Vega10_I2CLineID_DDC2:
323 *scl = Vega10_I2C_DDC2CLK;
324 *sda = Vega10_I2C_DDC2DATA;
326 case Vega10_I2CLineID_DDC3:
327 *scl = Vega10_I2C_DDC3CLK;
328 *sda = Vega10_I2C_DDC3DATA;
330 case Vega10_I2CLineID_DDC4:
331 *scl = Vega10_I2C_DDC4CLK;
332 *sda = Vega10_I2C_DDC4DATA;
334 case Vega10_I2CLineID_DDC5:
335 *scl = Vega10_I2C_DDC5CLK;
336 *sda = Vega10_I2C_DDC5DATA;
338 case Vega10_I2CLineID_DDC6:
339 *scl = Vega10_I2C_DDC6CLK;
340 *sda = Vega10_I2C_DDC6DATA;
342 case Vega10_I2CLineID_SCLSDA:
343 *scl = Vega10_I2C_SCL;
344 *sda = Vega10_I2C_SDA;
346 case Vega10_I2CLineID_DDCVGA:
347 *scl = Vega10_I2C_DDCVGACLK;
348 *sda = Vega10_I2C_DDCVGADATA;
357 static int get_tdp_table(
358 struct pp_hwmgr *hwmgr,
359 struct phm_tdp_table **info_tdp_table,
360 const Vega10_PPTable_Generic_SubTable_Header *table)
363 struct phm_tdp_table *tdp_table;
366 const ATOM_Vega10_PowerTune_Table *power_tune_table;
367 const ATOM_Vega10_PowerTune_Table_V2 *power_tune_table_v2;
368 const ATOM_Vega10_PowerTune_Table_V3 *power_tune_table_v3;
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);
411 } else if (table->ucRevId == 6) {
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);
458 power_tune_table_v3 = (ATOM_Vega10_PowerTune_Table_V3 *)table;
459 tdp_table->usMaximumPowerDeliveryLimit = power_tune_table_v3->usSocketPowerLimit;
460 tdp_table->usTDC = power_tune_table_v3->usTdcLimit;
461 tdp_table->usEDCLimit = power_tune_table_v3->usEdcLimit;
462 tdp_table->usSoftwareShutdownTemp = power_tune_table_v3->usSoftwareShutdownTemp;
463 tdp_table->usTemperatureLimitTedge = power_tune_table_v3->usTemperatureLimitTedge;
464 tdp_table->usTemperatureLimitHotspot = power_tune_table_v3->usTemperatureLimitHotSpot;
465 tdp_table->usTemperatureLimitLiquid1 = power_tune_table_v3->usTemperatureLimitLiquid1;
466 tdp_table->usTemperatureLimitLiquid2 = power_tune_table_v3->usTemperatureLimitLiquid2;
467 tdp_table->usTemperatureLimitHBM = power_tune_table_v3->usTemperatureLimitHBM;
468 tdp_table->usTemperatureLimitVrVddc = power_tune_table_v3->usTemperatureLimitVrSoc;
469 tdp_table->usTemperatureLimitVrMvdd = power_tune_table_v3->usTemperatureLimitVrMem;
470 tdp_table->usTemperatureLimitPlx = power_tune_table_v3->usTemperatureLimitPlx;
471 tdp_table->ucLiquid1_I2C_address = power_tune_table_v3->ucLiquid1_I2C_address;
472 tdp_table->ucLiquid2_I2C_address = power_tune_table_v3->ucLiquid2_I2C_address;
473 tdp_table->usBoostStartTemperature = power_tune_table_v3->usBoostStartTemperature;
474 tdp_table->usBoostStopTemperature = power_tune_table_v3->usBoostStopTemperature;
475 tdp_table->ulBoostClock = power_tune_table_v3->ulBoostClock;
477 get_scl_sda_value(power_tune_table_v3->ucLiquid_I2C_Line, &scl, &sda);
479 tdp_table->ucLiquid_I2C_Line = scl;
480 tdp_table->ucLiquid_I2C_LineSDA = sda;
482 tdp_table->ucVr_I2C_address = power_tune_table_v3->ucVr_I2C_address;
484 get_scl_sda_value(power_tune_table_v3->ucVr_I2C_Line, &scl, &sda);
486 tdp_table->ucVr_I2C_Line = scl;
487 tdp_table->ucVr_I2C_LineSDA = sda;
489 tdp_table->ucPlx_I2C_address = power_tune_table_v3->ucPlx_I2C_address;
491 get_scl_sda_value(power_tune_table_v3->ucPlx_I2C_Line, &scl, &sda);
493 tdp_table->ucPlx_I2C_Line = scl;
494 tdp_table->ucPlx_I2C_LineSDA = sda;
496 hwmgr->platform_descriptor.LoadLineSlope =
497 le16_to_cpu(power_tune_table_v3->usLoadLineResistance);
500 *info_tdp_table = tdp_table;
505 static int get_socclk_voltage_dependency_table(
506 struct pp_hwmgr *hwmgr,
507 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_clk_dep_table,
508 const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table)
510 uint32_t table_size, i;
511 phm_ppt_v1_clock_voltage_dependency_table *clk_table;
513 PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries,
514 "Invalid PowerPlay Table!", return -1);
516 table_size = sizeof(uint32_t) +
517 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
518 clk_dep_table->ucNumEntries;
520 clk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
521 kzalloc(table_size, GFP_KERNEL);
526 clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;
528 for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
529 clk_table->entries[i].vddInd =
530 clk_dep_table->entries[i].ucVddInd;
531 clk_table->entries[i].clk =
532 le32_to_cpu(clk_dep_table->entries[i].ulClk);
535 *pp_vega10_clk_dep_table = clk_table;
540 static int get_mclk_voltage_dependency_table(
541 struct pp_hwmgr *hwmgr,
542 phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_mclk_dep_table,
543 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table)
545 uint32_t table_size, i;
546 phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
548 PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries,
549 "Invalid PowerPlay Table!", return -1);
551 table_size = sizeof(uint32_t) +
552 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
553 mclk_dep_table->ucNumEntries;
555 mclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
556 kzalloc(table_size, GFP_KERNEL);
561 mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
563 for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
564 mclk_table->entries[i].vddInd =
565 mclk_dep_table->entries[i].ucVddInd;
566 mclk_table->entries[i].vddciInd =
567 mclk_dep_table->entries[i].ucVddciInd;
568 mclk_table->entries[i].mvddInd =
569 mclk_dep_table->entries[i].ucVddMemInd;
570 mclk_table->entries[i].clk =
571 le32_to_cpu(mclk_dep_table->entries[i].ulMemClk);
574 *pp_vega10_mclk_dep_table = mclk_table;
579 static int get_gfxclk_voltage_dependency_table(
580 struct pp_hwmgr *hwmgr,
581 struct phm_ppt_v1_clock_voltage_dependency_table
582 **pp_vega10_clk_dep_table,
583 const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table)
585 uint32_t table_size, i;
586 struct phm_ppt_v1_clock_voltage_dependency_table
589 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
590 "Invalid PowerPlay Table!", return -1);
592 table_size = sizeof(uint32_t) +
593 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
594 clk_dep_table->ucNumEntries;
596 clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)
597 kzalloc(table_size, GFP_KERNEL);
602 clk_table->count = clk_dep_table->ucNumEntries;
604 for (i = 0; i < clk_table->count; i++) {
605 clk_table->entries[i].vddInd =
606 clk_dep_table->entries[i].ucVddInd;
607 clk_table->entries[i].clk =
608 le32_to_cpu(clk_dep_table->entries[i].ulClk);
609 clk_table->entries[i].cks_enable =
610 (((clk_dep_table->entries[i].usCKSVOffsetandDisable & 0x8000)
611 >> 15) == 0) ? 1 : 0;
612 clk_table->entries[i].cks_voffset =
613 (clk_dep_table->entries[i].usCKSVOffsetandDisable & 0x7F);
614 clk_table->entries[i].sclk_offset =
615 clk_dep_table->entries[i].usAVFSOffset;
618 *pp_vega10_clk_dep_table = clk_table;
623 static int get_dcefclk_voltage_dependency_table(
624 struct pp_hwmgr *hwmgr,
625 struct phm_ppt_v1_clock_voltage_dependency_table
626 **pp_vega10_clk_dep_table,
627 const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
629 uint32_t table_size, i;
630 struct phm_ppt_v1_clock_voltage_dependency_table
633 PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
634 "Invalid PowerPlay Table!", return -1);
636 table_size = sizeof(uint32_t) +
637 sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
638 clk_dep_table->ucNumEntries;
640 clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)
641 kzalloc(table_size, GFP_KERNEL);
646 clk_table->count = clk_dep_table->ucNumEntries;
648 for (i = 0; i < clk_table->count; i++) {
649 clk_table->entries[i].vddInd =
650 clk_dep_table->entries[i].ucVddInd;
651 clk_table->entries[i].clk =
652 le32_to_cpu(clk_dep_table->entries[i].ulClk);
655 *pp_vega10_clk_dep_table = clk_table;
660 static int get_pcie_table(struct pp_hwmgr *hwmgr,
661 struct phm_ppt_v1_pcie_table **vega10_pcie_table,
662 const Vega10_PPTable_Generic_SubTable_Header *table)
664 uint32_t table_size, i, pcie_count;
665 struct phm_ppt_v1_pcie_table *pcie_table;
666 struct phm_ppt_v2_information *table_info =
667 (struct phm_ppt_v2_information *)(hwmgr->pptable);
668 const ATOM_Vega10_PCIE_Table *atom_pcie_table =
669 (ATOM_Vega10_PCIE_Table *)table;
671 PP_ASSERT_WITH_CODE(atom_pcie_table->ucNumEntries,
672 "Invalid PowerPlay Table!",
675 table_size = sizeof(uint32_t) +
676 sizeof(struct phm_ppt_v1_pcie_record) *
677 atom_pcie_table->ucNumEntries;
679 pcie_table = (struct phm_ppt_v1_pcie_table *)
680 kzalloc(table_size, GFP_KERNEL);
685 pcie_count = table_info->vdd_dep_on_sclk->count;
686 if (atom_pcie_table->ucNumEntries <= pcie_count)
687 pcie_count = atom_pcie_table->ucNumEntries;
689 pr_info("Number of Pcie Entries exceed the number of"
690 " GFXCLK Dpm Levels!"
691 " Disregarding the excess entries...\n");
693 pcie_table->count = pcie_count;
695 for (i = 0; i < pcie_count; i++) {
696 pcie_table->entries[i].gen_speed =
697 atom_pcie_table->entries[i].ucPCIEGenSpeed;
698 pcie_table->entries[i].lane_width =
699 atom_pcie_table->entries[i].ucPCIELaneWidth;
700 pcie_table->entries[i].pcie_sclk =
701 atom_pcie_table->entries[i].ulLCLK;
704 *vega10_pcie_table = pcie_table;
709 static int get_hard_limits(
710 struct pp_hwmgr *hwmgr,
711 struct phm_clock_and_voltage_limits *limits,
712 const ATOM_Vega10_Hard_Limit_Table *limit_table)
714 PP_ASSERT_WITH_CODE(limit_table->ucNumEntries,
715 "Invalid PowerPlay Table!", return -1);
717 /* currently we always take entries[0] parameters */
718 limits->sclk = le32_to_cpu(limit_table->entries[0].ulSOCCLKLimit);
719 limits->mclk = le32_to_cpu(limit_table->entries[0].ulMCLKLimit);
720 limits->gfxclk = le32_to_cpu(limit_table->entries[0].ulGFXCLKLimit);
721 limits->vddc = le16_to_cpu(limit_table->entries[0].usVddcLimit);
722 limits->vddci = le16_to_cpu(limit_table->entries[0].usVddciLimit);
723 limits->vddmem = le16_to_cpu(limit_table->entries[0].usVddMemLimit);
728 static int get_valid_clk(
729 struct pp_hwmgr *hwmgr,
730 struct phm_clock_array **clk_table,
731 const phm_ppt_v1_clock_voltage_dependency_table *clk_volt_pp_table)
733 uint32_t table_size, i;
734 struct phm_clock_array *table;
736 PP_ASSERT_WITH_CODE(clk_volt_pp_table->count,
737 "Invalid PowerPlay Table!", return -1);
739 table_size = sizeof(uint32_t) +
740 sizeof(uint32_t) * clk_volt_pp_table->count;
742 table = kzalloc(table_size, GFP_KERNEL);
747 table->count = (uint32_t)clk_volt_pp_table->count;
749 for (i = 0; i < table->count; i++)
750 table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk;
757 static int init_powerplay_extended_tables(
758 struct pp_hwmgr *hwmgr,
759 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
762 struct phm_ppt_v2_information *pp_table_info =
763 (struct phm_ppt_v2_information *)(hwmgr->pptable);
765 const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table =
766 (const ATOM_Vega10_MM_Dependency_Table *)
767 (((unsigned long) powerplay_table) +
768 le16_to_cpu(powerplay_table->usMMDependencyTableOffset));
769 const Vega10_PPTable_Generic_SubTable_Header *power_tune_table =
770 (const Vega10_PPTable_Generic_SubTable_Header *)
771 (((unsigned long) powerplay_table) +
772 le16_to_cpu(powerplay_table->usPowerTuneTableOffset));
773 const ATOM_Vega10_SOCCLK_Dependency_Table *socclk_dep_table =
774 (const ATOM_Vega10_SOCCLK_Dependency_Table *)
775 (((unsigned long) powerplay_table) +
776 le16_to_cpu(powerplay_table->usSocclkDependencyTableOffset));
777 const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
778 (const ATOM_Vega10_GFXCLK_Dependency_Table *)
779 (((unsigned long) powerplay_table) +
780 le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
781 const ATOM_Vega10_DCEFCLK_Dependency_Table *dcefclk_dep_table =
782 (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
783 (((unsigned long) powerplay_table) +
784 le16_to_cpu(powerplay_table->usDcefclkDependencyTableOffset));
785 const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table =
786 (const ATOM_Vega10_MCLK_Dependency_Table *)
787 (((unsigned long) powerplay_table) +
788 le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
789 const ATOM_Vega10_Hard_Limit_Table *hard_limits =
790 (const ATOM_Vega10_Hard_Limit_Table *)
791 (((unsigned long) powerplay_table) +
792 le16_to_cpu(powerplay_table->usHardLimitTableOffset));
793 const Vega10_PPTable_Generic_SubTable_Header *pcie_table =
794 (const Vega10_PPTable_Generic_SubTable_Header *)
795 (((unsigned long) powerplay_table) +
796 le16_to_cpu(powerplay_table->usPCIETableOffset));
797 const ATOM_Vega10_PIXCLK_Dependency_Table *pixclk_dep_table =
798 (const ATOM_Vega10_PIXCLK_Dependency_Table *)
799 (((unsigned long) powerplay_table) +
800 le16_to_cpu(powerplay_table->usPixclkDependencyTableOffset));
801 const ATOM_Vega10_PHYCLK_Dependency_Table *phyclk_dep_table =
802 (const ATOM_Vega10_PHYCLK_Dependency_Table *)
803 (((unsigned long) powerplay_table) +
804 le16_to_cpu(powerplay_table->usPhyClkDependencyTableOffset));
805 const ATOM_Vega10_DISPCLK_Dependency_Table *dispclk_dep_table =
806 (const ATOM_Vega10_DISPCLK_Dependency_Table *)
807 (((unsigned long) powerplay_table) +
808 le16_to_cpu(powerplay_table->usDispClkDependencyTableOffset));
810 pp_table_info->vdd_dep_on_socclk = NULL;
811 pp_table_info->vdd_dep_on_sclk = NULL;
812 pp_table_info->vdd_dep_on_mclk = NULL;
813 pp_table_info->vdd_dep_on_dcefclk = NULL;
814 pp_table_info->mm_dep_table = NULL;
815 pp_table_info->tdp_table = NULL;
816 pp_table_info->vdd_dep_on_pixclk = NULL;
817 pp_table_info->vdd_dep_on_phyclk = NULL;
818 pp_table_info->vdd_dep_on_dispclk = NULL;
820 if (powerplay_table->usMMDependencyTableOffset)
821 result = get_mm_clock_voltage_table(hwmgr,
822 &pp_table_info->mm_dep_table,
823 mm_dependency_table);
825 if (!result && powerplay_table->usPowerTuneTableOffset)
826 result = get_tdp_table(hwmgr,
827 &pp_table_info->tdp_table,
830 if (!result && powerplay_table->usSocclkDependencyTableOffset)
831 result = get_socclk_voltage_dependency_table(hwmgr,
832 &pp_table_info->vdd_dep_on_socclk,
835 if (!result && powerplay_table->usGfxclkDependencyTableOffset)
836 result = get_gfxclk_voltage_dependency_table(hwmgr,
837 &pp_table_info->vdd_dep_on_sclk,
840 if (!result && powerplay_table->usPixclkDependencyTableOffset)
841 result = get_dcefclk_voltage_dependency_table(hwmgr,
842 &pp_table_info->vdd_dep_on_pixclk,
843 (const ATOM_Vega10_DCEFCLK_Dependency_Table*)
846 if (!result && powerplay_table->usPhyClkDependencyTableOffset)
847 result = get_dcefclk_voltage_dependency_table(hwmgr,
848 &pp_table_info->vdd_dep_on_phyclk,
849 (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
852 if (!result && powerplay_table->usDispClkDependencyTableOffset)
853 result = get_dcefclk_voltage_dependency_table(hwmgr,
854 &pp_table_info->vdd_dep_on_dispclk,
855 (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
858 if (!result && powerplay_table->usDcefclkDependencyTableOffset)
859 result = get_dcefclk_voltage_dependency_table(hwmgr,
860 &pp_table_info->vdd_dep_on_dcefclk,
863 if (!result && powerplay_table->usMclkDependencyTableOffset)
864 result = get_mclk_voltage_dependency_table(hwmgr,
865 &pp_table_info->vdd_dep_on_mclk,
868 if (!result && powerplay_table->usPCIETableOffset)
869 result = get_pcie_table(hwmgr,
870 &pp_table_info->pcie_table,
873 if (!result && powerplay_table->usHardLimitTableOffset)
874 result = get_hard_limits(hwmgr,
875 &pp_table_info->max_clock_voltage_on_dc,
878 hwmgr->dyn_state.max_clock_voltage_on_dc.sclk =
879 pp_table_info->max_clock_voltage_on_dc.sclk;
880 hwmgr->dyn_state.max_clock_voltage_on_dc.mclk =
881 pp_table_info->max_clock_voltage_on_dc.mclk;
882 hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
883 pp_table_info->max_clock_voltage_on_dc.vddc;
884 hwmgr->dyn_state.max_clock_voltage_on_dc.vddci =
885 pp_table_info->max_clock_voltage_on_dc.vddci;
888 pp_table_info->vdd_dep_on_socclk &&
889 pp_table_info->vdd_dep_on_socclk->count)
890 result = get_valid_clk(hwmgr,
891 &pp_table_info->valid_socclk_values,
892 pp_table_info->vdd_dep_on_socclk);
895 pp_table_info->vdd_dep_on_sclk &&
896 pp_table_info->vdd_dep_on_sclk->count)
897 result = get_valid_clk(hwmgr,
898 &pp_table_info->valid_sclk_values,
899 pp_table_info->vdd_dep_on_sclk);
902 pp_table_info->vdd_dep_on_dcefclk &&
903 pp_table_info->vdd_dep_on_dcefclk->count)
904 result = get_valid_clk(hwmgr,
905 &pp_table_info->valid_dcefclk_values,
906 pp_table_info->vdd_dep_on_dcefclk);
909 pp_table_info->vdd_dep_on_mclk &&
910 pp_table_info->vdd_dep_on_mclk->count)
911 result = get_valid_clk(hwmgr,
912 &pp_table_info->valid_mclk_values,
913 pp_table_info->vdd_dep_on_mclk);
918 static int get_vddc_lookup_table(
919 struct pp_hwmgr *hwmgr,
920 phm_ppt_v1_voltage_lookup_table **lookup_table,
921 const ATOM_Vega10_Voltage_Lookup_Table *vddc_lookup_pp_tables,
924 uint32_t table_size, i;
925 phm_ppt_v1_voltage_lookup_table *table;
927 PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0),
928 "Invalid SOC_VDDD Lookup Table!", return 1);
930 table_size = sizeof(uint32_t) +
931 sizeof(phm_ppt_v1_voltage_lookup_record) * max_levels;
933 table = (phm_ppt_v1_voltage_lookup_table *)
934 kzalloc(table_size, GFP_KERNEL);
939 table->count = vddc_lookup_pp_tables->ucNumEntries;
941 for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++)
942 table->entries[i].us_vdd =
943 le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd);
945 *lookup_table = table;
950 static int init_dpm_2_parameters(
951 struct pp_hwmgr *hwmgr,
952 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
955 struct phm_ppt_v2_information *pp_table_info =
956 (struct phm_ppt_v2_information *)(hwmgr->pptable);
957 uint32_t disable_power_control = 0;
959 pp_table_info->us_ulv_voltage_offset =
960 le16_to_cpu(powerplay_table->usUlvVoltageOffset);
962 pp_table_info->us_ulv_smnclk_did =
963 le16_to_cpu(powerplay_table->usUlvSmnclkDid);
964 pp_table_info->us_ulv_mp1clk_did =
965 le16_to_cpu(powerplay_table->usUlvMp1clkDid);
966 pp_table_info->us_ulv_gfxclk_bypass =
967 le16_to_cpu(powerplay_table->usUlvGfxclkBypass);
968 pp_table_info->us_gfxclk_slew_rate =
969 le16_to_cpu(powerplay_table->usGfxclkSlewRate);
970 pp_table_info->uc_gfx_dpm_voltage_mode =
971 le16_to_cpu(powerplay_table->ucGfxVoltageMode);
972 pp_table_info->uc_soc_dpm_voltage_mode =
973 le16_to_cpu(powerplay_table->ucSocVoltageMode);
974 pp_table_info->uc_uclk_dpm_voltage_mode =
975 le16_to_cpu(powerplay_table->ucUclkVoltageMode);
976 pp_table_info->uc_uvd_dpm_voltage_mode =
977 le16_to_cpu(powerplay_table->ucUvdVoltageMode);
978 pp_table_info->uc_vce_dpm_voltage_mode =
979 le16_to_cpu(powerplay_table->ucVceVoltageMode);
980 pp_table_info->uc_mp0_dpm_voltage_mode =
981 le16_to_cpu(powerplay_table->ucMp0VoltageMode);
982 pp_table_info->uc_dcef_dpm_voltage_mode =
983 le16_to_cpu(powerplay_table->ucDcefVoltageMode);
985 pp_table_info->ppm_parameter_table = NULL;
986 pp_table_info->vddc_lookup_table = NULL;
987 pp_table_info->vddmem_lookup_table = NULL;
988 pp_table_info->vddci_lookup_table = NULL;
991 hwmgr->platform_descriptor.TDPODLimit =
992 le16_to_cpu(powerplay_table->usPowerControlLimit);
993 hwmgr->platform_descriptor.TDPAdjustment = 0;
994 hwmgr->platform_descriptor.VidAdjustment = 0;
995 hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
996 hwmgr->platform_descriptor.VidMinLimit = 0;
997 hwmgr->platform_descriptor.VidMaxLimit = 1500000;
998 hwmgr->platform_descriptor.VidStep = 6250;
1000 disable_power_control = 0;
1001 if (!disable_power_control) {
1002 /* enable TDP overdrive (PowerControl) feature as well if supported */
1003 if (hwmgr->platform_descriptor.TDPODLimit)
1004 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
1005 PHM_PlatformCaps_PowerControl);
1008 if (powerplay_table->usVddcLookupTableOffset) {
1009 const ATOM_Vega10_Voltage_Lookup_Table *vddc_table =
1010 (ATOM_Vega10_Voltage_Lookup_Table *)
1011 (((unsigned long)powerplay_table) +
1012 le16_to_cpu(powerplay_table->usVddcLookupTableOffset));
1013 result = get_vddc_lookup_table(hwmgr,
1014 &pp_table_info->vddc_lookup_table, vddc_table, 8);
1017 if (powerplay_table->usVddmemLookupTableOffset) {
1018 const ATOM_Vega10_Voltage_Lookup_Table *vdd_mem_table =
1019 (ATOM_Vega10_Voltage_Lookup_Table *)
1020 (((unsigned long)powerplay_table) +
1021 le16_to_cpu(powerplay_table->usVddmemLookupTableOffset));
1022 result = get_vddc_lookup_table(hwmgr,
1023 &pp_table_info->vddmem_lookup_table, vdd_mem_table, 4);
1026 if (powerplay_table->usVddciLookupTableOffset) {
1027 const ATOM_Vega10_Voltage_Lookup_Table *vddci_table =
1028 (ATOM_Vega10_Voltage_Lookup_Table *)
1029 (((unsigned long)powerplay_table) +
1030 le16_to_cpu(powerplay_table->usVddciLookupTableOffset));
1031 result = get_vddc_lookup_table(hwmgr,
1032 &pp_table_info->vddci_lookup_table, vddci_table, 4);
1038 int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr)
1041 const ATOM_Vega10_POWERPLAYTABLE *powerplay_table;
1043 hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL);
1045 PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable),
1046 "Failed to allocate hwmgr->pptable!", return -ENOMEM);
1048 powerplay_table = get_powerplay_table(hwmgr);
1050 PP_ASSERT_WITH_CODE((NULL != powerplay_table),
1051 "Missing PowerPlay Table!", return -1);
1053 result = check_powerplay_tables(hwmgr, powerplay_table);
1055 PP_ASSERT_WITH_CODE((result == 0),
1056 "check_powerplay_tables failed", return result);
1058 result = set_platform_caps(hwmgr,
1059 le32_to_cpu(powerplay_table->ulPlatformCaps));
1061 PP_ASSERT_WITH_CODE((result == 0),
1062 "set_platform_caps failed", return result);
1064 result = init_thermal_controller(hwmgr, powerplay_table);
1066 PP_ASSERT_WITH_CODE((result == 0),
1067 "init_thermal_controller failed", return result);
1069 result = init_over_drive_limits(hwmgr, powerplay_table);
1071 PP_ASSERT_WITH_CODE((result == 0),
1072 "init_over_drive_limits failed", return result);
1074 result = init_powerplay_extended_tables(hwmgr, powerplay_table);
1076 PP_ASSERT_WITH_CODE((result == 0),
1077 "init_powerplay_extended_tables failed", return result);
1079 result = init_dpm_2_parameters(hwmgr, powerplay_table);
1081 PP_ASSERT_WITH_CODE((result == 0),
1082 "init_dpm_2_parameters failed", return result);
1087 static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
1090 struct phm_ppt_v2_information *pp_table_info =
1091 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1093 kfree(pp_table_info->vdd_dep_on_sclk);
1094 pp_table_info->vdd_dep_on_sclk = NULL;
1096 kfree(pp_table_info->vdd_dep_on_mclk);
1097 pp_table_info->vdd_dep_on_mclk = NULL;
1099 kfree(pp_table_info->valid_mclk_values);
1100 pp_table_info->valid_mclk_values = NULL;
1102 kfree(pp_table_info->valid_sclk_values);
1103 pp_table_info->valid_sclk_values = NULL;
1105 kfree(pp_table_info->vddc_lookup_table);
1106 pp_table_info->vddc_lookup_table = NULL;
1108 kfree(pp_table_info->vddmem_lookup_table);
1109 pp_table_info->vddmem_lookup_table = NULL;
1111 kfree(pp_table_info->vddci_lookup_table);
1112 pp_table_info->vddci_lookup_table = NULL;
1114 kfree(pp_table_info->ppm_parameter_table);
1115 pp_table_info->ppm_parameter_table = NULL;
1117 kfree(pp_table_info->mm_dep_table);
1118 pp_table_info->mm_dep_table = NULL;
1120 kfree(pp_table_info->cac_dtp_table);
1121 pp_table_info->cac_dtp_table = NULL;
1123 kfree(hwmgr->dyn_state.cac_dtp_table);
1124 hwmgr->dyn_state.cac_dtp_table = NULL;
1126 kfree(pp_table_info->tdp_table);
1127 pp_table_info->tdp_table = NULL;
1129 kfree(hwmgr->pptable);
1130 hwmgr->pptable = NULL;
1135 const struct pp_table_func vega10_pptable_funcs = {
1136 .pptable_init = vega10_pp_tables_initialize,
1137 .pptable_fini = vega10_pp_tables_uninitialize,
1140 int vega10_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr)
1142 const ATOM_Vega10_State_Array *state_arrays;
1143 const ATOM_Vega10_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
1145 PP_ASSERT_WITH_CODE((NULL != pp_table),
1146 "Missing PowerPlay Table!", return -1);
1147 PP_ASSERT_WITH_CODE((pp_table->sHeader.format_revision >=
1148 ATOM_Vega10_TABLE_REVISION_VEGA10),
1149 "Incorrect PowerPlay table revision!", return -1);
1151 state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)pp_table) +
1152 le16_to_cpu(pp_table->usStateArrayOffset));
1154 return (uint32_t)(state_arrays->ucNumEntries);
1157 static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
1158 uint16_t classification, uint16_t classification2)
1160 uint32_t result = 0;
1162 if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
1163 result |= PP_StateClassificationFlag_Boot;
1165 if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1166 result |= PP_StateClassificationFlag_Thermal;
1168 if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
1169 result |= PP_StateClassificationFlag_LimitedPowerSource;
1171 if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
1172 result |= PP_StateClassificationFlag_Rest;
1174 if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
1175 result |= PP_StateClassificationFlag_Forced;
1177 if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
1178 result |= PP_StateClassificationFlag_ACPI;
1180 if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
1181 result |= PP_StateClassificationFlag_LimitedPowerSource_2;
1186 int vega10_get_powerplay_table_entry(struct pp_hwmgr *hwmgr,
1187 uint32_t entry_index, struct pp_power_state *power_state,
1188 int (*call_back_func)(struct pp_hwmgr *, void *,
1189 struct pp_power_state *, void *, uint32_t))
1192 const ATOM_Vega10_State_Array *state_arrays;
1193 const ATOM_Vega10_State *state_entry;
1194 const ATOM_Vega10_POWERPLAYTABLE *pp_table =
1195 get_powerplay_table(hwmgr);
1197 PP_ASSERT_WITH_CODE(pp_table, "Missing PowerPlay Table!",
1199 power_state->classification.bios_index = entry_index;
1201 if (pp_table->sHeader.format_revision >=
1202 ATOM_Vega10_TABLE_REVISION_VEGA10) {
1203 state_arrays = (ATOM_Vega10_State_Array *)
1204 (((unsigned long)pp_table) +
1205 le16_to_cpu(pp_table->usStateArrayOffset));
1207 PP_ASSERT_WITH_CODE(pp_table->usStateArrayOffset > 0,
1208 "Invalid PowerPlay Table State Array Offset.",
1210 PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
1211 "Invalid PowerPlay Table State Array.",
1213 PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
1214 "Invalid PowerPlay Table State Array Entry.",
1217 state_entry = &(state_arrays->states[entry_index]);
1219 result = call_back_func(hwmgr, (void *)state_entry, power_state,
1221 make_classification_flags(hwmgr,
1222 le16_to_cpu(state_entry->usClassification),
1223 le16_to_cpu(state_entry->usClassification2)));
1226 if (!result && (power_state->classification.flags &
1227 PP_StateClassificationFlag_Boot))
1228 result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));