drm/amd/pm: correct the fan speed RPM setting
The relationship "PWM = RPM / smu->fan_max_rpm" between fan speed PWM and RPM is not true for SMU11 ASICs. So, we need a new way to perform the fan speed RPM setting. Signed-off-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
893cf382c0
commit
f3289d0497
|
@ -1047,6 +1047,11 @@ struct pptable_funcs {
|
||||||
*/
|
*/
|
||||||
int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed);
|
int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @set_fan_speed_rpm: Set a static fan speed in rpm.
|
||||||
|
*/
|
||||||
|
int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @set_xgmi_pstate: Set inter-chip global memory interconnect pstate.
|
* @set_xgmi_pstate: Set inter-chip global memory interconnect pstate.
|
||||||
* &pstate: Pstate to set. D0 if Nonzero, D3 otherwise.
|
* &pstate: Pstate to set. D0 if Nonzero, D3 otherwise.
|
||||||
|
|
|
@ -224,6 +224,9 @@ smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
||||||
int smu_v11_0_set_fan_speed_percent(struct smu_context *smu,
|
int smu_v11_0_set_fan_speed_percent(struct smu_context *smu,
|
||||||
uint32_t speed);
|
uint32_t speed);
|
||||||
|
|
||||||
|
int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
||||||
|
uint32_t speed);
|
||||||
|
|
||||||
int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
|
int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
|
||||||
uint32_t pstate);
|
uint32_t pstate);
|
||||||
|
|
||||||
|
|
|
@ -2190,11 +2190,12 @@ static int smu_set_fan_speed_rpm(void *handle, uint32_t speed)
|
||||||
|
|
||||||
mutex_lock(&smu->mutex);
|
mutex_lock(&smu->mutex);
|
||||||
|
|
||||||
if (smu->ppt_funcs->set_fan_speed_percent) {
|
if (smu->ppt_funcs->set_fan_speed_rpm) {
|
||||||
percent = speed * 100 / smu->fan_max_rpm;
|
ret = smu->ppt_funcs->set_fan_speed_rpm(smu, speed);
|
||||||
ret = smu->ppt_funcs->set_fan_speed_percent(smu, percent);
|
if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE)) {
|
||||||
if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
|
percent = speed * 100 / smu->fan_max_rpm;
|
||||||
smu->user_dpm_profile.fan_speed_percent = percent;
|
smu->user_dpm_profile.fan_speed_percent = percent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&smu->mutex);
|
mutex_unlock(&smu->mutex);
|
||||||
|
|
|
@ -2316,6 +2316,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
|
||||||
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||||
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
||||||
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||||
|
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
||||||
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
||||||
.gfx_off_control = smu_v11_0_gfx_off_control,
|
.gfx_off_control = smu_v11_0_gfx_off_control,
|
||||||
.register_irq_handler = smu_v11_0_register_irq_handler,
|
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||||
|
|
|
@ -3271,6 +3271,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
|
||||||
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||||
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
||||||
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||||
|
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
||||||
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
||||||
.gfx_off_control = smu_v11_0_gfx_off_control,
|
.gfx_off_control = smu_v11_0_gfx_off_control,
|
||||||
.register_irq_handler = smu_v11_0_register_irq_handler,
|
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||||
|
|
|
@ -3903,6 +3903,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
|
||||||
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||||
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
||||||
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||||
|
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
||||||
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
||||||
.gfx_off_control = smu_v11_0_gfx_off_control,
|
.gfx_off_control = smu_v11_0_gfx_off_control,
|
||||||
.register_irq_handler = smu_v11_0_register_irq_handler,
|
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||||
|
|
|
@ -1228,6 +1228,41 @@ smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
|
||||||
return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
|
return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
||||||
|
uint32_t speed)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
/*
|
||||||
|
* crystal_clock_freq used for fan speed rpm calculation is
|
||||||
|
* always 25Mhz. So, hardcode it as 2500(in 10K unit).
|
||||||
|
*/
|
||||||
|
uint32_t crystal_clock_freq = 2500;
|
||||||
|
uint32_t tach_period;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = smu_v11_0_auto_fan_control(smu, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To prevent from possible overheat, some ASICs may have requirement
|
||||||
|
* for minimum fan speed:
|
||||||
|
* - For some NV10 SKU, the fan speed cannot be set lower than
|
||||||
|
* 700 RPM.
|
||||||
|
* - For some Sienna Cichlid SKU, the fan speed cannot be set
|
||||||
|
* lower than 500 RPM.
|
||||||
|
*/
|
||||||
|
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
|
||||||
|
WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
|
||||||
|
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
|
||||||
|
CG_TACH_CTRL, TARGET_PERIOD,
|
||||||
|
tach_period));
|
||||||
|
|
||||||
|
ret = smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC_RPM);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
||||||
uint32_t mode)
|
uint32_t mode)
|
||||||
|
|
Loading…
Reference in New Issue