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

Let's store the plane allocation in a manner which more closely
matches how the hw operates. That is, we store the packed/CbCr
ddb in one struct, and the Y ddb in another. Currently we're
storing packed/Y in one struct, CbCr in the other.

This also works pretty well for icl+ where the UV plane is
the main plane and the Y plane is subservient to it. Although
in this case we do not even use ddb_y as we do the ddb allocation
in terms of hw planes.

v2: Rebase

Reviewed-by: Stanislav Lisovskiy <stanislav.lisovs...@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c |  32 +++---
 drivers/gpu/drm/i915/display/intel_bw.c       |   6 +-
 drivers/gpu/drm/i915/display/intel_display.c  |   8 +-
 .../drm/i915/display/intel_display_debugfs.c  |   4 +-
 .../drm/i915/display/intel_display_types.h    |   7 +-
 drivers/gpu/drm/i915/intel_pm.c               | 108 ++++++++----------
 6 files changed, 74 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 5712688232fb..0da9e2fa79eb 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -616,8 +616,8 @@ int intel_plane_atomic_check(struct intel_atomic_state 
*state,
 static struct intel_plane *
 skl_next_plane_to_commit(struct intel_atomic_state *state,
                         struct intel_crtc *crtc,
-                        struct skl_ddb_entry entries_y[I915_MAX_PLANES],
-                        struct skl_ddb_entry entries_uv[I915_MAX_PLANES],
+                        struct skl_ddb_entry ddb[I915_MAX_PLANES],
+                        struct skl_ddb_entry ddb_y[I915_MAX_PLANES],
                         unsigned int *update_mask)
 {
        struct intel_crtc_state *crtc_state =
@@ -636,17 +636,15 @@ skl_next_plane_to_commit(struct intel_atomic_state *state,
                    !(*update_mask & BIT(plane_id)))
                        continue;
 
-               if 
(skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id],
-                                               entries_y,
-                                               I915_MAX_PLANES, plane_id) ||
-                   
skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_uv[plane_id],
-                                               entries_uv,
-                                               I915_MAX_PLANES, plane_id))
+               if 
(skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb[plane_id],
+                                               ddb, I915_MAX_PLANES, plane_id) 
||
+                   
skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id],
+                                               ddb_y, I915_MAX_PLANES, 
plane_id))
                        continue;
 
                *update_mask &= ~BIT(plane_id);
-               entries_y[plane_id] = crtc_state->wm.skl.plane_ddb_y[plane_id];
-               entries_uv[plane_id] = 
crtc_state->wm.skl.plane_ddb_uv[plane_id];
+               ddb[plane_id] = crtc_state->wm.skl.plane_ddb[plane_id];
+               ddb_y[plane_id] = crtc_state->wm.skl.plane_ddb_y[plane_id];
 
                return plane;
        }
@@ -728,19 +726,17 @@ static void skl_crtc_planes_update_arm(struct 
intel_atomic_state *state,
                intel_atomic_get_old_crtc_state(state, crtc);
        struct intel_crtc_state *new_crtc_state =
                intel_atomic_get_new_crtc_state(state, crtc);
-       struct skl_ddb_entry entries_y[I915_MAX_PLANES];
-       struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
+       struct skl_ddb_entry ddb[I915_MAX_PLANES];
+       struct skl_ddb_entry ddb_y[I915_MAX_PLANES];
        u32 update_mask = new_crtc_state->update_planes;
        struct intel_plane *plane;
 
-       memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
+       memcpy(ddb, old_crtc_state->wm.skl.plane_ddb,
+              sizeof(old_crtc_state->wm.skl.plane_ddb));
+       memcpy(ddb_y, old_crtc_state->wm.skl.plane_ddb_y,
               sizeof(old_crtc_state->wm.skl.plane_ddb_y));
-       memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
-              sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
 
-       while ((plane = skl_next_plane_to_commit(state, crtc,
-                                                entries_y, entries_uv,
-                                                &update_mask))) {
+       while ((plane = skl_next_plane_to_commit(state, crtc, ddb, ddb_y, 
&update_mask))) {
                struct intel_plane_state *new_plane_state =
                        intel_atomic_get_new_plane_state(state, plane);
 
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
b/drivers/gpu/drm/i915/display/intel_bw.c
index ad1564ca7269..e8fc14ff133f 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -688,16 +688,16 @@ static void skl_crtc_calc_dbuf_bw(struct intel_bw_state 
*bw_state,
                return;
 
        for_each_plane_id_on_crtc(crtc, plane_id) {
+               const struct skl_ddb_entry *ddb =
+                       &crtc_state->wm.skl.plane_ddb[plane_id];
                const struct skl_ddb_entry *ddb_y =
                        &crtc_state->wm.skl.plane_ddb_y[plane_id];
-               const struct skl_ddb_entry *ddb_uv =
-                       &crtc_state->wm.skl.plane_ddb_uv[plane_id];
                unsigned int data_rate = crtc_state->data_rate[plane_id];
                unsigned int dbuf_mask = 0;
                enum dbuf_slice slice;
 
+               dbuf_mask |= skl_ddb_dbuf_slice_mask(i915, ddb);
                dbuf_mask |= skl_ddb_dbuf_slice_mask(i915, ddb_y);
-               dbuf_mask |= skl_ddb_dbuf_slice_mask(i915, ddb_uv);
 
                /*
                 * FIXME: To calculate that more properly we probably
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 10d483ce04a7..165e8f1ad14a 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6433,8 +6433,8 @@ static void verify_wm_state(struct intel_crtc *crtc,
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct skl_hw_state {
+               struct skl_ddb_entry ddb[I915_MAX_PLANES];
                struct skl_ddb_entry ddb_y[I915_MAX_PLANES];
-               struct skl_ddb_entry ddb_uv[I915_MAX_PLANES];
                struct skl_pipe_wm wm;
        } *hw;
        const struct skl_pipe_wm *sw_wm = &new_crtc_state->wm.skl.optimal;
@@ -6451,7 +6451,7 @@ static void verify_wm_state(struct intel_crtc *crtc,
 
        skl_pipe_wm_get_hw_state(crtc, &hw->wm);
 
-       skl_pipe_ddb_get_hw_state(crtc, hw->ddb_y, hw->ddb_uv);
+       skl_pipe_ddb_get_hw_state(crtc, hw->ddb, hw->ddb_y);
 
        hw_enabled_slices = intel_enabled_dbuf_slices_mask(dev_priv);
 
@@ -6533,8 +6533,8 @@ static void verify_wm_state(struct intel_crtc *crtc,
                }
 
                /* DDB */
-               hw_ddb_entry = &hw->ddb_y[plane->id];
-               sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb_y[plane->id];
+               hw_ddb_entry = &hw->ddb[PLANE_CURSOR];
+               sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb[PLANE_CURSOR];
 
                if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
                        drm_err(&dev_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index ac141c911685..415dc77abfe8 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -1127,13 +1127,13 @@ static int i915_ddb_info(struct seq_file *m, void 
*unused)
                seq_printf(m, "Pipe %c\n", pipe_name(pipe));
 
                for_each_plane_id_on_crtc(crtc, plane_id) {
-                       entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
+                       entry = &crtc_state->wm.skl.plane_ddb[plane_id];
                        seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
                                   entry->start, entry->end,
                                   skl_ddb_entry_size(entry));
                }
 
-               entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
+               entry = &crtc_state->wm.skl.plane_ddb[PLANE_CURSOR];
                seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
                           entry->end, skl_ddb_entry_size(entry));
        }
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 776b3e6662f2..e35002ecdcf8 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -847,8 +847,13 @@ struct intel_crtc_wm_state {
                        /* gen9+ only needs 1-step wm programming */
                        struct skl_pipe_wm optimal;
                        struct skl_ddb_entry ddb;
+                       /*
+                        * pre-icl: for packed/planar CbCr
+                        * icl+: for everything
+                        */
+                       struct skl_ddb_entry plane_ddb[I915_MAX_PLANES];
+                       /* pre-icl: for planar Y */
                        struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
-                       struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES];
                } skl;
 
                struct {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f70eb10ab24d..191ef54a2f00 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4327,46 +4327,31 @@ static void
 skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
                           const enum pipe pipe,
                           const enum plane_id plane_id,
-                          struct skl_ddb_entry *ddb_y,
-                          struct skl_ddb_entry *ddb_uv)
+                          struct skl_ddb_entry *ddb,
+                          struct skl_ddb_entry *ddb_y)
 {
-       u32 val, val2;
-       u32 fourcc = 0;
+       u32 val;
 
        /* Cursor doesn't support NV12/planar, so no extra calculation needed */
        if (plane_id == PLANE_CURSOR) {
                val = intel_uncore_read(&dev_priv->uncore, CUR_BUF_CFG(pipe));
-               skl_ddb_entry_init_from_hw(ddb_y, val);
+               skl_ddb_entry_init_from_hw(ddb, val);
                return;
        }
 
-       val = intel_uncore_read(&dev_priv->uncore, PLANE_CTL(pipe, plane_id));
+       val = intel_uncore_read(&dev_priv->uncore, PLANE_BUF_CFG(pipe, 
plane_id));
+       skl_ddb_entry_init_from_hw(ddb, val);
 
-       /* No DDB allocated for disabled planes */
-       if (val & PLANE_CTL_ENABLE)
-               fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK_SKL,
-                                             val & PLANE_CTL_ORDER_RGBX,
-                                             val & PLANE_CTL_ALPHA_MASK);
-
-       if (DISPLAY_VER(dev_priv) >= 11) {
-               val = intel_uncore_read(&dev_priv->uncore, PLANE_BUF_CFG(pipe, 
plane_id));
-               skl_ddb_entry_init_from_hw(ddb_y, val);
-       } else {
-               val = intel_uncore_read(&dev_priv->uncore, PLANE_BUF_CFG(pipe, 
plane_id));
-               val2 = intel_uncore_read(&dev_priv->uncore, 
PLANE_NV12_BUF_CFG(pipe, plane_id));
-
-               if (fourcc &&
-                   drm_format_info_is_yuv_semiplanar(drm_format_info(fourcc)))
-                       swap(val, val2);
+       if (DISPLAY_VER(dev_priv) >= 11)
+               return;
 
-               skl_ddb_entry_init_from_hw(ddb_y, val);
-               skl_ddb_entry_init_from_hw(ddb_uv, val2);
-       }
+       val = intel_uncore_read(&dev_priv->uncore, PLANE_NV12_BUF_CFG(pipe, 
plane_id));
+       skl_ddb_entry_init_from_hw(ddb_y, val);
 }
 
 void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
-                              struct skl_ddb_entry *ddb_y,
-                              struct skl_ddb_entry *ddb_uv)
+                              struct skl_ddb_entry *ddb,
+                              struct skl_ddb_entry *ddb_y)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum intel_display_power_domain power_domain;
@@ -4382,8 +4367,8 @@ void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
        for_each_plane_id_on_crtc(crtc, plane_id)
                skl_ddb_get_hw_plane_state(dev_priv, pipe,
                                           plane_id,
-                                          &ddb_y[plane_id],
-                                          &ddb_uv[plane_id]);
+                                          &ddb[plane_id],
+                                          &ddb_y[plane_id]);
 
        intel_display_power_put(dev_priv, power_domain, wakeref);
 }
@@ -5176,8 +5161,8 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
        int level;
 
        /* Clear the partitioning for disabled planes. */
+       memset(crtc_state->wm.skl.plane_ddb, 0, 
sizeof(crtc_state->wm.skl.plane_ddb));
        memset(crtc_state->wm.skl.plane_ddb_y, 0, 
sizeof(crtc_state->wm.skl.plane_ddb_y));
-       memset(crtc_state->wm.skl.plane_ddb_uv, 0, 
sizeof(crtc_state->wm.skl.plane_ddb_uv));
 
        if (!crtc_state->hw.active)
                return 0;
@@ -5194,7 +5179,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
        /* Allocate fixed number of blocks for cursor. */
        iter.total[PLANE_CURSOR] = skl_cursor_allocation(crtc_state, 
num_active);
        iter.size -= iter.total[PLANE_CURSOR];
-       skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR],
+       skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[PLANE_CURSOR],
                           alloc->end - iter.total[PLANE_CURSOR], alloc->end);
 
        /*
@@ -5264,10 +5249,10 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
        /* Set the actual DDB start/end points for each plane */
        iter.start = alloc->start;
        for_each_plane_id_on_crtc(crtc, plane_id) {
-               struct skl_ddb_entry *plane_alloc =
+               struct skl_ddb_entry *ddb =
+                       &crtc_state->wm.skl.plane_ddb[plane_id];
+               struct skl_ddb_entry *ddb_y =
                        &crtc_state->wm.skl.plane_ddb_y[plane_id];
-               struct skl_ddb_entry *uv_plane_alloc =
-                       &crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
                if (plane_id == PLANE_CURSOR)
                        continue;
@@ -5278,12 +5263,15 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
 
                /* Leave disabled planes at (0,0) */
                if (iter.total[plane_id])
-                       iter.start = skl_ddb_entry_init(plane_alloc, iter.start,
+                       iter.start = skl_ddb_entry_init(ddb, iter.start,
                                                        iter.start + 
iter.total[plane_id]);
 
-               if (iter.uv_total[plane_id])
-                       iter.start = skl_ddb_entry_init(uv_plane_alloc, 
iter.start,
+               if (iter.uv_total[plane_id]) {
+                       /* hardware wants these swapped */
+                       *ddb_y = *ddb;
+                       iter.start = skl_ddb_entry_init(ddb, iter.start,
                                                        iter.start + 
iter.uv_total[plane_id]);
+               }
        }
 
        /*
@@ -5940,11 +5928,10 @@ void skl_write_plane_wm(struct intel_plane *plane,
        enum plane_id plane_id = plane->id;
        enum pipe pipe = plane->pipe;
        const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
-       const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+       const struct skl_ddb_entry *ddb =
+               &crtc_state->wm.skl.plane_ddb[plane_id];
        const struct skl_ddb_entry *ddb_y =
                &crtc_state->wm.skl.plane_ddb_y[plane_id];
-       const struct skl_ddb_entry *ddb_uv =
-               &crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
        for (level = 0; level <= max_level; level++)
                skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level),
@@ -5954,25 +5941,20 @@ void skl_write_plane_wm(struct intel_plane *plane,
                           skl_plane_trans_wm(pipe_wm, plane_id));
 
        if (HAS_HW_SAGV_WM(dev_priv)) {
+               const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+
                skl_write_wm_level(dev_priv, PLANE_WM_SAGV(pipe, plane_id),
                                   &wm->sagv.wm0);
                skl_write_wm_level(dev_priv, PLANE_WM_SAGV_TRANS(pipe, 
plane_id),
                                   &wm->sagv.trans_wm);
        }
 
-       if (DISPLAY_VER(dev_priv) >= 11) {
+       skl_ddb_entry_write(dev_priv,
+                           PLANE_BUF_CFG(pipe, plane_id), ddb);
+
+       if (DISPLAY_VER(dev_priv) < 11)
                skl_ddb_entry_write(dev_priv,
-                                   PLANE_BUF_CFG(pipe, plane_id), ddb_y);
-               return;
-       }
-
-       if (wm->is_planar)
-               swap(ddb_y, ddb_uv);
-
-       skl_ddb_entry_write(dev_priv,
-                           PLANE_BUF_CFG(pipe, plane_id), ddb_y);
-       skl_ddb_entry_write(dev_priv,
-                           PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv);
+                                   PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_y);
 }
 
 void skl_write_cursor_wm(struct intel_plane *plane,
@@ -5984,7 +5966,7 @@ void skl_write_cursor_wm(struct intel_plane *plane,
        enum pipe pipe = plane->pipe;
        const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
        const struct skl_ddb_entry *ddb =
-               &crtc_state->wm.skl.plane_ddb_y[plane_id];
+               &crtc_state->wm.skl.plane_ddb[plane_id];
 
        for (level = 0; level <= max_level; level++)
                skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
@@ -6081,10 +6063,10 @@ skl_ddb_add_affected_planes(const struct 
intel_crtc_state *old_crtc_state,
                struct intel_plane_state *plane_state;
                enum plane_id plane_id = plane->id;
 
-               if 
(skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
-                                       
&new_crtc_state->wm.skl.plane_ddb_y[plane_id]) &&
-                   
skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id],
-                                       
&new_crtc_state->wm.skl.plane_ddb_uv[plane_id]))
+               if 
(skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb[plane_id],
+                                       
&new_crtc_state->wm.skl.plane_ddb[plane_id]) &&
+                   
skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
+                                       
&new_crtc_state->wm.skl.plane_ddb_y[plane_id]))
                        continue;
 
                plane_state = intel_atomic_get_plane_state(state, plane);
@@ -6253,8 +6235,8 @@ skl_print_wm_changes(struct intel_atomic_state *state)
                        enum plane_id plane_id = plane->id;
                        const struct skl_ddb_entry *old, *new;
 
-                       old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id];
-                       new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id];
+                       old = &old_crtc_state->wm.skl.plane_ddb[plane_id];
+                       new = &new_crtc_state->wm.skl.plane_ddb[plane_id];
 
                        if (skl_ddb_entry_equal(old, new))
                                continue;
@@ -6656,16 +6638,16 @@ void skl_wm_get_hw_state(struct drm_i915_private 
*dev_priv)
                memset(&dbuf_state->ddb[pipe], 0, 
sizeof(dbuf_state->ddb[pipe]));
 
                for_each_plane_id_on_crtc(crtc, plane_id) {
+                       struct skl_ddb_entry *ddb =
+                               &crtc_state->wm.skl.plane_ddb[plane_id];
                        struct skl_ddb_entry *ddb_y =
                                &crtc_state->wm.skl.plane_ddb_y[plane_id];
-                       struct skl_ddb_entry *ddb_uv =
-                               &crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
                        skl_ddb_get_hw_plane_state(dev_priv, crtc->pipe,
-                                                  plane_id, ddb_y, ddb_uv);
+                                                  plane_id, ddb, ddb_y);
 
+                       skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb);
                        skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_y);
-                       skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_uv);
                }
 
                dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state);
-- 
2.34.1

Reply via email to