[PATCH v2 2/2] drm/amd/pm: add zero RPM stop temperature OD setting support for SMU13

Feng, Kenneth Kenneth.Feng at amd.com
Wed Oct 30 01:01:57 UTC 2024


[AMD Official Use Only - AMD Internal Distribution Only]

Series is Reviewed-by: Kenneth Feng <kenneth.feng at amd.com>


-----Original Message-----
From: Wolfgang Müller <wolf at oriole.systems>
Sent: Tuesday, October 29, 2024 7:18 PM
To: amd-gfx at lists.freedesktop.org
Cc: Feng, Kenneth <Kenneth.Feng at 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 at 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



More information about the amd-gfx mailing list