[Intel-gfx] [PATCH] drm/i915: Explicit Raw and Adjusted WM latencies.
Rodrigo Vivi
rodrigo.vivi at intel.com
Wed Feb 21 15:53:12 UTC 2018
On Wed, Feb 21, 2018 at 03:09:30PM +0200, Ville Syrjälä wrote:
> On Tue, Feb 20, 2018 at 05:51:47PM -0800, Rodrigo Vivi wrote:
> > Current code has some limitations:
> >
> > 1. debugfs only shows raw latency we read from PCODE,
> > not the ones we are configuring.
> >
> > 2. When determining if SAGV can be enabled we only
> > apply adjusted wa, but we don't apply the IPC one.
> > So there is the risk of enabling SAGV when we should
> > actually disable it.
> >
> > Cc: Mahesh Kumar <mahesh1.kumar at intel.com>
> > Cc: Ashar Shaikh <azhar.shaikh at intel.com>
> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
> > ---
> > drivers/gpu/drm/i915/i915_debugfs.c | 48 ++++++++++++++++++-------------------
> > drivers/gpu/drm/i915/i915_drv.h | 7 ++++--
> > drivers/gpu/drm/i915/intel_pm.c | 31 ++++++++++++------------
> > 3 files changed, 43 insertions(+), 43 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> > index f260bb39d733..94fcb0360b14 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -3664,7 +3664,8 @@ static const struct file_operations i915_displayport_test_type_fops = {
> > .release = single_release
> > };
> >
> > -static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
> > +static void wm_latency_show(struct seq_file *m, const uint16_t wm[8],
> > + const char *header)
> > {
> > struct drm_i915_private *dev_priv = m->private;
> > struct drm_device *dev = &dev_priv->drm;
> > @@ -3680,6 +3681,9 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
> > else
> > num_levels = ilk_wm_max_level(dev_priv) + 1;
> >
> > + if (header)
> > + seq_printf(m, "%s\n", header);
> > +
> > drm_modeset_lock_all(dev);
> >
> > for (level = 0; level < num_levels; level++) {
> > @@ -3707,14 +3711,12 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
> > static int pri_wm_latency_show(struct seq_file *m, void *data)
> > {
> > struct drm_i915_private *dev_priv = m->private;
> > - const uint16_t *latencies;
> > -
> > - if (INTEL_GEN(dev_priv) >= 9)
> > - latencies = dev_priv->wm.skl_latency;
> > - else
> > - latencies = dev_priv->wm.pri_latency;
> >
> > - wm_latency_show(m, latencies);
> > + if (INTEL_GEN(dev_priv) >= 9) {
> > + wm_latency_show(m, dev_priv->wm.skl_latency.raw, "Raw");
> > + wm_latency_show(m, dev_priv->wm.skl_latency.adjusted, "Adjusted");
> > + } else
> > + wm_latency_show(m, dev_priv->wm.pri_latency, NULL);
> >
> > return 0;
> > }
> > @@ -3722,14 +3724,12 @@ static int pri_wm_latency_show(struct seq_file *m, void *data)
> > static int spr_wm_latency_show(struct seq_file *m, void *data)
> > {
> > struct drm_i915_private *dev_priv = m->private;
> > - const uint16_t *latencies;
> > -
> > - if (INTEL_GEN(dev_priv) >= 9)
> > - latencies = dev_priv->wm.skl_latency;
> > - else
> > - latencies = dev_priv->wm.spr_latency;
> >
> > - wm_latency_show(m, latencies);
> > + if (INTEL_GEN(dev_priv) >= 9) {
> > + wm_latency_show(m, dev_priv->wm.skl_latency.raw, "Raw");
> > + wm_latency_show(m, dev_priv->wm.skl_latency.adjusted, "Adjusted");
> > + } else
> > + wm_latency_show(m, dev_priv->wm.spr_latency, NULL);
> >
> > return 0;
> > }
> > @@ -3737,14 +3737,12 @@ static int spr_wm_latency_show(struct seq_file *m, void *data)
> > static int cur_wm_latency_show(struct seq_file *m, void *data)
> > {
> > struct drm_i915_private *dev_priv = m->private;
> > - const uint16_t *latencies;
> > -
> > - if (INTEL_GEN(dev_priv) >= 9)
> > - latencies = dev_priv->wm.skl_latency;
> > - else
> > - latencies = dev_priv->wm.cur_latency;
> >
> > - wm_latency_show(m, latencies);
> > + if (INTEL_GEN(dev_priv) >= 9) {
> > + wm_latency_show(m, dev_priv->wm.skl_latency.raw, "Raw");
> > + wm_latency_show(m, dev_priv->wm.skl_latency.adjusted, "Adjusted");
> > + } else
> > + wm_latency_show(m, dev_priv->wm.cur_latency, NULL);
> >
> > return 0;
> > }
> > @@ -3833,7 +3831,7 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
> > uint16_t *latencies;
> >
> > if (INTEL_GEN(dev_priv) >= 9)
> > - latencies = dev_priv->wm.skl_latency;
> > + latencies = dev_priv->wm.skl_latency.raw;
> > else
> > latencies = dev_priv->wm.pri_latency;
> >
> > @@ -3848,7 +3846,7 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
> > uint16_t *latencies;
> >
> > if (INTEL_GEN(dev_priv) >= 9)
> > - latencies = dev_priv->wm.skl_latency;
> > + latencies = dev_priv->wm.skl_latency.raw;
> > else
> > latencies = dev_priv->wm.spr_latency;
> >
> > @@ -3863,7 +3861,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
> > uint16_t *latencies;
> >
> > if (INTEL_GEN(dev_priv) >= 9)
> > - latencies = dev_priv->wm.skl_latency;
> > + latencies = dev_priv->wm.skl_latency.raw;
> > else
> > latencies = dev_priv->wm.cur_latency;
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 490ff041fb1e..6969bbb203bc 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2136,11 +2136,14 @@ struct drm_i915_private {
> > /* cursor */
> > uint16_t cur_latency[5];
> > /*
> > - * Raw watermark memory latency values
> > + * Watermark memory latency values
> > * for SKL for all 8 levels
> > * in 1us units.
> > */
> > - uint16_t skl_latency[8];
> > + struct {
> > + uint16_t raw[8];
> > + uint16_t adjusted[8];
> > + } skl_latency;
> >
> > /* current hardware state */
> > union {
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index a0a6b4b7c47b..78b52e5a1f8e 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3030,8 +3030,9 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
> >
> > static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
> > {
> > - intel_read_wm_latency(dev_priv, dev_priv->wm.skl_latency);
> > - intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency);
> > + intel_read_wm_latency(dev_priv, dev_priv->wm.skl_latency.raw);
> > + intel_print_wm_latency(dev_priv, "Gen9 Plane",
> > + dev_priv->wm.skl_latency.raw);
> > }
> >
> > static bool ilk_validate_pipe_wm(struct drm_device *dev,
> > @@ -3745,12 +3746,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
> > !wm->wm[level].plane_en; --level)
> > { }
> >
> > - latency = dev_priv->wm.skl_latency[level];
> > -
> > - if (skl_needs_memory_bw_wa(intel_state) &&
> > - plane->base.state->fb->modifier ==
> > - I915_FORMAT_MOD_X_TILED)
> > - latency += 15;
> > + latency = dev_priv->wm.skl_latency.adjusted[level];
>
> The latency adjustment depends on plane configuratiuon so we can't just
> stick into a global array.
Duh! Indeed...
> I would suggest that for cases like this we
> should either stuck into the plane state and dump it out alongside the
> rest (if we had decent plane state dumps... as usual I have a branch
> somewhere that converts us over to the atomic state dump framework), or
> we just have a debug print when computing the thing.
on debug side a debug message is ok.
But I see other bugs on the current code:
SAGV adjusted latency is missing some cases that we consider for latency++
on plane calculation.
So I thought that for this we could simply have an unified function.
But also I'm not sure if this will actually be effective. I don't believe
we are executing the disable sequence as expected when some plane has latency below
that threshhold.
So, maybe add this unified function but also on atomic_commit_tail we do more of
if (!intel_can_enable_sagv(state))
intel_disable_sagv(dev_priv);
not only on full modeset...
maybe something like:
if (intel_can_enable_sagv(state)) {
if (disabled) intel_enable_sagv()
} else {
if (enabled) intel_disable_sagv()
}
?! :/
I really believe we can be smarter there... I'm just out of good ideas.
>
> >
> > /*
> > * If any of the planes on this pipe don't enable wm levels that
> > @@ -4503,7 +4499,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
> > return 0;
> > }
> >
> > -static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> > +static int skl_compute_plane_wm(struct drm_i915_private *dev_priv,
> > struct intel_crtc_state *cstate,
> > const struct intel_plane_state *intel_pstate,
> > uint16_t ddb_allocation,
> > @@ -4514,7 +4510,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> > bool *enabled /* out */)
> > {
> > const struct drm_plane_state *pstate = &intel_pstate->base;
> > - uint32_t latency = dev_priv->wm.skl_latency[level];
> > + uint16_t latency = dev_priv->wm.skl_latency.raw[level];
> > uint_fixed_16_16_t method1, method2;
> > uint_fixed_16_16_t selected_result;
> > uint32_t res_blocks, res_lines;
> > @@ -4538,11 +4534,14 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> > if (apply_memory_bw_wa && wp->x_tiled)
> > latency += 15;
> >
> > - method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate,
> > - wp->cpp, latency, wp->dbuf_block_size);
> > + dev_priv->wm.skl_latency.adjusted[level] = latency;
> > +
> > + method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate, wp->cpp,
> > + dev_priv->wm.skl_latency.adjusted[level],
> > + wp->dbuf_block_size);
> > method2 = skl_wm_method2(wp->plane_pixel_rate,
> > cstate->base.adjusted_mode.crtc_htotal,
> > - latency,
> > + dev_priv->wm.skl_latency.adjusted[level],
> > wp->plane_blocks_per_line);
> >
> > if (wp->y_tiled) {
> > @@ -4555,7 +4554,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> > else if (ddb_allocation >=
> > fixed16_to_u32_round_up(wp->plane_blocks_per_line))
> > selected_result = min_fixed16(method1, method2);
> > - else if (latency >= wp->linetime_us)
> > + else if (dev_priv->wm.skl_latency.adjusted[level] >= wp->linetime_us)
> > selected_result = min_fixed16(method1, method2);
> > else
> > selected_result = method1;
> > @@ -4634,7 +4633,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> > }
> >
> > static int
> > -skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
> > +skl_compute_wm_levels(struct drm_i915_private *dev_priv,
> > struct skl_ddb_allocation *ddb,
> > struct intel_crtc_state *cstate,
> > const struct intel_plane_state *intel_pstate,
> > @@ -4756,7 +4755,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
> > {
> > struct drm_device *dev = cstate->base.crtc->dev;
> > struct drm_crtc_state *crtc_state = &cstate->base;
> > - const struct drm_i915_private *dev_priv = to_i915(dev);
> > + struct drm_i915_private *dev_priv = to_i915(dev);
> > struct drm_plane *plane;
> > const struct drm_plane_state *pstate;
> > struct skl_plane_wm *wm;
> > --
> > 2.13.6
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Ville Syrjälä
> Intel OTC
More information about the Intel-gfx
mailing list