GFXOFF may be flushed at suspend entry and it may be important to ensure it reaches desired target state. Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> --- .../drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 86d6e88c7386..bd5bf9182e06 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -345,36 +345,11 @@ static bool smu10_is_gfx_on(struct pp_hwmgr *hwmgr) return false; } -static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - - if (adev->pm.pp_feature & PP_GFXOFF_MASK) { - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff, NULL); - - /* confirm gfx is back to "on" state */ - while (!smu10_is_gfx_on(hwmgr)) - msleep(1); - } - - return 0; -} - static int smu10_disable_dpm_tasks(struct pp_hwmgr *hwmgr) { return 0; } -static int smu10_enable_gfx_off(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - - if (adev->pm.pp_feature & PP_GFXOFF_MASK) - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableGfxOff, NULL); - - return 0; -} - static void smu10_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) { hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK; @@ -416,10 +391,34 @@ static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) static int smu10_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable) { - if (enable) - return smu10_enable_gfx_off(hwmgr); - else - return smu10_disable_gfx_off(hwmgr); + struct amdgpu_device *adev = hwmgr->adev; + int r, timeout = 500; + bool target; + + if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) + return 0; + + if (enable) { + r = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableGfxOff, NULL); + target = false; + } else { + r = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff, NULL); + target = true; + } + if (r) + return r; + + /* confirm gfx is back to intended state, timeout is 0.5 second */ + while (smu10_is_gfx_on(hwmgr) != target) { + msleep(1); + timeout--; + if (timeout == 0) { + DRM_ERROR("%s gfxoff timeout and failed!\n", enable ? "enable" : "disable"); + return -ETIMEDOUT; + } + } + + return 0; } static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, -- 2.34.1