* [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13
@ 2024-10-19 14:37 Wolfgang Müller
2024-10-28 9:05 ` Wolfgang Müller
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Wolfgang Müller @ 2024-10-19 14:37 UTC (permalink / raw)
To: amd-gfx
Whilst we have support for setting fan curves there is no support for
disabling the zero RPM feature. Since the relevant bits are already
present in the OverDriveTable, hook them up to a sysctl setting so users
can influence this behaviour.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3489
Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
---
I've been wanting this feature for a while so today I sat down and had a
look at how to best implement it. This is my first ever look at amdgpu
code, so I've marked it with RFC. I've based it on the implementation of
eedd5a343d22 (drm/amd/pm: add fan target temperature OD setting support
for SMU13, 2023-08-11) and also hooked resetting the knob with "r".
One thing I'm unsure about is using PP_OD_FEATURE_ZERO_FAN_BIT for
FeatureCtrlMask. I'm not sure this is the right thing to use there.
I successfully tested this on my own system with a 7900XTX; enabling and
disabling as well as resetting the knob to its default value work fine.
Thanks!
Documentation/gpu/amdgpu/thermal.rst | 6 ++
.../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 62 +++++++++++++++++++
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 +
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++-
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
8 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst
index 6d942b5c5..442b242f9 100644
--- a/Documentation/gpu/amdgpu/thermal.rst
+++ b/Documentation/gpu/amdgpu/thermal.rst
@@ -100,6 +100,12 @@ fan_minimum_pwm
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: fan_minimum_pwm
+fan_zero_rpm
+----------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
+ :doc: fan_zero_rpm
+
GFXOFF
======
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 2fa71f682..c6343e813 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -119,6 +119,7 @@ enum pp_clock_type {
OD_ACOUSTIC_TARGET,
OD_FAN_TARGET_TEMPERATURE,
OD_FAN_MINIMUM_PWM,
+ OD_FAN_ZERO_RPM,
};
enum amd_pp_sensors {
@@ -199,6 +200,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
PP_OD_EDIT_ACOUSTIC_TARGET,
PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
PP_OD_EDIT_FAN_MINIMUM_PWM,
+ PP_OD_EDIT_FAN_ZERO_RPM,
};
struct pp_states_info {
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index ea9407733..52efc5ac6 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -4109,6 +4109,60 @@ static umode_t fan_minimum_pwm_visible(struct amdgpu_device *adev)
return umode;
}
+/**
+ * DOC: fan_zero_rpm
+ *
+ * The amdgpu driver provides a sysfs API for checking and adjusting the
+ * zero RPM feature.
+ *
+ * Reading back the file shows you the current setting and the permitted
+ * ranges if changable.
+ *
+ * Writing an integer to the file, change the setting accordingly.
+ *
+ * When you have finished the editing, write "c" (commit) to the file to commit
+ * your changes.
+ *
+ * If you want to reset to the default value, write "r" (reset) to the file to
+ * reset them.
+ */
+static ssize_t fan_zero_rpm_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM, buf);
+}
+
+static ssize_t fan_zero_rpm_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
+ PP_OD_EDIT_FAN_ZERO_RPM,
+ buf,
+ count);
+}
+
+static umode_t fan_zero_rpm_visible(struct amdgpu_device *adev)
+{
+ umode_t umode = 0000;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE)
+ umode |= S_IRUSR | S_IRGRP | S_IROTH;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_SET)
+ umode |= S_IWUSR;
+
+ return umode;
+}
+
static struct od_feature_set amdgpu_od_set = {
.containers = {
[0] = {
@@ -4154,6 +4208,14 @@ static struct od_feature_set amdgpu_od_set = {
.store = fan_minimum_pwm_store,
},
},
+ [5] = {
+ .name = "fan_zero_rpm",
+ .ops = {
+ .is_visible = fan_zero_rpm_visible,
+ .show = fan_zero_rpm_show,
+ .store = fan_zero_rpm_store,
+ },
+ },
},
},
},
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
index f5bf41f21..be8de30ae 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
@@ -328,6 +328,8 @@ struct config_table_setting
#define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7)
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8)
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE BIT(10)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_SET BIT(11)
struct amdgpu_pm {
struct mutex mutex;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index accc96a03..3c6b14f7b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -2874,6 +2874,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break;
case OD_FAN_MINIMUM_PWM:
clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
+ case OD_FAN_ZERO_RPM:
+ clk_type = SMU_OD_FAN_ZERO_RPM; break;
default:
clk_type = SMU_CLK_COUNT; break;
}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
index e71a721c1..4d0558470 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
@@ -313,6 +313,7 @@ enum smu_clk_type {
SMU_OD_ACOUSTIC_TARGET,
SMU_OD_FAN_TARGET_TEMPERATURE,
SMU_OD_FAN_MINIMUM_PWM,
+ SMU_OD_FAN_ZERO_RPM,
SMU_CLK_COUNT,
};
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 3e2277abc..092fd4806 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -107,6 +107,7 @@
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
+#define PP_OD_FEATURE_FAN_ZERO_RPM 11
#define LINK_SPEED_MAX 3
@@ -1130,6 +1131,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1450,6 +1455,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM:
+ if (!smu_v13_0_0_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -1547,6 +1570,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1840,6 +1868,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM:
+ if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmEnable = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_0_od_restore_table_single(smu, input[0]);
@@ -2110,7 +2159,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
}
static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
@@ -2176,6 +2227,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanTargetTemperature;
user_od_table->OverDriveTable.FanMinimumPwm =
user_od_table_bak.OverDriveTable.FanMinimumPwm;
+ user_od_table->OverDriveTable.FanZeroRpmEnable =
+ user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
}
smu_v13_0_0_set_supported_od_feature_mask(smu);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 23f133884..735ed3d4f 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -83,6 +83,7 @@
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
+#define PP_OD_FEATURE_FAN_ZERO_RPM 11
#define LINK_SPEED_MAX 3
@@ -1119,6 +1120,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1439,6 +1444,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM:
+ if (!smu_v13_0_7_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -1535,6 +1558,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1828,6 +1856,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM:
+ if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmEnable = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_7_od_restore_table_single(smu, input[0]);
@@ -2094,7 +2143,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
}
static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
@@ -2160,6 +2211,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanTargetTemperature;
user_od_table->OverDriveTable.FanMinimumPwm =
user_od_table_bak.OverDriveTable.FanMinimumPwm;
+ user_od_table->OverDriveTable.FanZeroRpmEnable =
+ user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
}
smu_v13_0_7_set_supported_od_feature_mask(smu);
base-commit: 3631f572ee38bed4c3d0a9003570c63eaa9fd4e3
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13
2024-10-19 14:37 [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
@ 2024-10-28 9:05 ` Wolfgang Müller
2024-10-28 20:28 ` Alex Deucher
2024-10-29 11:17 ` [PATCH v2 0/2] Two zero RPM features Wolfgang Müller
2 siblings, 0 replies; 10+ messages in thread
From: Wolfgang Müller @ 2024-10-28 9:05 UTC (permalink / raw)
To: amd-gfx
On 2024-10-19 16:37, Wolfgang Müller wrote:
> Whilst we have support for setting fan curves there is no support for
> disabling the zero RPM feature. Since the relevant bits are already
> present in the OverDriveTable, hook them up to a sysctl setting so users
> can influence this behaviour.
>
> Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3489
> Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
> ---
> I've been wanting this feature for a while so today I sat down and had a
> look at how to best implement it. This is my first ever look at amdgpu
> code, so I've marked it with RFC. I've based it on the implementation of
> eedd5a343d22 (drm/amd/pm: add fan target temperature OD setting support
> for SMU13, 2023-08-11) and also hooked resetting the knob with "r".
>
> One thing I'm unsure about is using PP_OD_FEATURE_ZERO_FAN_BIT for
> FeatureCtrlMask. I'm not sure this is the right thing to use there.
>
> I successfully tested this on my own system with a 7900XTX; enabling and
> disabling as well as resetting the knob to its default value work fine.
I'd love to see this feature in the driver, so would very much welcome
some feedback on this topic.
Thanks!
--
Wolf
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13
2024-10-19 14:37 [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
2024-10-28 9:05 ` Wolfgang Müller
@ 2024-10-28 20:28 ` Alex Deucher
2024-10-29 2:52 ` Feng, Kenneth
2024-10-29 11:17 ` [PATCH v2 0/2] Two zero RPM features Wolfgang Müller
2 siblings, 1 reply; 10+ messages in thread
From: Alex Deucher @ 2024-10-28 20:28 UTC (permalink / raw)
To: Wolfgang Müller, Kenneth Feng; +Cc: amd-gfx
+ Kenneth to help review
On Sat, Oct 19, 2024 at 10:43 AM Wolfgang Müller <wolf@oriole.systems> wrote:
>
> Whilst we have support for setting fan curves there is no support for
> disabling the zero RPM feature. Since the relevant bits are already
> present in the OverDriveTable, hook them up to a sysctl setting so users
> can influence this behaviour.
>
> Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3489
> Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
> ---
> I've been wanting this feature for a while so today I sat down and had a
> look at how to best implement it. This is my first ever look at amdgpu
> code, so I've marked it with RFC. I've based it on the implementation of
> eedd5a343d22 (drm/amd/pm: add fan target temperature OD setting support
> for SMU13, 2023-08-11) and also hooked resetting the knob with "r".
>
> One thing I'm unsure about is using PP_OD_FEATURE_ZERO_FAN_BIT for
> FeatureCtrlMask. I'm not sure this is the right thing to use there.
>
> I successfully tested this on my own system with a 7900XTX; enabling and
> disabling as well as resetting the knob to its default value work fine.
>
> Thanks!
>
> Documentation/gpu/amdgpu/thermal.rst | 6 ++
> .../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
> drivers/gpu/drm/amd/pm/amdgpu_pm.c | 62 +++++++++++++++++++
> drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
> drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 +
> .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++-
> .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
> 8 files changed, 183 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst
> index 6d942b5c5..442b242f9 100644
> --- a/Documentation/gpu/amdgpu/thermal.rst
> +++ b/Documentation/gpu/amdgpu/thermal.rst
> @@ -100,6 +100,12 @@ fan_minimum_pwm
> .. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
> :doc: fan_minimum_pwm
>
> +fan_zero_rpm
> +----------------------
> +
> +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
> + :doc: fan_zero_rpm
> +
> GFXOFF
> ======
>
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 2fa71f682..c6343e813 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -119,6 +119,7 @@ enum pp_clock_type {
> OD_ACOUSTIC_TARGET,
> OD_FAN_TARGET_TEMPERATURE,
> OD_FAN_MINIMUM_PWM,
> + OD_FAN_ZERO_RPM,
> };
>
> enum amd_pp_sensors {
> @@ -199,6 +200,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
> PP_OD_EDIT_ACOUSTIC_TARGET,
> PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
> PP_OD_EDIT_FAN_MINIMUM_PWM,
> + PP_OD_EDIT_FAN_ZERO_RPM,
> };
>
> struct pp_states_info {
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index ea9407733..52efc5ac6 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -4109,6 +4109,60 @@ static umode_t fan_minimum_pwm_visible(struct amdgpu_device *adev)
> return umode;
> }
>
> +/**
> + * DOC: fan_zero_rpm
> + *
> + * The amdgpu driver provides a sysfs API for checking and adjusting the
> + * zero RPM feature.
> + *
> + * Reading back the file shows you the current setting and the permitted
> + * ranges if changable.
> + *
> + * Writing an integer to the file, change the setting accordingly.
> + *
> + * When you have finished the editing, write "c" (commit) to the file to commit
> + * your changes.
> + *
> + * If you want to reset to the default value, write "r" (reset) to the file to
> + * reset them.
> + */
> +static ssize_t fan_zero_rpm_show(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + char *buf)
> +{
> + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
> + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
> +
> + return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM, buf);
> +}
> +
> +static ssize_t fan_zero_rpm_store(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + const char *buf,
> + size_t count)
> +{
> + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
> + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
> +
> + return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
> + PP_OD_EDIT_FAN_ZERO_RPM,
> + buf,
> + count);
> +}
> +
> +static umode_t fan_zero_rpm_visible(struct amdgpu_device *adev)
> +{
> + umode_t umode = 0000;
> +
> + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE)
> + umode |= S_IRUSR | S_IRGRP | S_IROTH;
> +
> + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_SET)
> + umode |= S_IWUSR;
> +
> + return umode;
> +}
> +
> static struct od_feature_set amdgpu_od_set = {
> .containers = {
> [0] = {
> @@ -4154,6 +4208,14 @@ static struct od_feature_set amdgpu_od_set = {
> .store = fan_minimum_pwm_store,
> },
> },
> + [5] = {
> + .name = "fan_zero_rpm",
> + .ops = {
> + .is_visible = fan_zero_rpm_visible,
> + .show = fan_zero_rpm_show,
> + .store = fan_zero_rpm_store,
> + },
> + },
> },
> },
> },
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> index f5bf41f21..be8de30ae 100644
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> @@ -328,6 +328,8 @@ struct config_table_setting
> #define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7)
> #define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8)
> #define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
> +#define OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE BIT(10)
> +#define OD_OPS_SUPPORT_FAN_ZERO_RPM_SET BIT(11)
>
> struct amdgpu_pm {
> struct mutex mutex;
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index accc96a03..3c6b14f7b 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -2874,6 +2874,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
> clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break;
> case OD_FAN_MINIMUM_PWM:
> clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
> + case OD_FAN_ZERO_RPM:
> + clk_type = SMU_OD_FAN_ZERO_RPM; break;
> default:
> clk_type = SMU_CLK_COUNT; break;
> }
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> index e71a721c1..4d0558470 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> @@ -313,6 +313,7 @@ enum smu_clk_type {
> SMU_OD_ACOUSTIC_TARGET,
> SMU_OD_FAN_TARGET_TEMPERATURE,
> SMU_OD_FAN_MINIMUM_PWM,
> + SMU_OD_FAN_ZERO_RPM,
> SMU_CLK_COUNT,
> };
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> index 3e2277abc..092fd4806 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> @@ -107,6 +107,7 @@
> #define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
> #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
> #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
> +#define PP_OD_FEATURE_FAN_ZERO_RPM 11
>
> #define LINK_SPEED_MAX 3
>
> @@ -1130,6 +1131,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
> od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
> od_max_setting = overdrive_upperlimits->FanMinimumPwm;
> break;
> + case PP_OD_FEATURE_FAN_ZERO_RPM:
> + od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
> + od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
> + break;
> default:
> od_min_setting = od_max_setting = INT_MAX;
> break;
> @@ -1450,6 +1455,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
> min_value, max_value);
> break;
>
> + case SMU_OD_FAN_ZERO_RPM:
> + if (!smu_v13_0_0_is_od_feature_supported(smu,
> + PP_OD_FEATURE_ZERO_FAN_BIT))
> + break;
> +
> + size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
> + size += sysfs_emit_at(buf, size, "%d\n",
> + (int)od_table->OverDriveTable.FanZeroRpmEnable);
> +
> + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
> + smu_v13_0_0_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &min_value,
> + &max_value);
> + size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
> + min_value, max_value);
> + break;
> +
> case SMU_OD_RANGE:
> if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
> !smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
> @@ -1547,6 +1570,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
> od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + od_table->OverDriveTable.FanZeroRpmEnable =
> + boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> default:
> dev_info(adev->dev, "Invalid table index: %ld\n", input);
> return -EINVAL;
> @@ -1840,6 +1868,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
>
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
> + dev_warn(adev->dev, "Zero RPM setting not supported!\n");
> + return -ENOTSUPP;
> + }
> +
> + smu_v13_0_0_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &minimum,
> + &maximum);
> + if (input[0] < minimum ||
> + input[0] > maximum) {
> + dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
> + input[0], minimum, maximum);
> + return -EINVAL;
> + }
> +
> + od_table->OverDriveTable.FanZeroRpmEnable = input[0];
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> +
> case PP_OD_RESTORE_DEFAULT_TABLE:
> if (size == 1) {
> ret = smu_v13_0_0_od_restore_table_single(smu, input[0]);
> @@ -2110,7 +2159,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
> - OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
> + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
> }
>
> static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
> @@ -2176,6 +2227,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
> user_od_table_bak.OverDriveTable.FanTargetTemperature;
> user_od_table->OverDriveTable.FanMinimumPwm =
> user_od_table_bak.OverDriveTable.FanMinimumPwm;
> + user_od_table->OverDriveTable.FanZeroRpmEnable =
> + user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
> }
>
> smu_v13_0_0_set_supported_od_feature_mask(smu);
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> index 23f133884..735ed3d4f 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> @@ -83,6 +83,7 @@
> #define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
> #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
> #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
> +#define PP_OD_FEATURE_FAN_ZERO_RPM 11
>
> #define LINK_SPEED_MAX 3
>
> @@ -1119,6 +1120,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
> od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
> od_max_setting = overdrive_upperlimits->FanMinimumPwm;
> break;
> + case PP_OD_FEATURE_FAN_ZERO_RPM:
> + od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
> + od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
> + break;
> default:
> od_min_setting = od_max_setting = INT_MAX;
> break;
> @@ -1439,6 +1444,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
> min_value, max_value);
> break;
>
> + case SMU_OD_FAN_ZERO_RPM:
> + if (!smu_v13_0_7_is_od_feature_supported(smu,
> + PP_OD_FEATURE_ZERO_FAN_BIT))
> + break;
> +
> + size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
> + size += sysfs_emit_at(buf, size, "%d\n",
> + (int)od_table->OverDriveTable.FanZeroRpmEnable);
> +
> + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
> + smu_v13_0_7_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &min_value,
> + &max_value);
> + size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
> + min_value, max_value);
> + break;
> +
> case SMU_OD_RANGE:
> if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
> !smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
> @@ -1535,6 +1558,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
> od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + od_table->OverDriveTable.FanZeroRpmEnable =
> + boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> default:
> dev_info(adev->dev, "Invalid table index: %ld\n", input);
> return -EINVAL;
> @@ -1828,6 +1856,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
>
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
> + dev_warn(adev->dev, "Zero RPM setting not supported!\n");
> + return -ENOTSUPP;
> + }
> +
> + smu_v13_0_7_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &minimum,
> + &maximum);
> + if (input[0] < minimum ||
> + input[0] > maximum) {
> + dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
> + input[0], minimum, maximum);
> + return -EINVAL;
> + }
> +
> + od_table->OverDriveTable.FanZeroRpmEnable = input[0];
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> +
> case PP_OD_RESTORE_DEFAULT_TABLE:
> if (size == 1) {
> ret = smu_v13_0_7_od_restore_table_single(smu, input[0]);
> @@ -2094,7 +2143,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
> - OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
> + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
> }
>
> static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
> @@ -2160,6 +2211,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
> user_od_table_bak.OverDriveTable.FanTargetTemperature;
> user_od_table->OverDriveTable.FanMinimumPwm =
> user_od_table_bak.OverDriveTable.FanMinimumPwm;
> + user_od_table->OverDriveTable.FanZeroRpmEnable =
> + user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
> }
>
> smu_v13_0_7_set_supported_od_feature_mask(smu);
>
> base-commit: 3631f572ee38bed4c3d0a9003570c63eaa9fd4e3
> --
> 2.47.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread* RE: [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13
2024-10-28 20:28 ` Alex Deucher
@ 2024-10-29 2:52 ` Feng, Kenneth
2024-10-29 9:02 ` Wolfgang Müller
0 siblings, 1 reply; 10+ messages in thread
From: Feng, Kenneth @ 2024-10-29 2:52 UTC (permalink / raw)
To: Alex Deucher, Wolfgang Müller; +Cc: amd-gfx@lists.freedesktop.org
[AMD Official Use Only - AMD Internal Distribution Only]
Hi Wolfgang,
It's good to add this interface.
However, I think it would be better to add the setting of OverDriveTable.FanZeroRpmStopTemp for this interface.
OverDriveTable.FanZeroRpmStopTemp determines if the fan can stop when the temperature is below this temperature setting(in the condition that zero RPM is enabled).
It makes this interface more advanced. OverDriveTable.FanZeroRpmEnable and OverDriveTable.FanZeroRpmStopTemp are a pair to be arbitered in pmfw.
Thanks.
-----Original Message-----
From: Alex Deucher <alexdeucher@gmail.com>
Sent: Tuesday, October 29, 2024 4:28 AM
To: Wolfgang Müller <wolf@oriole.systems>; Feng, Kenneth <Kenneth.Feng@amd.com>
Cc: amd-gfx@lists.freedesktop.org
Subject: Re: [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13
Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
+ Kenneth to help review
On Sat, Oct 19, 2024 at 10:43 AM Wolfgang Müller <wolf@oriole.systems> wrote:
>
> Whilst we have support for setting fan curves there is no support for
> disabling the zero RPM feature. Since the relevant bits are already
> present in the OverDriveTable, hook them up to a sysctl setting so
> users can influence this behaviour.
>
> Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3489
> Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
> ---
> I've been wanting this feature for a while so today I sat down and had
> a look at how to best implement it. This is my first ever look at
> amdgpu code, so I've marked it with RFC. I've based it on the
> implementation of
> eedd5a343d22 (drm/amd/pm: add fan target temperature OD setting
> support for SMU13, 2023-08-11) and also hooked resetting the knob with "r".
>
> One thing I'm unsure about is using PP_OD_FEATURE_ZERO_FAN_BIT for
> FeatureCtrlMask. I'm not sure this is the right thing to use there.
>
> I successfully tested this on my own system with a 7900XTX; enabling
> and disabling as well as resetting the knob to its default value work fine.
>
> Thanks!
>
> Documentation/gpu/amdgpu/thermal.rst | 6 ++
> .../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
> drivers/gpu/drm/amd/pm/amdgpu_pm.c | 62 +++++++++++++++++++
> drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
> drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 +
> .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++-
> .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
> 8 files changed, 183 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/gpu/amdgpu/thermal.rst
> b/Documentation/gpu/amdgpu/thermal.rst
> index 6d942b5c5..442b242f9 100644
> --- a/Documentation/gpu/amdgpu/thermal.rst
> +++ b/Documentation/gpu/amdgpu/thermal.rst
> @@ -100,6 +100,12 @@ fan_minimum_pwm
> .. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
> :doc: fan_minimum_pwm
>
> +fan_zero_rpm
> +----------------------
> +
> +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
> + :doc: fan_zero_rpm
> +
> GFXOFF
> ======
>
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 2fa71f682..c6343e813 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -119,6 +119,7 @@ enum pp_clock_type {
> OD_ACOUSTIC_TARGET,
> OD_FAN_TARGET_TEMPERATURE,
> OD_FAN_MINIMUM_PWM,
> + OD_FAN_ZERO_RPM,
> };
>
> enum amd_pp_sensors {
> @@ -199,6 +200,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
> PP_OD_EDIT_ACOUSTIC_TARGET,
> PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
> PP_OD_EDIT_FAN_MINIMUM_PWM,
> + PP_OD_EDIT_FAN_ZERO_RPM,
> };
>
> struct pp_states_info {
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index ea9407733..52efc5ac6 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -4109,6 +4109,60 @@ static umode_t fan_minimum_pwm_visible(struct amdgpu_device *adev)
> return umode;
> }
>
> +/**
> + * DOC: fan_zero_rpm
> + *
> + * The amdgpu driver provides a sysfs API for checking and adjusting
> +the
> + * zero RPM feature.
> + *
> + * Reading back the file shows you the current setting and the
> +permitted
> + * ranges if changable.
> + *
> + * Writing an integer to the file, change the setting accordingly.
> + *
> + * When you have finished the editing, write "c" (commit) to the file
> +to commit
> + * your changes.
> + *
> + * If you want to reset to the default value, write "r" (reset) to
> +the file to
> + * reset them.
> + */
> +static ssize_t fan_zero_rpm_show(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + char *buf) {
> + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
> + struct amdgpu_device *adev = (struct amdgpu_device
> +*)container->priv;
> +
> + return (ssize_t)amdgpu_retrieve_od_settings(adev,
> +OD_FAN_ZERO_RPM, buf); }
> +
> +static ssize_t fan_zero_rpm_store(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + const char *buf,
> + size_t count) {
> + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
> + struct amdgpu_device *adev = (struct amdgpu_device
> +*)container->priv;
> +
> + return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
> + PP_OD_EDIT_FAN_ZERO_RPM,
> + buf,
> + count); }
> +
> +static umode_t fan_zero_rpm_visible(struct amdgpu_device *adev) {
> + umode_t umode = 0000;
> +
> + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE)
> + umode |= S_IRUSR | S_IRGRP | S_IROTH;
> +
> + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_SET)
> + umode |= S_IWUSR;
> +
> + return umode;
> +}
> +
> static struct od_feature_set amdgpu_od_set = {
> .containers = {
> [0] = {
> @@ -4154,6 +4208,14 @@ static struct od_feature_set amdgpu_od_set = {
> .store = fan_minimum_pwm_store,
> },
> },
> + [5] = {
> + .name = "fan_zero_rpm",
> + .ops = {
> + .is_visible = fan_zero_rpm_visible,
> + .show = fan_zero_rpm_show,
> + .store = fan_zero_rpm_store,
> + },
> + },
> },
> },
> },
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> index f5bf41f21..be8de30ae 100644
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> @@ -328,6 +328,8 @@ struct config_table_setting
> #define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7)
> #define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8)
> #define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
> +#define OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE BIT(10)
> +#define OD_OPS_SUPPORT_FAN_ZERO_RPM_SET BIT(11)
>
> struct amdgpu_pm {
> struct mutex mutex;
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index accc96a03..3c6b14f7b 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -2874,6 +2874,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
> clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break;
> case OD_FAN_MINIMUM_PWM:
> clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
> + case OD_FAN_ZERO_RPM:
> + clk_type = SMU_OD_FAN_ZERO_RPM; break;
> default:
> clk_type = SMU_CLK_COUNT; break;
> }
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> index e71a721c1..4d0558470 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> @@ -313,6 +313,7 @@ enum smu_clk_type {
> SMU_OD_ACOUSTIC_TARGET,
> SMU_OD_FAN_TARGET_TEMPERATURE,
> SMU_OD_FAN_MINIMUM_PWM,
> + SMU_OD_FAN_ZERO_RPM,
> SMU_CLK_COUNT,
> };
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> index 3e2277abc..092fd4806 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> @@ -107,6 +107,7 @@
> #define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
> #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
> #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
> +#define PP_OD_FEATURE_FAN_ZERO_RPM 11
>
> #define LINK_SPEED_MAX 3
>
> @@ -1130,6 +1131,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
> od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
> od_max_setting = overdrive_upperlimits->FanMinimumPwm;
> break;
> + case PP_OD_FEATURE_FAN_ZERO_RPM:
> + od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
> + od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
> + break;
> default:
> od_min_setting = od_max_setting = INT_MAX;
> break;
> @@ -1450,6 +1455,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
> min_value, max_value);
> break;
>
> + case SMU_OD_FAN_ZERO_RPM:
> + if (!smu_v13_0_0_is_od_feature_supported(smu,
> + PP_OD_FEATURE_ZERO_FAN_BIT))
> + break;
> +
> + size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
> + size += sysfs_emit_at(buf, size, "%d\n",
> +
> + (int)od_table->OverDriveTable.FanZeroRpmEnable);
> +
> + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
> + smu_v13_0_0_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &min_value,
> + &max_value);
> + size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
> + min_value, max_value);
> + break;
> +
> case SMU_OD_RANGE:
> if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
> !smu_v13_0_0_is_od_feature_supported(smu,
> PP_OD_FEATURE_UCLK_BIT) && @@ -1547,6 +1570,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
> od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + od_table->OverDriveTable.FanZeroRpmEnable =
> + boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> default:
> dev_info(adev->dev, "Invalid table index: %ld\n", input);
> return -EINVAL;
> @@ -1840,6 +1868,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
>
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
> + dev_warn(adev->dev, "Zero RPM setting not supported!\n");
> + return -ENOTSUPP;
> + }
> +
> + smu_v13_0_0_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &minimum,
> + &maximum);
> + if (input[0] < minimum ||
> + input[0] > maximum) {
> + dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
> + input[0], minimum, maximum);
> + return -EINVAL;
> + }
> +
> + od_table->OverDriveTable.FanZeroRpmEnable = input[0];
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> +
> case PP_OD_RESTORE_DEFAULT_TABLE:
> if (size == 1) {
> ret = smu_v13_0_0_od_restore_table_single(smu,
> input[0]); @@ -2110,7 +2159,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
> - OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
> + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
> +
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
> }
>
> static int smu_v13_0_0_set_default_od_settings(struct smu_context
> *smu) @@ -2176,6 +2227,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
> user_od_table_bak.OverDriveTable.FanTargetTemperature;
> user_od_table->OverDriveTable.FanMinimumPwm =
>
> user_od_table_bak.OverDriveTable.FanMinimumPwm;
> + user_od_table->OverDriveTable.FanZeroRpmEnable =
> +
> + user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
> }
>
> smu_v13_0_0_set_supported_od_feature_mask(smu);
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> index 23f133884..735ed3d4f 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> @@ -83,6 +83,7 @@
> #define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
> #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
> #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
> +#define PP_OD_FEATURE_FAN_ZERO_RPM 11
>
> #define LINK_SPEED_MAX 3
>
> @@ -1119,6 +1120,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
> od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
> od_max_setting = overdrive_upperlimits->FanMinimumPwm;
> break;
> + case PP_OD_FEATURE_FAN_ZERO_RPM:
> + od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
> + od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
> + break;
> default:
> od_min_setting = od_max_setting = INT_MAX;
> break;
> @@ -1439,6 +1444,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
> min_value, max_value);
> break;
>
> + case SMU_OD_FAN_ZERO_RPM:
> + if (!smu_v13_0_7_is_od_feature_supported(smu,
> + PP_OD_FEATURE_ZERO_FAN_BIT))
> + break;
> +
> + size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
> + size += sysfs_emit_at(buf, size, "%d\n",
> +
> + (int)od_table->OverDriveTable.FanZeroRpmEnable);
> +
> + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
> + smu_v13_0_7_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &min_value,
> + &max_value);
> + size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
> + min_value, max_value);
> + break;
> +
> case SMU_OD_RANGE:
> if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
> !smu_v13_0_7_is_od_feature_supported(smu,
> PP_OD_FEATURE_UCLK_BIT) && @@ -1535,6 +1558,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
> od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + od_table->OverDriveTable.FanZeroRpmEnable =
> + boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> default:
> dev_info(adev->dev, "Invalid table index: %ld\n", input);
> return -EINVAL;
> @@ -1828,6 +1856,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
> break;
>
> + case PP_OD_EDIT_FAN_ZERO_RPM:
> + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
> + dev_warn(adev->dev, "Zero RPM setting not supported!\n");
> + return -ENOTSUPP;
> + }
> +
> + smu_v13_0_7_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM,
> + &minimum,
> + &maximum);
> + if (input[0] < minimum ||
> + input[0] > maximum) {
> + dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
> + input[0], minimum, maximum);
> + return -EINVAL;
> + }
> +
> + od_table->OverDriveTable.FanZeroRpmEnable = input[0];
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> +
> case PP_OD_RESTORE_DEFAULT_TABLE:
> if (size == 1) {
> ret = smu_v13_0_7_od_restore_table_single(smu,
> input[0]); @@ -2094,7 +2143,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
> OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
> - OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
> + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
> +
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
> }
>
> static int smu_v13_0_7_set_default_od_settings(struct smu_context
> *smu) @@ -2160,6 +2211,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
> user_od_table_bak.OverDriveTable.FanTargetTemperature;
> user_od_table->OverDriveTable.FanMinimumPwm =
>
> user_od_table_bak.OverDriveTable.FanMinimumPwm;
> + user_od_table->OverDriveTable.FanZeroRpmEnable =
> +
> + user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
> }
>
> smu_v13_0_7_set_supported_od_feature_mask(smu);
>
> base-commit: 3631f572ee38bed4c3d0a9003570c63eaa9fd4e3
> --
> 2.47.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13
2024-10-29 2:52 ` Feng, Kenneth
@ 2024-10-29 9:02 ` Wolfgang Müller
0 siblings, 0 replies; 10+ messages in thread
From: Wolfgang Müller @ 2024-10-29 9:02 UTC (permalink / raw)
To: Feng, Kenneth; +Cc: Alex Deucher, amd-gfx@lists.freedesktop.org
On 2024-10-29 02:52, Feng, Kenneth wrote:
> However, I think it would be better to add the setting of
> OverDriveTable.FanZeroRpmStopTemp for this interface.
> OverDriveTable.FanZeroRpmStopTemp determines if the fan can stop when
> the temperature is below this temperature setting(in the condition
> that zero RPM is enabled).
> It makes this interface more advanced. OverDriveTable.FanZeroRpmEnable
> and OverDriveTable.FanZeroRpmStopTemp are a pair to be arbitered in
> pmfw.
Sure, that sounds good to me. I'll add a second commit implementing
this. With two settings now exposed I also think it'd be better to
rename the knob from fan_zero_rpm to fan_zero_rpm_enable. Makes its
purpose a whole lot clearer and is in line with the name in
OverDriveTable.
I'll send v2 along with these changes sometime today. Thanks for the
feedback!
--
Wolf
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 0/2] Two zero RPM features
2024-10-19 14:37 [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
2024-10-28 9:05 ` Wolfgang Müller
2024-10-28 20:28 ` Alex Deucher
@ 2024-10-29 11:17 ` Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 1/2] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature " Wolfgang Müller
2 siblings, 2 replies; 10+ messages in thread
From: Wolfgang Müller @ 2024-10-29 11:17 UTC (permalink / raw)
To: amd-gfx; +Cc: Kenneth.Feng
Here's v2 of this series, now also with support for setting the zero RPM
stop temperature. Additionally, the fan_zero_rpm knob has been renamed
fan_zero_rpm_enable.
As before I successfully tested both changes on my own system.
Wolfgang Müller (2):
drm/amd/pm: add zero RPM OD setting support for SMU13
drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
Documentation/gpu/amdgpu/thermal.rst | 12 ++
.../gpu/drm/amd/include/kgd_pp_interface.h | 4 +
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 127 ++++++++++++++++++
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 4 +
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 4 +
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 2 +
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 108 ++++++++++++++-
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 108 ++++++++++++++-
8 files changed, 367 insertions(+), 2 deletions(-)
Range-diff against v1:
1: 633acda07 ! 1: b6233aed7 drm/amd/pm: add zero RPM OD setting support for SMU13
@@ Documentation/gpu/amdgpu/thermal.rst: fan_minimum_pwm
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: fan_minimum_pwm
-+fan_zero_rpm
++fan_zero_rpm_enable
+----------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
-+ :doc: fan_zero_rpm
++ :doc: fan_zero_rpm_enable
+
GFXOFF
======
@@ drivers/gpu/drm/amd/include/kgd_pp_interface.h: enum pp_clock_type {
OD_ACOUSTIC_TARGET,
OD_FAN_TARGET_TEMPERATURE,
OD_FAN_MINIMUM_PWM,
-+ OD_FAN_ZERO_RPM,
++ OD_FAN_ZERO_RPM_ENABLE,
};
enum amd_pp_sensors {
@@ drivers/gpu/drm/amd/include/kgd_pp_interface.h: enum PP_OD_DPM_TABLE_COMMAND {
PP_OD_EDIT_ACOUSTIC_TARGET,
PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
PP_OD_EDIT_FAN_MINIMUM_PWM,
-+ PP_OD_EDIT_FAN_ZERO_RPM,
++ PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
};
struct pp_states_info {
@@ drivers/gpu/drm/amd/pm/amdgpu_pm.c: static umode_t fan_minimum_pwm_visible(struc
}
+/**
-+ * DOC: fan_zero_rpm
++ * DOC: fan_zero_rpm_enable
+ *
+ * The amdgpu driver provides a sysfs API for checking and adjusting the
+ * zero RPM feature.
@@ drivers/gpu/drm/amd/pm/amdgpu_pm.c: static umode_t fan_minimum_pwm_visible(struc
+ * If you want to reset to the default value, write "r" (reset) to the file to
+ * reset them.
+ */
-+static ssize_t fan_zero_rpm_show(struct kobject *kobj,
++static ssize_t fan_zero_rpm_enable_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
-+ return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM, buf);
++ return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM_ENABLE, buf);
+}
+
-+static ssize_t fan_zero_rpm_store(struct kobject *kobj,
++static ssize_t fan_zero_rpm_enable_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
@@ drivers/gpu/drm/amd/pm/amdgpu_pm.c: static umode_t fan_minimum_pwm_visible(struc
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
-+ PP_OD_EDIT_FAN_ZERO_RPM,
++ PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
+ buf,
+ count);
+}
+
-+static umode_t fan_zero_rpm_visible(struct amdgpu_device *adev)
++static umode_t fan_zero_rpm_enable_visible(struct amdgpu_device *adev)
+{
+ umode_t umode = 0000;
+
-+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE)
++ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE)
+ umode |= S_IRUSR | S_IRGRP | S_IROTH;
+
-+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_SET)
++ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET)
+ umode |= S_IWUSR;
+
+ return umode;
@@ drivers/gpu/drm/amd/pm/amdgpu_pm.c: static struct od_feature_set amdgpu_od_set =
},
},
+ [5] = {
-+ .name = "fan_zero_rpm",
++ .name = "fan_zero_rpm_enable",
+ .ops = {
-+ .is_visible = fan_zero_rpm_visible,
-+ .show = fan_zero_rpm_show,
-+ .store = fan_zero_rpm_store,
++ .is_visible = fan_zero_rpm_enable_visible,
++ .show = fan_zero_rpm_enable_show,
++ .store = fan_zero_rpm_enable_store,
+ },
+ },
},
@@ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h: struct config_table_setting
#define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7)
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8)
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
-+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE BIT(10)
-+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_SET BIT(11)
++#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE BIT(10)
++#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET BIT(11)
struct amdgpu_pm {
struct mutex mutex;
@@ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c: static enum smu_clk_type smu_convert_
clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break;
case OD_FAN_MINIMUM_PWM:
clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
-+ case OD_FAN_ZERO_RPM:
-+ clk_type = SMU_OD_FAN_ZERO_RPM; break;
++ case OD_FAN_ZERO_RPM_ENABLE:
++ clk_type = SMU_OD_FAN_ZERO_RPM_ENABLE; break;
default:
clk_type = SMU_CLK_COUNT; break;
}
@@ drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h: enum smu_clk_type {
SMU_OD_ACOUSTIC_TARGET,
SMU_OD_FAN_TARGET_TEMPERATURE,
SMU_OD_FAN_MINIMUM_PWM,
-+ SMU_OD_FAN_ZERO_RPM,
++ SMU_OD_FAN_ZERO_RPM_ENABLE,
SMU_CLK_COUNT,
};
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
-+#define PP_OD_FEATURE_FAN_ZERO_RPM 11
++#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
#define LINK_SPEED_MAX 3
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c: static void smu_v13_0_0_ge
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
-+ case PP_OD_FEATURE_FAN_ZERO_RPM:
++ case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c: static int smu_v13_0_0_pri
min_value, max_value);
break;
-+ case SMU_OD_FAN_ZERO_RPM:
++ case SMU_OD_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_0_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
-+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
++ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_0_get_od_setting_limits(smu,
-+ PP_OD_FEATURE_FAN_ZERO_RPM,
++ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &min_value,
+ &max_value);
-+ size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
++ size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
+ min_value, max_value);
+ break;
+
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c: static int smu_v13_0_0_od_
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
-+ case PP_OD_EDIT_FAN_ZERO_RPM:
++ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c: static int smu_v13_0_0_od_
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
-+ case PP_OD_EDIT_FAN_ZERO_RPM:
++ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_0_get_od_setting_limits(smu,
-+ PP_OD_FEATURE_FAN_ZERO_RPM,
++ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
-+ dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
++ dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c: static void smu_v13_0_0_se
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
-+ OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
-+ OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
++ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
++ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
}
static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
-+#define PP_OD_FEATURE_FAN_ZERO_RPM 11
++#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
#define LINK_SPEED_MAX 3
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c: static void smu_v13_0_7_ge
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
-+ case PP_OD_FEATURE_FAN_ZERO_RPM:
++ case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c: static int smu_v13_0_7_pri
min_value, max_value);
break;
-+ case SMU_OD_FAN_ZERO_RPM:
++ case SMU_OD_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_7_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
-+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM:\n");
++ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_7_get_od_setting_limits(smu,
-+ PP_OD_FEATURE_FAN_ZERO_RPM,
++ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &min_value,
+ &max_value);
-+ size += sysfs_emit_at(buf, size, "ZERO_RPM: %u %u\n",
++ size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
+ min_value, max_value);
+ break;
+
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c: static int smu_v13_0_7_od_
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
-+ case PP_OD_EDIT_FAN_ZERO_RPM:
++ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c: static int smu_v13_0_7_od_
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
-+ case PP_OD_EDIT_FAN_ZERO_RPM:
++ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_7_get_od_setting_limits(smu,
-+ PP_OD_FEATURE_FAN_ZERO_RPM,
++ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
-+ dev_info(adev->dev, "zero RPM setting(%ld) must be within [%d, %d]!\n",
++ dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
@@ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c: static void smu_v13_0_7_se
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
-+ OD_OPS_SUPPORT_FAN_ZERO_RPM_RETRIEVE|
-+ OD_OPS_SUPPORT_FAN_ZERO_RPM_SET;
++ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
++ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
}
static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
-: --------- > 2: 6c2af6efb drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
--
2.47.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v2 1/2] drm/amd/pm: add zero RPM OD setting support for SMU13
2024-10-29 11:17 ` [PATCH v2 0/2] Two zero RPM features Wolfgang Müller
@ 2024-10-29 11:17 ` Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature " Wolfgang Müller
1 sibling, 0 replies; 10+ messages in thread
From: Wolfgang Müller @ 2024-10-29 11:17 UTC (permalink / raw)
To: amd-gfx; +Cc: Kenneth.Feng
Whilst we have support for setting fan curves there is no support for
disabling the zero RPM feature. Since the relevant bits are already
present in the OverDriveTable, hook them up to a sysctl setting so users
can influence this behaviour.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3489
Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
---
Documentation/gpu/amdgpu/thermal.rst | 6 ++
.../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 62 +++++++++++++++++++
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 +
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++-
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
8 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst
index 6d942b5c5..ec6c1f1d5 100644
--- a/Documentation/gpu/amdgpu/thermal.rst
+++ b/Documentation/gpu/amdgpu/thermal.rst
@@ -100,6 +100,12 @@ fan_minimum_pwm
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: fan_minimum_pwm
+fan_zero_rpm_enable
+----------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
+ :doc: fan_zero_rpm_enable
+
GFXOFF
======
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 2fa71f682..80e4b5a7d 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -119,6 +119,7 @@ enum pp_clock_type {
OD_ACOUSTIC_TARGET,
OD_FAN_TARGET_TEMPERATURE,
OD_FAN_MINIMUM_PWM,
+ OD_FAN_ZERO_RPM_ENABLE,
};
enum amd_pp_sensors {
@@ -199,6 +200,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
PP_OD_EDIT_ACOUSTIC_TARGET,
PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
PP_OD_EDIT_FAN_MINIMUM_PWM,
+ PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
};
struct pp_states_info {
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index ea9407733..cb96f1f8c 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -4109,6 +4109,60 @@ static umode_t fan_minimum_pwm_visible(struct amdgpu_device *adev)
return umode;
}
+/**
+ * DOC: fan_zero_rpm_enable
+ *
+ * The amdgpu driver provides a sysfs API for checking and adjusting the
+ * zero RPM feature.
+ *
+ * Reading back the file shows you the current setting and the permitted
+ * ranges if changable.
+ *
+ * Writing an integer to the file, change the setting accordingly.
+ *
+ * When you have finished the editing, write "c" (commit) to the file to commit
+ * your changes.
+ *
+ * If you want to reset to the default value, write "r" (reset) to the file to
+ * reset them.
+ */
+static ssize_t fan_zero_rpm_enable_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM_ENABLE, buf);
+}
+
+static ssize_t fan_zero_rpm_enable_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
+ PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
+ buf,
+ count);
+}
+
+static umode_t fan_zero_rpm_enable_visible(struct amdgpu_device *adev)
+{
+ umode_t umode = 0000;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE)
+ umode |= S_IRUSR | S_IRGRP | S_IROTH;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET)
+ umode |= S_IWUSR;
+
+ return umode;
+}
+
static struct od_feature_set amdgpu_od_set = {
.containers = {
[0] = {
@@ -4154,6 +4208,14 @@ static struct od_feature_set amdgpu_od_set = {
.store = fan_minimum_pwm_store,
},
},
+ [5] = {
+ .name = "fan_zero_rpm_enable",
+ .ops = {
+ .is_visible = fan_zero_rpm_enable_visible,
+ .show = fan_zero_rpm_enable_show,
+ .store = fan_zero_rpm_enable_store,
+ },
+ },
},
},
},
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
index f5bf41f21..b5daa12c0 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
@@ -328,6 +328,8 @@ struct config_table_setting
#define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7)
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8)
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE BIT(10)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET BIT(11)
struct amdgpu_pm {
struct mutex mutex;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index accc96a03..8d3f3e735 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -2874,6 +2874,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break;
case OD_FAN_MINIMUM_PWM:
clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
+ case OD_FAN_ZERO_RPM_ENABLE:
+ clk_type = SMU_OD_FAN_ZERO_RPM_ENABLE; break;
default:
clk_type = SMU_CLK_COUNT; break;
}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
index e71a721c1..e0abb449a 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
@@ -313,6 +313,7 @@ enum smu_clk_type {
SMU_OD_ACOUSTIC_TARGET,
SMU_OD_FAN_TARGET_TEMPERATURE,
SMU_OD_FAN_MINIMUM_PWM,
+ SMU_OD_FAN_ZERO_RPM_ENABLE,
SMU_CLK_COUNT,
};
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 3e2277abc..0d9a4638e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -107,6 +107,7 @@
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
+#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
#define LINK_SPEED_MAX 3
@@ -1130,6 +1131,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1450,6 +1455,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_0_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -1547,6 +1570,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1840,6 +1868,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmEnable = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_0_od_restore_table_single(smu, input[0]);
@@ -2110,7 +2159,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
}
static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
@@ -2176,6 +2227,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanTargetTemperature;
user_od_table->OverDriveTable.FanMinimumPwm =
user_od_table_bak.OverDriveTable.FanMinimumPwm;
+ user_od_table->OverDriveTable.FanZeroRpmEnable =
+ user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
}
smu_v13_0_0_set_supported_od_feature_mask(smu);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 23f133884..6b61655f9 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -83,6 +83,7 @@
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
+#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
#define LINK_SPEED_MAX 3
@@ -1119,6 +1120,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1439,6 +1444,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_7_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -1535,6 +1558,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1828,6 +1856,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmEnable = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_7_od_restore_table_single(smu, input[0]);
@@ -2094,7 +2143,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
}
static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
@@ -2160,6 +2211,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanTargetTemperature;
user_od_table->OverDriveTable.FanMinimumPwm =
user_od_table_bak.OverDriveTable.FanMinimumPwm;
+ user_od_table->OverDriveTable.FanZeroRpmEnable =
+ user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
}
smu_v13_0_7_set_supported_od_feature_mask(smu);
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
2024-10-29 11:17 ` [PATCH v2 0/2] Two zero RPM features Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 1/2] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
@ 2024-10-29 11:17 ` Wolfgang Müller
2024-10-30 1:01 ` Feng, Kenneth
1 sibling, 1 reply; 10+ messages in thread
From: Wolfgang Müller @ 2024-10-29 11:17 UTC (permalink / raw)
To: amd-gfx; +Cc: Kenneth.Feng
Together with the feature to enable or disable zero RPM in the last
commit, it also makes sense to expose the OD setting determining under
which temperature the fan should stop if zero RPM is enabled.
Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
---
Documentation/gpu/amdgpu/thermal.rst | 6 ++
.../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 65 +++++++++++++++++++
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 +
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++-
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
8 files changed, 186 insertions(+), 2 deletions(-)
diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst
index ec6c1f1d5..1768a106a 100644
--- a/Documentation/gpu/amdgpu/thermal.rst
+++ b/Documentation/gpu/amdgpu/thermal.rst
@@ -106,6 +106,12 @@ fan_zero_rpm_enable
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: fan_zero_rpm_enable
+fan_zero_rpm_stop_temperature
+-----------------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
+ :doc: fan_zero_rpm_stop_temperature
+
GFXOFF
======
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 80e4b5a7d..bb27c0d2a 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -120,6 +120,7 @@ enum pp_clock_type {
OD_FAN_TARGET_TEMPERATURE,
OD_FAN_MINIMUM_PWM,
OD_FAN_ZERO_RPM_ENABLE,
+ OD_FAN_ZERO_RPM_STOP_TEMP,
};
enum amd_pp_sensors {
@@ -201,6 +202,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
PP_OD_EDIT_FAN_MINIMUM_PWM,
PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
+ PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP,
};
struct pp_states_info {
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index cb96f1f8c..136e81938 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -4163,6 +4163,63 @@ static umode_t fan_zero_rpm_enable_visible(struct amdgpu_device *adev)
return umode;
}
+/**
+ * DOC: fan_zero_rpm_stop_temperature
+ *
+ * The amdgpu driver provides a sysfs API for checking and adjusting the
+ * zero RPM stop temperature feature.
+ *
+ * Reading back the file shows you the current setting and the permitted
+ * ranges if changable.
+ *
+ * Writing an integer to the file, change the setting accordingly.
+ *
+ * When you have finished the editing, write "c" (commit) to the file to commit
+ * your changes.
+ *
+ * If you want to reset to the default value, write "r" (reset) to the file to
+ * reset them.
+ *
+ * This setting works only if the Zero RPM setting is enabled. It adjusts the
+ * temperature below which the fan can stop.
+ */
+static ssize_t fan_zero_rpm_stop_temp_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM_STOP_TEMP, buf);
+}
+
+static ssize_t fan_zero_rpm_stop_temp_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
+
+ return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
+ PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP,
+ buf,
+ count);
+}
+
+static umode_t fan_zero_rpm_stop_temp_visible(struct amdgpu_device *adev)
+{
+ umode_t umode = 0000;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE)
+ umode |= S_IRUSR | S_IRGRP | S_IROTH;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET)
+ umode |= S_IWUSR;
+
+ return umode;
+}
+
static struct od_feature_set amdgpu_od_set = {
.containers = {
[0] = {
@@ -4216,6 +4273,14 @@ static struct od_feature_set amdgpu_od_set = {
.store = fan_zero_rpm_enable_store,
},
},
+ [6] = {
+ .name = "fan_zero_rpm_stop_temperature",
+ .ops = {
+ .is_visible = fan_zero_rpm_stop_temp_visible,
+ .show = fan_zero_rpm_stop_temp_show,
+ .store = fan_zero_rpm_stop_temp_store,
+ },
+ },
},
},
},
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
index b5daa12c0..363af8990 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
@@ -330,6 +330,8 @@ struct config_table_setting
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE BIT(10)
#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET BIT(11)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE BIT(12)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET BIT(13)
struct amdgpu_pm {
struct mutex mutex;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 8d3f3e735..8148933cc 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -2876,6 +2876,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
case OD_FAN_ZERO_RPM_ENABLE:
clk_type = SMU_OD_FAN_ZERO_RPM_ENABLE; break;
+ case OD_FAN_ZERO_RPM_STOP_TEMP:
+ clk_type = SMU_OD_FAN_ZERO_RPM_STOP_TEMP; break;
default:
clk_type = SMU_CLK_COUNT; break;
}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
index e0abb449a..a299dc4a8 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
@@ -314,6 +314,7 @@ enum smu_clk_type {
SMU_OD_FAN_TARGET_TEMPERATURE,
SMU_OD_FAN_MINIMUM_PWM,
SMU_OD_FAN_ZERO_RPM_ENABLE,
+ SMU_OD_FAN_ZERO_RPM_STOP_TEMP,
SMU_CLK_COUNT,
};
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 0d9a4638e..93cc82fe2 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -108,6 +108,7 @@
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
+#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
#define LINK_SPEED_MAX 3
@@ -1135,6 +1136,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1473,6 +1478,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_0_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -1575,6 +1598,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ od_table->OverDriveTable.FanZeroRpmStopTemp =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1889,6 +1917,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_0_od_restore_table_single(smu, input[0]);
@@ -2161,7 +2210,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
- OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
}
static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
@@ -2229,6 +2280,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanMinimumPwm;
user_od_table->OverDriveTable.FanZeroRpmEnable =
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
+ user_od_table->OverDriveTable.FanZeroRpmStopTemp =
+ user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
}
smu_v13_0_0_set_supported_od_feature_mask(smu);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 6b61655f9..0b3c53324 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -84,6 +84,7 @@
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
+#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
#define LINK_SPEED_MAX 3
@@ -1124,6 +1125,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1462,6 +1467,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_7_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -1563,6 +1586,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ od_table->OverDriveTable.FanZeroRpmStopTemp =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1877,6 +1905,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_7_od_restore_table_single(smu, input[0]);
@@ -2145,7 +2194,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
- OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
}
static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
@@ -2213,6 +2264,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanMinimumPwm;
user_od_table->OverDriveTable.FanZeroRpmEnable =
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
+ user_od_table->OverDriveTable.FanZeroRpmStopTemp =
+ user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
}
smu_v13_0_7_set_supported_od_feature_mask(smu);
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* RE: [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
2024-10-29 11:17 ` [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature " Wolfgang Müller
@ 2024-10-30 1:01 ` Feng, Kenneth
2024-10-30 15:09 ` Alex Deucher
0 siblings, 1 reply; 10+ messages in thread
From: Feng, Kenneth @ 2024-10-30 1:01 UTC (permalink / raw)
To: Wolfgang Müller, amd-gfx@lists.freedesktop.org
[AMD Official Use Only - AMD Internal Distribution Only]
Series is Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
-----Original Message-----
From: Wolfgang Müller <wolf@oriole.systems>
Sent: Tuesday, October 29, 2024 7:18 PM
To: amd-gfx@lists.freedesktop.org
Cc: Feng, Kenneth <Kenneth.Feng@amd.com>
Subject: [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
Together with the feature to enable or disable zero RPM in the last commit, it also makes sense to expose the OD setting determining under which temperature the fan should stop if zero RPM is enabled.
Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
---
Documentation/gpu/amdgpu/thermal.rst | 6 ++
.../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 65 +++++++++++++++++++
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 + .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++- .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
8 files changed, 186 insertions(+), 2 deletions(-)
diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst
index ec6c1f1d5..1768a106a 100644
--- a/Documentation/gpu/amdgpu/thermal.rst
+++ b/Documentation/gpu/amdgpu/thermal.rst
@@ -106,6 +106,12 @@ fan_zero_rpm_enable .. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: fan_zero_rpm_enable
+fan_zero_rpm_stop_temperature
+-----------------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
+ :doc: fan_zero_rpm_stop_temperature
+
GFXOFF
======
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 80e4b5a7d..bb27c0d2a 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -120,6 +120,7 @@ enum pp_clock_type {
OD_FAN_TARGET_TEMPERATURE,
OD_FAN_MINIMUM_PWM,
OD_FAN_ZERO_RPM_ENABLE,
+ OD_FAN_ZERO_RPM_STOP_TEMP,
};
enum amd_pp_sensors {
@@ -201,6 +202,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
PP_OD_EDIT_FAN_MINIMUM_PWM,
PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
+ PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP,
};
struct pp_states_info {
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index cb96f1f8c..136e81938 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -4163,6 +4163,63 @@ static umode_t fan_zero_rpm_enable_visible(struct amdgpu_device *adev)
return umode;
}
+/**
+ * DOC: fan_zero_rpm_stop_temperature
+ *
+ * The amdgpu driver provides a sysfs API for checking and adjusting
+the
+ * zero RPM stop temperature feature.
+ *
+ * Reading back the file shows you the current setting and the
+permitted
+ * ranges if changable.
+ *
+ * Writing an integer to the file, change the setting accordingly.
+ *
+ * When you have finished the editing, write "c" (commit) to the file
+to commit
+ * your changes.
+ *
+ * If you want to reset to the default value, write "r" (reset) to the
+file to
+ * reset them.
+ *
+ * This setting works only if the Zero RPM setting is enabled. It
+adjusts the
+ * temperature below which the fan can stop.
+ */
+static ssize_t fan_zero_rpm_stop_temp_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf) {
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device
+*)container->priv;
+
+ return (ssize_t)amdgpu_retrieve_od_settings(adev,
+OD_FAN_ZERO_RPM_STOP_TEMP, buf); }
+
+static ssize_t fan_zero_rpm_stop_temp_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count) {
+ struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
+ struct amdgpu_device *adev = (struct amdgpu_device
+*)container->priv;
+
+ return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
+ PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP,
+ buf,
+ count); }
+
+static umode_t fan_zero_rpm_stop_temp_visible(struct amdgpu_device
+*adev) {
+ umode_t umode = 0000;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE)
+ umode |= S_IRUSR | S_IRGRP | S_IROTH;
+
+ if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET)
+ umode |= S_IWUSR;
+
+ return umode;
+}
+
static struct od_feature_set amdgpu_od_set = {
.containers = {
[0] = {
@@ -4216,6 +4273,14 @@ static struct od_feature_set amdgpu_od_set = {
.store = fan_zero_rpm_enable_store,
},
},
+ [6] = {
+ .name = "fan_zero_rpm_stop_temperature",
+ .ops = {
+ .is_visible = fan_zero_rpm_stop_temp_visible,
+ .show = fan_zero_rpm_stop_temp_show,
+ .store = fan_zero_rpm_stop_temp_store,
+ },
+ },
},
},
},
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
index b5daa12c0..363af8990 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
@@ -330,6 +330,8 @@ struct config_table_setting
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE BIT(10)
#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET BIT(11)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE BIT(12)
+#define OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET BIT(13)
struct amdgpu_pm {
struct mutex mutex;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 8d3f3e735..8148933cc 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -2876,6 +2876,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
case OD_FAN_ZERO_RPM_ENABLE:
clk_type = SMU_OD_FAN_ZERO_RPM_ENABLE; break;
+ case OD_FAN_ZERO_RPM_STOP_TEMP:
+ clk_type = SMU_OD_FAN_ZERO_RPM_STOP_TEMP; break;
default:
clk_type = SMU_CLK_COUNT; break;
}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
index e0abb449a..a299dc4a8 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
@@ -314,6 +314,7 @@ enum smu_clk_type {
SMU_OD_FAN_TARGET_TEMPERATURE,
SMU_OD_FAN_MINIMUM_PWM,
SMU_OD_FAN_ZERO_RPM_ENABLE,
+ SMU_OD_FAN_ZERO_RPM_STOP_TEMP,
SMU_CLK_COUNT,
};
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 0d9a4638e..93cc82fe2 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -108,6 +108,7 @@
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
+#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
#define LINK_SPEED_MAX 3
@@ -1135,6 +1136,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1473,6 +1478,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_0_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+
+ (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) && @@ -1575,6 +1598,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ od_table->OverDriveTable.FanZeroRpmStopTemp =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1889,6 +1917,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_0_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_0_od_restore_table_single(smu, input[0]); @@ -2161,7 +2210,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
- OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
+
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
}
static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu) @@ -2229,6 +2280,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanMinimumPwm;
user_od_table->OverDriveTable.FanZeroRpmEnable =
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
+ user_od_table->OverDriveTable.FanZeroRpmStopTemp =
+
+ user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
}
smu_v13_0_0_set_supported_od_feature_mask(smu);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 6b61655f9..0b3c53324 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -84,6 +84,7 @@
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
+#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
#define LINK_SPEED_MAX 3
@@ -1124,6 +1125,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1462,6 +1467,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_7_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+
+ (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) && @@ -1563,6 +1586,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ od_table->OverDriveTable.FanZeroRpmStopTemp =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
return -EINVAL;
@@ -1877,6 +1905,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
+ if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v13_0_7_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v13_0_7_od_restore_table_single(smu, input[0]); @@ -2145,7 +2194,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
- OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
+
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
}
static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu) @@ -2213,6 +2264,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanMinimumPwm;
user_od_table->OverDriveTable.FanZeroRpmEnable =
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
+ user_od_table->OverDriveTable.FanZeroRpmStopTemp =
+
+ user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
}
smu_v13_0_7_set_supported_od_feature_mask(smu);
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
2024-10-30 1:01 ` Feng, Kenneth
@ 2024-10-30 15:09 ` Alex Deucher
0 siblings, 0 replies; 10+ messages in thread
From: Alex Deucher @ 2024-10-30 15:09 UTC (permalink / raw)
To: Feng, Kenneth; +Cc: Wolfgang Müller, amd-gfx@lists.freedesktop.org
Applied. Thanks!
Alex
On Tue, Oct 29, 2024 at 9:02 PM Feng, Kenneth <Kenneth.Feng@amd.com> wrote:
>
> [AMD Official Use Only - AMD Internal Distribution Only]
>
> Series is Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
>
>
> -----Original Message-----
> From: Wolfgang Müller <wolf@oriole.systems>
> Sent: Tuesday, October 29, 2024 7:18 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Feng, Kenneth <Kenneth.Feng@amd.com>
> Subject: [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13
>
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> Together with the feature to enable or disable zero RPM in the last commit, it also makes sense to expose the OD setting determining under which temperature the fan should stop if zero RPM is enabled.
>
> Signed-off-by: Wolfgang Müller <wolf@oriole.systems>
> ---
> Documentation/gpu/amdgpu/thermal.rst | 6 ++
> .../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
> drivers/gpu/drm/amd/pm/amdgpu_pm.c | 65 +++++++++++++++++++
> drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +
> drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 1 + .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 55 +++++++++++++++- .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 55 +++++++++++++++-
> 8 files changed, 186 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst
> index ec6c1f1d5..1768a106a 100644
> --- a/Documentation/gpu/amdgpu/thermal.rst
> +++ b/Documentation/gpu/amdgpu/thermal.rst
> @@ -106,6 +106,12 @@ fan_zero_rpm_enable .. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
> :doc: fan_zero_rpm_enable
>
> +fan_zero_rpm_stop_temperature
> +-----------------------------
> +
> +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
> + :doc: fan_zero_rpm_stop_temperature
> +
> GFXOFF
> ======
>
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index 80e4b5a7d..bb27c0d2a 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -120,6 +120,7 @@ enum pp_clock_type {
> OD_FAN_TARGET_TEMPERATURE,
> OD_FAN_MINIMUM_PWM,
> OD_FAN_ZERO_RPM_ENABLE,
> + OD_FAN_ZERO_RPM_STOP_TEMP,
> };
>
> enum amd_pp_sensors {
> @@ -201,6 +202,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
> PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
> PP_OD_EDIT_FAN_MINIMUM_PWM,
> PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
> + PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP,
> };
>
> struct pp_states_info {
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index cb96f1f8c..136e81938 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -4163,6 +4163,63 @@ static umode_t fan_zero_rpm_enable_visible(struct amdgpu_device *adev)
> return umode;
> }
>
> +/**
> + * DOC: fan_zero_rpm_stop_temperature
> + *
> + * The amdgpu driver provides a sysfs API for checking and adjusting
> +the
> + * zero RPM stop temperature feature.
> + *
> + * Reading back the file shows you the current setting and the
> +permitted
> + * ranges if changable.
> + *
> + * Writing an integer to the file, change the setting accordingly.
> + *
> + * When you have finished the editing, write "c" (commit) to the file
> +to commit
> + * your changes.
> + *
> + * If you want to reset to the default value, write "r" (reset) to the
> +file to
> + * reset them.
> + *
> + * This setting works only if the Zero RPM setting is enabled. It
> +adjusts the
> + * temperature below which the fan can stop.
> + */
> +static ssize_t fan_zero_rpm_stop_temp_show(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + char *buf) {
> + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
> + struct amdgpu_device *adev = (struct amdgpu_device
> +*)container->priv;
> +
> + return (ssize_t)amdgpu_retrieve_od_settings(adev,
> +OD_FAN_ZERO_RPM_STOP_TEMP, buf); }
> +
> +static ssize_t fan_zero_rpm_stop_temp_store(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + const char *buf,
> + size_t count) {
> + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
> + struct amdgpu_device *adev = (struct amdgpu_device
> +*)container->priv;
> +
> + return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
> + PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP,
> + buf,
> + count); }
> +
> +static umode_t fan_zero_rpm_stop_temp_visible(struct amdgpu_device
> +*adev) {
> + umode_t umode = 0000;
> +
> + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE)
> + umode |= S_IRUSR | S_IRGRP | S_IROTH;
> +
> + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET)
> + umode |= S_IWUSR;
> +
> + return umode;
> +}
> +
> static struct od_feature_set amdgpu_od_set = {
> .containers = {
> [0] = {
> @@ -4216,6 +4273,14 @@ static struct od_feature_set amdgpu_od_set = {
> .store = fan_zero_rpm_enable_store,
> },
> },
> + [6] = {
> + .name = "fan_zero_rpm_stop_temperature",
> + .ops = {
> + .is_visible = fan_zero_rpm_stop_temp_visible,
> + .show = fan_zero_rpm_stop_temp_show,
> + .store = fan_zero_rpm_stop_temp_store,
> + },
> + },
> },
> },
> },
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> index b5daa12c0..363af8990 100644
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
> @@ -330,6 +330,8 @@ struct config_table_setting
> #define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
> #define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE BIT(10)
> #define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET BIT(11)
> +#define OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE BIT(12)
> +#define OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET BIT(13)
>
> struct amdgpu_pm {
> struct mutex mutex;
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index 8d3f3e735..8148933cc 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -2876,6 +2876,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
> clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
> case OD_FAN_ZERO_RPM_ENABLE:
> clk_type = SMU_OD_FAN_ZERO_RPM_ENABLE; break;
> + case OD_FAN_ZERO_RPM_STOP_TEMP:
> + clk_type = SMU_OD_FAN_ZERO_RPM_STOP_TEMP; break;
> default:
> clk_type = SMU_CLK_COUNT; break;
> }
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> index e0abb449a..a299dc4a8 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
> @@ -314,6 +314,7 @@ enum smu_clk_type {
> SMU_OD_FAN_TARGET_TEMPERATURE,
> SMU_OD_FAN_MINIMUM_PWM,
> SMU_OD_FAN_ZERO_RPM_ENABLE,
> + SMU_OD_FAN_ZERO_RPM_STOP_TEMP,
> SMU_CLK_COUNT,
> };
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> index 0d9a4638e..93cc82fe2 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
> @@ -108,6 +108,7 @@
> #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
> #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
> #define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
> +#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
>
> #define LINK_SPEED_MAX 3
>
> @@ -1135,6 +1136,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
> od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
> od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
> break;
> + case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
> + od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
> + od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
> + break;
> default:
> od_min_setting = od_max_setting = INT_MAX;
> break;
> @@ -1473,6 +1478,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
> min_value, max_value);
> break;
>
> + case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
> + if (!smu_v13_0_0_is_od_feature_supported(smu,
> + PP_OD_FEATURE_ZERO_FAN_BIT))
> + break;
> +
> + size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
> + size += sysfs_emit_at(buf, size, "%d\n",
> +
> + (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
> +
> + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
> + smu_v13_0_0_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
> + &min_value,
> + &max_value);
> + size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
> + min_value, max_value);
> + break;
> +
> case SMU_OD_RANGE:
> if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
> !smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) && @@ -1575,6 +1598,11 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp
> boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> break;
> + case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
> + od_table->OverDriveTable.FanZeroRpmStopTemp =
> + boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> default:
> dev_info(adev->dev, "Invalid table index: %ld\n", input);
> return -EINVAL;
> @@ -1889,6 +1917,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> break;
>
> + case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
> + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
> + dev_warn(adev->dev, "Zero RPM setting not supported!\n");
> + return -ENOTSUPP;
> + }
> +
> + smu_v13_0_0_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
> + &minimum,
> + &maximum);
> + if (input[0] < minimum ||
> + input[0] > maximum) {
> + dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
> + input[0], minimum, maximum);
> + return -EINVAL;
> + }
> +
> + od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> +
> case PP_OD_RESTORE_DEFAULT_TABLE:
> if (size == 1) {
> ret = smu_v13_0_0_od_restore_table_single(smu, input[0]); @@ -2161,7 +2210,9 @@ static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
> OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
> - OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
> +
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
> }
>
> static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu) @@ -2229,6 +2280,8 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
> user_od_table_bak.OverDriveTable.FanMinimumPwm;
> user_od_table->OverDriveTable.FanZeroRpmEnable =
> user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
> + user_od_table->OverDriveTable.FanZeroRpmStopTemp =
> +
> + user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
> }
>
> smu_v13_0_0_set_supported_od_feature_mask(smu);
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> index 6b61655f9..0b3c53324 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
> @@ -84,6 +84,7 @@
> #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
> #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
> #define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
> +#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
>
> #define LINK_SPEED_MAX 3
>
> @@ -1124,6 +1125,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
> od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
> od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
> break;
> + case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
> + od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
> + od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
> + break;
> default:
> od_min_setting = od_max_setting = INT_MAX;
> break;
> @@ -1462,6 +1467,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
> min_value, max_value);
> break;
>
> + case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
> + if (!smu_v13_0_7_is_od_feature_supported(smu,
> + PP_OD_FEATURE_ZERO_FAN_BIT))
> + break;
> +
> + size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
> + size += sysfs_emit_at(buf, size, "%d\n",
> +
> + (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
> +
> + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
> + smu_v13_0_7_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
> + &min_value,
> + &max_value);
> + size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
> + min_value, max_value);
> + break;
> +
> case SMU_OD_RANGE:
> if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
> !smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) && @@ -1563,6 +1586,11 @@ static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long inp
> boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> break;
> + case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
> + od_table->OverDriveTable.FanZeroRpmStopTemp =
> + boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> default:
> dev_info(adev->dev, "Invalid table index: %ld\n", input);
> return -EINVAL;
> @@ -1877,6 +1905,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
> od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> break;
>
> + case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
> + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
> + dev_warn(adev->dev, "Zero RPM setting not supported!\n");
> + return -ENOTSUPP;
> + }
> +
> + smu_v13_0_7_get_od_setting_limits(smu,
> + PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
> + &minimum,
> + &maximum);
> + if (input[0] < minimum ||
> + input[0] > maximum) {
> + dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
> + input[0], minimum, maximum);
> + return -EINVAL;
> + }
> +
> + od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
> + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
> + break;
> +
> case PP_OD_RESTORE_DEFAULT_TABLE:
> if (size == 1) {
> ret = smu_v13_0_7_od_restore_table_single(smu, input[0]); @@ -2145,7 +2194,9 @@ static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu)
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
> OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
> OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
> - OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
> +
> + OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
> }
>
> static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu) @@ -2213,6 +2264,8 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
> user_od_table_bak.OverDriveTable.FanMinimumPwm;
> user_od_table->OverDriveTable.FanZeroRpmEnable =
> user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
> + user_od_table->OverDriveTable.FanZeroRpmStopTemp =
> +
> + user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
> }
>
> smu_v13_0_7_set_supported_od_feature_mask(smu);
> --
> 2.47.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-10-30 15:10 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-19 14:37 [RFC PATCH] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
2024-10-28 9:05 ` Wolfgang Müller
2024-10-28 20:28 ` Alex Deucher
2024-10-29 2:52 ` Feng, Kenneth
2024-10-29 9:02 ` Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 0/2] Two zero RPM features Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 1/2] drm/amd/pm: add zero RPM OD setting support for SMU13 Wolfgang Müller
2024-10-29 11:17 ` [PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature " Wolfgang Müller
2024-10-30 1:01 ` Feng, Kenneth
2024-10-30 15:09 ` Alex Deucher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox