drm/i915: Populate pipe dbuf slices more accurately during readout
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 4 Feb 2022 14:18:17 +0000 (16:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Feb 2022 11:56:20 +0000 (12:56 +0100)
commit 85bb289215cf37e05e9581b39b114db1293f9ecd upstream.

During readout we cannot assume the planes are actually using the
slices they are supposed to use. The BIOS may have misprogrammed
things and put the planes onto the wrong dbuf slices. So let's
do the readout more carefully to make sure we really know which
dbuf slices are actually in use by the pipe at the time.

Cc: <stable@vger.kernel.org> # v5.14+
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220204141818.1900-2-ville.syrjala@linux.intel.com
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
(cherry picked from commit b3dcc6dc0f32612d04839c2fb32e94d0ebf92c98)
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/i915/intel_pm.c

index 949720e9dc9b58be8187466c7aa72b4f8c4a9d9d..aea4cc2b3486e9c497ee908c559e01cf0edd3279 100644 (file)
@@ -6634,6 +6634,7 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
                enum pipe pipe = crtc->pipe;
                unsigned int mbus_offset;
                enum plane_id plane_id;
+               u8 slices;
 
                skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
                crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
@@ -6653,20 +6654,22 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
                        skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_uv);
                }
 
-               dbuf_state->slices[pipe] =
-                       skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
-                                               dbuf_state->joined_mbus);
-
                dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state);
 
                /*
                 * Used for checking overlaps, so we need absolute
                 * offsets instead of MBUS relative offsets.
                 */
-               mbus_offset = mbus_ddb_offset(dev_priv, dbuf_state->slices[pipe]);
+               slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
+                                                dbuf_state->joined_mbus);
+               mbus_offset = mbus_ddb_offset(dev_priv, slices);
                crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start;
                crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end;
 
+               /* The slices actually used by the planes on the pipe */
+               dbuf_state->slices[pipe] =
+                       skl_ddb_dbuf_slice_mask(dev_priv, &crtc_state->wm.skl.ddb);
+
                drm_dbg_kms(&dev_priv->drm,
                            "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n",
                            crtc->base.base.id, crtc->base.name,