2 * Copyright 2015 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.
26 #include "fiji_hwmgr.h"
27 #include "fiji_powertune.h"
28 #include "fiji_smumgr.h"
29 #include "smu73_discrete.h"
32 #define VOLTAGE_SCALE 4
33 #define POWERTUNE_DEFAULT_SET_MAX 1
35 struct fiji_pt_defaults fiji_power_tune_data_set_array
[POWERTUNE_DEFAULT_SET_MAX
] = {
36 /*sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc */
38 /* TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase */
42 void fiji_initialize_power_tune_defaults(struct pp_hwmgr
*hwmgr
)
44 struct fiji_hwmgr
*fiji_hwmgr
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
45 struct phm_ppt_v1_information
*table_info
=
46 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
50 table_info
->cac_dtp_table
->usPowerTuneDataSetID
<= POWERTUNE_DEFAULT_SET_MAX
&&
51 table_info
->cac_dtp_table
->usPowerTuneDataSetID
)
52 fiji_hwmgr
->power_tune_defaults
=
53 &fiji_power_tune_data_set_array
54 [table_info
->cac_dtp_table
->usPowerTuneDataSetID
- 1];
56 fiji_hwmgr
->power_tune_defaults
= &fiji_power_tune_data_set_array
[0];
59 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
60 PHM_PlatformCaps_PowerContainment
);
61 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
62 PHM_PlatformCaps_CAC
);
63 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
64 PHM_PlatformCaps_SQRamping
);
65 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
66 PHM_PlatformCaps_DBRamping
);
67 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
68 PHM_PlatformCaps_TDRamping
);
69 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
70 PHM_PlatformCaps_TCPRamping
);
72 fiji_hwmgr
->dte_tj_offset
= tmp
;
75 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
76 PHM_PlatformCaps_PowerContainment
);
78 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
79 PHM_PlatformCaps_CAC
);
81 fiji_hwmgr
->fast_watermark_threshold
= 100;
84 fiji_hwmgr
->enable_dte_feature
= tmp
? false : true;
85 fiji_hwmgr
->enable_tdc_limit_feature
= tmp
? true : false;
86 fiji_hwmgr
->enable_pkg_pwr_tracking_feature
= tmp
? true : false;
90 /* PPGen has the gain setting generated in x * 100 unit
91 * This function is to convert the unit to x * 4096(0x1000) unit.
92 * This is the unit expected by SMC firmware
94 static uint16_t scale_fan_gain_settings(uint16_t raw_setting
)
97 tmp
= raw_setting
* 4096 / 100;
101 static void get_scl_sda_value(uint8_t line
, uint8_t *scl
, uint8_t* sda
)
104 case Fiji_I2CLineID_DDC1
:
105 *scl
= Fiji_I2C_DDC1CLK
;
106 *sda
= Fiji_I2C_DDC1DATA
;
108 case Fiji_I2CLineID_DDC2
:
109 *scl
= Fiji_I2C_DDC2CLK
;
110 *sda
= Fiji_I2C_DDC2DATA
;
112 case Fiji_I2CLineID_DDC3
:
113 *scl
= Fiji_I2C_DDC3CLK
;
114 *sda
= Fiji_I2C_DDC3DATA
;
116 case Fiji_I2CLineID_DDC4
:
117 *scl
= Fiji_I2C_DDC4CLK
;
118 *sda
= Fiji_I2C_DDC4DATA
;
120 case Fiji_I2CLineID_DDC5
:
121 *scl
= Fiji_I2C_DDC5CLK
;
122 *sda
= Fiji_I2C_DDC5DATA
;
124 case Fiji_I2CLineID_DDC6
:
125 *scl
= Fiji_I2C_DDC6CLK
;
126 *sda
= Fiji_I2C_DDC6DATA
;
128 case Fiji_I2CLineID_SCLSDA
:
132 case Fiji_I2CLineID_DDCVGA
:
133 *scl
= Fiji_I2C_DDCVGACLK
;
134 *sda
= Fiji_I2C_DDCVGADATA
;
143 int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr
*hwmgr
)
145 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
146 struct fiji_pt_defaults
*defaults
= data
->power_tune_defaults
;
147 SMU73_Discrete_DpmTable
*dpm_table
= &(data
->smc_state_table
);
148 struct phm_ppt_v1_information
*table_info
=
149 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
150 struct phm_cac_tdp_table
*cac_dtp_table
= table_info
->cac_dtp_table
;
151 struct pp_advance_fan_control_parameters
*fan_table
=
152 &hwmgr
->thermal_controller
.advanceFanControlParameters
;
153 uint8_t uc_scl
, uc_sda
;
155 /* TDP number of fraction bits are changed from 8 to 7 for Fiji
156 * as requested by SMC team
158 dpm_table
->DefaultTdp
= PP_HOST_TO_SMC_US(
159 (uint16_t)(cac_dtp_table
->usTDP
* 128));
160 dpm_table
->TargetTdp
= PP_HOST_TO_SMC_US(
161 (uint16_t)(cac_dtp_table
->usTDP
* 128));
163 PP_ASSERT_WITH_CODE(cac_dtp_table
->usTargetOperatingTemp
<= 255,
164 "Target Operating Temp is out of Range!",);
166 dpm_table
->GpuTjMax
= (uint8_t)(cac_dtp_table
->usTargetOperatingTemp
);
167 dpm_table
->GpuTjHyst
= 8;
169 dpm_table
->DTEAmbientTempBase
= defaults
->DTEAmbientTempBase
;
171 /* The following are for new Fiji Multi-input fan/thermal control */
172 dpm_table
->TemperatureLimitEdge
= PP_HOST_TO_SMC_US(
173 cac_dtp_table
->usTargetOperatingTemp
* 256);
174 dpm_table
->TemperatureLimitHotspot
= PP_HOST_TO_SMC_US(
175 cac_dtp_table
->usTemperatureLimitHotspot
* 256);
176 dpm_table
->TemperatureLimitLiquid1
= PP_HOST_TO_SMC_US(
177 cac_dtp_table
->usTemperatureLimitLiquid1
* 256);
178 dpm_table
->TemperatureLimitLiquid2
= PP_HOST_TO_SMC_US(
179 cac_dtp_table
->usTemperatureLimitLiquid2
* 256);
180 dpm_table
->TemperatureLimitVrVddc
= PP_HOST_TO_SMC_US(
181 cac_dtp_table
->usTemperatureLimitVrVddc
* 256);
182 dpm_table
->TemperatureLimitVrMvdd
= PP_HOST_TO_SMC_US(
183 cac_dtp_table
->usTemperatureLimitVrMvdd
* 256);
184 dpm_table
->TemperatureLimitPlx
= PP_HOST_TO_SMC_US(
185 cac_dtp_table
->usTemperatureLimitPlx
* 256);
187 dpm_table
->FanGainEdge
= PP_HOST_TO_SMC_US(
188 scale_fan_gain_settings(fan_table
->usFanGainEdge
));
189 dpm_table
->FanGainHotspot
= PP_HOST_TO_SMC_US(
190 scale_fan_gain_settings(fan_table
->usFanGainHotspot
));
191 dpm_table
->FanGainLiquid
= PP_HOST_TO_SMC_US(
192 scale_fan_gain_settings(fan_table
->usFanGainLiquid
));
193 dpm_table
->FanGainVrVddc
= PP_HOST_TO_SMC_US(
194 scale_fan_gain_settings(fan_table
->usFanGainVrVddc
));
195 dpm_table
->FanGainVrMvdd
= PP_HOST_TO_SMC_US(
196 scale_fan_gain_settings(fan_table
->usFanGainVrMvdd
));
197 dpm_table
->FanGainPlx
= PP_HOST_TO_SMC_US(
198 scale_fan_gain_settings(fan_table
->usFanGainPlx
));
199 dpm_table
->FanGainHbm
= PP_HOST_TO_SMC_US(
200 scale_fan_gain_settings(fan_table
->usFanGainHbm
));
202 dpm_table
->Liquid1_I2C_address
= cac_dtp_table
->ucLiquid1_I2C_address
;
203 dpm_table
->Liquid2_I2C_address
= cac_dtp_table
->ucLiquid2_I2C_address
;
204 dpm_table
->Vr_I2C_address
= cac_dtp_table
->ucVr_I2C_address
;
205 dpm_table
->Plx_I2C_address
= cac_dtp_table
->ucPlx_I2C_address
;
207 get_scl_sda_value(cac_dtp_table
->ucLiquid_I2C_Line
, &uc_scl
, &uc_sda
);
208 dpm_table
->Liquid_I2C_LineSCL
= uc_scl
;
209 dpm_table
->Liquid_I2C_LineSDA
= uc_sda
;
211 get_scl_sda_value(cac_dtp_table
->ucVr_I2C_Line
, &uc_scl
, &uc_sda
);
212 dpm_table
->Vr_I2C_LineSCL
= uc_scl
;
213 dpm_table
->Vr_I2C_LineSDA
= uc_sda
;
215 get_scl_sda_value(cac_dtp_table
->ucPlx_I2C_Line
, &uc_scl
, &uc_sda
);
216 dpm_table
->Plx_I2C_LineSCL
= uc_scl
;
217 dpm_table
->Plx_I2C_LineSDA
= uc_sda
;
222 static int fiji_populate_svi_load_line(struct pp_hwmgr
*hwmgr
)
224 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
225 struct fiji_pt_defaults
*defaults
= data
->power_tune_defaults
;
227 data
->power_tune_table
.SviLoadLineEn
= defaults
->SviLoadLineEn
;
228 data
->power_tune_table
.SviLoadLineVddC
= defaults
->SviLoadLineVddC
;
229 data
->power_tune_table
.SviLoadLineTrimVddC
= 3;
230 data
->power_tune_table
.SviLoadLineOffsetVddC
= 0;
235 static int fiji_populate_tdc_limit(struct pp_hwmgr
*hwmgr
)
238 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
239 struct phm_ppt_v1_information
*table_info
=
240 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
241 struct fiji_pt_defaults
*defaults
= data
->power_tune_defaults
;
243 /* TDC number of fraction bits are changed from 8 to 7
244 * for Fiji as requested by SMC team
246 tdc_limit
= (uint16_t)(table_info
->cac_dtp_table
->usTDC
* 128);
247 data
->power_tune_table
.TDC_VDDC_PkgLimit
=
248 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit
);
249 data
->power_tune_table
.TDC_VDDC_ThrottleReleaseLimitPerc
=
250 defaults
->TDC_VDDC_ThrottleReleaseLimitPerc
;
251 data
->power_tune_table
.TDC_MAWt
= defaults
->TDC_MAWt
;
256 static int fiji_populate_dw8(struct pp_hwmgr
*hwmgr
, uint32_t fuse_table_offset
)
258 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
259 struct fiji_pt_defaults
*defaults
= data
->power_tune_defaults
;
262 if (fiji_read_smc_sram_dword(hwmgr
->smumgr
,
264 offsetof(SMU73_Discrete_PmFuses
, TdcWaterfallCtl
),
265 (uint32_t *)&temp
, data
->sram_end
))
266 PP_ASSERT_WITH_CODE(false,
267 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
270 data
->power_tune_table
.TdcWaterfallCtl
= defaults
->TdcWaterfallCtl
;
271 data
->power_tune_table
.LPMLTemperatureMin
=
272 (uint8_t)((temp
>> 16) & 0xff);
273 data
->power_tune_table
.LPMLTemperatureMax
=
274 (uint8_t)((temp
>> 8) & 0xff);
275 data
->power_tune_table
.Reserved
= (uint8_t)(temp
& 0xff);
280 static int fiji_populate_temperature_scaler(struct pp_hwmgr
*hwmgr
)
283 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
285 /* Currently not used. Set all to zero. */
286 for (i
= 0; i
< 16; i
++)
287 data
->power_tune_table
.LPMLTemperatureScaler
[i
] = 0;
292 static int fiji_populate_fuzzy_fan(struct pp_hwmgr
*hwmgr
)
294 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
296 if( (hwmgr
->thermal_controller
.advanceFanControlParameters
.
297 usFanOutputSensitivity
& (1 << 15)) ||
298 0 == hwmgr
->thermal_controller
.advanceFanControlParameters
.
299 usFanOutputSensitivity
)
300 hwmgr
->thermal_controller
.advanceFanControlParameters
.
301 usFanOutputSensitivity
= hwmgr
->thermal_controller
.
302 advanceFanControlParameters
.usDefaultFanOutputSensitivity
;
304 data
->power_tune_table
.FuzzyFan_PwmSetDelta
=
305 PP_HOST_TO_SMC_US(hwmgr
->thermal_controller
.
306 advanceFanControlParameters
.usFanOutputSensitivity
);
310 static int fiji_populate_gnb_lpml(struct pp_hwmgr
*hwmgr
)
313 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
315 /* Currently not used. Set all to zero. */
316 for (i
= 0; i
< 16; i
++)
317 data
->power_tune_table
.GnbLPML
[i
] = 0;
322 static int fiji_min_max_vgnb_lpml_id_from_bapm_vddc(struct pp_hwmgr
*hwmgr
)
325 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
326 uint8_t * pHiVID = data->power_tune_table.BapmVddCVidHiSidd;
327 uint8_t * pLoVID = data->power_tune_table.BapmVddCVidLoSidd;
329 min = max = pHiVID[0];
330 for (i = 0; i < 8; i++) {
331 if (0 != pHiVID[i]) {
338 if (0 != pLoVID[i]) {
346 PP_ASSERT_WITH_CODE((0 != min) && (0 != max), "BapmVddcVidSidd table does not exist!", return int_Failed);
347 data->power_tune_table.GnbLPMLMaxVid = (uint8_t)max;
348 data->power_tune_table.GnbLPMLMinVid = (uint8_t)min;
353 static int fiji_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr
*hwmgr
)
355 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
356 struct phm_ppt_v1_information
*table_info
=
357 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
358 uint16_t HiSidd
= data
->power_tune_table
.BapmVddCBaseLeakageHiSidd
;
359 uint16_t LoSidd
= data
->power_tune_table
.BapmVddCBaseLeakageLoSidd
;
360 struct phm_cac_tdp_table
*cac_table
= table_info
->cac_dtp_table
;
362 HiSidd
= (uint16_t)(cac_table
->usHighCACLeakage
/ 100 * 256);
363 LoSidd
= (uint16_t)(cac_table
->usLowCACLeakage
/ 100 * 256);
365 data
->power_tune_table
.BapmVddCBaseLeakageHiSidd
=
366 CONVERT_FROM_HOST_TO_SMC_US(HiSidd
);
367 data
->power_tune_table
.BapmVddCBaseLeakageLoSidd
=
368 CONVERT_FROM_HOST_TO_SMC_US(LoSidd
);
373 int fiji_populate_pm_fuses(struct pp_hwmgr
*hwmgr
)
375 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
376 uint32_t pm_fuse_table_offset
;
378 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
379 PHM_PlatformCaps_PowerContainment
)) {
380 if (fiji_read_smc_sram_dword(hwmgr
->smumgr
,
381 SMU7_FIRMWARE_HEADER_LOCATION
+
382 offsetof(SMU73_Firmware_Header
, PmFuseTable
),
383 &pm_fuse_table_offset
, data
->sram_end
))
384 PP_ASSERT_WITH_CODE(false,
385 "Attempt to get pm_fuse_table_offset Failed!",
389 if (fiji_populate_svi_load_line(hwmgr
))
390 PP_ASSERT_WITH_CODE(false,
391 "Attempt to populate SviLoadLine Failed!",
394 if (fiji_populate_tdc_limit(hwmgr
))
395 PP_ASSERT_WITH_CODE(false,
396 "Attempt to populate TDCLimit Failed!", return -EINVAL
);
398 if (fiji_populate_dw8(hwmgr
, pm_fuse_table_offset
))
399 PP_ASSERT_WITH_CODE(false,
400 "Attempt to populate TdcWaterfallCtl, "
401 "LPMLTemperature Min and Max Failed!",
405 if (0 != fiji_populate_temperature_scaler(hwmgr
))
406 PP_ASSERT_WITH_CODE(false,
407 "Attempt to populate LPMLTemperatureScaler Failed!",
411 if(fiji_populate_fuzzy_fan(hwmgr
))
412 PP_ASSERT_WITH_CODE(false,
413 "Attempt to populate Fuzzy Fan Control parameters Failed!",
417 if (fiji_populate_gnb_lpml(hwmgr
))
418 PP_ASSERT_WITH_CODE(false,
419 "Attempt to populate GnbLPML Failed!",
423 if (fiji_min_max_vgnb_lpml_id_from_bapm_vddc(hwmgr
))
424 PP_ASSERT_WITH_CODE(false,
425 "Attempt to populate GnbLPML Min and Max Vid Failed!",
429 if (fiji_populate_bapm_vddc_base_leakage_sidd(hwmgr
))
430 PP_ASSERT_WITH_CODE(false,
431 "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
432 "Sidd Failed!", return -EINVAL
);
434 if (fiji_copy_bytes_to_smc(hwmgr
->smumgr
, pm_fuse_table_offset
,
435 (uint8_t *)&data
->power_tune_table
,
436 sizeof(struct SMU73_Discrete_PmFuses
), data
->sram_end
))
437 PP_ASSERT_WITH_CODE(false,
438 "Attempt to download PmFuseTable Failed!",
444 int fiji_enable_smc_cac(struct pp_hwmgr
*hwmgr
)
446 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
449 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
450 PHM_PlatformCaps_CAC
)) {
452 smc_result
= smum_send_msg_to_smc(hwmgr
->smumgr
,
453 (uint16_t)(PPSMC_MSG_EnableCac
));
454 PP_ASSERT_WITH_CODE((0 == smc_result
),
455 "Failed to enable CAC in SMC.", result
= -1);
457 data
->cac_enabled
= (0 == smc_result
) ? true : false;
462 int fiji_set_power_limit(struct pp_hwmgr
*hwmgr
, uint32_t n
)
464 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
466 if(data
->power_containment_features
&
467 POWERCONTAINMENT_FEATURE_PkgPwrLimit
)
468 return smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
,
469 PPSMC_MSG_PkgPwrSetLimit
, n
);
473 static int fiji_set_overdriver_target_tdp(struct pp_hwmgr
*pHwMgr
, uint32_t target_tdp
)
475 return smum_send_msg_to_smc_with_parameter(pHwMgr
->smumgr
,
476 PPSMC_MSG_OverDriveSetTargetTdp
, target_tdp
);
479 int fiji_enable_power_containment(struct pp_hwmgr
*hwmgr
)
481 struct fiji_hwmgr
*data
= (struct fiji_hwmgr
*)(hwmgr
->backend
);
482 struct phm_ppt_v1_information
*table_info
=
483 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
487 data
->power_containment_features
= 0;
488 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
489 PHM_PlatformCaps_PowerContainment
)) {
490 if (data
->enable_dte_feature
) {
491 smc_result
= smum_send_msg_to_smc(hwmgr
->smumgr
,
492 (uint16_t)(PPSMC_MSG_EnableDTE
));
493 PP_ASSERT_WITH_CODE((0 == smc_result
),
494 "Failed to enable DTE in SMC.", result
= -1;);
496 data
->power_containment_features
|= POWERCONTAINMENT_FEATURE_DTE
;
499 if (data
->enable_tdc_limit_feature
) {
500 smc_result
= smum_send_msg_to_smc(hwmgr
->smumgr
,
501 (uint16_t)(PPSMC_MSG_TDCLimitEnable
));
502 PP_ASSERT_WITH_CODE((0 == smc_result
),
503 "Failed to enable TDCLimit in SMC.", result
= -1;);
505 data
->power_containment_features
|=
506 POWERCONTAINMENT_FEATURE_TDCLimit
;
509 if (data
->enable_pkg_pwr_tracking_feature
) {
510 smc_result
= smum_send_msg_to_smc(hwmgr
->smumgr
,
511 (uint16_t)(PPSMC_MSG_PkgPwrLimitEnable
));
512 PP_ASSERT_WITH_CODE((0 == smc_result
),
513 "Failed to enable PkgPwrTracking in SMC.", result
= -1;);
514 if (0 == smc_result
) {
515 struct phm_cac_tdp_table
*cac_table
=
516 table_info
->cac_dtp_table
;
517 uint32_t default_limit
=
518 (uint32_t)(cac_table
->usMaximumPowerDeliveryLimit
* 256);
520 data
->power_containment_features
|=
521 POWERCONTAINMENT_FEATURE_PkgPwrLimit
;
523 if (fiji_set_power_limit(hwmgr
, default_limit
))
524 printk(KERN_ERR
"Failed to set Default Power Limit in SMC!");
531 int fiji_power_control_set_level(struct pp_hwmgr
*hwmgr
)
533 struct phm_ppt_v1_information
*table_info
=
534 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
535 struct phm_cac_tdp_table
*cac_table
= table_info
->cac_dtp_table
;
536 int adjust_percent
, target_tdp
;
539 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
540 PHM_PlatformCaps_PowerContainment
)) {
541 /* adjustment percentage has already been validated */
542 adjust_percent
= hwmgr
->platform_descriptor
.TDPAdjustmentPolarity
?
543 hwmgr
->platform_descriptor
.TDPAdjustment
:
544 (-1 * hwmgr
->platform_descriptor
.TDPAdjustment
);
545 /* SMC requested that target_tdp to be 7 bit fraction in DPM table
546 * but message to be 8 bit fraction for messages
548 target_tdp
= ((100 + adjust_percent
) * (int)(cac_table
->usTDP
* 256)) / 100;
549 result
= fiji_set_overdriver_target_tdp(hwmgr
, (uint32_t)target_tdp
);