[Intel-gfx] [PATCH] drm/i915: Dump watermark info in i915_display_info.
Maarten Lankhorst
maarten.lankhorst at linux.intel.com
Tue Oct 24 11:44:11 UTC 2017
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.lankhorst at 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
More information about the Intel-gfx
mailing list