drm/amd/powerplay: enable SW SMU power profile switch support in KFD
authorEvan Quan <evan.quan@amd.com>
Wed, 31 Jul 2019 02:34:36 +0000 (10:34 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 2 Aug 2019 15:30:39 +0000 (10:30 -0500)
Hook up the SW SMU power profile switch in KFD routine.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Kevin Wang <kevin1.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h

index 0640fcd..f1cba95 100644 (file)
@@ -655,8 +655,12 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
 
-       if (adev->powerplay.pp_funcs &&
-           adev->powerplay.pp_funcs->switch_power_profile)
+       if (is_support_sw_smu(adev))
+               smu_switch_power_profile(&adev->smu,
+                                        PP_SMC_POWER_PROFILE_COMPUTE,
+                                        !idle);
+       else if (adev->powerplay.pp_funcs &&
+                adev->powerplay.pp_funcs->switch_power_profile)
                amdgpu_dpm_switch_power_profile(adev,
                                                PP_SMC_POWER_PROFILE_COMPUTE,
                                                !idle);
index 0a20279..07d0f0c 100644 (file)
@@ -1677,6 +1677,42 @@ int smu_handle_task(struct smu_context *smu,
        return ret;
 }
 
+int smu_switch_power_profile(struct smu_context *smu,
+                            enum PP_SMC_POWER_PROFILE type,
+                            bool en)
+{
+       struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+       long workload;
+       uint32_t index;
+
+       if (!smu->pm_enabled)
+               return -EINVAL;
+
+       if (!(type < PP_SMC_POWER_PROFILE_CUSTOM))
+               return -EINVAL;
+
+       mutex_lock(&smu->mutex);
+
+       if (!en) {
+               smu->workload_mask &= ~(1 << smu->workload_prority[type]);
+               index = fls(smu->workload_mask);
+               index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
+               workload = smu->workload_setting[index];
+       } else {
+               smu->workload_mask |= (1 << smu->workload_prority[type]);
+               index = fls(smu->workload_mask);
+               index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
+               workload = smu->workload_setting[index];
+       }
+
+       if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
+               smu_set_power_profile_mode(smu, &workload, 0);
+
+       mutex_unlock(&smu->mutex);
+
+       return 0;
+}
+
 enum amd_dpm_forced_level smu_get_performance_level(struct smu_context *smu)
 {
        struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
index 1ecd73c..d3a4784 100644 (file)
@@ -787,6 +787,9 @@ extern int smu_dpm_set_power_gate(struct smu_context *smu,uint32_t block_type, b
 extern int smu_handle_task(struct smu_context *smu,
                           enum amd_dpm_forced_level level,
                           enum amd_pp_task task_id);
+int smu_switch_power_profile(struct smu_context *smu,
+                            enum PP_SMC_POWER_PROFILE type,
+                            bool en);
 int smu_get_smc_version(struct smu_context *smu, uint32_t *if_version, uint32_t *smu_version);
 int smu_get_dpm_freq_by_index(struct smu_context *smu, enum smu_clk_type clk_type,
                              uint16_t level, uint32_t *value);