This will make it easier to debug whether the hardware watermarks match
what's calculated for intermediate and optimal watermarks.

Signed-off-by: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 153 ++++++++++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index c65e381b85f3..ac9ea47ac89f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3170,6 +3170,158 @@ static void intel_scaler_info(struct seq_file *m, 
struct intel_crtc *intel_crtc)
        }
 }
 
+static void intel_watermark_info(struct seq_file *m,
+                                struct drm_i915_private *dev_priv,
+                                struct intel_crtc *crtc)
+{
+       struct intel_crtc_state *crtc_state =
+               to_intel_crtc_state(crtc->base.state);
+       int i, j;
+       const char *names[3] = {
+               "hardware",
+               "intermediate",
+               "optimal"
+       };
+
+       if (INTEL_GEN(dev_priv) >= 9) {
+               struct skl_pipe_wm *wm = &crtc_state->wm.skl.optimal;
+               struct skl_ddb_entry *entry = &crtc_state->wm.skl.ddb;
+               struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
+
+               seq_printf(m, "\tDDB allocation: start %u end %u, size %u\n",
+                          entry->start, entry->end, skl_ddb_entry_size(entry));
+               for (i = 0; i < ARRAY_SIZE(ddb->plane[crtc->pipe]); i++) {
+                       entry = &ddb->plane[crtc->pipe][i];
+
+                       if (!skl_ddb_entry_size(entry))
+                               continue;
+
+                       seq_printf(m, "\t\tplane %d%c DDB allocation: start %u 
end %u, size %u, ",
+                                  i, pipe_name(crtc->pipe), entry->start, 
entry->end,
+                                  skl_ddb_entry_size(entry));
+
+                       entry = &ddb->y_plane[crtc->pipe][i];
+                       if (!skl_ddb_entry_size(entry))
+                               continue;
+
+                       seq_printf(m, "\t\tplane %d%c DDB Y allocation: start 
%u end %u, size %u, ",
+                                  i, pipe_name(crtc->pipe), entry->start, 
entry->end,
+                                  skl_ddb_entry_size(entry));
+               }
+
+               seq_printf(m, "\tLinetime: %u\n", wm->linetime);
+
+               for (i = 0; i < ARRAY_SIZE(wm->planes); i++) {
+                       struct skl_plane_wm *pwm = &wm->planes[i];
+
+                       seq_printf(m, "\tplane %d%c, wm enabled: %s",
+                                  i, pipe_name(crtc->pipe),
+                                  enableddisabled(pwm->wm[0].plane_en));
+                       if (!pwm->wm[0].plane_en)
+                               continue;
+
+                       seq_printf(m, "\t\tTransition wm: %s, lines %u, blocks 
%u",
+                                  enableddisabled(pwm->trans_wm.plane_en),
+                                  pwm->trans_wm.plane_res_b, 
pwm->trans_wm.plane_res_l);
+
+                       for (j = 0; j < ARRAY_SIZE(pwm->wm); j++) {
+                               if (!pwm->wm[j].plane_en)
+                                       break;
+
+                                 seq_printf(m, "\t\tLevel[%u]: lines %u, 
blocks %u",
+                                            j, pwm->trans_wm.plane_res_b,
+                                            pwm->trans_wm.plane_res_l);
+                       }
+               }
+       } else if (HAS_PCH_SPLIT(dev_priv)) {
+               struct intel_pipe_wm *wm;
+               struct intel_pipe_wm *wms[3] = {
+                       &crtc->wm.active.ilk,
+                       &crtc_state->wm.ilk.intermediate,
+                       &crtc_state->wm.ilk.optimal };
+
+               for (j = 0, wm = *wms; j < 3; j++, wm = wms[j]) {
+                       seq_printf(m, "\tDumping %s watermarks, post vbl 
update: %s\n",
+                                  names[j], 
yesno(crtc_state->wm.need_postvbl_update));
+
+                       for (i = 0; i < ARRAY_SIZE(wm->wm); i++) {
+                               struct intel_wm_level *lvl = &wm->wm[i];
+
+                               seq_printf(m, "\t\twm level[%i], enabled: %s, 
vals: %u, %u, %u, %u\n",
+                                         i, yesno(lvl->enable), lvl->pri_val,
+                                         lvl->spr_val, lvl->cur_val, 
lvl->fbc_val);
+                       }
+
+                       seq_printf(m, "\tLinetime: %u\n", wm->linetime);
+                       seq_printf(m, "\tfbc wm enabled: %s, pipe: %s, sprites 
enabled: %s, scaled: %s\n",
+                                 yesno(wm->fbc_wm_enabled), 
yesno(wm->pipe_enabled),
+                                 yesno(wm->sprites_enabled), 
yesno(wm->sprites_scaled));
+               }
+       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+               struct vlv_wm_state *wm;
+               struct vlv_wm_state *wms[3] = {
+                       &crtc->wm.active.vlv,
+                       &crtc_state->wm.vlv.intermediate,
+                       &crtc_state->wm.vlv.optimal };
+
+               for (j = 0, wm = *wms; j < 3; j++, wm = wms[j]) {
+                       seq_printf(m, "\tDumping %s watermarks, CxSR: %s, num 
levels: %u\n",
+                                  names[j], yesno(wm->cxsr), wm->num_levels);
+
+                       for (i = 0; i < wm->num_levels; i++) {
+                               struct g4x_pipe_wm *pwm = &wm->wm[i];
+                               struct g4x_sr_wm *sr = &wm->sr[i];
+                               int k;
+
+                               seq_printf(m, "\tLevel %u allocations:\n", i);
+                               for (k = 0; k < ARRAY_SIZE(pwm->plane); k++)
+                                       seq_printf(m, "\t\tPlane %u: %u\n", k, 
pwm->plane[k]);
+                               seq_printf(m, "\t\tFBC: %u\n", pwm->fbc);
+
+                               if (!wm->cxsr)
+                                       continue;
+
+                               seq_printf(m, "\t\tSR: plane %u, cursor %u, FBC 
%u\n",
+                                          sr->plane, sr->cursor, sr->fbc);
+                       }
+               }
+       } else if (IS_G4X(dev_priv)) {
+               struct g4x_wm_state *wm;
+               struct g4x_wm_state *wms[3] = {
+                       &crtc->wm.active.g4x,
+                       &crtc_state->wm.g4x.intermediate,
+                       &crtc_state->wm.g4x.optimal };
+
+               for (j = 0, wm = *wms; j < 3; j++, wm = wms[j]) {
+                       struct g4x_pipe_wm *pwm = &wm->wm;
+                       struct g4x_sr_wm *sr = &wm->sr;
+                       struct g4x_sr_wm *hpll = &wm->hpll;
+
+                       seq_printf(m, "\tDumping %s watermarks, CxSR: %s, HPLL: 
%s, fbc: %s\n",
+                                  names[j], yesno(wm->cxsr), 
yesno(wm->hpll_en),
+                                  yesno(wm->fbc_en));
+
+                       for (i = 0; i < ARRAY_SIZE(pwm->plane); i++)
+                               seq_printf(m, "\t\tPlane %u: %u\n", i, 
pwm->plane[i]);
+
+                       if (wm->fbc_en)
+                               seq_printf(m, "\t\tFBC: %u\n", pwm->fbc);
+
+                       if (wm->cxsr)
+                               seq_printf(m, "\t\tSR: plane %u, cursor %u, FBC 
%u\n",
+                                          sr->plane, sr->cursor, sr->fbc);
+
+                       if (wm->hpll_en)
+                               seq_printf(m, "\t\tHPLL: plane %u, cursor %u, 
FBC %u\n",
+                                          hpll->plane, hpll->cursor, 
hpll->fbc);
+               }
+       }
+
+       if (dev_priv->display.optimize_watermarks)
+               seq_printf(m, "\tNeed post vblank update: %s\n",
+                          yesno(crtc_state->wm.need_postvbl_update));
+}
+
 static int i915_display_info(struct seq_file *m, void *unused)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -3208,6 +3360,7 @@ static int i915_display_info(struct seq_file *m, void 
*unused)
                                   cursor->cursor.base);
                        intel_scaler_info(m, crtc);
                        intel_plane_info(m, crtc);
+                       intel_watermark_info(m, dev_priv, crtc);
                }
 
                seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n",
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to