Avoid cross callings which make lock protection enforcement
on amdgpu_dpm_force_performance_level() impossible.

Signed-off-by: Evan Quan <evan.q...@amd.com>
Change-Id: Ie658140f40ab906ce2ec47576a086062b61076a6
---
 drivers/gpu/drm/amd/pm/amdgpu_pm.c            | 29 ++++++++++++++++---
 .../gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c    | 17 ++++++-----
 .../gpu/drm/amd/pm/powerplay/amd_powerplay.c  | 12 --------
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c     | 12 --------
 4 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 89e1134d660f..28150267832c 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -305,6 +305,10 @@ static ssize_t 
amdgpu_set_power_dpm_force_performance_level(struct device *dev,
        enum amd_dpm_forced_level level;
        enum amd_dpm_forced_level current_level;
        int ret = 0;
+       uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
+                                       AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
+                                       AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
+                                       AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
 
        if (amdgpu_in_reset(adev))
                return -EPERM;
@@ -358,10 +362,7 @@ static ssize_t 
amdgpu_set_power_dpm_force_performance_level(struct device *dev,
        }
 
        /* profile_exit setting is valid only when current mode is in profile 
mode */
-       if (!(current_level & (AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
-           AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
-           AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
-           AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)) &&
+       if (!(current_level & profile_mode_mask) &&
            (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)) {
                pr_err("Currently not in any profile mode!\n");
                pm_runtime_mark_last_busy(ddev->dev);
@@ -369,6 +370,26 @@ static ssize_t 
amdgpu_set_power_dpm_force_performance_level(struct device *dev,
                return -EINVAL;
        }
 
+       if (!(current_level & profile_mode_mask) &&
+             (level & profile_mode_mask)) {
+               /* enter UMD Pstate */
+               amdgpu_device_ip_set_powergating_state(adev,
+                                                      AMD_IP_BLOCK_TYPE_GFX,
+                                                      AMD_PG_STATE_UNGATE);
+               amdgpu_device_ip_set_clockgating_state(adev,
+                                                      AMD_IP_BLOCK_TYPE_GFX,
+                                                      AMD_CG_STATE_UNGATE);
+       } else if ((current_level & profile_mode_mask) &&
+                   !(level & profile_mode_mask)) {
+               /* exit UMD Pstate */
+               amdgpu_device_ip_set_clockgating_state(adev,
+                                                      AMD_IP_BLOCK_TYPE_GFX,
+                                                      AMD_CG_STATE_GATE);
+               amdgpu_device_ip_set_powergating_state(adev,
+                                                      AMD_IP_BLOCK_TYPE_GFX,
+                                                      AMD_PG_STATE_GATE);
+       }
+
        if (amdgpu_dpm_force_performance_level(adev, level)) {
                pm_runtime_mark_last_busy(ddev->dev);
                pm_runtime_put_autosuspend(ddev->dev);
diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c 
b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
index 9e6bc562fc5a..8d5916087861 100644
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
@@ -1382,6 +1382,7 @@ static struct amdgpu_ps 
*amdgpu_dpm_pick_power_state(struct amdgpu_device *adev,
 
 static int amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
 {
+       const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
        struct amdgpu_ps *ps;
        enum amd_pm_state_type dpm_state;
        int ret;
@@ -1405,7 +1406,7 @@ static int amdgpu_dpm_change_power_state_locked(struct 
amdgpu_device *adev)
        else
                return -EINVAL;
 
-       if (amdgpu_dpm == 1 && adev->powerplay.pp_funcs->print_power_state) {
+       if (amdgpu_dpm == 1 && pp_funcs->print_power_state) {
                printk("switching from power state:\n");
                amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps);
                printk("switching to power state:\n");
@@ -1414,14 +1415,14 @@ static int amdgpu_dpm_change_power_state_locked(struct 
amdgpu_device *adev)
 
        /* update whether vce is active */
        ps->vce_active = adev->pm.dpm.vce_active;
-       if (adev->powerplay.pp_funcs->display_configuration_changed)
+       if (pp_funcs->display_configuration_changed)
                amdgpu_dpm_display_configuration_changed(adev);
 
        ret = amdgpu_dpm_pre_set_power_state(adev);
        if (ret)
                return ret;
 
-       if (adev->powerplay.pp_funcs->check_state_equal) {
+       if (pp_funcs->check_state_equal) {
                if (0 != amdgpu_dpm_check_state_equal(adev, 
adev->pm.dpm.current_ps, adev->pm.dpm.requested_ps, &equal))
                        equal = false;
        }
@@ -1429,24 +1430,24 @@ static int amdgpu_dpm_change_power_state_locked(struct 
amdgpu_device *adev)
        if (equal)
                return 0;
 
-       if (adev->powerplay.pp_funcs->set_power_state)
-               
adev->powerplay.pp_funcs->set_power_state(adev->powerplay.pp_handle);
+       if (pp_funcs->set_power_state)
+               pp_funcs->set_power_state(adev->powerplay.pp_handle);
 
        amdgpu_dpm_post_set_power_state(adev);
 
        adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
        adev->pm.dpm.current_active_crtc_count = 
adev->pm.dpm.new_active_crtc_count;
 
-       if (adev->powerplay.pp_funcs->force_performance_level) {
+       if (pp_funcs->force_performance_level) {
                if (adev->pm.dpm.thermal_active) {
                        enum amd_dpm_forced_level level = 
adev->pm.dpm.forced_level;
                        /* force low perf level for thermal */
-                       amdgpu_dpm_force_performance_level(adev, 
AMD_DPM_FORCED_LEVEL_LOW);
+                       pp_funcs->force_performance_level(adev, 
AMD_DPM_FORCED_LEVEL_LOW);
                        /* save the user's level */
                        adev->pm.dpm.forced_level = level;
                } else {
                        /* otherwise, user selected level */
-                       amdgpu_dpm_force_performance_level(adev, 
adev->pm.dpm.forced_level);
+                       pp_funcs->force_performance_level(adev, 
adev->pm.dpm.forced_level);
                }
        }
 
diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c 
b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
index d57d5c28c013..5a14ddd3ef05 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
@@ -323,12 +323,6 @@ static void pp_dpm_en_umd_pstate(struct pp_hwmgr  *hwmgr,
                if (*level & profile_mode_mask) {
                        hwmgr->saved_dpm_level = hwmgr->dpm_level;
                        hwmgr->en_umd_pstate = true;
-                       amdgpu_device_ip_set_powergating_state(hwmgr->adev,
-                                       AMD_IP_BLOCK_TYPE_GFX,
-                                       AMD_PG_STATE_UNGATE);
-                       amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
-                                               AMD_IP_BLOCK_TYPE_GFX,
-                                               AMD_CG_STATE_UNGATE);
                }
        } else {
                /* exit umd pstate, restore level, enable gfx cg*/
@@ -336,12 +330,6 @@ static void pp_dpm_en_umd_pstate(struct pp_hwmgr  *hwmgr,
                        if (*level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
                                *level = hwmgr->saved_dpm_level;
                        hwmgr->en_umd_pstate = false;
-                       amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
-                                       AMD_IP_BLOCK_TYPE_GFX,
-                                       AMD_CG_STATE_GATE);
-                       amdgpu_device_ip_set_powergating_state(hwmgr->adev,
-                                       AMD_IP_BLOCK_TYPE_GFX,
-                                       AMD_PG_STATE_GATE);
                }
        }
 }
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 6f5a6886d3cc..241eebef9939 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -1681,12 +1681,6 @@ static int smu_enable_umd_pstate(void *handle,
                        smu_dpm_ctx->saved_dpm_level = smu_dpm_ctx->dpm_level;
                        smu_dpm_ctx->enable_umd_pstate = true;
                        smu_gpo_control(smu, false);
-                       amdgpu_device_ip_set_powergating_state(smu->adev,
-                                                              
AMD_IP_BLOCK_TYPE_GFX,
-                                                              
AMD_PG_STATE_UNGATE);
-                       amdgpu_device_ip_set_clockgating_state(smu->adev,
-                                                              
AMD_IP_BLOCK_TYPE_GFX,
-                                                              
AMD_CG_STATE_UNGATE);
                        smu_gfx_ulv_control(smu, false);
                        smu_deep_sleep_control(smu, false);
                        amdgpu_asic_update_umd_stable_pstate(smu->adev, true);
@@ -1700,12 +1694,6 @@ static int smu_enable_umd_pstate(void *handle,
                        amdgpu_asic_update_umd_stable_pstate(smu->adev, false);
                        smu_deep_sleep_control(smu, true);
                        smu_gfx_ulv_control(smu, true);
-                       amdgpu_device_ip_set_clockgating_state(smu->adev,
-                                                              
AMD_IP_BLOCK_TYPE_GFX,
-                                                              
AMD_CG_STATE_GATE);
-                       amdgpu_device_ip_set_powergating_state(smu->adev,
-                                                              
AMD_IP_BLOCK_TYPE_GFX,
-                                                              
AMD_PG_STATE_GATE);
                        smu_gpo_control(smu, true);
                }
        }
-- 
2.29.0

Reply via email to