diff options
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/amdgpu_smu.c')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 82 |
1 files changed, 54 insertions, 28 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index c058c784180e..9c67adee2c9e 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -20,9 +20,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "pp_debug.h" #include <linux/firmware.h> -#include <drm/drmP.h> + +#include "pp_debug.h" #include "amdgpu.h" #include "amdgpu_smu.h" #include "soc15_common.h" @@ -30,6 +30,36 @@ #include "atom.h" #include "amd_pcie.h" +int smu_get_smc_version(struct smu_context *smu, uint32_t *if_version, uint32_t *smu_version) +{ + int ret = 0; + + if (!if_version && !smu_version) + return -EINVAL; + + if (if_version) { + ret = smu_send_smc_msg(smu, SMU_MSG_GetDriverIfVersion); + if (ret) + return ret; + + ret = smu_read_smc_arg(smu, if_version); + if (ret) + return ret; + } + + if (smu_version) { + ret = smu_send_smc_msg(smu, SMU_MSG_GetSmuVersion); + if (ret) + return ret; + + ret = smu_read_smc_arg(smu, smu_version); + if (ret) + return ret; + } + + return ret; +} + int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type, bool gate) { @@ -168,6 +198,8 @@ int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size) ATOM_COMMON_TABLE_HEADER *header = (ATOM_COMMON_TABLE_HEADER *)buf; int ret = 0; + if (!smu->pm_enabled) + return -EINVAL; if (header->usStructureSize != size) { pr_err("pp table size not matched !\n"); return -EIO; @@ -203,6 +235,8 @@ int smu_feature_init_dpm(struct smu_context *smu) int ret = 0; uint32_t unallowed_feature_mask[SMU_FEATURE_MAX/32]; + if (!smu->pm_enabled) + return ret; mutex_lock(&feature->mutex); bitmap_fill(feature->allowed, SMU_FEATURE_MAX); mutex_unlock(&feature->mutex); @@ -280,7 +314,7 @@ int smu_feature_set_supported(struct smu_context *smu, int feature_id, WARN_ON(feature_id > feature->feature_num); - mutex_unlock(&feature->mutex); + mutex_lock(&feature->mutex); if (enable) test_and_set_bit(feature_id, feature->supported); else @@ -314,6 +348,7 @@ static int smu_early_init(void *handle) struct smu_context *smu = &adev->smu; smu->adev = adev; + smu->pm_enabled = !!amdgpu_dpm; mutex_init(&smu->mutex); return smu_set_funcs(adev); @@ -323,6 +358,9 @@ static int smu_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = &adev->smu; + + if (!smu->pm_enabled) + return 0; mutex_lock(&smu->mutex); smu_handle_task(&adev->smu, smu->smu_dpm.dpm_level, @@ -406,9 +444,6 @@ static int smu_sw_init(void *handle) struct smu_context *smu = &adev->smu; int ret; - if (!is_support_sw_smu(adev)) - return -EINVAL; - smu->pool_size = adev->pm.smu_prv_buffer_size; smu->smu_feature.feature_num = SMU_FEATURE_MAX; mutex_init(&smu->smu_feature.mutex); @@ -460,9 +495,6 @@ static int smu_sw_fini(void *handle) struct smu_context *smu = &adev->smu; int ret; - if (!is_support_sw_smu(adev)) - return -EINVAL; - ret = smu_smc_table_sw_fini(smu); if (ret) { pr_err("Failed to sw fini smc table!\n"); @@ -612,10 +644,6 @@ static int smu_smc_table_hw_init(struct smu_context *smu, * check if the format_revision in vbios is up to pptable header * version, and the structure size is not 0. */ - ret = smu_get_clk_info_from_vbios(smu); - if (ret) - return ret; - ret = smu_check_pptable(smu); if (ret) return ret; @@ -716,6 +744,9 @@ static int smu_smc_table_hw_init(struct smu_context *smu, */ ret = smu_set_tool_table_location(smu); + if (!smu_is_dpm_running(smu)) + pr_info("dpm has been disabled\n"); + return ret; } @@ -788,9 +819,6 @@ static int smu_hw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = &adev->smu; - if (!is_support_sw_smu(adev)) - return -EINVAL; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { ret = smu_load_microcode(smu); if (ret) @@ -831,7 +859,10 @@ static int smu_hw_init(void *handle) mutex_unlock(&smu->mutex); - adev->pm.dpm_enabled = true; + if (!smu->pm_enabled) + adev->pm.dpm_enabled = false; + else + adev->pm.dpm_enabled = true; pr_info("SMU is initialized successfully!\n"); @@ -849,9 +880,6 @@ static int smu_hw_fini(void *handle) struct smu_table_context *table_context = &smu->smu_table; int ret = 0; - if (!is_support_sw_smu(adev)) - return -EINVAL; - kfree(table_context->driver_pptable); table_context->driver_pptable = NULL; @@ -906,9 +934,6 @@ static int smu_suspend(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = &adev->smu; - if (!is_support_sw_smu(adev)) - return -EINVAL; - ret = smu_system_features_control(smu, false); if (ret) return ret; @@ -924,9 +949,6 @@ static int smu_resume(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = &adev->smu; - if (!is_support_sw_smu(adev)) - return -EINVAL; - pr_info("SMU is resuming...\n"); mutex_lock(&smu->mutex); @@ -955,7 +977,7 @@ int smu_display_configuration_change(struct smu_context *smu, int index = 0; int num_of_active_display = 0; - if (!is_support_sw_smu(smu->adev)) + if (!smu->pm_enabled || !is_support_sw_smu(smu->adev)) return -EINVAL; if (!display_config) @@ -1083,7 +1105,7 @@ static int smu_enable_umd_pstate(void *handle, struct smu_context *smu = (struct smu_context*)(handle); struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); - if (!smu_dpm_ctx->dpm_context) + if (!smu->pm_enabled || !smu_dpm_ctx->dpm_context) return -EINVAL; if (!(smu_dpm_ctx->dpm_level & profile_mode_mask)) { @@ -1126,6 +1148,8 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu, long workload; struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); + if (!smu->pm_enabled) + return -EINVAL; if (!skip_display_settings) { ret = smu_display_config_changed(smu); if (ret) { @@ -1134,6 +1158,8 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu, } } + if (!smu->pm_enabled) + return -EINVAL; ret = smu_apply_clocks_adjust_rules(smu); if (ret) { pr_err("Failed to apply clocks adjust rules!"); |