diff options
author | Evan Quan <evan.quan@amd.com> | 2021-02-09 12:10:43 +0800 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-08-16 15:35:56 -0400 |
commit | fb1f667e71c079defa5918b8f457faa48120b6f1 (patch) | |
tree | a4245e3e8de76642188a8cfe006ebd1be26ad0a3 /drivers/gpu/drm/amd/pm/powerplay | |
parent | 96401f7c21900ad03b67e49cc3b8e6aa7cccba74 (diff) |
drm/amd/pm: correct the fan speed PWM retrieving
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
retrieving the fan speed PWM.
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>
Diffstat (limited to 'drivers/gpu/drm/amd/pm/powerplay')
-rw-r--r-- | drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c index 269dd7e95a44..43d754952bd9 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c @@ -117,18 +117,24 @@ static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed) { - struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); - PPTable_t *pp_table = &(data->smc_state_table.pp_table); - uint32_t current_rpm, percent = 0; - int ret = 0; + struct amdgpu_device *adev = hwmgr->adev; + uint32_t duty100, duty; + uint64_t tmp64; - ret = vega20_get_current_rpm(hwmgr, ¤t_rpm); - if (ret) - return ret; + duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), + CG_FDO_CTRL1, FMAX_DUTY100); + duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS), + CG_THERMAL_STATUS, FDO_PWM_DUTY); + + if (!duty100) + return -EINVAL; - percent = current_rpm * 100 / pp_table->FanMaximumRpm; + tmp64 = (uint64_t)duty * 100; + do_div(tmp64, duty100); + *speed = (uint32_t)tmp64; - *speed = percent > 100 ? 100 : percent; + if (*speed > 100) + *speed = 100; return 0; } |