]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915: Make sure all planes in use by the joiner have their crtc included
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 12 Feb 2025 16:43:21 +0000 (18:43 +0200)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Mon, 17 Feb 2025 14:23:03 +0000 (09:23 -0500)
Any active plane needs to have its crtc included in the atomic
state. For planes enabled via uapi that is all handler in the core.
But when we use a plane for joiner the uapi code things the plane
is disabled and therefore doesn't have a crtc. So we need to pull
those in by hand. We do it first thing in
intel_joiner_add_affected_crtcs() so that any newly added crtc will
subsequently pull in all of its joined crtcs as well.

The symptoms from failing to do this are:
- duct tape in the form of commit 1d5b09f8daf8 ("drm/i915: Fix NULL
  ptr deref by checking new_crtc_state")
- the plane's hw state will get overwritten by the disabled
  uapi state if it can't find the uapi counterpart plane in
  the atomic state from where it should copy the correct state

Cc: stable@vger.kernel.org
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-2-ville.syrjala@linux.intel.com
(cherry picked from commit 91077d1deb5374eb8be00fb391710f00e751dc4b)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/i915/display/intel_display.c

index 4271da219b4105630106a2bc7e1fa42015ede1e1..41128469f12a219584ad41075ffc485deefbf2f1 100644 (file)
@@ -6628,12 +6628,30 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
 static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state)
 {
        struct drm_i915_private *i915 = to_i915(state->base.dev);
+       const struct intel_plane_state *plane_state;
        struct intel_crtc_state *crtc_state;
+       struct intel_plane *plane;
        struct intel_crtc *crtc;
        u8 affected_pipes = 0;
        u8 modeset_pipes = 0;
        int i;
 
+       /*
+        * Any plane which is in use by the joiner needs its crtc.
+        * Pull those in first as this will not have happened yet
+        * if the plane remains disabled according to uapi.
+        */
+       for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+               crtc = to_intel_crtc(plane_state->hw.crtc);
+               if (!crtc)
+                       continue;
+
+               crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
+               if (IS_ERR(crtc_state))
+                       return PTR_ERR(crtc_state);
+       }
+
+       /* Now pull in all joined crtcs */
        for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
                affected_pipes |= crtc_state->joiner_pipes;
                if (intel_crtc_needs_modeset(crtc_state))