Commit 2c34c960 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

drm/amd/powerplay: update swSMU VCN/JPEG PG logics

Add lock protections and avoid unnecessary actions
if the PG state is already the same as required.
Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Tested-by: default avatarMatt Coffin <mcoffin13@gmail.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f2e2573c
...@@ -133,6 +133,56 @@ int smu_get_dpm_freq_range(struct smu_context *smu, ...@@ -133,6 +133,56 @@ int smu_get_dpm_freq_range(struct smu_context *smu,
return ret; return ret;
} }
static int smu_dpm_set_vcn_enable(struct smu_context *smu,
bool enable)
{
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0;
if (!smu->ppt_funcs->dpm_set_vcn_enable)
return 0;
mutex_lock(&power_gate->vcn_gate_lock);
if (atomic_read(&power_gate->vcn_gated) ^ enable)
goto out;
ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable);
if (!ret)
atomic_set(&power_gate->vcn_gated, !enable);
out:
mutex_unlock(&power_gate->vcn_gate_lock);
return ret;
}
static int smu_dpm_set_jpeg_enable(struct smu_context *smu,
bool enable)
{
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0;
if (!smu->ppt_funcs->dpm_set_jpeg_enable)
return 0;
mutex_lock(&power_gate->jpeg_gate_lock);
if (atomic_read(&power_gate->jpeg_gated) ^ enable)
goto out;
ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable);
if (!ret)
atomic_set(&power_gate->jpeg_gated, !enable);
out:
mutex_unlock(&power_gate->jpeg_gate_lock);
return ret;
}
/** /**
* smu_dpm_set_power_gate - power gate/ungate the specific IP block * smu_dpm_set_power_gate - power gate/ungate the specific IP block
* *
...@@ -649,6 +699,11 @@ static int smu_sw_init(void *handle) ...@@ -649,6 +699,11 @@ static int smu_sw_init(void *handle)
smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);
atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);
mutex_init(&smu->smu_power.power_gate.vcn_gate_lock);
mutex_init(&smu->smu_power.power_gate.jpeg_gate_lock);
smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1; smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
...@@ -1973,7 +2028,7 @@ int smu_read_sensor(struct smu_context *smu, ...@@ -1973,7 +2028,7 @@ int smu_read_sensor(struct smu_context *smu,
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_VCN_POWER_STATE: case AMDGPU_PP_SENSOR_VCN_POWER_STATE:
*(uint32_t *)data = smu->smu_power.power_gate.vcn_gated ? 0 : 1; *(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0: 1;
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_MIN_FAN_RPM: case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
......
...@@ -1849,8 +1849,6 @@ static bool arcturus_is_dpm_running(struct smu_context *smu) ...@@ -1849,8 +1849,6 @@ static bool arcturus_is_dpm_running(struct smu_context *smu)
static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable) static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -1861,7 +1859,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable) ...@@ -1861,7 +1859,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
return ret; return ret;
} }
} }
power_gate->vcn_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0); ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0);
...@@ -1870,7 +1867,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable) ...@@ -1870,7 +1867,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
return ret; return ret;
} }
} }
power_gate->vcn_gated = true;
} }
return ret; return ret;
......
...@@ -292,8 +292,10 @@ struct smu_dpm_context { ...@@ -292,8 +292,10 @@ struct smu_dpm_context {
struct smu_power_gate { struct smu_power_gate {
bool uvd_gated; bool uvd_gated;
bool vce_gated; bool vce_gated;
bool vcn_gated; atomic_t vcn_gated;
bool jpeg_gated; atomic_t jpeg_gated;
struct mutex vcn_gate_lock;
struct mutex jpeg_gate_lock;
}; };
struct smu_power_context { struct smu_power_context {
......
...@@ -785,8 +785,6 @@ static int navi10_set_default_dpm_table(struct smu_context *smu) ...@@ -785,8 +785,6 @@ static int navi10_set_default_dpm_table(struct smu_context *smu)
static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable) static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -796,14 +794,12 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable) ...@@ -796,14 +794,12 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
if (ret) if (ret)
return ret; return ret;
} }
power_gate->vcn_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL); ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
if (ret) if (ret)
return ret; return ret;
} }
power_gate->vcn_gated = true;
} }
return ret; return ret;
...@@ -811,8 +807,6 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable) ...@@ -811,8 +807,6 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -821,14 +815,12 @@ static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) ...@@ -821,14 +815,12 @@ static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
if (ret) if (ret)
return ret; return ret;
} }
power_gate->jpeg_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL); ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL);
if (ret) if (ret)
return ret; return ret;
} }
power_gate->jpeg_gated = true;
} }
return ret; return ret;
......
...@@ -459,8 +459,6 @@ static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context ...@@ -459,8 +459,6 @@ static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context
static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable) static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -470,14 +468,12 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable) ...@@ -470,14 +468,12 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
if (ret) if (ret)
return ret; return ret;
} }
power_gate->vcn_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL); ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
if (ret) if (ret)
return ret; return ret;
} }
power_gate->vcn_gated = true;
} }
return ret; return ret;
...@@ -485,8 +481,6 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable) ...@@ -485,8 +481,6 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -495,14 +489,12 @@ static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) ...@@ -495,14 +489,12 @@ static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
if (ret) if (ret)
return ret; return ret;
} }
power_gate->jpeg_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL); ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
if (ret) if (ret)
return ret; return ret;
} }
power_gate->jpeg_gated = true;
} }
return ret; return ret;
......
...@@ -766,10 +766,7 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu) ...@@ -766,10 +766,7 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu)
static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable) static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
struct amdgpu_device *adev = smu->adev; struct amdgpu_device *adev = smu->adev;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -785,7 +782,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl ...@@ -785,7 +782,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
return ret; return ret;
} }
} }
power_gate->vcn_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL); ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL);
...@@ -798,7 +794,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl ...@@ -798,7 +794,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
return ret; return ret;
} }
} }
power_gate->vcn_gated = true;
} }
return ret; return ret;
...@@ -806,8 +801,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl ...@@ -806,8 +801,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
{ {
struct smu_power_context *smu_power = &smu->smu_power;
struct smu_power_gate *power_gate = &smu_power->power_gate;
int ret = 0; int ret = 0;
if (enable) { if (enable) {
...@@ -816,14 +809,12 @@ static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enab ...@@ -816,14 +809,12 @@ static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enab
if (ret) if (ret)
return ret; return ret;
} }
power_gate->jpeg_gated = false;
} else { } else {
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL); ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
if (ret) if (ret)
return ret; return ret;
} }
power_gate->jpeg_gated = true;
} }
return ret; return ret;
......
...@@ -77,8 +77,6 @@ ...@@ -77,8 +77,6 @@
#define smu_get_dal_power_level(smu, clocks) smu_ppt_funcs(get_dal_power_level, 0, smu, clocks) #define smu_get_dal_power_level(smu, clocks) smu_ppt_funcs(get_dal_power_level, 0, smu, clocks)
#define smu_get_perf_level(smu, designation, level) smu_ppt_funcs(get_perf_level, 0, smu, designation, level) #define smu_get_perf_level(smu, designation, level) smu_ppt_funcs(get_perf_level, 0, smu, designation, level)
#define smu_get_current_shallow_sleep_clocks(smu, clocks) smu_ppt_funcs(get_current_shallow_sleep_clocks, 0, smu, clocks) #define smu_get_current_shallow_sleep_clocks(smu, clocks) smu_ppt_funcs(get_current_shallow_sleep_clocks, 0, smu, clocks)
#define smu_dpm_set_vcn_enable(smu, enable) smu_ppt_funcs(dpm_set_vcn_enable, 0, smu, enable)
#define smu_dpm_set_jpeg_enable(smu, enable) smu_ppt_funcs(dpm_set_jpeg_enable, 0, smu, enable)
#define smu_set_watermarks_table(smu, clock_ranges) smu_ppt_funcs(set_watermarks_table, 0, smu, clock_ranges) #define smu_set_watermarks_table(smu, clock_ranges) smu_ppt_funcs(set_watermarks_table, 0, smu, clock_ranges)
#define smu_thermal_temperature_range_update(smu, range, rw) smu_ppt_funcs(thermal_temperature_range_update, 0, smu, range, rw) #define smu_thermal_temperature_range_update(smu, range, rw) smu_ppt_funcs(thermal_temperature_range_update, 0, smu, range, rw)
#define smu_register_irq_handler(smu) smu_ppt_funcs(register_irq_handler, 0, smu) #define smu_register_irq_handler(smu) smu_ppt_funcs(register_irq_handler, 0, smu)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment