drm/i915: Allow the initial async flip to change modifier
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 30 Apr 2024 09:56:37 +0000 (12:56 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 3 May 2024 10:13:51 +0000 (13:13 +0300)
With Xorg+modesetting on skl+ we see the following behaviour:
1. root pixmap is X-tiled
2. client submitted buffers can be Y-tiled (w/ 'Option "dmabuf_capable"')
3. we try to switch from the X-tiled buffer to the Y-tiled buffer
   using an async flip (when vsync is disabled).
4. the async flip will be rejected by i915 due to the modifier change

Relax the rules a bit by turning the first async flip into a sync
flip so that we can change the modifier if necessary. Note that
we already convert the first async flip into a sync flip on adl+
in order to reprogram the watermarks.

Reviewed-by: Vandita Kulkarni <vandita.kulkarni@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240430095639.26390-4-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/intel_atomic_plane.c
drivers/gpu/drm/i915/display/intel_display.c

index 76d77d5..769010d 100644 (file)
@@ -429,10 +429,20 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
         * In platforms after DISPLAY13, we might need to override
         * first async flip in order to change watermark levels
         * as part of optimization.
-        * So for those, we are checking if this is a first async flip.
-        * For platforms earlier than DISPLAY13 we always do async flip.
+        *
+        * And let's do this for all skl+ so that we can eg. change the
+        * modifier as well.
+        *
+        * TODO: For older platforms there is less reason to do this as
+        * only X-tile is supported with async flips, though we could
+        * extend this so other scanout parameters (stride/etc) could
+        * be changed as well...
+        *
+        * FIXME: Platforms with need_async_flip_disable_wa==true will
+        * now end up doing two sync flips initially. Would be nice to
+        * combine those into just the one sync flip...
         */
-       return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
+       return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip;
 }
 
 static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
index 273323f..a98dcbd 100644 (file)
@@ -6166,6 +6166,13 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
                        return -EINVAL;
                }
 
+               /*
+                * We turn the first async flip request into a sync flip
+                * so that we can reconfigure the plane (eg. change modifier).
+                */
+               if (!new_crtc_state->do_async_flip)
+                       continue;
+
                if (old_plane_state->view.color_plane[0].mapping_stride !=
                    new_plane_state->view.color_plane[0].mapping_stride) {
                        drm_dbg_kms(&i915->drm,