All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Paulo Zanoni <przanoni@gmail.com>
Cc: Intel Graphics Development <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 10/16] drm/i915: Improve watermark dirtyness checks
Date: Fri, 11 Oct 2013 18:48:57 +0300	[thread overview]
Message-ID: <20131011154857.GW13047@intel.com> (raw)
In-Reply-To: <CA+gsUGTTEbUHhmjGeLGiMkpfoYRJOeWDvvZnp-o375H0-UjZBA@mail.gmail.com>

On Fri, Oct 11, 2013 at 12:02:53PM -0300, Paulo Zanoni wrote:
> 2013/10/9  <ville.syrjala@linux.intel.com>:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > Currently hsw_write_vm_values() may write to certain watermark
> > registers needlessly. For instance it will disable LP1+ watermarks
> > around WM_PIPE changes even though that's not needed. Also if only,
> > say, LP3 changes, the current code will again disable all LP1+
> > watermarks even though only LP3 needs to be reconfigured.
> >
> > Add an easy to read function that will compute the dirtyness of the
> > watermarks, and use that information to further optimize the watermark
> > programming.
> 
> Clever solution to the problem!
> 
> Some comments below.
> 
> 
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 95 +++++++++++++++++++++++++++++++++--------
> >  1 file changed, 77 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index bed96fb..5bd8c73 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2776,6 +2776,63 @@ static struct intel_pipe_wm *hsw_find_best_result(struct drm_device *dev,
> >         }
> >  }
> >
> > +/* dirty bits used to track which watermarks need changes */
> > +#define WM_DIRTY_PIPE(pipe) (1 << (pipe))
> > +#define WM_DIRTY_LINETIME(pipe) (1 << (8 + (pipe)))
> > +#define WM_DIRTY_LP(wm_lp) (1 << (15 + (wm_lp)))
> > +#define WM_DIRTY_LP_ALL (WM_DIRTY_LP(1) | WM_DIRTY_LP(2) | WM_DIRTY_LP(3))
> > +#define WM_DIRTY_FBC (1 << 24)
> > +#define WM_DIRTY_DDB (1 << 25)
> > +
> > +static unsigned int ilk_compute_wm_dirty(struct drm_device *dev,
> > +                                        const struct hsw_wm_values *old,
> > +                                        const struct hsw_wm_values *new)
> > +{
> > +       unsigned int dirty = 0;
> > +       enum pipe pipe;
> > +       int wm_lp;
> > +
> > +       for_each_pipe(pipe) {
> > +               if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) {
> > +                       dirty |= WM_DIRTY_LINETIME(pipe);
> > +                       /* Must disable LP1+ watermarks too */
> > +                       dirty |= WM_DIRTY_LP_ALL;
> > +               }
> > +
> > +               if (old->wm_pipe[pipe] != new->wm_pipe[pipe])
> > +                       dirty |= WM_DIRTY_PIPE(pipe);
> 
> I think this one also needs WM_DIRTY_LP_ALL. I don't think changing
> level zero without stopping the LP levels is safe.

Dunno. Spec doesn't tell me to do it. Although I haven't even bothered
to check how hard it would be to cook up a configuration where just
WM_PIPE changes but WM_LPx stays the same.

Actually the spec doesn't even say that we should disable a particular
LP1+ watermark if we want to change it. It just says that you have to
disable and enable them in order.

> 
> 
> > +       }
> > +
> > +       if (old->enable_fbc_wm != new->enable_fbc_wm) {
> > +               dirty |= WM_DIRTY_FBC;
> > +               /* Must disable LP1+ watermarks too */
> > +               dirty |= WM_DIRTY_LP_ALL;
> > +       }
> > +
> > +       if (old->partitioning != new->partitioning) {
> > +               dirty |= WM_DIRTY_DDB;
> > +               /* Must disable LP1+ watermarks too */
> > +               dirty |= WM_DIRTY_LP_ALL;
> > +       }
> > +
> > +       /* LP1+ watermarks already deemed dirty, no need to continue */
> > +       if (dirty & WM_DIRTY_LP_ALL)
> > +               return dirty;
> > +
> > +       /* Find the lowest numbered LP1+ watermark in need of an update... */
> > +       for (wm_lp = 1; wm_lp <= 3; wm_lp++) {
> > +               if (old->wm_lp[wm_lp - 1] != new->wm_lp[wm_lp - 1] ||
> > +                   old->wm_lp_spr[wm_lp - 1] != new->wm_lp_spr[wm_lp - 1])
> > +                       break;
> > +       }
> > +
> > +       /* ...and mark it and all higher numbered LP1+ watermarks as dirty */
> > +       for (; wm_lp <= 3; wm_lp++)
> > +               dirty |= WM_DIRTY_LP(wm_lp);
> > +
> > +       return dirty;
> > +}
> > +
> >  /*
> >   * The spec says we shouldn't write when we don't need, because every write
> >   * causes WMs to be re-evaluated, expending some power.
> > @@ -2784,6 +2841,7 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
> >                                 struct hsw_wm_values *results)
> >  {
> >         struct hsw_wm_values previous;
> > +       unsigned int dirty;
> >         uint32_t val;
> >
> >         previous.wm_pipe[0] = I915_READ(WM0_PIPEA_ILK);
> > @@ -2804,31 +2862,32 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
> >
> >         previous.enable_fbc_wm = !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
> >
> > -       if (memcmp(results, &previous, sizeof(*results)) == 0)
> 
> Oh, you've just removed the memcmp I complained about... Still, I
> believe it had a bug.
> 
> 
> > +       dirty = ilk_compute_wm_dirty(dev_priv->dev, &previous, results);
> > +       if (!dirty)
> >                 return;
> >
> > -       if (previous.wm_lp[2] != 0)
> > +       if (dirty & WM_DIRTY_LP(3) && previous.wm_lp[2] != 0)
> >                 I915_WRITE(WM3_LP_ILK, 0);
> > -       if (previous.wm_lp[1] != 0)
> > +       if (dirty & WM_DIRTY_LP(2) && previous.wm_lp[1] != 0)
> >                 I915_WRITE(WM2_LP_ILK, 0);
> > -       if (previous.wm_lp[0] != 0)
> > +       if (dirty & WM_DIRTY_LP(1) && previous.wm_lp[0] != 0)
> >                 I915_WRITE(WM1_LP_ILK, 0);
> >
> > -       if (previous.wm_pipe[0] != results->wm_pipe[0])
> > +       if (dirty & WM_DIRTY_PIPE(PIPE_A))
> >                 I915_WRITE(WM0_PIPEA_ILK, results->wm_pipe[0]);
> > -       if (previous.wm_pipe[1] != results->wm_pipe[1])
> > +       if (dirty & WM_DIRTY_PIPE(PIPE_B))
> >                 I915_WRITE(WM0_PIPEB_ILK, results->wm_pipe[1]);
> > -       if (previous.wm_pipe[2] != results->wm_pipe[2])
> > +       if (dirty & WM_DIRTY_PIPE(PIPE_C))
> >                 I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]);
> >
> > -       if (previous.wm_linetime[0] != results->wm_linetime[0])
> > +       if (dirty & WM_DIRTY_LINETIME(PIPE_A))
> >                 I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]);
> > -       if (previous.wm_linetime[1] != results->wm_linetime[1])
> > +       if (dirty & WM_DIRTY_LINETIME(PIPE_B))
> >                 I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]);
> > -       if (previous.wm_linetime[2] != results->wm_linetime[2])
> > +       if (dirty & WM_DIRTY_LINETIME(PIPE_C))
> >                 I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]);
> >
> > -       if (previous.partitioning != results->partitioning) {
> > +       if (dirty & WM_DIRTY_DDB) {
> >                 val = I915_READ(WM_MISC);
> >                 if (results->partitioning == INTEL_DDB_PART_1_2)
> >                         val &= ~WM_MISC_DATA_PARTITION_5_6;
> > @@ -2837,7 +2896,7 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
> >                 I915_WRITE(WM_MISC, val);
> >         }
> >
> > -       if (previous.enable_fbc_wm != results->enable_fbc_wm) {
> > +       if (dirty & WM_DIRTY_FBC) {
> >                 val = I915_READ(DISP_ARB_CTL);
> >                 if (results->enable_fbc_wm)
> >                         val &= ~DISP_FBC_WM_DIS;
> > @@ -2846,18 +2905,18 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
> >                 I915_WRITE(DISP_ARB_CTL, val);
> >         }
> >
> > -       if (previous.wm_lp_spr[0] != results->wm_lp_spr[0])
> > +       if (dirty & WM_DIRTY_LP(1) && previous.wm_lp_spr[0] != results->wm_lp_spr[0])
> >                 I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]);
> 
> As far as I understood, if previous.wm_lp_spr[X] !=
> results->wm_lp_spr[X], then for sure "dirty & WM_DIRTY_LP(X)", right?
> So the "dirty" check would be redundant here. And we can't remove the
> second part because we can have "dirty & WM_DIRTY_LP(X) while the
> sprite values don't change.

Right, because there's no separate enable bit for the sprite LP1+
watermarks, the dirty check is not really needed here. You want me to
remove it?

> 
> > -       if (previous.wm_lp_spr[1] != results->wm_lp_spr[1])
> > +       if (dirty & WM_DIRTY_LP(2) && previous.wm_lp_spr[1] != results->wm_lp_spr[1])
> >                 I915_WRITE(WM2S_LP_IVB, results->wm_lp_spr[1]);
> > -       if (previous.wm_lp_spr[2] != results->wm_lp_spr[2])
> > +       if (dirty & WM_DIRTY_LP(3) && previous.wm_lp_spr[2] != results->wm_lp_spr[2])
> >                 I915_WRITE(WM3S_LP_IVB, results->wm_lp_spr[2]);
> >
> > -       if (results->wm_lp[0] != 0)
> > +       if (dirty & WM_DIRTY_LP(1) && results->wm_lp[0] != 0)
> >                 I915_WRITE(WM1_LP_ILK, results->wm_lp[0]);
> > -       if (results->wm_lp[1] != 0)
> > +       if (dirty & WM_DIRTY_LP(2) && results->wm_lp[1] != 0)
> >                 I915_WRITE(WM2_LP_ILK, results->wm_lp[1]);
> > -       if (results->wm_lp[2] != 0)
> > +       if (dirty & WM_DIRTY_LP(3) && results->wm_lp[2] != 0)
> >                 I915_WRITE(WM3_LP_ILK, results->wm_lp[2]);
> >
> >         dev_priv->wm.hw = *results;
> > --
> > 1.8.1.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

-- 
Ville Syrjälä
Intel OTC

  reply	other threads:[~2013-10-11 15:49 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-09 16:17 [PATCH 00/16] drm/i915: More HSW watermark prep work v2 ville.syrjala
2013-10-09 16:17 ` [PATCH v2 01/16] drm/i915: Add intel_pipe_wm and prepare for watermark pre-compute ville.syrjala
2013-10-10 21:43   ` Paulo Zanoni
2013-10-11  8:07     ` Ville Syrjälä
2013-10-11 13:51       ` Paulo Zanoni
2013-10-09 16:17 ` [PATCH 02/16] drm/i915: Don't re-compute pipe watermarks except for the affected pipe ville.syrjala
2013-10-10 21:57   ` Paulo Zanoni
2013-10-09 16:17 ` [PATCH 03/16] drm/i915: Move LP1+ watermark merging out from hsw_compute_wm_results() ville.syrjala
2013-10-10 22:04   ` Paulo Zanoni
2013-10-09 16:17 ` [PATCH 04/16] drm/i915: Use intel_pipe_wm in hsw_find_best_results ville.syrjala
2013-10-10 22:20   ` Paulo Zanoni
2013-10-09 16:17 ` [PATCH 05/16] drm/i915: Move some computations out from hsw_compute_wm_parameters() ville.syrjala
2013-10-10 22:34   ` Paulo Zanoni
2013-10-11  8:26     ` Ville Syrjälä
2013-10-11 12:26       ` [PATCH 17/16] drm/i915: Check 5/6 DDB split only when sprites are enabled ville.syrjala
2013-10-11 17:21         ` Paulo Zanoni
2013-10-11 13:53       ` [PATCH 05/16] drm/i915: Move some computations out from hsw_compute_wm_parameters() Paulo Zanoni
2013-10-09 16:18 ` [PATCH 06/16] drm/i915: Don't compute 5/6 DDB split w/ zero active pipes ville.syrjala
2013-10-10 22:38   ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 07/16] drm/i915: Refactor wm_lp to level calculation ville.syrjala
2013-10-10 22:42   ` Paulo Zanoni
2013-10-11  8:10     ` Ville Syrjälä
2013-10-09 16:18 ` [PATCH 08/16] drm/i915: Kill fbc_wm_enabled from intel_wm_config ville.syrjala
2013-10-10 22:45   ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 09/16] drm/i915: Store current watermark state in dev_priv->wm ville.syrjala
2013-10-11 14:21   ` Paulo Zanoni
2013-10-15  8:24     ` Daniel Vetter
2013-10-15 16:49       ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 10/16] drm/i915: Improve watermark dirtyness checks ville.syrjala
2013-10-11 15:02   ` Paulo Zanoni
2013-10-11 15:48     ` Ville Syrjälä [this message]
2013-10-11 16:12       ` Paulo Zanoni
2013-10-11 16:39         ` [PATCH v2 " ville.syrjala
2013-10-11 17:57           ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 11/16] drm/i915: Init HSW watermark tracking in intel_modeset_setup_hw_state() ville.syrjala
2013-10-11 16:45   ` Paulo Zanoni
2013-10-11 17:15     ` Ville Syrjälä
2013-10-11 18:15       ` Paulo Zanoni
2013-10-11 19:12         ` Ville Syrjälä
2013-10-11 19:46           ` Paulo Zanoni
2013-10-14 11:21             ` Ville Syrjälä
2013-10-14 11:55     ` [PATCH v2 " ville.syrjala
2013-10-14 13:56       ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 12/16] drm/i915: Remove a somewhat silly debug print from watermark code ville.syrjala
2013-10-11 16:48   ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH v2 13/16] drm/i915: Adjust watermark register masks ville.syrjala
2013-10-11 17:02   ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 14/16] drm/i915: Add watermark tracepoints ville.syrjala
2013-10-11 19:40   ` Paulo Zanoni
2013-10-15  8:43     ` Daniel Vetter
2013-10-15 10:11       ` Ville Syrjälä
2013-10-15 10:59         ` Daniel Vetter
2013-10-09 16:18 ` [PATCH 15/16] drm/i915: Rename ilk_wm_max to ilk_compute_wm_maximums ville.syrjala
2013-10-11 17:07   ` Paulo Zanoni
2013-10-09 16:18 ` [PATCH 16/16] drm/i915: Rename ilk_check_wm to ilk_validate_wm_level ville.syrjala
2013-10-11 17:08   ` Paulo Zanoni
2013-10-15  9:16     ` Daniel Vetter
2013-10-15 17:01       ` Paulo Zanoni
2013-10-15 17:46         ` Ville Syrjälä

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131011154857.GW13047@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=przanoni@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.