public inbox for intel-gfx@lists.freedesktop.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 11/24] drm/i915: Check hw vs. sw watermark state after programming
Date: Tue, 29 Apr 2014 15:54:10 +0300	[thread overview]
Message-ID: <20140429125410.GD18465@intel.com> (raw)
In-Reply-To: <CA+gsUGT5dvueOzCsehBrkE3MPoSuLzm3DQW=yJ-UHXw6PHKAhA@mail.gmail.com>

On Wed, Apr 23, 2014 at 06:16:07PM -0300, Paulo Zanoni wrote:
> 2014-03-07 13:32 GMT-03:00  <ville.syrjala@linux.intel.com>:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > Make sure we programmed the watermarks correctly, by reading out the
> > hardware state again after programming and comparing it with the
> > state we supposedly programmed into hardware. Dump the watermark
> > registers after a mismatch, very much like we for the pipe config.
> > The only difference is that we don't dump the entire watermark
> > software tracking state since that's spread around a bit.
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> This one could also have been split into more than one patch: first
> you extract the functions, then later you add the new callers.
> 
> My only comment is: do we really want to check HW/SW state right after
> we write the register values? Shouldn't  this be done at some other
> time, like the end of the modeset sequence?

There's no guarantee that the WM update has finished there. I guess we
could sprinkle such checks to a few places. The check would have to merge
the active watermarks from all pipes and compare that with the register
contents. So it would check that our hardware state matches the software
active state at some point in time. But it can't really check that our
idea of active watermarks is correct.

This patch just checks that we actually wrote what we inteded into the
registers. So it basically tests that ilk_compute_wm_dirty() works and
that ilk_write_wm_values() didn't neglect to update something that was
deemed dirty.

> 
> Still, the patch seems correct, so: Reviewed-by: Paulo Zanoni
> <paulo.r.zanoni@intel.com>
> 
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 117 ++++++++++++++++++++++++++++------------
> >  1 file changed, 83 insertions(+), 34 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index ba4b23e..e519578a1 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2524,15 +2524,84 @@ static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv,
> >         return changed;
> >  }
> >
> > +static void _ilk_pipe_wm_get_hw_state(struct drm_device *dev,
> > +                                     enum pipe pipe,
> > +                                     struct ilk_wm_values *hw)
> > +{
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       static const unsigned int wm0_pipe_reg[] = {
> > +               [PIPE_A] = WM0_PIPEA_ILK,
> > +               [PIPE_B] = WM0_PIPEB_ILK,
> > +               [PIPE_C] = WM0_PIPEC_IVB,
> > +       };
> > +
> > +       hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]);
> > +
> > +       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> > +               hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
> > +}
> > +
> > +static void _ilk_wm_get_hw_state(struct drm_device *dev,
> > +                                struct ilk_wm_values *hw)
> > +{
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       enum pipe pipe;
> > +
> > +       for_each_pipe(pipe)
> > +               _ilk_pipe_wm_get_hw_state(dev, pipe, hw);
> > +
> > +       hw->wm_lp[0] = I915_READ(WM1_LP_ILK);
> > +       hw->wm_lp[1] = I915_READ(WM2_LP_ILK);
> > +       hw->wm_lp[2] = I915_READ(WM3_LP_ILK);
> > +
> > +       hw->wm_lp_spr[0] = I915_READ(WM1S_LP_ILK);
> > +       if (INTEL_INFO(dev)->gen >= 7) {
> > +               hw->wm_lp_spr[1] = I915_READ(WM2S_LP_IVB);
> > +               hw->wm_lp_spr[2] = I915_READ(WM3S_LP_IVB);
> > +       }
> > +
> > +       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> > +               hw->partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ?
> > +                       INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
> > +       else if (IS_IVYBRIDGE(dev))
> > +               hw->partitioning = (I915_READ(DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ?
> > +                       INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
> > +
> > +       hw->enable_fbc_wm =
> > +               !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
> > +}
> > +
> > +static void ilk_dump_wm_values(const struct ilk_wm_values *hw,
> > +                              const char *context)
> > +{
> > +       DRM_DEBUG_KMS("%s watermark values\n", context);
> > +       DRM_DEBUG_KMS("WM_PIPE_A = 0x%08x\n",  hw->wm_pipe[PIPE_A]);
> > +       DRM_DEBUG_KMS("WM_PIPE_B = 0x%08x\n",  hw->wm_pipe[PIPE_B]);
> > +       DRM_DEBUG_KMS("WM_PIPE_C = 0x%08x\n",  hw->wm_pipe[PIPE_C]);
> > +       DRM_DEBUG_KMS("WM_LP_1 = 0x%08x\n", hw->wm_lp[0]);
> > +       DRM_DEBUG_KMS("WM_LP_2 = 0x%08x\n", hw->wm_lp[1]);
> > +       DRM_DEBUG_KMS("WM_LP_3 = 0x%08x\n", hw->wm_lp[2]);
> > +       DRM_DEBUG_KMS("WM_LP_SPR_1 = 0x%08x\n", hw->wm_lp_spr[0]);
> > +       DRM_DEBUG_KMS("WM_LP_SPR_2 = 0x%08x\n", hw->wm_lp_spr[1]);
> > +       DRM_DEBUG_KMS("WM_LP_SPR_3 = 0x%08x\n", hw->wm_lp_spr[2]);
> > +       DRM_DEBUG_KMS("WM_LINETIME_A = 0x%08x\n", hw->wm_linetime[PIPE_A]);
> > +       DRM_DEBUG_KMS("WM_LINETIME_B = 0x%08x\n", hw->wm_linetime[PIPE_B]);
> > +       DRM_DEBUG_KMS("WM_LINETIME_C = 0x%08x\n", hw->wm_linetime[PIPE_C]);
> > +       DRM_DEBUG_KMS("enable FBC watermark = %d\n", hw->enable_fbc_wm);
> > +       DRM_DEBUG_KMS("DDB partitioning = %s\n",
> > +                     hw->partitioning == INTEL_DDB_PART_1_2 ? "1/2" : "5/6");
> > +}
> > +
> >  /*
> >   * The spec says we shouldn't write when we don't need, because every write
> >   * causes WMs to be re-evaluated, expending some power.
> >   */
> >  static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
> > -                               struct ilk_wm_values *results)
> > +                               const struct ilk_wm_values *results)
> >  {
> >         struct drm_device *dev = dev_priv->dev;
> >         struct ilk_wm_values *previous = &dev_priv->wm.hw;
> > +       struct ilk_wm_values hw = {};
> >         unsigned int dirty;
> >         uint32_t val;
> >
> > @@ -2602,6 +2671,14 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
> >                 I915_WRITE(WM3_LP_ILK, results->wm_lp[2]);
> >
> >         dev_priv->wm.hw = *results;
> > +
> > +       _ilk_wm_get_hw_state(dev, &hw);
> > +
> > +       if (memcmp(results, &hw, sizeof(hw))) {
> > +               WARN(1, "watermark state doesn't match!\n");
> > +               ilk_dump_wm_values(&hw, "[hw state]");
> > +               ilk_dump_wm_values(results, "[sw state]");
> > +       }
> >  }
> >
> >  static bool ilk_disable_lp_wm(struct drm_device *dev)
> > @@ -2683,23 +2760,14 @@ static void ilk_update_sprite_wm(struct drm_plane *plane,
> >         ilk_update_wm(crtc);
> >  }
> >
> > -static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> > +static void _ilk_pipe_wm_hw_to_sw(struct drm_crtc *crtc)
> >  {
> >         struct drm_device *dev = crtc->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct ilk_wm_values *hw = &dev_priv->wm.hw;
> > +       const struct ilk_wm_values *hw = &dev_priv->wm.hw;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >         struct intel_pipe_wm *active = &intel_crtc->wm.active;
> >         enum pipe pipe = intel_crtc->pipe;
> > -       static const unsigned int wm0_pipe_reg[] = {
> > -               [PIPE_A] = WM0_PIPEA_ILK,
> > -               [PIPE_B] = WM0_PIPEB_ILK,
> > -               [PIPE_C] = WM0_PIPEC_IVB,
> > -       };
> > -
> > -       hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]);
> > -       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> > -               hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
> >
> >         active->pipe_enabled = intel_crtc_active(crtc);
> >
> > @@ -2733,31 +2801,12 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> >  void ilk_wm_get_hw_state(struct drm_device *dev)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct ilk_wm_values *hw = &dev_priv->wm.hw;
> >         struct drm_crtc *crtc;
> >
> > -       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> > -               ilk_pipe_wm_get_hw_state(crtc);
> > -
> > -       hw->wm_lp[0] = I915_READ(WM1_LP_ILK);
> > -       hw->wm_lp[1] = I915_READ(WM2_LP_ILK);
> > -       hw->wm_lp[2] = I915_READ(WM3_LP_ILK);
> > -
> > -       hw->wm_lp_spr[0] = I915_READ(WM1S_LP_ILK);
> > -       if (INTEL_INFO(dev)->gen >= 7) {
> > -               hw->wm_lp_spr[1] = I915_READ(WM2S_LP_IVB);
> > -               hw->wm_lp_spr[2] = I915_READ(WM3S_LP_IVB);
> > -       }
> > +       _ilk_wm_get_hw_state(dev, &dev_priv->wm.hw);
> >
> > -       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> > -               hw->partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ?
> > -                       INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
> > -       else if (IS_IVYBRIDGE(dev))
> > -               hw->partitioning = (I915_READ(DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ?
> > -                       INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
> > -
> > -       hw->enable_fbc_wm =
> > -               !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
> > +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> > +               _ilk_pipe_wm_hw_to_sw(crtc);
> >  }
> >
> >  /**
> > --
> > 1.8.3.2
> >
> > _______________________________________________
> > 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:[~2014-04-29 12:54 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-07 16:32 [PATCH 00/24] drm/i915: Two part watermark update for ILK+ ville.syrjala
2014-03-07 16:32 ` [PATCH 01/24] drm/i915: Don't read sprite LP2+ registers on ILK/SNB ville.syrjala
2014-04-04 21:35   ` Paulo Zanoni
2014-04-05 15:19     ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 02/24] drm/i915: Add some more tracked state to intel_pipe_wm ville.syrjala
2014-04-07 14:14   ` Paulo Zanoni
2014-04-29 11:18     ` Daniel Vetter
2014-04-29 11:20       ` Daniel Vetter
2014-04-29 12:34         ` Paulo Zanoni
2014-04-29 13:57           ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 03/24] drm/i915: Skip watermark merging for inactive pipes ville.syrjala
2014-04-07 16:23   ` Paulo Zanoni
2014-03-07 16:32 ` [PATCH 04/24] drm/i916: Refactor WM register maximums ville.syrjala
2014-04-07 16:34   ` Paulo Zanoni
2014-04-09 12:22     ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 05/24] drm/i915: Merge LP1+ watermarks in safer way ville.syrjala
2014-04-23 19:13   ` Paulo Zanoni
2014-04-23 20:28     ` Ville Syrjälä
2014-04-28 12:44     ` [PATCH 05.1/24] drm/i915: Make sure computed watermarks never overflow the registers ville.syrjala
2014-04-28 12:44       ` [PATCH v2 05.2/24] drm/i915: Merge LP1+ watermarks in safer way ville.syrjala
2014-04-28 21:35         ` Paulo Zanoni
2014-04-28 21:23       ` [PATCH 05.1/24] drm/i915: Make sure computed watermarks never overflow the registers Paulo Zanoni
2014-03-07 16:32 ` [PATCH 06/24] drm/i915: Disable/enable planes as the first/last thing during modeset on ILK+ ville.syrjala
2014-04-07 19:51   ` Paulo Zanoni
2014-04-15 21:23     ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 07/24] drm/i915: Remove useless checks from primary enable/disable ville.syrjala
2014-03-07 21:29   ` Daniel Vetter
2014-03-10 11:20     ` Ville Syrjälä
2014-03-10 11:57       ` Daniel Vetter
2014-04-07 20:04         ` Paulo Zanoni
2014-04-28 12:53     ` [PATCH v2 " ville.syrjala
2014-04-28 21:39       ` Paulo Zanoni
2014-04-30 11:28       ` Chris Wilson
2014-04-30 11:40         ` Ville Syrjälä
2014-04-30 11:43           ` Chris Wilson
2014-04-30 12:34             ` Daniel Vetter
2014-04-30 14:43             ` [PATCH] drm/i915: Make primary_enabled match the actual hardware state ville.syrjala
2014-04-30 16:01               ` Chris Wilson
2014-03-07 16:32 ` [PATCH 08/24] drm/i915: Shuffle wait_for_vblank out of primary_enable/disable funcs ville.syrjala
2014-04-07 20:27   ` Paulo Zanoni
2014-04-08 18:55     ` Ville Syrjälä
2014-04-29 14:00       ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 09/24] drm/i915: Keep vblank interrupts enabled while enabling/disabling planes ville.syrjala
2014-04-07 21:21   ` Paulo Zanoni
2014-04-08 18:19     ` Ville Syrjälä
2014-04-28 12:58     ` [PATCH v2 " ville.syrjala
2014-04-28 21:42       ` Paulo Zanoni
2014-04-29 14:04         ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 10/24] drm/i915: Leave interrupts enabled while disabling crtcs during suspend ville.syrjala
2014-04-24 13:33   ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 11/24] drm/i915: Check hw vs. sw watermark state after programming ville.syrjala
2014-04-23 21:16   ` Paulo Zanoni
2014-04-29 12:54     ` Ville Syrjälä [this message]
2014-03-07 16:32 ` [PATCH 12/24] drm/i915: Refactor ilk_validate_pipe_wm() ville.syrjala
2014-04-23 21:23   ` Paulo Zanoni
2014-03-07 16:32 ` [PATCH 13/24] drm/i915: Refactor ilk_update_wm ville.syrjala
2014-04-23 21:31   ` Paulo Zanoni
2014-03-07 16:32 ` [PATCH 14/24] drm/i915: Add dev_priv->wm.mutex ville.syrjala
2014-04-23 21:47   ` Paulo Zanoni
2014-04-24  8:07     ` Ville Syrjälä
2014-03-07 16:32 ` [PATCH 15/24] drm/i915: Add vblank based delayed watermark update mechanism ville.syrjala
2014-03-07 16:32 ` [PATCH 16/24] drm/i915: Split watermark programming into pre and post steps ville.syrjala
2014-03-07 16:32 ` [PATCH 17/24] drm/i915: Actually perform the watermark update in two phases ville.syrjala
2014-03-07 16:32 ` [PATCH 18/24] drm/i915: Wait for watermark updates to finish before disabling a pipe ville.syrjala
2014-03-07 16:32 ` [PATCH 19/24] drm/i915: Refactor get_other_active_crtc() ville.syrjala
2014-03-07 16:32 ` [PATCH 20/24] drm/i915: Disable LP1+ watermarks while changing the number of active pipes ville.syrjala
2014-03-07 16:32 ` [PATCH 21/24] drm/i915: Keep track of who disabled LP1+ watermarks ville.syrjala
2014-03-07 16:32 ` [PATCH 22/24] drm/i915: Prefer the 5/6 DDB split when primary is disabled ville.syrjala
2014-03-07 16:32 ` [PATCH 23/24] drm/i915: Add a workaround for sprite only <-> primary only switching ville.syrjala
2014-03-07 21:32   ` Daniel Vetter
2014-03-07 16:32 ` [PATCH 24/24] drm/i915: Don't disable LP1+ watermarks for every frame when scaled ville.syrjala

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=20140429125410.GD18465@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox