Commit cb8f81c1 authored by Maarten Lankhorst's avatar Maarten Lankhorst

drm/xe/display: Make display suspend/resume work on discrete

We should unpin before evicting all memory, and repin after GT resume.
This way, we preserve the contents of the framebuffers, and won't hang
on resume due to migration engine not being restored yet.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: dd08ebf6 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Cc: stable@vger.kernel.org # v6.8+
Reviewed-by: default avatarUma Shankar <uma.shankar@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240806105044.596842-3-maarten.lankhorst@linux.intel.comSigned-off-by: default avatarMaarten Lankhorst,,, <maarten.lankhorst@linux.intel.com>
parent 492be2a0
......@@ -287,6 +287,27 @@ static bool suspend_to_idle(void)
return false;
}
static void xe_display_flush_cleanup_work(struct xe_device *xe)
{
struct intel_crtc *crtc;
for_each_intel_crtc(&xe->drm, crtc) {
struct drm_crtc_commit *commit;
spin_lock(&crtc->base.commit_lock);
commit = list_first_entry_or_null(&crtc->base.commit_list,
struct drm_crtc_commit, commit_entry);
if (commit)
drm_crtc_commit_get(commit);
spin_unlock(&crtc->base.commit_lock);
if (commit) {
wait_for_completion(&commit->cleanup_done);
drm_crtc_commit_put(commit);
}
}
}
void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
{
struct intel_display *display = &xe->display;
......@@ -308,6 +329,8 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
if (!runtime)
intel_display_driver_suspend(xe);
xe_display_flush_cleanup_work(xe);
intel_dp_mst_suspend(xe);
intel_hpd_cancel_work(xe);
......
......@@ -93,13 +93,13 @@ int xe_pm_suspend(struct xe_device *xe)
for_each_gt(gt, xe, id)
xe_gt_suspend_prepare(gt);
xe_display_pm_suspend(xe, false);
/* FIXME: Super racey... */
err = xe_bo_evict_all(xe);
if (err)
goto err;
xe_display_pm_suspend(xe, false);
for_each_gt(gt, xe, id) {
err = xe_gt_suspend(gt);
if (err) {
......@@ -154,11 +154,11 @@ int xe_pm_resume(struct xe_device *xe)
xe_irq_resume(xe);
xe_display_pm_resume(xe, false);
for_each_gt(gt, xe, id)
xe_gt_resume(gt);
xe_display_pm_resume(xe, false);
err = xe_bo_restore_user(xe);
if (err)
goto err;
......@@ -367,10 +367,11 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
mutex_unlock(&xe->mem_access.vram_userfault.lock);
if (xe->d3cold.allowed) {
xe_display_pm_suspend(xe, true);
err = xe_bo_evict_all(xe);
if (err)
goto out;
xe_display_pm_suspend(xe, true);
}
for_each_gt(gt, xe, id) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment