smu_late_init() re-applies the DPM level after a reset with smu_handle_task(smu, smu->smu_dpm.dpm_level, AMD_PP_TASK_COMPLETE_INIT);
but smu_adjust_power_state_dynamic() only programs the hardware when if (smu_dpm_ctx->dpm_level != level) and smu_dpm_ctx is &smu->smu_dpm, so the level is compared against itself. The branch is never taken for this caller and smu_asic_set_performance_level() is never called. PMFW is reinitialised by the reset and comes back on its default curve, while smu_dpm.dpm_level still holds the level the user forced. The device therefore runs at the default level while sysfs keeps reporting the forced one. On an SMU 14.0.1 APU gfxclk drops from 2.8GHz to 600MHz while sysfs still reports high. Writing the same level again does not help either, as amdgpu_dpm_force_performance_level() returns early when the requested level matches the cached one. Sync the cached level with the state PMFW came back in before re-applying the forced level, so that it is programmed again. Suspend/resume is not covered, as PMFW retains its state across s2idle and the forced level still applies on resume. Signed-off-by: Priya Hosur <[email protected]> --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index a65aa2129845..2d318726c521 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -998,9 +998,18 @@ static int smu_late_init(struct amdgpu_ip_block *ip_block) smu_get_fan_parameters(smu); - smu_handle_task(smu, - smu->smu_dpm.dpm_level, - AMD_PP_TASK_COMPLETE_INIT); + if (amdgpu_reset_in_recovery(adev)) { + enum amd_dpm_forced_level level = smu->smu_dpm.dpm_level; + + /* PMFW is reinitialised by the reset, so sync the cached level + * before re-applying the forced one + */ + smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; + smu_handle_task(smu, level, AMD_PP_TASK_COMPLETE_INIT); + } else { + smu_handle_task(smu, smu->smu_dpm.dpm_level, + AMD_PP_TASK_COMPLETE_INIT); + } ret = smu_apply_default_config_table_settings(smu); if (ret && (ret != -EOPNOTSUPP)) { -- 2.43.0
