]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/i915: Get the uapi state from the correct plane when bigjoiner is used
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 17 Nov 2020 19:47:12 +0000 (11:47 -0800)
committerManasi Navare <manasi.d.navare@intel.com>
Wed, 18 Nov 2020 19:41:53 +0000 (11:41 -0800)
When using bigjoiner userspace is only controlling the "master"
plane, so use its uapi state for the "slave" plane as well.

hw.crtc needs a bit of magic since we don't want to copy that from
the uapi state (as it points to the wrong pipe for the "slave
" plane). Instead we pass the right crtc in explicitly but only
assign it when the uapi state indicates the plane to be logically
enabled (ie. uapi.crtc != NULL).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201117194718.11462-10-manasi.d.navare@intel.com
drivers/gpu/drm/i915/display/intel_atomic_plane.c
drivers/gpu/drm/i915/display/intel_atomic_plane.h
drivers/gpu/drm/i915/display/intel_display.c

index f47558efb3c2b89a597f792321e8a785125357ec..7abb0e3d6c0b8d3ab03d4a685a37a1f85002b33b 100644 (file)
@@ -247,11 +247,19 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
 }
 
 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
-                                      const struct intel_plane_state *from_plane_state)
+                                      const struct intel_plane_state *from_plane_state,
+                                      struct intel_crtc *crtc)
 {
        intel_plane_clear_hw_state(plane_state);
 
-       plane_state->hw.crtc = from_plane_state->uapi.crtc;
+       /*
+        * For the bigjoiner slave uapi.crtc will point at
+        * the master crtc. So we explicitly assign the right
+        * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
+        * the plane is logically enabled on the uapi level.
+        */
+       plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
+
        plane_state->hw.fb = from_plane_state->uapi.fb;
        if (plane_state->hw.fb)
                drm_framebuffer_get(plane_state->hw.fb);
@@ -331,15 +339,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
                                               old_plane_state, new_plane_state);
 }
 
-static struct intel_crtc *
-get_crtc_from_states(const struct intel_plane_state *old_plane_state,
-                    const struct intel_plane_state *new_plane_state)
+static struct intel_plane *
+intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
 {
-       if (new_plane_state->uapi.crtc)
-               return to_intel_crtc(new_plane_state->uapi.crtc);
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+       struct intel_plane *plane;
 
-       if (old_plane_state->uapi.crtc)
-               return to_intel_crtc(old_plane_state->uapi.crtc);
+       for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
+               if (plane->id == plane_id)
+                       return plane;
+       }
 
        return NULL;
 }
@@ -347,23 +356,37 @@ get_crtc_from_states(const struct intel_plane_state *old_plane_state,
 int intel_plane_atomic_check(struct intel_atomic_state *state,
                             struct intel_plane *plane)
 {
+       struct drm_i915_private *i915 = to_i915(state->base.dev);
        struct intel_plane_state *new_plane_state =
                intel_atomic_get_new_plane_state(state, plane);
        const struct intel_plane_state *old_plane_state =
                intel_atomic_get_old_plane_state(state, plane);
-       struct intel_crtc *crtc =
-               get_crtc_from_states(old_plane_state, new_plane_state);
-       const struct intel_crtc_state *old_crtc_state;
-       struct intel_crtc_state *new_crtc_state;
+       const struct intel_plane_state *new_master_plane_state;
+       struct intel_crtc *crtc = intel_get_crtc_for_pipe(i915, plane->pipe);
+       const struct intel_crtc_state *old_crtc_state =
+               intel_atomic_get_old_crtc_state(state, crtc);
+       struct intel_crtc_state *new_crtc_state =
+               intel_atomic_get_new_crtc_state(state, crtc);
+
+       if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
+               struct intel_plane *master_plane =
+                       intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
+                                            plane->id);
+
+               new_master_plane_state =
+                       intel_atomic_get_new_plane_state(state, master_plane);
+       } else {
+               new_master_plane_state = new_plane_state;
+       }
+
+       intel_plane_copy_uapi_to_hw_state(new_plane_state,
+                                         new_master_plane_state,
+                                         crtc);
 
-       intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
        new_plane_state->uapi.visible = false;
-       if (!crtc)
+       if (!new_crtc_state)
                return 0;
 
-       old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
-       new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
-
        return intel_plane_atomic_check_with_state(old_crtc_state,
                                                   new_crtc_state,
                                                   old_plane_state,
index 24a3a148aa623abd257e9107883242c6488bd6e4..5cae9db41062a84926c226b8f3b7a9f00c443c56 100644 (file)
@@ -24,7 +24,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
 unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
                                   const struct intel_plane_state *plane_state);
 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
-                                      const struct intel_plane_state *from_plane_state);
+                                      const struct intel_plane_state *from_plane_state,
+                                      struct intel_crtc *crtc);
 void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
                               const struct intel_plane_state *from_plane_state);
 void intel_update_plane(struct intel_plane *plane,
index 78f89ecdda797d3e237558587eacac71bc13f4b7..e1ed651276473345dbb065c263c1d49d7153cb03 100644 (file)
@@ -3718,7 +3718,8 @@ valid_fb:
        drm_framebuffer_get(fb);
 
        plane_state->crtc = &intel_crtc->base;
-       intel_plane_copy_uapi_to_hw_state(intel_state, intel_state);
+       intel_plane_copy_uapi_to_hw_state(intel_state, intel_state,
+                                         intel_crtc);
 
        intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
 
@@ -16981,7 +16982,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
        new_plane_state->uapi.crtc_w = crtc_w;
        new_plane_state->uapi.crtc_h = crtc_h;
 
-       intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
+       intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc);
 
        ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
                                                  old_plane_state, new_plane_state);