[PATCH] RFC: drm/amdgpu/pp: writable hwmon/pwm1_min on vega10
Aleksandr Mezin
mezin.alexander at gmail.com
Thu Aug 9 02:53:19 UTC 2018
Sapphire Vega 64 Nitro+ is too noisy at idle, frequently switching
between zero-rpm mode and 1200 RPM.
As pwm1_min is currently always 0 (and thus completely useless), I:
- Made it writable so I can adjust min fan speed for "automatic" fan
control
- Changed amdgpu_hwmon_get_pwm1_min to return the value from fan
configuration table instead of 0
Probably pwm1_auto_point#_pwm and pwm1_auto_point#_temp are a better
interface to configure the fan curve, but for me it is not clear how
zero-rpm mode and parameters like FanThrottlingRpm should map to it.
Signed-off-by: Aleksandr Mezin <mezin.alexander at gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 37 +++++++++++++++++-
.../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 39 +++++++++++++++++++
.../drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +
.../drm/amd/powerplay/hwmgr/vega10_thermal.c | 23 +++++++++++
.../drm/amd/powerplay/hwmgr/vega10_thermal.h | 4 ++
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +
7 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 8f98629fbe59..588f4b4fdc76 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1057,7 +1057,40 @@ static ssize_t amdgpu_hwmon_get_pwm1_min(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%i\n", 0);
+ struct amdgpu_device *adev = dev_get_drvdata(dev);
+ void *handle = adev->powerplay.pp_handle;
+ int err;
+ u16 value = 0;
+
+ if (adev->powerplay.pp_funcs->get_min_fan_pwm) {
+ err = adev->powerplay.pp_funcs->get_min_fan_pwm(handle, &value);
+ if (err)
+ return err;
+ }
+
+ return sprintf(buf, "%u\n", (unsigned int)value);
+}
+
+static ssize_t amdgpu_hwmon_set_pwm1_min(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct amdgpu_device *adev = dev_get_drvdata(dev);
+ void *handle = adev->powerplay.pp_handle;
+ int err;
+ u16 value;
+
+ err = kstrtou16(buf, 10, &value);
+ if (err)
+ return err;
+
+ if (adev->powerplay.pp_funcs->set_min_fan_pwm) {
+ err = adev->powerplay.pp_funcs->set_min_fan_pwm(handle, value);
+ if (err)
+ return err;
+ }
+
+ return count;
}
static ssize_t amdgpu_hwmon_get_pwm1_max(struct device *dev,
@@ -1371,7 +1404,7 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NU
static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1);
static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1, amdgpu_hwmon_set_pwm1, 0);
static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1_enable, amdgpu_hwmon_set_pwm1_enable, 0);
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, amdgpu_hwmon_get_pwm1_min, NULL, 0);
+static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1_min, amdgpu_hwmon_set_pwm1_min, 0);
static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO, amdgpu_hwmon_get_pwm1_max, NULL, 0);
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, amdgpu_hwmon_get_fan1_input, NULL, 0);
static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, amdgpu_hwmon_show_vddgfx, NULL, 0);
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 6a41b81c7325..e421a6752d01 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -269,6 +269,8 @@ struct amd_pm_funcs {
int (*get_display_mode_validation_clocks)(void *handle,
struct amd_pp_simple_clock_info *clocks);
int (*notify_smu_enable_pwe)(void *handle);
+ int (*set_min_fan_pwm)(void *handle, u16 value);
+ int (*get_min_fan_pwm)(void *handle, u16 *value);
};
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 7a646f94b478..f3c4b0b937e3 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -522,6 +522,43 @@ static uint32_t pp_dpm_get_fan_control_mode(void *handle)
return mode;
}
+static int pp_dpm_set_min_fan_pwm(void *handle, uint16_t value)
+{
+ struct pp_hwmgr *hwmgr = handle;
+ int ret = 0;
+
+ if (!hwmgr || !hwmgr->pm_en)
+ return -EINVAL;
+
+ if (hwmgr->hwmgr_func->set_min_fan_pwm == NULL) {
+ pr_info("%s was not implemented.\n", __func__);
+ return 0;
+ }
+ mutex_lock(&hwmgr->smu_lock);
+ ret = hwmgr->hwmgr_func->set_min_fan_pwm(hwmgr, value);
+ mutex_unlock(&hwmgr->smu_lock);
+ return ret;
+}
+
+static int pp_dpm_get_min_fan_pwm(void *handle, uint16_t *value)
+{
+ struct pp_hwmgr *hwmgr = handle;
+ int ret = 0;
+
+ if (!hwmgr || !hwmgr->pm_en)
+ return -EINVAL;
+
+ if (hwmgr->hwmgr_func->get_min_fan_pwm == NULL) {
+ *value = 0;
+ return 0;
+ }
+
+ mutex_lock(&hwmgr->smu_lock);
+ ret = hwmgr->hwmgr_func->get_min_fan_pwm(hwmgr, value);
+ mutex_unlock(&hwmgr->smu_lock);
+ return ret;
+}
+
static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
{
struct pp_hwmgr *hwmgr = handle;
@@ -1269,4 +1306,6 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
.display_clock_voltage_request = pp_display_clock_voltage_request,
.get_display_mode_validation_clocks = pp_get_display_mode_validation_clocks,
.notify_smu_enable_pwe = pp_notify_smu_enable_pwe,
+ .set_min_fan_pwm = pp_dpm_set_min_fan_pwm,
+ .get_min_fan_pwm = pp_dpm_get_min_fan_pwm,
};
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index fb86c24394ff..6d766949ff26 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -4913,6 +4913,8 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
.set_power_profile_mode = vega10_set_power_profile_mode,
.set_power_limit = vega10_set_power_limit,
.odn_edit_dpm_table = vega10_odn_edit_dpm_table,
+ .get_min_fan_pwm = vega10_fan_ctrl_get_min_pwm,
+ .set_min_fan_pwm = vega10_fan_ctrl_set_min_pwm,
};
int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
index aa044c1955fe..28ebea24576b 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
@@ -616,3 +616,26 @@ int vega10_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
}
return 0;
}
+
+int vega10_fan_ctrl_get_min_pwm(struct pp_hwmgr *hwmgr, uint16_t *value)
+{
+ struct vega10_hwmgr *data = hwmgr->backend;
+ PPTable_t *table = &(data->smc_state_table.pp_table);
+
+ *value = table->FanPwmMin;
+ return 0;
+}
+
+int vega10_fan_ctrl_set_min_pwm(struct pp_hwmgr *hwmgr, uint16_t value)
+{
+ struct vega10_hwmgr *data = hwmgr->backend;
+ PPTable_t *table = &(data->smc_state_table.pp_table);
+
+ if (value > 255)
+ value = 255;
+
+ table->FanPwmMin = value;
+ hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin = value * 100 / 255;
+
+ return smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetFanMinPwm, table->FanPwmMin);
+}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h
index 21e7c4dfa2ca..bce15e293e6b 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h
@@ -73,6 +73,10 @@ extern int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr);
extern int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);
extern int vega10_start_thermal_controller(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range);
+extern int vega10_fan_ctrl_get_min_pwm(struct pp_hwmgr *hwmgr,
+ uint16_t *value);
+extern int vega10_fan_ctrl_set_min_pwm(struct pp_hwmgr *hwmgr,
+ uint16_t value);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index d3d96260f440..f104b8212e89 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -328,6 +328,8 @@ struct pp_hwmgr_func {
int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n);
int (*powergate_mmhub)(struct pp_hwmgr *hwmgr);
int (*smus_notify_pwe)(struct pp_hwmgr *hwmgr);
+ int (*get_min_fan_pwm)(struct pp_hwmgr *hwmgr, uint16_t *value);
+ int (*set_min_fan_pwm)(struct pp_hwmgr *hwmgr, uint16_t value);
};
struct pp_table_func {
--
2.18.0
More information about the amd-gfx
mailing list