drm/amd/powerplay: put VCN/JPEG into PG ungate state before dpm table setup(V3)
authorEvan Quan <evan.quan@amd.com>
Wed, 5 Aug 2020 09:24:41 +0000 (17:24 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 7 Aug 2020 21:29:54 +0000 (17:29 -0400)
As VCN related dpm table setup needs VCN be in PG ungate state. Same logics
applies to JPEG.

V2: fix paste typo
V3: code cosmetic

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/smu_internal.h

index 1b64ca9..1ffacc7 100644 (file)
@@ -133,8 +133,8 @@ 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)
+static int smu_dpm_set_vcn_enable_locked(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;
@@ -143,23 +143,34 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu,
        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;
+               return 0;
 
        ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable);
        if (!ret)
                atomic_set(&power_gate->vcn_gated, !enable);
 
-out:
+       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;
+
+       mutex_lock(&power_gate->vcn_gate_lock);
+
+       ret = smu_dpm_set_vcn_enable_locked(smu, enable);
+
        mutex_unlock(&power_gate->vcn_gate_lock);
 
        return ret;
 }
 
-static int smu_dpm_set_jpeg_enable(struct smu_context *smu,
-                                  bool enable)
+static int smu_dpm_set_jpeg_enable_locked(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;
@@ -168,16 +179,27 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu,
        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;
+               return 0;
 
        ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable);
        if (!ret)
                atomic_set(&power_gate->jpeg_gated, !enable);
 
-out:
+       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;
+
+       mutex_lock(&power_gate->jpeg_gate_lock);
+
+       ret = smu_dpm_set_jpeg_enable_locked(smu, enable);
+
        mutex_unlock(&power_gate->jpeg_gate_lock);
 
        return ret;
@@ -403,6 +425,45 @@ static int smu_early_init(void *handle)
        return smu_set_funcs(adev);
 }
 
+static int smu_set_default_dpm_table(struct smu_context *smu)
+{
+       struct smu_power_context *smu_power = &smu->smu_power;
+       struct smu_power_gate *power_gate = &smu_power->power_gate;
+       int vcn_gate, jpeg_gate;
+       int ret = 0;
+
+       if (!smu->ppt_funcs->set_default_dpm_table)
+               return 0;
+
+       mutex_lock(&power_gate->vcn_gate_lock);
+       mutex_lock(&power_gate->jpeg_gate_lock);
+
+       vcn_gate = atomic_read(&power_gate->vcn_gated);
+       jpeg_gate = atomic_read(&power_gate->jpeg_gated);
+
+       ret = smu_dpm_set_vcn_enable_locked(smu, true);
+       if (ret)
+               goto err0_out;
+
+       ret = smu_dpm_set_jpeg_enable_locked(smu, true);
+       if (ret)
+               goto err1_out;
+
+       ret = smu->ppt_funcs->set_default_dpm_table(smu);
+       if (ret)
+               dev_err(smu->adev->dev,
+                       "Failed to setup default dpm clock tables!\n");
+
+       smu_dpm_set_jpeg_enable_locked(smu, !jpeg_gate);
+err1_out:
+       smu_dpm_set_vcn_enable_locked(smu, !vcn_gate);
+err0_out:
+       mutex_unlock(&power_gate->jpeg_gate_lock);
+       mutex_unlock(&power_gate->vcn_gate_lock);
+
+       return ret;
+}
+
 static int smu_late_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
index f1d8f24..264073d 100644 (file)
@@ -60,7 +60,6 @@
 #define smu_disable_all_features_with_exception(smu, mask)             smu_ppt_funcs(disable_all_features_with_exception, 0, smu, mask)
 #define smu_is_dpm_running(smu)                                                smu_ppt_funcs(is_dpm_running, 0 , smu)
 #define smu_notify_display_change(smu)                                 smu_ppt_funcs(notify_display_change, 0, smu)
-#define smu_set_default_dpm_table(smu)                                 smu_ppt_funcs(set_default_dpm_table, 0, smu)
 #define smu_populate_umd_state_clk(smu)                                        smu_ppt_funcs(populate_umd_state_clk, 0, smu)
 #define smu_set_default_od8_settings(smu)                              smu_ppt_funcs(set_default_od8_settings, 0, smu)
 #define smu_enable_thermal_alert(smu)                                  smu_ppt_funcs(enable_thermal_alert, 0, smu)