[PATCH 130/138] drm/amd/powerplay: adjust power state when set od_clk
Huang Rui
ray.huang at amd.com
Fri Jan 25 10:25:37 UTC 2019
From: Likun Gao <Likun.Gao at amd.com>
Expose the function of adjust_power_state_dynamic to make it common to
other functions.
Add the operate of adjust powet state when set od percentage or
overdrive commit dpm table.
Signed-off-by: Likun Gao <Likun.Gao at amd.com>
Reviewed-by: Huang Rui <ray.huang at amd.com>
Reviewed-by: Kevin Wang <kevin1.wang at amd.com>
---
drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 80 +++++++++++++++++++++---------
1 file changed, 56 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
index 7745319..e117af4 100644
--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
@@ -1764,44 +1764,35 @@ static enum amd_dpm_forced_level vega20_get_performance_level(struct smu_context
return smu_dpm_ctx->dpm_level;
}
-static int
-vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
+static int vega20_adjust_power_state_dynamic(struct smu_context *smu,
+ enum amd_dpm_forced_level level)
{
int ret = 0;
int index = 0;
- int i = 0;
uint32_t sclk_mask, mclk_mask, soc_mask;
long workload;
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
- if (!smu_dpm_ctx->dpm_context)
- return -EINVAL;
- for (i = 0; i < smu->adev->num_ip_blocks; i++) {
- if (smu->adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC)
- break;
- }
- mutex_lock(&smu->mutex);
- smu->adev->ip_blocks[i].version->funcs->enable_umd_pstate(smu, &level);
ret = vega20_display_config_changed(smu);
if (ret) {
pr_err("Failed to change display config!");
- goto failed;
+ return ret;
}
ret = vega20_apply_clocks_adjust_rules(smu);
if (ret) {
pr_err("Failed to apply clocks adjust rules!");
- goto failed;
+ return ret;
}
ret = vega20_notify_smc_dispaly_config(smu);
if (ret) {
pr_err("Failed to notify smc display config!");
- goto failed;
+ return ret;
}
+
switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH:
ret = vega20_force_dpm_highest(smu);
break;
-
case AMD_DPM_FORCED_LEVEL_LOW:
ret = vega20_force_dpm_lowest(smu);
break;
@@ -1819,7 +1810,7 @@ vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_leve
&mclk_mask,
&soc_mask);
if (ret)
- goto failed;
+ return ret;
vega20_force_clk_levels(smu, PP_SCLK, 1 << sclk_mask);
vega20_force_clk_levels(smu, PP_MCLK, 1 << mclk_mask);
break;
@@ -1842,8 +1833,31 @@ vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_leve
smu->funcs->set_power_profile_mode(smu, &workload, 0);
}
-failed:
+ return ret;
+}
+
+static int
+vega20_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
+{
+ int ret = 0;
+ int i;
+ struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+
+ if (!smu_dpm_ctx->dpm_context)
+ return -EINVAL;
+
+ for (i = 0; i < smu->adev->num_ip_blocks; i++) {
+ if (smu->adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC)
+ break;
+ }
+
+ mutex_lock(&smu->mutex);
+
+ smu->adev->ip_blocks[i].version->funcs->enable_umd_pstate(smu, &level);
+ ret = vega20_adjust_power_state_dynamic(smu, level);
+
mutex_unlock(&smu->mutex);
+
return ret;
}
@@ -1934,9 +1948,12 @@ static int vega20_set_od_percentage(struct smu_context *smu,
struct vega20_single_dpm_table *single_dpm_table;
struct vega20_single_dpm_table *golden_dpm_table;
uint32_t od_clk, index;
- int ret, feature_enabled;
+ int ret = 0;
+ int feature_enabled;
PPCLK_e clk_id;
+ mutex_lock(&(smu->mutex));
+
dpm_table = smu_dpm->dpm_context;
golden_table = smu_dpm->golden_dpm_context;
@@ -1956,10 +1973,13 @@ static int vega20_set_od_percentage(struct smu_context *smu,
index = OD8_SETTING_UCLK_FMAX;
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
break;
}
+ if (ret)
+ goto set_od_failed;
+
od_clk = golden_dpm_table->dpm_levels[golden_dpm_table->count - 1].value * value;
od_clk /= 100;
od_clk += golden_dpm_table->dpm_levels[golden_dpm_table->count - 1].value;
@@ -1967,7 +1987,7 @@ static int vega20_set_od_percentage(struct smu_context *smu,
ret = smu_update_od8_settings(smu, index, od_clk);
if (ret) {
pr_err("[Setoverdrive] failed to set od clk!\n");
- return ret;
+ goto set_od_failed;
}
if (feature_enabled) {
@@ -1975,14 +1995,19 @@ static int vega20_set_od_percentage(struct smu_context *smu,
clk_id);
if (ret) {
pr_err("[Setoverdrive] failed to refresh dpm table!\n");
- return ret;
+ goto set_od_failed;
}
} else {
single_dpm_table->count = 1;
single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
}
- return 0;
+ ret = vega20_adjust_power_state_dynamic(smu, smu_dpm->dpm_level);
+
+set_od_failed:
+ mutex_unlock(&(smu->mutex));
+
+ return ret;
}
static int vega20_odn_edit_dpm_table(struct smu_context *smu,
@@ -1999,7 +2024,8 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu,
(struct vega20_od8_settings *)table_context->od8_settings;
struct pp_clock_levels_with_latency clocks;
int32_t input_index, input_clk, input_vol, i;
- int od8_id, ret;
+ int od8_id;
+ int ret = 0;
dpm_table = smu_dpm->dpm_context;
@@ -2204,7 +2230,13 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu,
return -EINVAL;
}
- return 0;
+ if (type == PP_OD_COMMIT_DPM_TABLE) {
+ mutex_lock(&(smu->mutex));
+ ret = vega20_adjust_power_state_dynamic(smu, smu_dpm->dpm_level);
+ mutex_unlock(&(smu->mutex));
+ }
+
+ return ret;
}
static const struct pptable_funcs vega20_ppt_funcs = {
--
2.7.4
More information about the amd-gfx
mailing list