Commit 47089160 authored by Yang Wang's avatar Yang Wang Committed by Alex Deucher
Browse files

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]!

Closes: https://github.com/ROCm/amdgpu/issues/208


Signed-off-by: default avatarYang Wang <kevinyang.wang@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 896ffa98
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -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),
@@ -1043,8 +1047,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,
+32 −1
Original line number Diff line number Diff line
@@ -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),
@@ -1053,8 +1057,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,