From: Ville Syrjälä <ville.syrj...@linux.intel.com>

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.kulka...@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c    | 16 +++++++++++++---
 drivers/gpu/drm/i915/display/intel_display.c     |  7 +++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 76d77d5a0409..769010d0ebc4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -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,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index f45e5f02096d..fa1ddb558f48 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6165,6 +6165,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,
-- 
2.43.2

Reply via email to