Skip to content

Commit cfffd98

Browse files
wylfenalexdeucher
authored andcommitted
drm/amd/pm: add zero RPM OD setting support for SMU13
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 Reviewed-by: Kenneth Feng <[email protected]> Signed-off-by: Wolfgang Müller <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 8cc438b commit cfffd98

File tree

8 files changed

+183
-2
lines changed

8 files changed

+183
-2
lines changed

Documentation/gpu/amdgpu/thermal.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ fan_minimum_pwm
100100
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
101101
:doc: fan_minimum_pwm
102102

103+
fan_zero_rpm_enable
104+
----------------------
105+
106+
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
107+
:doc: fan_zero_rpm_enable
108+
103109
GFXOFF
104110
======
105111

drivers/gpu/drm/amd/include/kgd_pp_interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ enum pp_clock_type {
119119
OD_ACOUSTIC_TARGET,
120120
OD_FAN_TARGET_TEMPERATURE,
121121
OD_FAN_MINIMUM_PWM,
122+
OD_FAN_ZERO_RPM_ENABLE,
122123
};
123124

124125
enum amd_pp_sensors {
@@ -199,6 +200,7 @@ enum PP_OD_DPM_TABLE_COMMAND {
199200
PP_OD_EDIT_ACOUSTIC_TARGET,
200201
PP_OD_EDIT_FAN_TARGET_TEMPERATURE,
201202
PP_OD_EDIT_FAN_MINIMUM_PWM,
203+
PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
202204
};
203205

204206
struct pp_states_info {

drivers/gpu/drm/amd/pm/amdgpu_pm.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4109,6 +4109,60 @@ static umode_t fan_minimum_pwm_visible(struct amdgpu_device *adev)
41094109
return umode;
41104110
}
41114111

4112+
/**
4113+
* DOC: fan_zero_rpm_enable
4114+
*
4115+
* The amdgpu driver provides a sysfs API for checking and adjusting the
4116+
* zero RPM feature.
4117+
*
4118+
* Reading back the file shows you the current setting and the permitted
4119+
* ranges if changable.
4120+
*
4121+
* Writing an integer to the file, change the setting accordingly.
4122+
*
4123+
* When you have finished the editing, write "c" (commit) to the file to commit
4124+
* your changes.
4125+
*
4126+
* If you want to reset to the default value, write "r" (reset) to the file to
4127+
* reset them.
4128+
*/
4129+
static ssize_t fan_zero_rpm_enable_show(struct kobject *kobj,
4130+
struct kobj_attribute *attr,
4131+
char *buf)
4132+
{
4133+
struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
4134+
struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
4135+
4136+
return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_ZERO_RPM_ENABLE, buf);
4137+
}
4138+
4139+
static ssize_t fan_zero_rpm_enable_store(struct kobject *kobj,
4140+
struct kobj_attribute *attr,
4141+
const char *buf,
4142+
size_t count)
4143+
{
4144+
struct od_kobj *container = container_of(kobj, struct od_kobj, kobj);
4145+
struct amdgpu_device *adev = (struct amdgpu_device *)container->priv;
4146+
4147+
return (ssize_t)amdgpu_distribute_custom_od_settings(adev,
4148+
PP_OD_EDIT_FAN_ZERO_RPM_ENABLE,
4149+
buf,
4150+
count);
4151+
}
4152+
4153+
static umode_t fan_zero_rpm_enable_visible(struct amdgpu_device *adev)
4154+
{
4155+
umode_t umode = 0000;
4156+
4157+
if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE)
4158+
umode |= S_IRUSR | S_IRGRP | S_IROTH;
4159+
4160+
if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET)
4161+
umode |= S_IWUSR;
4162+
4163+
return umode;
4164+
}
4165+
41124166
static struct od_feature_set amdgpu_od_set = {
41134167
.containers = {
41144168
[0] = {
@@ -4154,6 +4208,14 @@ static struct od_feature_set amdgpu_od_set = {
41544208
.store = fan_minimum_pwm_store,
41554209
},
41564210
},
4211+
[5] = {
4212+
.name = "fan_zero_rpm_enable",
4213+
.ops = {
4214+
.is_visible = fan_zero_rpm_enable_visible,
4215+
.show = fan_zero_rpm_enable_show,
4216+
.store = fan_zero_rpm_enable_store,
4217+
},
4218+
},
41574219
},
41584220
},
41594221
},

drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ struct config_table_setting
328328
#define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7)
329329
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8)
330330
#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9)
331+
#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE BIT(10)
332+
#define OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET BIT(11)
331333

332334
struct amdgpu_pm {
333335
struct mutex mutex;

drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,6 +2895,8 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
28952895
clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break;
28962896
case OD_FAN_MINIMUM_PWM:
28972897
clk_type = SMU_OD_FAN_MINIMUM_PWM; break;
2898+
case OD_FAN_ZERO_RPM_ENABLE:
2899+
clk_type = SMU_OD_FAN_ZERO_RPM_ENABLE; break;
28982900
default:
28992901
clk_type = SMU_CLK_COUNT; break;
29002902
}

drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ enum smu_clk_type {
313313
SMU_OD_ACOUSTIC_TARGET,
314314
SMU_OD_FAN_TARGET_TEMPERATURE,
315315
SMU_OD_FAN_MINIMUM_PWM,
316+
SMU_OD_FAN_ZERO_RPM_ENABLE,
316317
SMU_CLK_COUNT,
317318
};
318319

drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
108108
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
109109
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
110+
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
110111

111112
#define LINK_SPEED_MAX 3
112113

@@ -1130,6 +1131,10 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
11301131
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
11311132
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
11321133
break;
1134+
case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
1135+
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
1136+
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
1137+
break;
11331138
default:
11341139
od_min_setting = od_max_setting = INT_MAX;
11351140
break;
@@ -1450,6 +1455,24 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
14501455
min_value, max_value);
14511456
break;
14521457

1458+
case SMU_OD_FAN_ZERO_RPM_ENABLE:
1459+
if (!smu_v13_0_0_is_od_feature_supported(smu,
1460+
PP_OD_FEATURE_ZERO_FAN_BIT))
1461+
break;
1462+
1463+
size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
1464+
size += sysfs_emit_at(buf, size, "%d\n",
1465+
(int)od_table->OverDriveTable.FanZeroRpmEnable);
1466+
1467+
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1468+
smu_v13_0_0_get_od_setting_limits(smu,
1469+
PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
1470+
&min_value,
1471+
&max_value);
1472+
size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
1473+
min_value, max_value);
1474+
break;
1475+
14531476
case SMU_OD_RANGE:
14541477
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
14551478
!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
15471570
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
15481571
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
15491572
break;
1573+
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
1574+
od_table->OverDriveTable.FanZeroRpmEnable =
1575+
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
1576+
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1577+
break;
15501578
default:
15511579
dev_info(adev->dev, "Invalid table index: %ld\n", input);
15521580
return -EINVAL;
@@ -1840,6 +1868,27 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
18401868
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
18411869
break;
18421870

1871+
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
1872+
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
1873+
dev_warn(adev->dev, "Zero RPM setting not supported!\n");
1874+
return -ENOTSUPP;
1875+
}
1876+
1877+
smu_v13_0_0_get_od_setting_limits(smu,
1878+
PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
1879+
&minimum,
1880+
&maximum);
1881+
if (input[0] < minimum ||
1882+
input[0] > maximum) {
1883+
dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
1884+
input[0], minimum, maximum);
1885+
return -EINVAL;
1886+
}
1887+
1888+
od_table->OverDriveTable.FanZeroRpmEnable = input[0];
1889+
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1890+
break;
1891+
18431892
case PP_OD_RESTORE_DEFAULT_TABLE:
18441893
if (size == 1) {
18451894
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)
21102159
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
21112160
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
21122161
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
2113-
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
2162+
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
2163+
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
2164+
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
21142165
}
21152166

21162167
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)
21762227
user_od_table_bak.OverDriveTable.FanTargetTemperature;
21772228
user_od_table->OverDriveTable.FanMinimumPwm =
21782229
user_od_table_bak.OverDriveTable.FanMinimumPwm;
2230+
user_od_table->OverDriveTable.FanZeroRpmEnable =
2231+
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
21792232
}
21802233

21812234
smu_v13_0_0_set_supported_od_feature_mask(smu);

drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
8484
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
8585
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
86+
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
8687

8788
#define LINK_SPEED_MAX 3
8889

@@ -1119,6 +1120,10 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
11191120
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
11201121
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
11211122
break;
1123+
case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
1124+
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
1125+
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
1126+
break;
11221127
default:
11231128
od_min_setting = od_max_setting = INT_MAX;
11241129
break;
@@ -1439,6 +1444,24 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
14391444
min_value, max_value);
14401445
break;
14411446

1447+
case SMU_OD_FAN_ZERO_RPM_ENABLE:
1448+
if (!smu_v13_0_7_is_od_feature_supported(smu,
1449+
PP_OD_FEATURE_ZERO_FAN_BIT))
1450+
break;
1451+
1452+
size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
1453+
size += sysfs_emit_at(buf, size, "%d\n",
1454+
(int)od_table->OverDriveTable.FanZeroRpmEnable);
1455+
1456+
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1457+
smu_v13_0_7_get_od_setting_limits(smu,
1458+
PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
1459+
&min_value,
1460+
&max_value);
1461+
size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
1462+
min_value, max_value);
1463+
break;
1464+
14421465
case SMU_OD_RANGE:
14431466
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
14441467
!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
15351558
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
15361559
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
15371560
break;
1561+
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
1562+
od_table->OverDriveTable.FanZeroRpmEnable =
1563+
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
1564+
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1565+
break;
15381566
default:
15391567
dev_info(adev->dev, "Invalid table index: %ld\n", input);
15401568
return -EINVAL;
@@ -1828,6 +1856,27 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
18281856
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
18291857
break;
18301858

1859+
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
1860+
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
1861+
dev_warn(adev->dev, "Zero RPM setting not supported!\n");
1862+
return -ENOTSUPP;
1863+
}
1864+
1865+
smu_v13_0_7_get_od_setting_limits(smu,
1866+
PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
1867+
&minimum,
1868+
&maximum);
1869+
if (input[0] < minimum ||
1870+
input[0] > maximum) {
1871+
dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
1872+
input[0], minimum, maximum);
1873+
return -EINVAL;
1874+
}
1875+
1876+
od_table->OverDriveTable.FanZeroRpmEnable = input[0];
1877+
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1878+
break;
1879+
18311880
case PP_OD_RESTORE_DEFAULT_TABLE:
18321881
if (size == 1) {
18331882
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)
20942143
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
20952144
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
20962145
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
2097-
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
2146+
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
2147+
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
2148+
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
20982149
}
20992150

21002151
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)
21602211
user_od_table_bak.OverDriveTable.FanTargetTemperature;
21612212
user_od_table->OverDriveTable.FanMinimumPwm =
21622213
user_od_table_bak.OverDriveTable.FanMinimumPwm;
2214+
user_od_table->OverDriveTable.FanZeroRpmEnable =
2215+
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
21632216
}
21642217

21652218
smu_v13_0_7_set_supported_od_feature_mask(smu);

0 commit comments

Comments
 (0)