Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Cc: stable@vger.kernel.org # v6.8+
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240806105044.596842-3-maarten.lankhorst@linux.intel.com
Signed-off-by: Maarten Lankhorst,,, <maarten.lankhorst@linux.intel.com>
(cherry picked from commit cb8f81c1753187995b7a43e79c12959f14eb32d3)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Maarten Lankhorst and committed by
Rodrigo Vivi
ddf6492e 730b7248

+29 -5
+23
drivers/gpu/drm/xe/display/xe_display.c
··· 283 283 return false; 284 284 } 285 285 286 + static void xe_display_flush_cleanup_work(struct xe_device *xe) 287 + { 288 + struct intel_crtc *crtc; 289 + 290 + for_each_intel_crtc(&xe->drm, crtc) { 291 + struct drm_crtc_commit *commit; 292 + 293 + spin_lock(&crtc->base.commit_lock); 294 + commit = list_first_entry_or_null(&crtc->base.commit_list, 295 + struct drm_crtc_commit, commit_entry); 296 + if (commit) 297 + drm_crtc_commit_get(commit); 298 + spin_unlock(&crtc->base.commit_lock); 299 + 300 + if (commit) { 301 + wait_for_completion(&commit->cleanup_done); 302 + drm_crtc_commit_put(commit); 303 + } 304 + } 305 + } 306 + 286 307 void xe_display_pm_suspend(struct xe_device *xe, bool runtime) 287 308 { 288 309 bool s2idle = suspend_to_idle(); ··· 320 299 321 300 if (!runtime) 322 301 intel_display_driver_suspend(xe); 302 + 303 + xe_display_flush_cleanup_work(xe); 323 304 324 305 intel_dp_mst_suspend(xe); 325 306
+6 -5
drivers/gpu/drm/xe/xe_pm.c
··· 91 91 for_each_gt(gt, xe, id) 92 92 xe_gt_suspend_prepare(gt); 93 93 94 + xe_display_pm_suspend(xe, false); 95 + 94 96 /* FIXME: Super racey... */ 95 97 err = xe_bo_evict_all(xe); 96 98 if (err) 97 99 goto err; 98 - 99 - xe_display_pm_suspend(xe, false); 100 100 101 101 for_each_gt(gt, xe, id) { 102 102 err = xe_gt_suspend(gt); ··· 151 151 152 152 xe_irq_resume(xe); 153 153 154 - xe_display_pm_resume(xe, false); 155 - 156 154 for_each_gt(gt, xe, id) 157 155 xe_gt_resume(gt); 156 + 157 + xe_display_pm_resume(xe, false); 158 158 159 159 err = xe_bo_restore_user(xe); 160 160 if (err) ··· 363 363 mutex_unlock(&xe->mem_access.vram_userfault.lock); 364 364 365 365 if (xe->d3cold.allowed) { 366 + xe_display_pm_suspend(xe, true); 367 + 366 368 err = xe_bo_evict_all(xe); 367 369 if (err) 368 370 goto out; 369 - xe_display_pm_suspend(xe, true); 370 371 } 371 372 372 373 for_each_gt(gt, xe, id) {