On Thu, Mar 19, 2026 at 11:24 PM Wang, Yang(Kevin) <[email protected]> wrote: > > [AMD Official Use Only - AMD Internal Distribution Only] > > Extra information: > > [Issue]: Can not set fan speed on Radeon Pro W7900 > Closes: https://github.com/ROCm/amdgpu/issues/208
With that line added to the commit, Acked-by: Alex Deucher <[email protected]> > > Best Regards, > Kevin > > -----Original Message----- > From: amd-gfx <[email protected]> On Behalf Of Yang Wang > Sent: Friday, March 20, 2026 09:48 > To: [email protected] > Cc: Deucher, Alexander <[email protected]>; Zhang, Hawking > <[email protected]>; Feng, Kenneth <[email protected]> > Subject: [PATCH 1/2] drm/amd/pm: disable OD_FAN_CURVE if temp or pwm range > invalid for smu v13 > > Forcibly disable the OD_FAN_CURVE feature when temperature or PWM range is > invalid, otherwise PMFW will reject this configuration on smu v13.0.x > > example: > $ sudo cat /sys/bus/pci/devices/<BDF>/gpu_od/fan_ctrl/fan_curve > > OD_FAN_CURVE: > 0: 0C 0% > 1: 0C 0% > 2: 0C 0% > 3: 0C 0% > 4: 0C 0% > OD_RANGE: > FAN_CURVE(hotspot temp): 0C 0C > FAN_CURVE(fan speed): 0% 0% > > $ echo "0 50 40" | sudo tee fan_curve > > kernel log: > [ 756.442527] amdgpu 0000:03:00.0: amdgpu: Fan curve temp setting(50) must > be within [0, 0]! > [ 777.345800] amdgpu 0000:03:00.0: amdgpu: Fan curve temp setting(50) must > be within [0, 0]! > > Signed-off-by: Yang Wang <[email protected]> > --- > .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 33 ++++++++++++++++++- > .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 33 ++++++++++++++++++- > 2 files changed, 64 insertions(+), 2 deletions(-) > > 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 cd077151f3e4..9be7a2af560d 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 > @@ -59,6 +59,10 @@ > > #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, > pm.smu_i2c)) > > +static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, > + int od_feature_bit, > + int32_t *min, int32_t *max); > + > static const struct smu_feature_bits smu_v13_0_0_dpm_features = { > .bits = { > SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), > @@ -1044,8 +1048,35 @@ static bool smu_v13_0_0_is_od_feature_supported(struct > smu_context *smu, > PPTable_t *pptable = smu->smu_table.driver_pptable; > const OverDriveLimits_t * const overdrive_upperlimits = > &pptable->SkuTable.OverDriveLimitsBasicMax; > + int32_t min_value, max_value; > + bool feature_enabled; > > - return overdrive_upperlimits->FeatureCtrlMask & (1U << > od_feature_bit); > + switch (od_feature_bit) { > + case PP_OD_FEATURE_FAN_CURVE_BIT: > + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & > (1U << od_feature_bit)); > + if (feature_enabled) { > + smu_v13_0_0_get_od_setting_limits(smu, > PP_OD_FEATURE_FAN_CURVE_TEMP, > + &min_value, > &max_value); > + if (!min_value && !max_value) { > + feature_enabled = false; > + goto out; > + } > + > + smu_v13_0_0_get_od_setting_limits(smu, > PP_OD_FEATURE_FAN_CURVE_PWM, > + &min_value, > &max_value); > + if (!min_value && !max_value) { > + feature_enabled = false; > + goto out; > + } > + } > + break; > + default: > + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & > (1U << od_feature_bit)); > + break; > + } > + > +out: > + return feature_enabled; > } > > static void smu_v13_0_0_get_od_setting_limits(struct smu_context *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 a1d50654db72..5cc15545da6e 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 > @@ -59,6 +59,10 @@ > > #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, > pm.smu_i2c)) > > +static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, > + int od_feature_bit, > + int32_t *min, int32_t *max); > + > static const struct smu_feature_bits smu_v13_0_7_dpm_features = { > .bits = { > SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), > @@ -1054,8 +1058,35 @@ static bool smu_v13_0_7_is_od_feature_supported(struct > smu_context *smu, > PPTable_t *pptable = smu->smu_table.driver_pptable; > const OverDriveLimits_t * const overdrive_upperlimits = > &pptable->SkuTable.OverDriveLimitsBasicMax; > + int32_t min_value, max_value; > + bool feature_enabled; > > - return overdrive_upperlimits->FeatureCtrlMask & (1U << > od_feature_bit); > + switch (od_feature_bit) { > + case PP_OD_FEATURE_FAN_CURVE_BIT: > + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & > (1U << od_feature_bit)); > + if (feature_enabled) { > + smu_v13_0_7_get_od_setting_limits(smu, > PP_OD_FEATURE_FAN_CURVE_TEMP, > + &min_value, > &max_value); > + if (!min_value && !max_value) { > + feature_enabled = false; > + goto out; > + } > + > + smu_v13_0_7_get_od_setting_limits(smu, > PP_OD_FEATURE_FAN_CURVE_PWM, > + &min_value, > &max_value); > + if (!min_value && !max_value) { > + feature_enabled = false; > + goto out; > + } > + } > + break; > + default: > + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & > (1U << od_feature_bit)); > + break; > + } > + > +out: > + return feature_enabled; > } > > static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, > -- > 2.47.3 >
