Commit 337443d0 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu/smu: make the set_performance_level logic easier to follow



Have every asic provide a callback for this rather than a mix
of generic and asic specific code.

Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c00ca07f
Loading
Loading
Loading
Loading
+2 −42
Original line number Diff line number Diff line
@@ -1607,43 +1607,6 @@ static int smu_enable_umd_pstate(void *handle,
	return 0;
}

static int smu_default_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
{
	int ret = 0;
	uint32_t sclk_mask, mclk_mask, soc_mask;

	switch (level) {
	case AMD_DPM_FORCED_LEVEL_HIGH:
		ret = smu_force_dpm_limit_value(smu, true);
		break;
	case AMD_DPM_FORCED_LEVEL_LOW:
		ret = smu_force_dpm_limit_value(smu, false);
		break;
	case AMD_DPM_FORCED_LEVEL_AUTO:
	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
		ret = smu_unforce_dpm_levels(smu);
		break;
	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
		ret = smu_get_profiling_clk_mask(smu, level,
						 &sclk_mask,
						 &mclk_mask,
						 &soc_mask);
		if (ret)
			return ret;
		smu_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask, false);
		smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
		smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
		break;
	case AMD_DPM_FORCED_LEVEL_MANUAL:
	case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
	default:
		break;
	}
	return ret;
}

int smu_adjust_power_state_dynamic(struct smu_context *smu,
				   enum amd_dpm_forced_level level,
				   bool skip_display_settings)
@@ -1680,13 +1643,10 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,

	if (smu_dpm_ctx->dpm_level != level) {
		ret = smu_asic_set_performance_level(smu, level);
		if (ret) {
			ret = smu_default_set_performance_level(smu, level);
		if (ret) {
			pr_err("Failed to set performance level!");
			return ret;
		}
		}

		/* update the saved copy */
		smu_dpm_ctx->dpm_level = level;
+1 −0
Original line number Diff line number Diff line
@@ -2237,6 +2237,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
	.get_profiling_clk_mask = arcturus_get_profiling_clk_mask,
	.get_power_profile_mode = arcturus_get_power_profile_mode,
	.set_power_profile_mode = arcturus_set_power_profile_mode,
	.set_performance_level = smu_v11_0_set_performance_level,
	/* debug (internal used) */
	.dump_pptable = arcturus_dump_pptable,
	.get_power_limit = arcturus_get_power_limit,
+3 −0
Original line number Diff line number Diff line
@@ -262,4 +262,7 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize,

uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu);

int smu_v11_0_set_performance_level(struct smu_context *smu,
				    enum amd_dpm_forced_level level);

#endif
+27 −3
Original line number Diff line number Diff line
@@ -1658,19 +1658,43 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu)
	return ret;
}

static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
static int navi10_set_performance_level(struct smu_context *smu,
					enum amd_dpm_forced_level level)
{
	int ret = 0;
	uint32_t sclk_mask, mclk_mask, soc_mask;

	switch (level) {
	case AMD_DPM_FORCED_LEVEL_HIGH:
		ret = smu_force_dpm_limit_value(smu, true);
		break;
	case AMD_DPM_FORCED_LEVEL_LOW:
		ret = smu_force_dpm_limit_value(smu, false);
		break;
	case AMD_DPM_FORCED_LEVEL_AUTO:
	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
		ret = smu_unforce_dpm_levels(smu);
		break;
	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
		ret = smu_get_profiling_clk_mask(smu, level,
						 &sclk_mask,
						 &mclk_mask,
						 &soc_mask);
		if (ret)
			return ret;
		smu_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask, false);
		smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
		smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
		break;
	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
		ret = navi10_set_peak_clock_by_device(smu);
		break;
	case AMD_DPM_FORCED_LEVEL_MANUAL:
	case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

+27 −3
Original line number Diff line number Diff line
@@ -708,19 +708,43 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
	return ret;
}

static int renoir_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
static int renoir_set_performance_level(struct smu_context *smu,
					enum amd_dpm_forced_level level)
{
	int ret = 0;
	uint32_t sclk_mask, mclk_mask, soc_mask;

	switch (level) {
	case AMD_DPM_FORCED_LEVEL_HIGH:
		ret = smu_force_dpm_limit_value(smu, true);
		break;
	case AMD_DPM_FORCED_LEVEL_LOW:
		ret = smu_force_dpm_limit_value(smu, false);
		break;
	case AMD_DPM_FORCED_LEVEL_AUTO:
	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
		ret = smu_unforce_dpm_levels(smu);
		break;
	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
		ret = smu_get_profiling_clk_mask(smu, level,
						 &sclk_mask,
						 &mclk_mask,
						 &soc_mask);
		if (ret)
			return ret;
		smu_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask, false);
		smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
		smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
		break;
	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
		ret = renoir_set_peak_clock_by_device(smu);
		break;
	case AMD_DPM_FORCED_LEVEL_MANUAL:
	case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

Loading