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.
24 #include "vega10_thermal.h"
25 #include "vega10_hwmgr.h"
26 #include "vega10_smumgr.h"
27 #include "vega10_ppsmc.h"
28 #include "vega10_inc.h"
32 static int vega10_get_current_rpm(struct pp_hwmgr
*hwmgr
, uint32_t *current_rpm
)
34 PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr
->smumgr
,
35 PPSMC_MSG_GetCurrentRpm
),
36 "Attempt to get current RPM from SMC Failed!",
38 PP_ASSERT_WITH_CODE(!vega10_read_arg_from_smc(hwmgr
->smumgr
,
40 "Attempt to read current RPM from SMC Failed!",
45 int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr
*hwmgr
,
46 struct phm_fan_speed_info
*fan_speed_info
)
49 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
52 fan_speed_info
->supports_percent_read
= true;
53 fan_speed_info
->supports_percent_write
= true;
54 fan_speed_info
->min_percent
= 0;
55 fan_speed_info
->max_percent
= 100;
57 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
58 PHM_PlatformCaps_FanSpeedInTableIsRPM
) &&
59 hwmgr
->thermal_controller
.fanInfo
.
60 ucTachometerPulsesPerRevolution
) {
61 fan_speed_info
->supports_rpm_read
= true;
62 fan_speed_info
->supports_rpm_write
= true;
63 fan_speed_info
->min_rpm
=
64 hwmgr
->thermal_controller
.fanInfo
.ulMinRPM
;
65 fan_speed_info
->max_rpm
=
66 hwmgr
->thermal_controller
.fanInfo
.ulMaxRPM
;
68 fan_speed_info
->min_rpm
= 0;
69 fan_speed_info
->max_rpm
= 0;
75 int vega10_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr
*hwmgr
,
81 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
84 if (vega10_get_current_rpm(hwmgr
, ¤t_rpm
))
87 if (hwmgr
->thermal_controller
.
88 advanceFanControlParameters
.usMaxFanRPM
!= 0)
89 percent
= current_rpm
* 100 /
90 hwmgr
->thermal_controller
.
91 advanceFanControlParameters
.usMaxFanRPM
;
93 *speed
= percent
> 100 ? 100 : percent
;
98 int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr
*hwmgr
, uint32_t *speed
)
100 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
101 uint32_t tach_period
;
102 uint32_t crystal_clock_freq
;
105 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
108 if (data
->smu_features
[GNLD_FAN_CONTROL
].supported
)
109 result
= vega10_get_current_rpm(hwmgr
, speed
);
111 uint32_t reg
= soc15_get_register_offset(THM_HWID
, 0,
112 mmCG_TACH_STATUS_BASE_IDX
, mmCG_TACH_STATUS
);
113 tach_period
= (cgs_read_register(hwmgr
->device
,
114 reg
) & CG_TACH_STATUS__TACH_PERIOD_MASK
) >>
115 CG_TACH_STATUS__TACH_PERIOD__SHIFT
;
117 if (tach_period
== 0)
120 crystal_clock_freq
= smu7_get_xclk(hwmgr
);
122 *speed
= 60 * crystal_clock_freq
* 10000 / tach_period
;
129 * Set Fan Speed Control to static mode,
130 * so that the user can decide what speed to use.
131 * @param hwmgr the address of the powerplay hardware manager.
132 * mode the fan control mode, 0 default, 1 by percent, 5, by RPM
133 * @exception Should always succeed.
135 int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr
*hwmgr
, uint32_t mode
)
139 reg
= soc15_get_register_offset(THM_HWID
, 0,
140 mmCG_FDO_CTRL2_BASE_IDX
, mmCG_FDO_CTRL2
);
142 if (hwmgr
->fan_ctrl_is_in_default_mode
) {
143 hwmgr
->fan_ctrl_default_mode
=
144 (cgs_read_register(hwmgr
->device
, reg
) &
145 CG_FDO_CTRL2__FDO_PWM_MODE_MASK
) >>
146 CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT
;
147 hwmgr
->tmin
= (cgs_read_register(hwmgr
->device
, reg
) &
148 CG_FDO_CTRL2__TMIN_MASK
) >>
149 CG_FDO_CTRL2__TMIN__SHIFT
;
150 hwmgr
->fan_ctrl_is_in_default_mode
= false;
153 cgs_write_register(hwmgr
->device
, reg
,
154 (cgs_read_register(hwmgr
->device
, reg
) &
155 ~CG_FDO_CTRL2__TMIN_MASK
) |
156 (0 << CG_FDO_CTRL2__TMIN__SHIFT
));
157 cgs_write_register(hwmgr
->device
, reg
,
158 (cgs_read_register(hwmgr
->device
, reg
) &
159 ~CG_FDO_CTRL2__FDO_PWM_MODE_MASK
) |
160 (mode
<< CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT
));
166 * Reset Fan Speed Control to default mode.
167 * @param hwmgr the address of the powerplay hardware manager.
168 * @exception Should always succeed.
170 int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr
*hwmgr
)
174 reg
= soc15_get_register_offset(THM_HWID
, 0,
175 mmCG_FDO_CTRL2_BASE_IDX
, mmCG_FDO_CTRL2
);
177 if (!hwmgr
->fan_ctrl_is_in_default_mode
) {
178 cgs_write_register(hwmgr
->device
, reg
,
179 (cgs_read_register(hwmgr
->device
, reg
) &
180 ~CG_FDO_CTRL2__FDO_PWM_MODE_MASK
) |
181 (hwmgr
->fan_ctrl_default_mode
<<
182 CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT
));
183 cgs_write_register(hwmgr
->device
, reg
,
184 (cgs_read_register(hwmgr
->device
, reg
) &
185 ~CG_FDO_CTRL2__TMIN_MASK
) |
186 (hwmgr
->tmin
<< CG_FDO_CTRL2__TMIN__SHIFT
));
187 hwmgr
->fan_ctrl_is_in_default_mode
= true;
194 * @fn vega10_enable_fan_control_feature
195 * @brief Enables the SMC Fan Control Feature.
197 * @param hwmgr - the address of the powerplay hardware manager.
198 * @return 0 on success. -1 otherwise.
200 static int vega10_enable_fan_control_feature(struct pp_hwmgr
*hwmgr
)
202 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
204 if (data
->smu_features
[GNLD_FAN_CONTROL
].supported
) {
205 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(
207 data
->smu_features
[GNLD_FAN_CONTROL
].
209 "Attempt to Enable FAN CONTROL feature Failed!",
211 data
->smu_features
[GNLD_FAN_CONTROL
].enabled
= true;
217 static int vega10_disable_fan_control_feature(struct pp_hwmgr
*hwmgr
)
219 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
221 if (data
->smu_features
[GNLD_FAN_CONTROL
].supported
) {
222 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(
223 hwmgr
->smumgr
, false,
224 data
->smu_features
[GNLD_FAN_CONTROL
].
226 "Attempt to Enable FAN CONTROL feature Failed!",
228 data
->smu_features
[GNLD_FAN_CONTROL
].enabled
= false;
234 int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr
*hwmgr
)
236 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
239 PP_ASSERT_WITH_CODE(!vega10_enable_fan_control_feature(hwmgr
),
240 "Attempt to Enable SMC FAN CONTROL Feature Failed!",
247 int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr
*hwmgr
)
249 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
251 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
254 if (data
->smu_features
[GNLD_FAN_CONTROL
].supported
) {
255 PP_ASSERT_WITH_CODE(!vega10_disable_fan_control_feature(hwmgr
),
256 "Attempt to Disable SMC FAN CONTROL Feature Failed!",
263 * Set Fan Speed in percent.
264 * @param hwmgr the address of the powerplay hardware manager.
265 * @param speed is the percentage value (0% - 100%) to be set.
266 * @exception Fails is the 100% setting appears to be 0.
268 int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr
*hwmgr
,
276 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
282 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
283 PHM_PlatformCaps_MicrocodeFanControl
))
284 vega10_fan_ctrl_stop_smc_fan_control(hwmgr
);
286 reg
= soc15_get_register_offset(THM_HWID
, 0,
287 mmCG_FDO_CTRL1_BASE_IDX
, mmCG_FDO_CTRL1
);
289 duty100
= (cgs_read_register(hwmgr
->device
, reg
) &
290 CG_FDO_CTRL1__FMAX_DUTY100_MASK
) >>
291 CG_FDO_CTRL1__FMAX_DUTY100__SHIFT
;
296 tmp64
= (uint64_t)speed
* duty100
;
298 duty
= (uint32_t)tmp64
;
300 reg
= soc15_get_register_offset(THM_HWID
, 0,
301 mmCG_FDO_CTRL0_BASE_IDX
, mmCG_FDO_CTRL0
);
302 cgs_write_register(hwmgr
->device
, reg
,
303 (cgs_read_register(hwmgr
->device
, reg
) &
304 ~CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK
) |
305 (duty
<< CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT
));
307 return vega10_fan_ctrl_set_static_mode(hwmgr
, FDO_PWM_MODE_STATIC
);
311 * Reset Fan Speed to default.
312 * @param hwmgr the address of the powerplay hardware manager.
313 * @exception Always succeeds.
315 int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr
*hwmgr
)
319 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
322 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
323 PHM_PlatformCaps_MicrocodeFanControl
)) {
324 result
= vega10_fan_ctrl_set_static_mode(hwmgr
,
325 FDO_PWM_MODE_STATIC
);
327 result
= vega10_fan_ctrl_start_smc_fan_control(hwmgr
);
329 result
= vega10_fan_ctrl_set_default_mode(hwmgr
);
335 * Set Fan Speed in RPM.
336 * @param hwmgr the address of the powerplay hardware manager.
337 * @param speed is the percentage value (min - max) to be set.
338 * @exception Fails is the speed not lie between min and max.
340 int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr
*hwmgr
, uint32_t speed
)
342 uint32_t tach_period
;
343 uint32_t crystal_clock_freq
;
347 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
||
348 (speed
< hwmgr
->thermal_controller
.fanInfo
.ulMinRPM
) ||
349 (speed
> hwmgr
->thermal_controller
.fanInfo
.ulMaxRPM
))
352 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
353 PHM_PlatformCaps_MicrocodeFanControl
))
354 result
= vega10_fan_ctrl_stop_smc_fan_control(hwmgr
);
357 crystal_clock_freq
= smu7_get_xclk(hwmgr
);
358 tach_period
= 60 * crystal_clock_freq
* 10000 / (8 * speed
);
359 reg
= soc15_get_register_offset(THM_HWID
, 0,
360 mmCG_TACH_STATUS_BASE_IDX
, mmCG_TACH_STATUS
);
361 cgs_write_register(hwmgr
->device
, reg
,
362 (cgs_read_register(hwmgr
->device
, reg
) &
363 ~CG_TACH_STATUS__TACH_PERIOD_MASK
) |
364 (tach_period
<< CG_TACH_STATUS__TACH_PERIOD__SHIFT
));
366 return vega10_fan_ctrl_set_static_mode(hwmgr
, FDO_PWM_MODE_STATIC_RPM
);
370 * Reads the remote temperature from the SIslands thermal controller.
372 * @param hwmgr The address of the hardware manager.
374 int vega10_thermal_get_temperature(struct pp_hwmgr
*hwmgr
)
379 reg
= soc15_get_register_offset(THM_HWID
, 0,
380 mmCG_TACH_STATUS_BASE_IDX
, mmCG_MULT_THERMAL_STATUS
);
382 temp
= cgs_read_register(hwmgr
->device
, reg
);
384 temp
= (temp
& CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK
) >>
385 CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP__SHIFT
;
389 temp
*= PP_TEMPERATURE_UNITS_PER_CENTIGRADES
;
395 * Set the requested temperature range for high and low alert signals
397 * @param hwmgr The address of the hardware manager.
398 * @param range Temperature range to be programmed for
399 * high and low alert signals
400 * @exception PP_Result_BadInput if the input data is not valid.
402 static int vega10_thermal_set_temperature_range(struct pp_hwmgr
*hwmgr
,
403 struct PP_TemperatureRange
*range
)
405 uint32_t low
= VEGA10_THERMAL_MINIMUM_ALERT_TEMP
*
406 PP_TEMPERATURE_UNITS_PER_CENTIGRADES
;
407 uint32_t high
= VEGA10_THERMAL_MAXIMUM_ALERT_TEMP
*
408 PP_TEMPERATURE_UNITS_PER_CENTIGRADES
;
411 if (low
< range
->min
)
413 if (high
> range
->max
)
419 reg
= soc15_get_register_offset(THM_HWID
, 0,
420 mmTHM_THERMAL_INT_CTRL_BASE_IDX
, mmTHM_THERMAL_INT_CTRL
);
422 val
= cgs_read_register(hwmgr
->device
, reg
);
424 val
&= (~THM_THERMAL_INT_CTRL__MAX_IH_CREDIT_MASK
);
425 val
|= (5 << THM_THERMAL_INT_CTRL__MAX_IH_CREDIT__SHIFT
);
427 val
&= (~THM_THERMAL_INT_CTRL__THERM_IH_HW_ENA_MASK
);
428 val
|= (1 << THM_THERMAL_INT_CTRL__THERM_IH_HW_ENA__SHIFT
);
430 val
&= (~THM_THERMAL_INT_CTRL__DIG_THERM_INTH_MASK
);
431 val
|= ((high
/ PP_TEMPERATURE_UNITS_PER_CENTIGRADES
)
432 << THM_THERMAL_INT_CTRL__DIG_THERM_INTH__SHIFT
);
434 val
&= (~THM_THERMAL_INT_CTRL__DIG_THERM_INTL_MASK
);
435 val
|= ((low
/ PP_TEMPERATURE_UNITS_PER_CENTIGRADES
)
436 << THM_THERMAL_INT_CTRL__DIG_THERM_INTL__SHIFT
);
438 val
= val
& (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK
);
440 cgs_write_register(hwmgr
->device
, reg
, val
);
446 * Programs thermal controller one-time setting registers
448 * @param hwmgr The address of the hardware manager.
450 static int vega10_thermal_initialize(struct pp_hwmgr
*hwmgr
)
454 if (hwmgr
->thermal_controller
.fanInfo
.ucTachometerPulsesPerRevolution
) {
455 reg
= soc15_get_register_offset(THM_HWID
, 0,
456 mmCG_TACH_CTRL_BASE_IDX
, mmCG_TACH_CTRL
);
457 cgs_write_register(hwmgr
->device
, reg
,
458 (cgs_read_register(hwmgr
->device
, reg
) &
459 ~CG_TACH_CTRL__EDGE_PER_REV_MASK
) |
460 ((hwmgr
->thermal_controller
.fanInfo
.
461 ucTachometerPulsesPerRevolution
- 1) <<
462 CG_TACH_CTRL__EDGE_PER_REV__SHIFT
));
465 reg
= soc15_get_register_offset(THM_HWID
, 0,
466 mmCG_FDO_CTRL2_BASE_IDX
, mmCG_FDO_CTRL2
);
467 cgs_write_register(hwmgr
->device
, reg
,
468 (cgs_read_register(hwmgr
->device
, reg
) &
469 ~CG_FDO_CTRL2__TACH_PWM_RESP_RATE_MASK
) |
470 (0x28 << CG_FDO_CTRL2__TACH_PWM_RESP_RATE__SHIFT
));
476 * Enable thermal alerts on the RV770 thermal controller.
478 * @param hwmgr The address of the hardware manager.
480 static int vega10_thermal_enable_alert(struct pp_hwmgr
*hwmgr
)
482 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
486 if (data
->smu_features
[GNLD_FW_CTF
].supported
) {
487 if (data
->smu_features
[GNLD_FW_CTF
].enabled
)
488 printk("[Thermal_EnableAlert] FW CTF Already Enabled!\n");
490 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr
->smumgr
,
492 data
->smu_features
[GNLD_FW_CTF
].smu_feature_bitmap
),
493 "Attempt to Enable FW CTF feature Failed!",
495 data
->smu_features
[GNLD_FW_CTF
].enabled
= true;
498 val
|= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT
);
499 val
|= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT
);
500 val
|= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT
);
502 reg
= soc15_get_register_offset(THM_HWID
, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX
, mmTHM_THERMAL_INT_ENA
);
503 cgs_write_register(hwmgr
->device
, reg
, val
);
509 * Disable thermal alerts on the RV770 thermal controller.
510 * @param hwmgr The address of the hardware manager.
512 int vega10_thermal_disable_alert(struct pp_hwmgr
*hwmgr
)
514 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
517 if (data
->smu_features
[GNLD_FW_CTF
].supported
) {
518 if (!data
->smu_features
[GNLD_FW_CTF
].enabled
)
519 printk("[Thermal_EnableAlert] FW CTF Already disabled!\n");
522 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr
->smumgr
,
524 data
->smu_features
[GNLD_FW_CTF
].smu_feature_bitmap
),
525 "Attempt to disable FW CTF feature Failed!",
527 data
->smu_features
[GNLD_FW_CTF
].enabled
= false;
530 reg
= soc15_get_register_offset(THM_HWID
, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX
, mmTHM_THERMAL_INT_ENA
);
531 cgs_write_register(hwmgr
->device
, reg
, 0);
537 * Uninitialize the thermal controller.
538 * Currently just disables alerts.
539 * @param hwmgr The address of the hardware manager.
541 int vega10_thermal_stop_thermal_controller(struct pp_hwmgr
*hwmgr
)
543 int result
= vega10_thermal_disable_alert(hwmgr
);
545 if (!hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
546 vega10_fan_ctrl_set_default_mode(hwmgr
);
552 * Set up the fan table to control the fan using the SMC.
553 * @param hwmgr the address of the powerplay hardware manager.
554 * @param pInput the pointer to input data
555 * @param pOutput the pointer to output data
556 * @param pStorage the pointer to temporary storage
557 * @param Result the last failure code
558 * @return result from set temperature range routine
560 int tf_vega10_thermal_setup_fan_table(struct pp_hwmgr
*hwmgr
,
561 void *input
, void *output
, void *storage
, int result
)
564 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
565 PPTable_t
*table
= &(data
->smc_state_table
.pp_table
);
567 if (!data
->smu_features
[GNLD_FAN_CONTROL
].supported
)
570 table
->FanMaximumRpm
= (uint16_t)hwmgr
->thermal_controller
.
571 advanceFanControlParameters
.usMaxFanRPM
;
572 table
->FanThrottlingRpm
= hwmgr
->thermal_controller
.
573 advanceFanControlParameters
.usFanRPMMaxLimit
;
574 table
->FanAcousticLimitRpm
= (uint16_t)(hwmgr
->thermal_controller
.
575 advanceFanControlParameters
.ulMinFanSCLKAcousticLimit
);
576 table
->FanTargetTemperature
= hwmgr
->thermal_controller
.
577 advanceFanControlParameters
.usTMax
;
579 smum_send_msg_to_smc_with_parameter(hwmgr
->smumgr
,
580 PPSMC_MSG_SetFanTemperatureTarget
,
581 (uint32_t)table
->FanTargetTemperature
);
583 table
->FanPwmMin
= hwmgr
->thermal_controller
.
584 advanceFanControlParameters
.usPWMMin
* 255 / 100;
585 table
->FanTargetGfxclk
= (uint16_t)(hwmgr
->thermal_controller
.
586 advanceFanControlParameters
.ulTargetGfxClk
);
587 table
->FanGainEdge
= hwmgr
->thermal_controller
.
588 advanceFanControlParameters
.usFanGainEdge
;
589 table
->FanGainHotspot
= hwmgr
->thermal_controller
.
590 advanceFanControlParameters
.usFanGainHotspot
;
591 table
->FanGainLiquid
= hwmgr
->thermal_controller
.
592 advanceFanControlParameters
.usFanGainLiquid
;
593 table
->FanGainVrVddc
= hwmgr
->thermal_controller
.
594 advanceFanControlParameters
.usFanGainVrVddc
;
595 table
->FanGainVrMvdd
= hwmgr
->thermal_controller
.
596 advanceFanControlParameters
.usFanGainVrMvdd
;
597 table
->FanGainPlx
= hwmgr
->thermal_controller
.
598 advanceFanControlParameters
.usFanGainPlx
;
599 table
->FanGainHbm
= hwmgr
->thermal_controller
.
600 advanceFanControlParameters
.usFanGainHbm
;
601 table
->FanZeroRpmEnable
= hwmgr
->thermal_controller
.
602 advanceFanControlParameters
.ucEnableZeroRPM
;
603 table
->FanStopTemp
= hwmgr
->thermal_controller
.
604 advanceFanControlParameters
.usZeroRPMStopTemperature
;
605 table
->FanStartTemp
= hwmgr
->thermal_controller
.
606 advanceFanControlParameters
.usZeroRPMStartTemperature
;
608 ret
= vega10_copy_table_to_smc(hwmgr
->smumgr
,
609 (uint8_t *)(&(data
->smc_state_table
.pp_table
)), PPTABLE
);
611 pr_info("Failed to update Fan Control Table in PPTable!");
617 * Start the fan control on the SMC.
618 * @param hwmgr the address of the powerplay hardware manager.
619 * @param pInput the pointer to input data
620 * @param pOutput the pointer to output data
621 * @param pStorage the pointer to temporary storage
622 * @param Result the last failure code
623 * @return result from set temperature range routine
625 int tf_vega10_thermal_start_smc_fan_control(struct pp_hwmgr
*hwmgr
,
626 void *input
, void *output
, void *storage
, int result
)
628 /* If the fantable setup has failed we could have disabled
629 * PHM_PlatformCaps_MicrocodeFanControl even after
630 * this function was included in the table.
631 * Make sure that we still think controlling the fan is OK.
633 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
634 PHM_PlatformCaps_MicrocodeFanControl
)) {
635 vega10_fan_ctrl_start_smc_fan_control(hwmgr
);
636 vega10_fan_ctrl_set_static_mode(hwmgr
, FDO_PWM_MODE_STATIC
);
643 * Set temperature range for high and low alerts
644 * @param hwmgr the address of the powerplay hardware manager.
645 * @param pInput the pointer to input data
646 * @param pOutput the pointer to output data
647 * @param pStorage the pointer to temporary storage
648 * @param Result the last failure code
649 * @return result from set temperature range routine
651 int tf_vega10_thermal_set_temperature_range(struct pp_hwmgr
*hwmgr
,
652 void *input
, void *output
, void *storage
, int result
)
654 struct PP_TemperatureRange
*range
= (struct PP_TemperatureRange
*)input
;
659 return vega10_thermal_set_temperature_range(hwmgr
, range
);
663 * Programs one-time setting registers
664 * @param hwmgr the address of the powerplay hardware manager.
665 * @param pInput the pointer to input data
666 * @param pOutput the pointer to output data
667 * @param pStorage the pointer to temporary storage
668 * @param Result the last failure code
669 * @return result from initialize thermal controller routine
671 int tf_vega10_thermal_initialize(struct pp_hwmgr
*hwmgr
,
672 void *input
, void *output
, void *storage
, int result
)
674 return vega10_thermal_initialize(hwmgr
);
678 * Enable high and low alerts
679 * @param hwmgr the address of the powerplay hardware manager.
680 * @param pInput the pointer to input data
681 * @param pOutput the pointer to output data
682 * @param pStorage the pointer to temporary storage
683 * @param Result the last failure code
684 * @return result from enable alert routine
686 int tf_vega10_thermal_enable_alert(struct pp_hwmgr
*hwmgr
,
687 void *input
, void *output
, void *storage
, int result
)
689 return vega10_thermal_enable_alert(hwmgr
);
693 * Disable high and low alerts
694 * @param hwmgr the address of the powerplay hardware manager.
695 * @param pInput the pointer to input data
696 * @param pOutput the pointer to output data
697 * @param pStorage the pointer to temporary storage
698 * @param Result the last failure code
699 * @return result from disable alert routine
701 static int tf_vega10_thermal_disable_alert(struct pp_hwmgr
*hwmgr
,
702 void *input
, void *output
, void *storage
, int result
)
704 return vega10_thermal_disable_alert(hwmgr
);
707 static struct phm_master_table_item
708 vega10_thermal_start_thermal_controller_master_list
[] = {
709 { .tableFunction
= tf_vega10_thermal_initialize
},
710 { .tableFunction
= tf_vega10_thermal_set_temperature_range
},
711 { .tableFunction
= tf_vega10_thermal_enable_alert
},
712 /* We should restrict performance levels to low before we halt the SMC.
713 * On the other hand we are still in boot state when we do this
714 * so it would be pointless.
715 * If this assumption changes we have to revisit this table.
717 { .tableFunction
= tf_vega10_thermal_setup_fan_table
},
718 { .tableFunction
= tf_vega10_thermal_start_smc_fan_control
},
722 static struct phm_master_table_header
723 vega10_thermal_start_thermal_controller_master
= {
725 PHM_MasterTableFlag_None
,
726 vega10_thermal_start_thermal_controller_master_list
729 static struct phm_master_table_item
730 vega10_thermal_set_temperature_range_master_list
[] = {
731 { .tableFunction
= tf_vega10_thermal_disable_alert
},
732 { .tableFunction
= tf_vega10_thermal_set_temperature_range
},
733 { .tableFunction
= tf_vega10_thermal_enable_alert
},
737 struct phm_master_table_header
738 vega10_thermal_set_temperature_range_master
= {
740 PHM_MasterTableFlag_None
,
741 vega10_thermal_set_temperature_range_master_list
744 int vega10_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr
*hwmgr
)
746 if (!hwmgr
->thermal_controller
.fanInfo
.bNoFan
) {
747 vega10_fan_ctrl_set_default_mode(hwmgr
);
748 vega10_fan_ctrl_stop_smc_fan_control(hwmgr
);
754 * Initializes the thermal controller related functions
755 * in the Hardware Manager structure.
756 * @param hwmgr The address of the hardware manager.
757 * @exception Any error code from the low-level communication.
759 int pp_vega10_thermal_initialize(struct pp_hwmgr
*hwmgr
)
763 result
= phm_construct_table(hwmgr
,
764 &vega10_thermal_set_temperature_range_master
,
765 &(hwmgr
->set_temperature_range
));
768 result
= phm_construct_table(hwmgr
,
769 &vega10_thermal_start_thermal_controller_master
,
770 &(hwmgr
->start_thermal_controller
));
772 phm_destroy_table(hwmgr
,
773 &(hwmgr
->set_temperature_range
));
777 hwmgr
->fan_ctrl_is_in_default_mode
= true;