mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
drm/amd/powerplay: implement pwm1 hwmon interface for SMU11 (v2)
added main functions: get_fan_speed_percent set_fan_speed_percent. added dependent functions: smc_fan_control set_fan_static_mode get_fan_speed_percent v2: fix coding style issue Signed-off-by: Chengming Gui <Jack.Gui@amd.com> Reviewed-by: Huang Rui <ray.huang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
46814f5152
commit
008a9524cf
3 changed files with 112 additions and 4 deletions
|
@ -1444,8 +1444,10 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,
|
|||
if ((adev->flags & AMD_IS_PX) &&
|
||||
(adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
|
||||
return -EINVAL;
|
||||
|
||||
pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
|
||||
if (is_support_sw_smu(adev))
|
||||
pwm_mode = smu_get_fan_control_mode(&adev->smu);
|
||||
else
|
||||
pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
|
||||
if (pwm_mode != AMD_FAN_CTRL_MANUAL) {
|
||||
pr_info("manual fan speed control should be enabled first\n");
|
||||
return -EINVAL;
|
||||
|
@ -1457,7 +1459,11 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,
|
|||
|
||||
value = (value * 100) / 255;
|
||||
|
||||
if (adev->powerplay.pp_funcs->set_fan_speed_percent) {
|
||||
if (is_support_sw_smu(adev)) {
|
||||
err = smu_set_fan_speed_percent(&adev->smu, value);
|
||||
if (err)
|
||||
return err;
|
||||
} else if (adev->powerplay.pp_funcs->set_fan_speed_percent) {
|
||||
err = amdgpu_dpm_set_fan_speed_percent(adev, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -1479,7 +1485,11 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev,
|
|||
(adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
|
||||
return -EINVAL;
|
||||
|
||||
if (adev->powerplay.pp_funcs->get_fan_speed_percent) {
|
||||
if (is_support_sw_smu(adev)) {
|
||||
err = smu_get_fan_speed_percent(&adev->smu, &speed);
|
||||
if (err)
|
||||
return err;
|
||||
} else if (adev->powerplay.pp_funcs->get_fan_speed_percent) {
|
||||
err = amdgpu_dpm_get_fan_speed_percent(adev, &speed);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
@ -532,6 +532,9 @@ struct smu_funcs
|
|||
uint32_t (*get_sclk)(struct smu_context *smu, bool low);
|
||||
uint32_t (*get_mclk)(struct smu_context *smu, bool low);
|
||||
int (*get_current_rpm)(struct smu_context *smu, uint32_t *speed);
|
||||
uint32_t (*get_fan_control_mode)(struct smu_context *smu);
|
||||
int (*get_fan_speed_percent)(struct smu_context *smu, uint32_t *speed);
|
||||
int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed);
|
||||
};
|
||||
|
||||
#define smu_init_microcode(smu) \
|
||||
|
@ -664,6 +667,12 @@ struct smu_funcs
|
|||
((smu)->ppt_funcs->get_profiling_clk_mask ? (smu)->ppt_funcs->get_profiling_clk_mask((smu), (level), (sclk_mask), (mclk_mask), (soc_mask)) : 0)
|
||||
#define smu_set_cpu_power_state(smu) \
|
||||
((smu)->ppt_funcs->set_cpu_power_state ? (smu)->ppt_funcs->set_cpu_power_state((smu)) : 0)
|
||||
#define smu_get_fan_control_mode(smu) \
|
||||
((smu)->funcs->get_fan_control_mode ? (smu)->funcs->get_fan_control_mode((smu)) : 0)
|
||||
#define smu_get_fan_speed_percent(smu, speed) \
|
||||
((smu)->funcs->get_fan_speed_percent ? (smu)->funcs->get_fan_speed_percent((smu), (speed)) : 0)
|
||||
#define smu_set_fan_speed_percent(smu, speed) \
|
||||
((smu)->funcs->set_fan_speed_percent ? (smu)->funcs->set_fan_speed_percent((smu), (speed)) : 0)
|
||||
|
||||
#define smu_msg_get_index(smu, msg) \
|
||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
||||
|
|
|
@ -1748,6 +1748,92 @@ static int smu_v11_0_get_current_rpm(struct smu_context *smu,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
smu_v11_0_get_fan_control_mode(struct smu_context *smu)
|
||||
{
|
||||
if (!smu_feature_is_enabled(smu, FEATURE_FAN_CONTROL_BIT))
|
||||
return AMD_FAN_CTRL_MANUAL;
|
||||
else
|
||||
return AMD_FAN_CTRL_AUTO;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v11_0_get_fan_speed_percent(struct smu_context *smu,
|
||||
uint32_t *speed)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t percent = 0;
|
||||
uint32_t current_rpm;
|
||||
PPTable_t *pptable = smu->smu_table.driver_pptable;
|
||||
|
||||
ret = smu_v11_0_get_current_rpm(smu, ¤t_rpm);
|
||||
percent = current_rpm * 100 / pptable->FanMaximumRpm;
|
||||
*speed = percent > 100 ? 100 : percent;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v11_0_smc_fan_control(struct smu_context *smu, bool start)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (smu_feature_is_supported(smu, FEATURE_FAN_CONTROL_BIT))
|
||||
return 0;
|
||||
|
||||
ret = smu_feature_set_enabled(smu, FEATURE_FAN_CONTROL_BIT, start);
|
||||
if (ret)
|
||||
pr_err("[%s]%s smc FAN CONTROL feature failed!",
|
||||
__func__, (start ? "Start" : "Stop"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
|
||||
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
|
||||
CG_FDO_CTRL2, TMIN, 0));
|
||||
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
|
||||
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
|
||||
CG_FDO_CTRL2, FDO_PWM_MODE, mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
uint32_t duty100;
|
||||
uint32_t duty;
|
||||
uint64_t tmp64;
|
||||
bool stop = 0;
|
||||
|
||||
if (speed > 100)
|
||||
speed = 100;
|
||||
|
||||
if (smu_v11_0_smc_fan_control(smu, stop))
|
||||
return -EINVAL;
|
||||
duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
|
||||
CG_FDO_CTRL1, FMAX_DUTY100);
|
||||
if (!duty100)
|
||||
return -EINVAL;
|
||||
|
||||
tmp64 = (uint64_t)speed * duty100;
|
||||
do_div(tmp64, 100);
|
||||
duty = (uint32_t)tmp64;
|
||||
|
||||
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
|
||||
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
|
||||
CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
|
||||
|
||||
return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
|
||||
}
|
||||
|
||||
static const struct smu_funcs smu_v11_0_funcs = {
|
||||
.init_microcode = smu_v11_0_init_microcode,
|
||||
.load_microcode = smu_v11_0_load_microcode,
|
||||
|
@ -1799,6 +1885,9 @@ static const struct smu_funcs smu_v11_0_funcs = {
|
|||
.dpm_set_uvd_enable = smu_v11_0_dpm_set_uvd_enable,
|
||||
.dpm_set_vce_enable = smu_v11_0_dpm_set_vce_enable,
|
||||
.get_current_rpm = smu_v11_0_get_current_rpm,
|
||||
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||
.get_fan_speed_percent = smu_v11_0_get_fan_speed_percent,
|
||||
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||
};
|
||||
|
||||
void smu_v11_0_set_smu_funcs(struct smu_context *smu)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue