[PATCH 2/3] drm/amd/powerplay: added hwmon interfaces for setting max/min fan speed

Evan Quan evan.quan at amd.com
Wed Oct 24 08:11:40 UTC 2018


New hwmon interfaces for maximum and minimum fan speed setting.

Change-Id: Ic9ec9f2427c6d3425e1c7e7b765d7d01a92f9a26
Signed-off-by: Evan Quan <evan.quan at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h       |  6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c        | 56 ++++++++++++++++++-
 .../gpu/drm/amd/include/kgd_pp_interface.h    |  2 +
 drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 46 +++++++++++++++
 drivers/gpu/drm/amd/powerplay/inc/hwmgr.h     |  2 +
 5 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index f972cd156795..12c4e461a7bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -364,6 +364,12 @@ enum amdgpu_pcie_gen {
 		((adev)->powerplay.pp_funcs->enable_mgpu_fan_boost(\
 			(adev)->powerplay.pp_handle))
 
+#define amdgpu_dpm_set_fan_speed_max_rpm(adev, s) \
+		((adev)->powerplay.pp_funcs->set_fan_speed_max_rpm)((adev)->powerplay.pp_handle, (s))
+
+#define amdgpu_dpm_set_fan_speed_min_rpm(adev, s) \
+		((adev)->powerplay.pp_funcs->set_fan_speed_min_rpm)((adev)->powerplay.pp_handle, (s))
+
 struct amdgpu_dpm {
 	struct amdgpu_ps        *ps;
 	/* number of valid power states */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 8e94255654ed..92da37bb51ba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1265,6 +1265,32 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", min_rpm);
 }
 
+static ssize_t amdgpu_hwmon_set_fan1_min(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct amdgpu_device *adev = dev_get_drvdata(dev);
+	int err;
+	u32 value;
+
+	/* Can't adjust fan when the card is off */
+	if  ((adev->flags & AMD_IS_PX) &&
+	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
+		return -EINVAL;
+
+	err = kstrtou32(buf, 10, &value);
+	if (err)
+		return err;
+
+	if (adev->powerplay.pp_funcs->set_fan_speed_min_rpm) {
+		err = amdgpu_dpm_set_fan_speed_min_rpm(adev, value);
+		if (err)
+			return err;
+	}
+
+	return count;
+}
+
 static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,
 					 struct device_attribute *attr,
 					 char *buf)
@@ -1285,6 +1311,32 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", max_rpm);
 }
 
+static ssize_t amdgpu_hwmon_set_fan1_max(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct amdgpu_device *adev = dev_get_drvdata(dev);
+	int err;
+	u32 value;
+
+	/* Can't adjust fan when the card is off */
+	if  ((adev->flags & AMD_IS_PX) &&
+	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
+		return -EINVAL;
+
+	err = kstrtou32(buf, 10, &value);
+	if (err)
+		return err;
+
+	if (adev->powerplay.pp_funcs->set_fan_speed_max_rpm) {
+		err = amdgpu_dpm_set_fan_speed_max_rpm(adev, value);
+		if (err)
+			return err;
+	}
+
+	return count;
+}
+
 static ssize_t amdgpu_hwmon_get_fan1_target(struct device *dev,
 					   struct device_attribute *attr,
 					   char *buf)
@@ -1628,8 +1680,8 @@ static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1_
 static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, amdgpu_hwmon_get_pwm1_min, NULL, 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(fan1_min, S_IRUGO, amdgpu_hwmon_get_fan1_min, NULL, 0);
-static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO, amdgpu_hwmon_get_fan1_max, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_fan1_min, amdgpu_hwmon_set_fan1_min, 0);
+static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_fan1_max, amdgpu_hwmon_set_fan1_max, 0);
 static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_fan1_target, amdgpu_hwmon_set_fan1_target, 0);
 static SENSOR_DEVICE_ATTR(fan1_enable, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_fan1_enable, amdgpu_hwmon_set_fan1_enable, 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 980e696989b1..1af55997bdb9 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -276,6 +276,8 @@ struct amd_pm_funcs {
 		struct amd_pp_simple_clock_info *clocks);
 	int (*notify_smu_enable_pwe)(void *handle);
 	int (*enable_mgpu_fan_boost)(void *handle);
+	int (*set_fan_speed_max_rpm)(void *handle, uint32_t rpm);
+	int (*set_fan_speed_min_rpm)(void *handle, uint32_t rpm);
 };
 
 #endif
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 586f1ff9f73e..f10237b4d057 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -603,6 +603,50 @@ static int pp_dpm_set_fan_speed_rpm(void *handle, uint32_t rpm)
 	return ret;
 }
 
+static int pp_dpm_set_fan_speed_max_rpm(void *handle, uint32_t rpm)
+{
+	struct pp_hwmgr *hwmgr = handle;
+	int ret = 0;
+
+	if (!hwmgr || !hwmgr->pm_en)
+		return -EINVAL;
+
+	if (hwmgr->hwmgr_func->set_fan_speed_max_rpm == NULL) {
+		pr_info("%s was not implemented.\n", __func__);
+		return -EOPNOTSUPP;
+	}
+	mutex_lock(&hwmgr->smu_lock);
+	ret = hwmgr->hwmgr_func->set_fan_speed_max_rpm(hwmgr, rpm);
+	mutex_unlock(&hwmgr->smu_lock);
+
+	if (!ret)
+		hwmgr->thermal_controller.fanInfo.ulMaxRPM = rpm;
+
+	return ret;
+}
+
+static int pp_dpm_set_fan_speed_min_rpm(void *handle, uint32_t rpm)
+{
+	struct pp_hwmgr *hwmgr = handle;
+	int ret = 0;
+
+	if (!hwmgr || !hwmgr->pm_en)
+		return -EINVAL;
+
+	if (hwmgr->hwmgr_func->set_fan_speed_min_rpm == NULL) {
+		pr_info("%s was not implemented.\n", __func__);
+		return -EOPNOTSUPP;
+	}
+	mutex_lock(&hwmgr->smu_lock);
+	ret = hwmgr->hwmgr_func->set_fan_speed_min_rpm(hwmgr, rpm);
+	mutex_unlock(&hwmgr->smu_lock);
+
+	if (!ret)
+		hwmgr->thermal_controller.fanInfo.ulMinRPM = rpm;
+
+	return ret;
+}
+
 static int pp_dpm_get_pp_num_states(void *handle,
 		struct pp_states_info *data)
 {
@@ -1342,6 +1386,8 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
 	.get_fan_speed_percent = pp_dpm_get_fan_speed_percent,
 	.get_fan_speed_rpm = pp_dpm_get_fan_speed_rpm,
 	.set_fan_speed_rpm = pp_dpm_set_fan_speed_rpm,
+	.set_fan_speed_max_rpm = pp_dpm_set_fan_speed_max_rpm,
+	.set_fan_speed_min_rpm = pp_dpm_set_fan_speed_min_rpm,
 	.get_pp_num_states = pp_dpm_get_pp_num_states,
 	.get_pp_table = pp_dpm_get_pp_table,
 	.set_pp_table = pp_dpm_set_pp_table,
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index 687f73fe4cf5..0242bc039a48 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -269,6 +269,8 @@ struct pp_hwmgr_func {
 	int (*get_fan_speed_percent)(struct pp_hwmgr *hwmgr, uint32_t *speed);
 	int (*set_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t percent);
 	int (*get_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t *speed);
+	int (*set_fan_speed_max_rpm)(struct pp_hwmgr *hwmgr, uint32_t max_rpm);
+	int (*set_fan_speed_min_rpm)(struct pp_hwmgr *hwmgr, uint32_t min_rpm);
 	int (*reset_fan_speed_to_default)(struct pp_hwmgr *hwmgr);
 	int (*uninitialize_thermal_controller)(struct pp_hwmgr *hwmgr);
 	int (*register_irq_handlers)(struct pp_hwmgr *hwmgr);
-- 
2.19.1



More information about the amd-gfx mailing list