mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-06 06:37:59 +00:00
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>
This commit is contained in:
parent
9ebbc1bb02
commit
4733cc7244
3 changed files with 95 additions and 99 deletions
|
@ -529,7 +529,8 @@ static int smu_fini_fb_allocations(struct smu_context *smu)
|
||||||
return 0;
|
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;
|
int ret;
|
||||||
|
|
||||||
|
@ -541,54 +542,56 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = smu_read_pptable_from_vbios(smu);
|
if (initialize) {
|
||||||
if (ret)
|
ret = smu_read_pptable_from_vbios(smu);
|
||||||
return ret;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* get boot_values from vbios to set revision, gfxclk, and etc. */
|
/* get boot_values from vbios to set revision, gfxclk, and etc. */
|
||||||
ret = smu_get_vbios_bootup_values(smu);
|
ret = smu_get_vbios_bootup_values(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = smu_get_clk_info_from_vbios(smu);
|
ret = smu_get_clk_info_from_vbios(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the format_revision in vbios is up to pptable header
|
* check if the format_revision in vbios is up to pptable header
|
||||||
* version, and the structure size is not 0.
|
* version, and the structure size is not 0.
|
||||||
*/
|
*/
|
||||||
ret = smu_get_clk_info_from_vbios(smu);
|
ret = smu_get_clk_info_from_vbios(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = smu_check_pptable(smu);
|
ret = smu_check_pptable(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* allocate vram bos to store smc table contents.
|
* allocate vram bos to store smc table contents.
|
||||||
*/
|
*/
|
||||||
ret = smu_init_fb_allocations(smu);
|
ret = smu_init_fb_allocations(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse pptable format and fill PPTable_t smc_pptable to
|
* Parse pptable format and fill PPTable_t smc_pptable to
|
||||||
* smu_table_context structure. And read the smc_dpm_table from vbios,
|
* smu_table_context structure. And read the smc_dpm_table from vbios,
|
||||||
* then fill it into smc_pptable.
|
* then fill it into smc_pptable.
|
||||||
*/
|
*/
|
||||||
ret = smu_parse_pptable(smu);
|
ret = smu_parse_pptable(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send msg GetDriverIfVersion to check if the return value is equal
|
* Send msg GetDriverIfVersion to check if the return value is equal
|
||||||
* with DRIVER_IF_VERSION of smc header.
|
* with DRIVER_IF_VERSION of smc header.
|
||||||
*/
|
*/
|
||||||
ret = smu_check_fw_version(smu);
|
ret = smu_check_fw_version(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy pptable bo in the vram to smc with SMU MSGs such as
|
* 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
|
* gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each
|
||||||
* type of clks.
|
* type of clks.
|
||||||
*/
|
*/
|
||||||
ret = smu_populate_smc_pptable(smu);
|
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_set_od8_default_settings(smu, initialize);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = smu_init_max_sustainable_clocks(smu);
|
if (initialize) {
|
||||||
if (ret)
|
ret = smu_populate_umd_state_clk(smu);
|
||||||
return ret;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = smu_set_od8_default_settings(smu);
|
ret = smu_get_power_limit(smu, &smu->default_power_limit, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools.
|
* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_hw_init(void *handle)
|
static int smu_hw_init(void *handle)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -741,7 +749,7 @@ static int smu_hw_init(void *handle)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
ret = smu_smc_table_hw_init(smu);
|
ret = smu_smc_table_hw_init(smu, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
@ -834,11 +842,19 @@ int smu_reset(struct smu_context *smu)
|
||||||
|
|
||||||
static int smu_suspend(void *handle)
|
static int smu_suspend(void *handle)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||||
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (!is_support_sw_smu(adev))
|
if (!is_support_sw_smu(adev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = smu_feature_disable_all(smu);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
smu->watermarks_bitmap &= ~(WATERMARKS_LOADED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,37 +869,13 @@ static int smu_resume(void *handle)
|
||||||
|
|
||||||
pr_info("SMU is resuming...\n");
|
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);
|
mutex_lock(&smu->mutex);
|
||||||
|
|
||||||
ret = smu_set_tool_table_location(smu);
|
ret = smu_smc_table_hw_init(smu, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
ret = smu_write_pptable(smu);
|
ret = smu_start_thermal_control(smu);
|
||||||
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);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
|
|
@ -518,7 +518,8 @@ struct smu_funcs
|
||||||
int (*notify_smu_enable_pwe)(struct smu_context *smu);
|
int (*notify_smu_enable_pwe)(struct smu_context *smu);
|
||||||
int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
|
int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
|
||||||
struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
|
struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
|
||||||
int (*set_od8_default_settings)(struct smu_context *smu);
|
int (*set_od8_default_settings)(struct smu_context *smu,
|
||||||
|
bool initialize);
|
||||||
int (*get_activity_monitor_coeff)(struct smu_context *smu,
|
int (*get_activity_monitor_coeff)(struct smu_context *smu,
|
||||||
uint8_t *table,
|
uint8_t *table,
|
||||||
uint16_t workload_type);
|
uint16_t workload_type);
|
||||||
|
@ -587,8 +588,8 @@ struct smu_funcs
|
||||||
((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
|
((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
|
||||||
#define smu_init_max_sustainable_clocks(smu) \
|
#define smu_init_max_sustainable_clocks(smu) \
|
||||||
((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
|
((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
|
||||||
#define smu_set_od8_default_settings(smu) \
|
#define smu_set_od8_default_settings(smu, initialize) \
|
||||||
((smu)->funcs->set_od8_default_settings ? (smu)->funcs->set_od8_default_settings((smu)) : 0)
|
((smu)->funcs->set_od8_default_settings ? (smu)->funcs->set_od8_default_settings((smu), (initialize)) : 0)
|
||||||
#define smu_update_od8_settings(smu, index, value) \
|
#define smu_update_od8_settings(smu, index, value) \
|
||||||
((smu)->funcs->update_od8_settings ? (smu)->funcs->update_od8_settings((smu), (index), (value)) : 0)
|
((smu)->funcs->update_od8_settings ? (smu)->funcs->update_od8_settings((smu), (index), (value)) : 0)
|
||||||
#define smu_get_current_rpm(smu, speed) \
|
#define smu_get_current_rpm(smu, speed) \
|
||||||
|
|
|
@ -1432,27 +1432,30 @@ static uint32_t smu_v11_0_dpm_get_mclk(struct smu_context *smu, bool low)
|
||||||
return (mem_clk * 100);
|
return (mem_clk * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_od8_default_settings(struct smu_context *smu)
|
static int smu_v11_0_set_od8_default_settings(struct smu_context *smu,
|
||||||
|
bool initialize)
|
||||||
{
|
{
|
||||||
struct smu_table_context *table_context = &smu->smu_table;
|
struct smu_table_context *table_context = &smu->smu_table;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (table_context->overdrive_table)
|
if (initialize) {
|
||||||
return -EINVAL;
|
if (table_context->overdrive_table)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
|
table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
|
||||||
|
|
||||||
if (!table_context->overdrive_table)
|
if (!table_context->overdrive_table)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, false);
|
ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, false);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to export over drive table!\n");
|
pr_err("Failed to export over drive table!\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
smu_set_default_od8_settings(smu);
|
||||||
}
|
}
|
||||||
|
|
||||||
smu_set_default_od8_settings(smu);
|
|
||||||
|
|
||||||
ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, true);
|
ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to import over drive table!\n");
|
pr_err("Failed to import over drive table!\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue