drm/i915/psr: Do not trigger Frame Change events from frontbuffer flush
authorJouni Högander <jouni.hogander@intel.com>
Fri, 1 Aug 2025 06:29:05 +0000 (09:29 +0300)
committerTvrtko Ursulin <tursulin@ursulin.net>
Tue, 12 Aug 2025 08:05:11 +0000 (09:05 +0100)
We want to get rid of triggering "Frame Change" events from
frontbuffer flush calls. We are about to move using TRANS_PUSH
register for this on LunarLake and onwards. Touching TRANS_PUSH
register from fronbuffer flush would be problematic as it's written by
DSB as well.

Fix this by using intel_psr_exit when flush or invalidate is done on
LunarLake and onwards. This is not possible on AlderLake and
MeteorLake due to HW bug in PSR2 disable.

This patch is also fixing problems with cursor plane where cursor is
disappearing or duplicate cursor is seen on the screen.

v2: Commit message updated

Bspec: 68927, 68934, 66624
Reported-by: Janna Martl <janna.martl109@gmail.com>
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/5522
Fixes: 411ad63877bb ("drm/i915/psr: Use SFF_CTL on invalidate/flush for LunarLake onwards")
Tested-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://lore.kernel.org/r/20250801062905.564453-1-jouni.hogander@intel.com
(cherry picked from commit 46fb38cb20c0d185a6391ab524b23e0e0219c41f)
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
drivers/gpu/drm/i915/display/intel_psr.c

index ae9053919211b17d0e6d3a47b8bbaa289acd0e2f..41988e193a415cc16c937f6f799215aa866538ec 100644 (file)
@@ -3275,7 +3275,9 @@ static void intel_psr_configure_full_frame_update(struct intel_dp *intel_dp)
 
 static void _psr_invalidate_handle(struct intel_dp *intel_dp)
 {
-       if (intel_dp->psr.psr2_sel_fetch_enabled) {
+       struct intel_display *display = to_intel_display(intel_dp);
+
+       if (DISPLAY_VER(display) < 20 && intel_dp->psr.psr2_sel_fetch_enabled) {
                if (!intel_dp->psr.psr2_sel_fetch_cff_enabled) {
                        intel_dp->psr.psr2_sel_fetch_cff_enabled = true;
                        intel_psr_configure_full_frame_update(intel_dp);
@@ -3361,7 +3363,7 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
 {
        struct intel_display *display = to_intel_display(intel_dp);
 
-       if (intel_dp->psr.psr2_sel_fetch_enabled) {
+       if (DISPLAY_VER(display) < 20 && intel_dp->psr.psr2_sel_fetch_enabled) {
                if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
                        /* can we turn CFF off? */
                        if (intel_dp->psr.busy_frontbuffer_bits == 0)
@@ -3378,11 +3380,13 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
                 * existing SU configuration
                 */
                intel_psr_configure_full_frame_update(intel_dp);
-       }
 
-       intel_psr_force_update(intel_dp);
+               intel_psr_force_update(intel_dp);
+       } else {
+               intel_psr_exit(intel_dp);
+       }
 
-       if (!intel_dp->psr.psr2_sel_fetch_enabled && !intel_dp->psr.active &&
+       if ((!intel_dp->psr.psr2_sel_fetch_enabled || DISPLAY_VER(display) >= 20) &&
            !intel_dp->psr.busy_frontbuffer_bits)
                queue_work(display->wq.unordered, &intel_dp->psr.work);
 }