drm/i915: Check tgl+ SAGV watermarks properly
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 26 Feb 2021 15:32:03 +0000 (17:32 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 3 Mar 2021 12:24:20 +0000 (14:24 +0200)
We know which WM0 (normal vs. SAGV) we supposedly programmed
into the hardware, so just check against that instead of accepting
either watermark as valid.

Cc: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210226153204.1270-7-ville.syrjala@linux.intel.com
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_pm.h

index 0bce9b1..bb70211 100644 (file)
@@ -9390,41 +9390,40 @@ static void verify_wm_state(struct intel_crtc *crtc,
 
        /* planes */
        for_each_universal_plane(dev_priv, pipe, plane) {
-               struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
-
-               hw_plane_wm = &hw->wm.planes[plane];
-               sw_plane_wm = &sw_wm->planes[plane];
+               const struct skl_wm_level *hw_wm_level, *sw_wm_level;
 
                /* Watermarks */
                for (level = 0; level <= max_level; level++) {
-                       if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-                                               &sw_plane_wm->wm[level]) ||
-                           (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
-                                                              &sw_plane_wm->sagv.wm0)))
+                       hw_wm_level = &hw->wm.planes[plane].wm[level];
+                       sw_wm_level = skl_plane_wm_level(sw_wm, plane, level);
+
+                       if (skl_wm_level_equals(hw_wm_level, sw_wm_level))
                                continue;
 
                        drm_err(&dev_priv->drm,
                                "mismatch in WM pipe %c plane %d level %d (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
                                pipe_name(pipe), plane + 1, level,
-                               sw_plane_wm->wm[level].plane_en,
-                               sw_plane_wm->wm[level].plane_res_b,
-                               sw_plane_wm->wm[level].plane_res_l,
-                               hw_plane_wm->wm[level].plane_en,
-                               hw_plane_wm->wm[level].plane_res_b,
-                               hw_plane_wm->wm[level].plane_res_l);
+                               sw_wm_level->plane_en,
+                               sw_wm_level->plane_res_b,
+                               sw_wm_level->plane_res_l,
+                               hw_wm_level->plane_en,
+                               hw_wm_level->plane_res_b,
+                               hw_wm_level->plane_res_l);
                }
 
-               if (!skl_wm_level_equals(&hw_plane_wm->trans_wm,
-                                        &sw_plane_wm->trans_wm)) {
+               hw_wm_level = &hw->wm.planes[plane].trans_wm;
+               sw_wm_level = skl_plane_trans_wm(sw_wm, plane);
+
+               if (!skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
                        drm_err(&dev_priv->drm,
                                "mismatch in trans WM pipe %c plane %d (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
                                pipe_name(pipe), plane + 1,
-                               sw_plane_wm->trans_wm.plane_en,
-                               sw_plane_wm->trans_wm.plane_res_b,
-                               sw_plane_wm->trans_wm.plane_res_l,
-                               hw_plane_wm->trans_wm.plane_en,
-                               hw_plane_wm->trans_wm.plane_res_b,
-                               hw_plane_wm->trans_wm.plane_res_l);
+                               sw_wm_level->plane_en,
+                               sw_wm_level->plane_res_b,
+                               sw_wm_level->plane_res_l,
+                               hw_wm_level->plane_en,
+                               hw_wm_level->plane_res_b,
+                               hw_wm_level->plane_res_l);
                }
 
                /* DDB */
@@ -9447,43 +9446,36 @@ static void verify_wm_state(struct intel_crtc *crtc,
         * once the plane becomes visible, we can skip this check
         */
        if (1) {
-               struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
-
-               hw_plane_wm = &hw->wm.planes[PLANE_CURSOR];
-               sw_plane_wm = &sw_wm->planes[PLANE_CURSOR];
+               const struct skl_wm_level *hw_wm_level, *sw_wm_level;
 
                /* Watermarks */
                for (level = 0; level <= max_level; level++) {
-                       if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-                                               &sw_plane_wm->wm[level]) ||
-                           (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
-                                                              &sw_plane_wm->sagv.wm0)))
-                               continue;
-
+                       hw_wm_level = &hw->wm.planes[PLANE_CURSOR].wm[level];
+                       sw_wm_level = skl_plane_wm_level(sw_wm, PLANE_CURSOR, level);
                        drm_err(&dev_priv->drm,
                                "mismatch in WM pipe %c cursor level %d (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
                                pipe_name(pipe), level,
-                               sw_plane_wm->wm[level].plane_en,
-                               sw_plane_wm->wm[level].plane_res_b,
-                               sw_plane_wm->wm[level].plane_res_l,
-                               hw_plane_wm->wm[level].plane_en,
-                               hw_plane_wm->wm[level].plane_res_b,
-                               hw_plane_wm->wm[level].plane_res_l);
+                               sw_wm_level->plane_en,
+                               sw_wm_level->plane_res_b,
+                               sw_wm_level->plane_res_l,
+                               hw_wm_level->plane_en,
+                               hw_wm_level->plane_res_b,
+                               hw_wm_level->plane_res_l);
                }
 
-               if (!skl_wm_level_equals(&hw_plane_wm->trans_wm,
-                                        &sw_plane_wm->trans_wm) &&
-                   !skl_wm_level_equals(&hw_plane_wm->trans_wm,
-                                        &sw_plane_wm->sagv.trans_wm)) {
+               hw_wm_level = &hw->wm.planes[PLANE_CURSOR].trans_wm;
+               sw_wm_level = skl_plane_trans_wm(sw_wm, PLANE_CURSOR);
+
+               if (!skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
                        drm_err(&dev_priv->drm,
                                "mismatch in trans WM pipe %c cursor (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
                                pipe_name(pipe),
-                               sw_plane_wm->trans_wm.plane_en,
-                               sw_plane_wm->trans_wm.plane_res_b,
-                               sw_plane_wm->trans_wm.plane_res_l,
-                               hw_plane_wm->trans_wm.plane_en,
-                               hw_plane_wm->trans_wm.plane_res_b,
-                               hw_plane_wm->trans_wm.plane_res_l);
+                               sw_wm_level->plane_en,
+                               sw_wm_level->plane_res_b,
+                               sw_wm_level->plane_res_l,
+                               hw_wm_level->plane_en,
+                               hw_wm_level->plane_res_b,
+                               hw_wm_level->plane_res_l);
                }
 
                /* DDB */
index 9d9ba63..854ffec 100644 (file)
@@ -4745,7 +4745,7 @@ icl_get_total_relative_data_rate(struct intel_atomic_state *state,
        return total_data_rate;
 }
 
-static const struct skl_wm_level *
+const struct skl_wm_level *
 skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
                   enum plane_id plane_id,
                   int level)
@@ -4758,7 +4758,7 @@ skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
        return &wm->wm[level];
 }
 
-static const struct skl_wm_level *
+const struct skl_wm_level *
 skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
                   enum plane_id plane_id)
 {
index 97550cf..669c8d5 100644 (file)
@@ -52,6 +52,11 @@ bool intel_can_enable_sagv(struct drm_i915_private *dev_priv,
                           const struct intel_bw_state *bw_state);
 void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
 void intel_sagv_post_plane_update(struct intel_atomic_state *state);
+const struct skl_wm_level *skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
+                                             enum plane_id plane_id,
+                                             int level);
+const struct skl_wm_level *skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
+                                             enum plane_id plane_id);
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
                         const struct skl_wm_level *l2);
 bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,