diff options
author | Likun Gao <Likun.Gao@amd.com> | 2019-02-14 18:35:14 +0800 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-03-19 15:04:01 -0500 |
commit | 4733cc7244c2f18292dbb78ba88dfee35b73ff67 (patch) | |
tree | 326f0ee3c9b32edd0530e6498d9aa26c5c67acda /drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | |
parent | 9ebbc1bb02c0ed03db9113d5b63011041e5870b3 (diff) |
drm/amd/powerplay: add suspend and resume function for smu
Functional the function of smu suspend and resume.
Modified the function of smu_smc_table_hw_init to make it useful for smu
resume.
Signed-off-by: Likun Gao <Likun.Gao@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/amdgpu_smu.c')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 156 |
1 files changed, 74 insertions, 82 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 9cb45fe0459b..0a9b87369f5c 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -529,7 +529,8 @@ static int smu_fini_fb_allocations(struct smu_context *smu) return 0; } -static int smu_smc_table_hw_init(struct smu_context *smu) +static int smu_smc_table_hw_init(struct smu_context *smu, + bool initialize) { int ret; @@ -541,54 +542,56 @@ static int smu_smc_table_hw_init(struct smu_context *smu) if (ret) return ret; - ret = smu_read_pptable_from_vbios(smu); - if (ret) - return ret; + if (initialize) { + ret = smu_read_pptable_from_vbios(smu); + if (ret) + return ret; - /* get boot_values from vbios to set revision, gfxclk, and etc. */ - ret = smu_get_vbios_bootup_values(smu); - if (ret) - return ret; + /* get boot_values from vbios to set revision, gfxclk, and etc. */ + ret = smu_get_vbios_bootup_values(smu); + if (ret) + return ret; - ret = smu_get_clk_info_from_vbios(smu); - if (ret) - return ret; + ret = smu_get_clk_info_from_vbios(smu); + if (ret) + return ret; - /* - * 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; + /* + * 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; + ret = smu_check_pptable(smu); + if (ret) + return ret; - /* - * allocate vram bos to store smc table contents. - */ - ret = smu_init_fb_allocations(smu); - if (ret) - return ret; + /* + * allocate vram bos to store smc table contents. + */ + ret = smu_init_fb_allocations(smu); + if (ret) + return ret; - /* - * Parse pptable format and fill PPTable_t smc_pptable to - * smu_table_context structure. And read the smc_dpm_table from vbios, - * then fill it into smc_pptable. - */ - ret = smu_parse_pptable(smu); - if (ret) - return ret; + /* + * Parse pptable format and fill PPTable_t smc_pptable to + * smu_table_context structure. And read the smc_dpm_table from vbios, + * then fill it into smc_pptable. + */ + ret = smu_parse_pptable(smu); + if (ret) + return ret; - /* - * Send msg GetDriverIfVersion to check if the return value is equal - * with DRIVER_IF_VERSION of smc header. - */ - ret = smu_check_fw_version(smu); - if (ret) - return ret; + /* + * Send msg GetDriverIfVersion to check if the return value is equal + * with DRIVER_IF_VERSION of smc header. + */ + ret = smu_check_fw_version(smu); + if (ret) + return ret; + } /* * Copy pptable bo in the vram to smc with SMU MSGs such as @@ -624,25 +627,29 @@ static int smu_smc_table_hw_init(struct smu_context *smu) * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each * type of clks. */ - ret = smu_populate_smc_pptable(smu); - if (ret) - return ret; + if (initialize) { + ret = smu_populate_smc_pptable(smu); + if (ret) + return ret; - ret = smu_init_max_sustainable_clocks(smu); - if (ret) - return ret; + ret = smu_init_max_sustainable_clocks(smu); + if (ret) + return ret; + } - ret = smu_set_od8_default_settings(smu); + ret = smu_set_od8_default_settings(smu, initialize); if (ret) return ret; - ret = smu_populate_umd_state_clk(smu); - if (ret) - return ret; + if (initialize) { + ret = smu_populate_umd_state_clk(smu); + if (ret) + return ret; - ret = smu_get_power_limit(smu, &smu->default_power_limit, false); - if (ret) - return ret; + ret = smu_get_power_limit(smu, &smu->default_power_limit, false); + if (ret) + return ret; + } /* * Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools. @@ -714,6 +721,7 @@ static int smu_free_memory_pool(struct smu_context *smu) return ret; } + static int smu_hw_init(void *handle) { int ret; @@ -741,7 +749,7 @@ static int smu_hw_init(void *handle) if (ret) goto failed; - ret = smu_smc_table_hw_init(smu); + ret = smu_smc_table_hw_init(smu, true); if (ret) goto failed; @@ -834,11 +842,19 @@ int smu_reset(struct smu_context *smu) static int smu_suspend(void *handle) { + int ret; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct smu_context *smu = &adev->smu; if (!is_support_sw_smu(adev)) return -EINVAL; + ret = smu_feature_disable_all(smu); + if (ret) + return ret; + + smu->watermarks_bitmap &= ~(WATERMARKS_LOADED); + return 0; } @@ -853,37 +869,13 @@ static int smu_resume(void *handle) pr_info("SMU is resuming...\n"); - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { - ret = smu_load_microcode(smu); - if (ret) - return ret; - } - - ret = smu_check_fw_status(smu); - if (ret) { - pr_err("SMC firmware status is not correct\n"); - return ret; - } - mutex_lock(&smu->mutex); - ret = smu_set_tool_table_location(smu); - if (ret) - goto failed; - - ret = smu_write_pptable(smu); + ret = smu_smc_table_hw_init(smu, false); if (ret) goto failed; - ret = smu_write_watermarks_table(smu); - if (ret) - goto failed; - - ret = smu_set_last_dcef_min_deep_sleep_clk(smu); - if (ret) - goto failed; - - ret = smu_system_features_control(smu, true); + ret = smu_start_thermal_control(smu); if (ret) goto failed; |