]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/amd/powerplay: update swSMU VCN/JPEG PG logics
authorEvan Quan <evan.quan@amd.com>
Mon, 3 Aug 2020 03:15:14 +0000 (11:15 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 7 Aug 2020 21:48:57 +0000 (17:48 -0400)
Add lock protections and avoid unnecessary actions
if the PG state is already the same as required.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Tested-by: Matt Coffin <mcoffin13@gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
drivers/gpu/drm/amd/powerplay/renoir_ppt.c
drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/powerplay/smu_internal.h

index ceef149d3410bda5c866f5988360ae5ee7227095..70a4e6dab16619e182f8dffbba949e01c8021f00 100644 (file)
@@ -133,6 +133,56 @@ int smu_get_dpm_freq_range(struct smu_context *smu,
        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
  *
@@ -649,6 +699,11 @@ static int smu_sw_init(void *handle)
        smu->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_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
        smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
@@ -1973,7 +2028,7 @@ int smu_read_sensor(struct smu_context *smu,
                *size = 4;
                break;
        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;
                break;
        case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
index 3b2ecb52a36fc2347a123978f5d5a49b5861118d..6c991de8f3712a5767388d198d8245b87ce51292 100644 (file)
@@ -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)
 {
-       struct smu_power_context *smu_power = &smu->smu_power;
-       struct smu_power_gate *power_gate = &smu_power->power_gate;
        int ret = 0;
 
        if (enable) {
@@ -1861,7 +1859,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
                                return ret;
                        }
                }
-               power_gate->vcn_gated = false;
        } else {
                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);
@@ -1870,7 +1867,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
                                return ret;
                        }
                }
-               power_gate->vcn_gated = true;
        }
 
        return ret;
index 28312d6dc187c364d904523712b1ee8dc733daf2..074458eb54076733fdf344d24fd50d21304a4c2b 100644 (file)
@@ -292,8 +292,10 @@ struct smu_dpm_context {
 struct smu_power_gate {
        bool uvd_gated;
        bool vce_gated;
-       bool vcn_gated;
-       bool jpeg_gated;
+       atomic_t vcn_gated;
+       atomic_t jpeg_gated;
+       struct mutex vcn_gate_lock;
+       struct mutex jpeg_gate_lock;
 };
 
 struct smu_power_context {
index c33bdc6747f299f83f6c0ab493b9563b518ab804..9f62af9abd23289f88fb9a2800a40c8f3f69d04c 100644 (file)
@@ -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)
 {
-       struct smu_power_context *smu_power = &smu->smu_power;
-       struct smu_power_gate *power_gate = &smu_power->power_gate;
        int ret = 0;
 
        if (enable) {
@@ -796,14 +794,12 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
                        if (ret)
                                return ret;
                }
-               power_gate->vcn_gated = false;
        } else {
                if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
                        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
                        if (ret)
                                return ret;
                }
-               power_gate->vcn_gated = true;
        }
 
        return ret;
@@ -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)
 {
-       struct smu_power_context *smu_power = &smu->smu_power;
-       struct smu_power_gate *power_gate = &smu_power->power_gate;
        int ret = 0;
 
        if (enable) {
@@ -821,14 +815,12 @@ static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
                        if (ret)
                                return ret;
                }
-               power_gate->jpeg_gated = false;
        } else {
                if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
                        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL);
                        if (ret)
                                return ret;
                }
-               power_gate->jpeg_gated = true;
        }
 
        return ret;
index 575ae4be98a2917b02f1ed50bb20f164d65e9362..dbb676c482fde957fcaf86c2cfcefadafb4a8b24 100644 (file)
@@ -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)
 {
-       struct smu_power_context *smu_power = &smu->smu_power;
-       struct smu_power_gate *power_gate = &smu_power->power_gate;
        int ret = 0;
 
        if (enable) {
@@ -470,14 +468,12 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
                        if (ret)
                                return ret;
                }
-               power_gate->vcn_gated = false;
        } else {
                if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
                        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
                        if (ret)
                                return ret;
                }
-               power_gate->vcn_gated = true;
        }
 
        return ret;
@@ -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)
 {
-       struct smu_power_context *smu_power = &smu->smu_power;
-       struct smu_power_gate *power_gate = &smu_power->power_gate;
        int ret = 0;
 
        if (enable) {
@@ -495,14 +489,12 @@ static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
                        if (ret)
                                return ret;
                }
-               power_gate->jpeg_gated = false;
        } else {
                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);
                        if (ret)
                                return ret;
                }
-               power_gate->jpeg_gated = true;
        }
 
        return ret;
index f373e2d0d31ca43b94350f7e665da52fadb7b28f..3865dbed5f935b89237107b8235c5be49f170396 100644 (file)
@@ -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)
 {
-       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;
-
        int ret = 0;
 
        if (enable) {
@@ -785,7 +782,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
                                        return ret;
                        }
                }
-               power_gate->vcn_gated = false;
        } else {
                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);
@@ -798,7 +794,6 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
                                        return ret;
                        }
                }
-               power_gate->vcn_gated = true;
        }
 
        return ret;
@@ -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)
 {
-       struct smu_power_context *smu_power = &smu->smu_power;
-       struct smu_power_gate *power_gate = &smu_power->power_gate;
        int ret = 0;
 
        if (enable) {
@@ -816,14 +809,12 @@ static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enab
                        if (ret)
                                return ret;
                }
-               power_gate->jpeg_gated = false;
        } else {
                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);
                        if (ret)
                                return ret;
                }
-               power_gate->jpeg_gated = true;
        }
 
        return ret;
index d0deaefd3feb7e319cfff04b3b282209b2fe5cf2..f1d8f247e589898b315ba36399c72b1e1a0a3996 100644 (file)
@@ -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_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_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_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)