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__CTF_TEMP_MASK
) >>
385 CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT
;
387 /* Bit 9 means the reading is lower than the lowest usable value. */
389 temp
= VEGA10_THERMAL_MAXIMUM_TEMP_READING
;
393 temp
*= PP_TEMPERATURE_UNITS_PER_CENTIGRADES
;
399 * Set the requested temperature range for high and low alert signals
401 * @param hwmgr The address of the hardware manager.
402 * @param range Temperature range to be programmed for
403 * high and low alert signals
404 * @exception PP_Result_BadInput if the input data is not valid.
406 static int vega10_thermal_set_temperature_range(struct pp_hwmgr
*hwmgr
,
407 struct PP_TemperatureRange
*range
)
409 uint32_t low
= VEGA10_THERMAL_MINIMUM_ALERT_TEMP
*
410 PP_TEMPERATURE_UNITS_PER_CENTIGRADES
;
411 uint32_t high
= VEGA10_THERMAL_MAXIMUM_ALERT_TEMP
*
412 PP_TEMPERATURE_UNITS_PER_CENTIGRADES
;
415 if (low
< range
->min
)
417 if (high
> range
->max
)
423 reg
= soc15_get_register_offset(THM_HWID
, 0,
424 mmTHM_THERMAL_INT_CTRL_BASE_IDX
, mmTHM_THERMAL_INT_CTRL
);
426 val
= cgs_read_register(hwmgr
->device
, reg
);
427 val
&= ~(THM_THERMAL_INT_CTRL__DIG_THERM_INTH_MASK
);
428 val
|= (high
/ PP_TEMPERATURE_UNITS_PER_CENTIGRADES
) <<
429 THM_THERMAL_INT_CTRL__DIG_THERM_INTH__SHIFT
;
430 val
&= ~(THM_THERMAL_INT_CTRL__DIG_THERM_INTL_MASK
);
431 val
|= (low
/ PP_TEMPERATURE_UNITS_PER_CENTIGRADES
) <<
432 THM_THERMAL_INT_CTRL__DIG_THERM_INTL__SHIFT
;
433 cgs_write_register(hwmgr
->device
, reg
, val
);
435 reg
= soc15_get_register_offset(THM_HWID
, 0,
436 mmTHM_TCON_HTC_BASE_IDX
, mmTHM_TCON_HTC
);
438 val
= cgs_read_register(hwmgr
->device
, reg
);
439 val
&= ~(THM_TCON_HTC__HTC_TMP_LMT_MASK
);
440 val
|= (high
/ PP_TEMPERATURE_UNITS_PER_CENTIGRADES
) <<
441 THM_TCON_HTC__HTC_TMP_LMT__SHIFT
;
442 cgs_write_register(hwmgr
->device
, reg
, val
);
448 * Programs thermal controller one-time setting registers
450 * @param hwmgr The address of the hardware manager.
452 static int vega10_thermal_initialize(struct pp_hwmgr
*hwmgr
)
456 if (hwmgr
->thermal_controller
.fanInfo
.ucTachometerPulsesPerRevolution
) {
457 reg
= soc15_get_register_offset(THM_HWID
, 0,
458 mmCG_TACH_CTRL_BASE_IDX
, mmCG_TACH_CTRL
);
459 cgs_write_register(hwmgr
->device
, reg
,
460 (cgs_read_register(hwmgr
->device
, reg
) &
461 ~CG_TACH_CTRL__EDGE_PER_REV_MASK
) |
462 ((hwmgr
->thermal_controller
.fanInfo
.
463 ucTachometerPulsesPerRevolution
- 1) <<
464 CG_TACH_CTRL__EDGE_PER_REV__SHIFT
));
467 reg
= soc15_get_register_offset(THM_HWID
, 0,
468 mmCG_FDO_CTRL2_BASE_IDX
, mmCG_FDO_CTRL2
);
469 cgs_write_register(hwmgr
->device
, reg
,
470 (cgs_read_register(hwmgr
->device
, reg
) &
471 ~CG_FDO_CTRL2__TACH_PWM_RESP_RATE_MASK
) |
472 (0x28 << CG_FDO_CTRL2__TACH_PWM_RESP_RATE__SHIFT
));
478 * Enable thermal alerts on the RV770 thermal controller.
480 * @param hwmgr The address of the hardware manager.
482 static int vega10_thermal_enable_alert(struct pp_hwmgr
*hwmgr
)
484 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");
491 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr
->smumgr
,
493 data
->smu_features
[GNLD_FW_CTF
].smu_feature_bitmap
),
494 "Attempt to Enable FW CTF feature Failed!",
496 data
->smu_features
[GNLD_FW_CTF
].enabled
= true;
501 * Disable thermal alerts on the RV770 thermal controller.
502 * @param hwmgr The address of the hardware manager.
504 static int vega10_thermal_disable_alert(struct pp_hwmgr
*hwmgr
)
506 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
508 if (data
->smu_features
[GNLD_FW_CTF
].supported
) {
509 if (!data
->smu_features
[GNLD_FW_CTF
].enabled
)
510 printk("[Thermal_EnableAlert] FW CTF Already disabled!\n");
513 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr
->smumgr
,
515 data
->smu_features
[GNLD_FW_CTF
].smu_feature_bitmap
),
516 "Attempt to disable FW CTF feature Failed!",
518 data
->smu_features
[GNLD_FW_CTF
].enabled
= false;
523 * Uninitialize the thermal controller.
524 * Currently just disables alerts.
525 * @param hwmgr The address of the hardware manager.
527 int vega10_thermal_stop_thermal_controller(struct pp_hwmgr
*hwmgr
)
529 int result
= vega10_thermal_disable_alert(hwmgr
);
531 if (!hwmgr
->thermal_controller
.fanInfo
.bNoFan
)
532 vega10_fan_ctrl_set_default_mode(hwmgr
);
538 * Set up the fan table to control the fan using the SMC.
539 * @param hwmgr the address of the powerplay hardware manager.
540 * @param pInput the pointer to input data
541 * @param pOutput the pointer to output data
542 * @param pStorage the pointer to temporary storage
543 * @param Result the last failure code
544 * @return result from set temperature range routine
546 int tf_vega10_thermal_setup_fan_table(struct pp_hwmgr
*hwmgr
,
547 void *input
, void *output
, void *storage
, int result
)
550 struct vega10_hwmgr
*data
= (struct vega10_hwmgr
*)(hwmgr
->backend
);
551 PPTable_t
*table
= &(data
->smc_state_table
.pp_table
);
553 if (!data
->smu_features
[GNLD_FAN_CONTROL
].supported
)
556 table
->FanMaximumRpm
= (uint16_t)hwmgr
->thermal_controller
.
557 advanceFanControlParameters
.usMaxFanRPM
;
558 table
->FanThrottlingRpm
= hwmgr
->thermal_controller
.
559 advanceFanControlParameters
.usFanRPMMaxLimit
;
560 table
->FanAcousticLimitRpm
= (uint16_t)(hwmgr
->thermal_controller
.
561 advanceFanControlParameters
.ulMinFanSCLKAcousticLimit
);
562 table
->FanTargetTemperature
= hwmgr
->thermal_controller
.
563 advanceFanControlParameters
.usTMax
;
564 table
->FanPwmMin
= hwmgr
->thermal_controller
.
565 advanceFanControlParameters
.usPWMMin
* 255 / 100;
566 table
->FanTargetGfxclk
= (uint16_t)(hwmgr
->thermal_controller
.
567 advanceFanControlParameters
.ulTargetGfxClk
);
568 table
->FanGainEdge
= hwmgr
->thermal_controller
.
569 advanceFanControlParameters
.usFanGainEdge
;
570 table
->FanGainHotspot
= hwmgr
->thermal_controller
.
571 advanceFanControlParameters
.usFanGainHotspot
;
572 table
->FanGainLiquid
= hwmgr
->thermal_controller
.
573 advanceFanControlParameters
.usFanGainLiquid
;
574 table
->FanGainVrVddc
= hwmgr
->thermal_controller
.
575 advanceFanControlParameters
.usFanGainVrVddc
;
576 table
->FanGainVrMvdd
= hwmgr
->thermal_controller
.
577 advanceFanControlParameters
.usFanGainVrMvdd
;
578 table
->FanGainPlx
= hwmgr
->thermal_controller
.
579 advanceFanControlParameters
.usFanGainPlx
;
580 table
->FanGainHbm
= hwmgr
->thermal_controller
.
581 advanceFanControlParameters
.usFanGainHbm
;
582 table
->FanZeroRpmEnable
= hwmgr
->thermal_controller
.
583 advanceFanControlParameters
.ucEnableZeroRPM
;
584 table
->FanStopTemp
= hwmgr
->thermal_controller
.
585 advanceFanControlParameters
.usZeroRPMStopTemperature
;
586 table
->FanStartTemp
= hwmgr
->thermal_controller
.
587 advanceFanControlParameters
.usZeroRPMStartTemperature
;
589 ret
= vega10_copy_table_to_smc(hwmgr
->smumgr
,
590 (uint8_t *)(&(data
->smc_state_table
.pp_table
)), PPTABLE
);
592 pr_info("Failed to update Fan Control Table in PPTable!");
598 * Start the fan control on the SMC.
599 * @param hwmgr the address of the powerplay hardware manager.
600 * @param pInput the pointer to input data
601 * @param pOutput the pointer to output data
602 * @param pStorage the pointer to temporary storage
603 * @param Result the last failure code
604 * @return result from set temperature range routine
606 int tf_vega10_thermal_start_smc_fan_control(struct pp_hwmgr
*hwmgr
,
607 void *input
, void *output
, void *storage
, int result
)
609 /* If the fantable setup has failed we could have disabled
610 * PHM_PlatformCaps_MicrocodeFanControl even after
611 * this function was included in the table.
612 * Make sure that we still think controlling the fan is OK.
614 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
615 PHM_PlatformCaps_MicrocodeFanControl
)) {
616 vega10_fan_ctrl_start_smc_fan_control(hwmgr
);
617 vega10_fan_ctrl_set_static_mode(hwmgr
, FDO_PWM_MODE_STATIC
);
624 * Set temperature range for high and low alerts
625 * @param hwmgr the address of the powerplay hardware manager.
626 * @param pInput the pointer to input data
627 * @param pOutput the pointer to output data
628 * @param pStorage the pointer to temporary storage
629 * @param Result the last failure code
630 * @return result from set temperature range routine
632 int tf_vega10_thermal_set_temperature_range(struct pp_hwmgr
*hwmgr
,
633 void *input
, void *output
, void *storage
, int result
)
635 struct PP_TemperatureRange
*range
= (struct PP_TemperatureRange
*)input
;
640 return vega10_thermal_set_temperature_range(hwmgr
, range
);
644 * Programs one-time setting registers
645 * @param hwmgr the address of the powerplay hardware manager.
646 * @param pInput the pointer to input data
647 * @param pOutput the pointer to output data
648 * @param pStorage the pointer to temporary storage
649 * @param Result the last failure code
650 * @return result from initialize thermal controller routine
652 int tf_vega10_thermal_initialize(struct pp_hwmgr
*hwmgr
,
653 void *input
, void *output
, void *storage
, int result
)
655 return vega10_thermal_initialize(hwmgr
);
659 * Enable high and low alerts
660 * @param hwmgr the address of the powerplay hardware manager.
661 * @param pInput the pointer to input data
662 * @param pOutput the pointer to output data
663 * @param pStorage the pointer to temporary storage
664 * @param Result the last failure code
665 * @return result from enable alert routine
667 int tf_vega10_thermal_enable_alert(struct pp_hwmgr
*hwmgr
,
668 void *input
, void *output
, void *storage
, int result
)
670 return vega10_thermal_enable_alert(hwmgr
);
674 * Disable high and low alerts
675 * @param hwmgr the address of the powerplay hardware manager.
676 * @param pInput the pointer to input data
677 * @param pOutput the pointer to output data
678 * @param pStorage the pointer to temporary storage
679 * @param Result the last failure code
680 * @return result from disable alert routine
682 static int tf_vega10_thermal_disable_alert(struct pp_hwmgr
*hwmgr
,
683 void *input
, void *output
, void *storage
, int result
)
685 return vega10_thermal_disable_alert(hwmgr
);
688 static struct phm_master_table_item
689 vega10_thermal_start_thermal_controller_master_list
[] = {
690 {NULL
, tf_vega10_thermal_initialize
},
691 {NULL
, tf_vega10_thermal_set_temperature_range
},
692 {NULL
, tf_vega10_thermal_enable_alert
},
693 /* We should restrict performance levels to low before we halt the SMC.
694 * On the other hand we are still in boot state when we do this
695 * so it would be pointless.
696 * If this assumption changes we have to revisit this table.
698 {NULL
, tf_vega10_thermal_setup_fan_table
},
699 {NULL
, tf_vega10_thermal_start_smc_fan_control
},
703 static struct phm_master_table_header
704 vega10_thermal_start_thermal_controller_master
= {
706 PHM_MasterTableFlag_None
,
707 vega10_thermal_start_thermal_controller_master_list
710 static struct phm_master_table_item
711 vega10_thermal_set_temperature_range_master_list
[] = {
712 {NULL
, tf_vega10_thermal_disable_alert
},
713 {NULL
, tf_vega10_thermal_set_temperature_range
},
714 {NULL
, tf_vega10_thermal_enable_alert
},
718 struct phm_master_table_header
719 vega10_thermal_set_temperature_range_master
= {
721 PHM_MasterTableFlag_None
,
722 vega10_thermal_set_temperature_range_master_list
725 int vega10_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr
*hwmgr
)
727 if (!hwmgr
->thermal_controller
.fanInfo
.bNoFan
) {
728 vega10_fan_ctrl_set_default_mode(hwmgr
);
729 vega10_fan_ctrl_stop_smc_fan_control(hwmgr
);
735 * Initializes the thermal controller related functions
736 * in the Hardware Manager structure.
737 * @param hwmgr The address of the hardware manager.
738 * @exception Any error code from the low-level communication.
740 int pp_vega10_thermal_initialize(struct pp_hwmgr
*hwmgr
)
744 result
= phm_construct_table(hwmgr
,
745 &vega10_thermal_set_temperature_range_master
,
746 &(hwmgr
->set_temperature_range
));
749 result
= phm_construct_table(hwmgr
,
750 &vega10_thermal_start_thermal_controller_master
,
751 &(hwmgr
->start_thermal_controller
));
753 phm_destroy_table(hwmgr
,
754 &(hwmgr
->set_temperature_range
));
758 hwmgr
->fan_ctrl_is_in_default_mode
= true;