All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matt Roper <matthew.d.roper@intel.com>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v3.1 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time (v3)
Date: Tue, 3 May 2016 13:44:29 -0700	[thread overview]
Message-ID: <20160503204429.GB28377@intel.com> (raw)
In-Reply-To: <1d012cee-b3ec-e262-79bd-9c3845e6c303@linux.intel.com>

On Mon, May 02, 2016 at 02:42:51PM +0200, Maarten Lankhorst wrote:
> Calculate the DDB blocks needed to satisfy the current atomic
> transaction at atomic check time.  This is a prerequisite to calculating
> SKL watermarks during the 'check' phase and rejecting any configurations
> that we can't find valid watermarks for.
> 
> Due to the nature of DDB allocation, it's possible for the addition of a
> new CRTC to make the watermark configuration already in use on another,
> unchanged CRTC become invalid.  A change in which CRTC's are active
> triggers a recompute of the entire DDB, which unfortunately means we
> need to disallow any other atomic commits from racing with such an
> update.  If the active CRTC's change, we need to grab the lock on all
> CRTC's and run all CRTC's through their 'check' handler to recompute and
> re-check their per-CRTC DDB allocations.
> 
> Note that with this patch we only compute the DDB allocation but we
> don't actually use the computed values during watermark programming yet.
> For ease of review/testing/bisecting, we still recompute the DDB at
> watermark programming time and just WARN() if it doesn't match the
> precomputed values.  A future patch will switch over to using the
> precomputed values once we're sure they're being properly computed.
> 
> Another clarifying note:  DDB allocation itself shouldn't ever fail with
> the algorithm we use today (i.e., we have enough DDB blocks on BXT to
> support the minimum needs of the worst-case scenario of every pipe/plane
> enabled at full size).  However the watermarks calculations based on the
> DDB may fail and we'll be moving those to the atomic check as well in
> future patches.
> 
> v2:
>  - Skip DDB calculations in the rare case where our transaction doesn't
>    actually touch any CRTC's at all.  Assuming at least one CRTC state
>    is present in our transaction, then it means we can't race with any
>    transactions that would update dev_priv->active_crtcs (which requires
>    _all_ CRTC locks).
> v3:
>  - Also calculate DDB during initial hw readout, to prevent using
>    incorrect bios values. (Maarten)

Yep, I suspect this should fix the final bug reported by Lyude and
others on this patch series.  I won't have hardware access to actually
test this out myself until next week though.

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

Thanks for taking care of this in my absence!

It might be worth adding a small blurb to the comment right above the
check of skip_intermediate_wm to explain why we're checking that field;
it was initially added and named for the two-stage watermark programming
we do on pre-gen9, so the name doesn't really represent how we're now
also using it on gen9 now (where there are no 'intermediate'
watermarks).  I suspect we'll probably just rename the field completely
in the future.


Matt

> 
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  5 +++
>  drivers/gpu/drm/i915/intel_display.c | 18 +++++++++
>  drivers/gpu/drm/i915/intel_drv.h     |  3 ++
>  drivers/gpu/drm/i915/intel_pm.c      | 71 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 97 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 97fdaaf09e44..d04fdf4cf632 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -339,6 +339,10 @@ struct i915_hotplug {
>  #define for_each_intel_crtc(dev, intel_crtc) \
>  	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
>  
> +#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \
> +	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) \
> +		for_each_if ((crtc_mask) & (1 << drm_crtc_index(&intel_crtc->base)))
> +
>  #define for_each_intel_encoder(dev, intel_encoder)		\
>  	list_for_each_entry(intel_encoder,			\
>  			    &(dev)->mode_config.encoder_list,	\
> @@ -594,6 +598,7 @@ struct drm_i915_display_funcs {
>  				       struct intel_crtc_state *newstate);
>  	void (*initial_watermarks)(struct intel_crtc_state *cstate);
>  	void (*optimize_watermarks)(struct intel_crtc_state *cstate);
> +	int (*compute_global_watermarks)(struct drm_atomic_state *state);
>  	void (*update_wm)(struct drm_crtc *crtc);
>  	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
>  	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5c2cf2738798..26ba8c7d1c75 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13310,6 +13310,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
>  static void calc_watermark_data(struct drm_atomic_state *state)
>  {
>  	struct drm_device *dev = state->dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *cstate;
> @@ -13339,6 +13340,10 @@ static void calc_watermark_data(struct drm_atomic_state *state)
>  		    pstate->crtc_h != pstate->src_h >> 16)
>  			intel_state->wm_config.sprites_scaled = true;
>  	}
> +
> +	/* Is there platform-specific watermark information to calculate? */
> +	if (dev_priv->display.compute_global_watermarks)
> +		dev_priv->display.compute_global_watermarks(state);
>  }
>  
>  /**
> @@ -13706,6 +13711,19 @@ static int intel_atomic_commit(struct drm_device *dev,
>  		intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
>  	}
>  
> +	/*
> +	 * Temporary sanity check: make sure our pre-computed DDB matches the
> +	 * one we actually wind up programming.
> +	 *
> +	 * Not a great place to put this, but the easiest place we have access
> +	 * to both the pre-computed and final DDB's; we'll be removing this
> +	 * check in the next patch anyway.
> +	 */
> +	WARN(IS_GEN9(dev) &&
> +	     memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
> +		    sizeof(intel_state->ddb)),
> +	     "Pre-computed DDB does not match final DDB!\n");
> +
>  	if (intel_state->modeset)
>  		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index c01edf390721..fa59784b3998 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -311,6 +311,9 @@ struct intel_atomic_state {
>  	 * don't bother calculating intermediate watermarks.
>  	 */
>  	bool skip_intermediate_wm;
> +
> +	/* Gen9+ only */
> +	struct skl_ddb_allocation ddb;
>  };
>  
>  struct intel_plane_state {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 540aa7d3a0e2..ab9c18dee567 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3812,6 +3812,76 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
>  
>  }
>  
> +static int
> +skl_compute_ddb(struct drm_atomic_state *state)
> +{
> +	struct drm_device *dev = state->dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> +	struct intel_crtc *intel_crtc;
> +	unsigned realloc_pipes = dev_priv->active_crtcs;
> +	int ret;
> +
> +	/*
> +	 * If the modeset changes which CRTC's are active, we need to
> +	 * recompute the DDB allocation for *all* active pipes, even
> +	 * those that weren't otherwise being modified in any way by this
> +	 * atomic commit.  Due to the shrinking of the per-pipe allocations
> +	 * when new active CRTC's are added, it's possible for a pipe that
> +	 * we were already using and aren't changing at all here to suddenly
> +	 * become invalid if its DDB needs exceeds its new allocation.
> +	 *
> +	 * Note that if we wind up doing a full DDB recompute, we can't let
> +	 * any other display updates race with this transaction, so we need
> +	 * to grab the lock on *all* CRTC's.
> +	 */
> +	if (intel_state->active_pipe_changes ||
> +	    intel_state->skip_intermediate_wm)
> +		realloc_pipes = ~0;
> +
> +	for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
> +		struct intel_crtc_state *cstate;
> +
> +		cstate = intel_atomic_get_crtc_state(state, intel_crtc);
> +		if (IS_ERR(cstate))
> +			return PTR_ERR(cstate);
> +
> +		ret = skl_allocate_pipe_ddb(cstate, &intel_state->ddb);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +skl_compute_wm(struct drm_atomic_state *state)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *cstate;
> +	int ret, i;
> +	bool changed = false;
> +
> +	/*
> +	 * If this transaction isn't actually touching any CRTC's, don't
> +	 * bother with watermark calculation.  Note that if we pass this
> +	 * test, we're guaranteed to hold at least one CRTC state mutex,
> +	 * which means we can safely use values like dev_priv->active_crtcs
> +	 * since any racing commits that want to update them would need to
> +	 * hold _all_ CRTC state mutexes.
> +	 */
> +	for_each_crtc_in_state(state, crtc, cstate, i)
> +		changed = true;
> +	if (!changed)
> +		return 0;
> +
> +	ret = skl_compute_ddb(state);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
>  static void skl_update_wm(struct drm_crtc *crtc)
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -7368,6 +7438,7 @@ void intel_init_pm(struct drm_device *dev)
>  	if (INTEL_INFO(dev)->gen >= 9) {
>  		skl_setup_wm_latency(dev);
>  		dev_priv->display.update_wm = skl_update_wm;
> +		dev_priv->display.compute_global_watermarks = skl_compute_wm;
>  	} else if (HAS_PCH_SPLIT(dev)) {
>  		ilk_setup_wm_latency(dev);
>  
> -- 
> 2.5.5
> 
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2016-05-03 20:44 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-21 23:16 [PATCH v3 00/16] Pre-calculate SKL-style atomic watermarks Matt Roper
2016-04-21 23:16 ` [PATCH v3 01/16] drm/i915: Reorganize WM structs/unions in CRTC state Matt Roper
2016-04-21 23:16 ` [PATCH v3 02/16] drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/ Matt Roper
2016-04-21 23:16 ` [PATCH v3 03/16] drm/i915/gen9: Cache plane data rates in CRTC state Matt Roper
2016-04-21 23:16 ` [PATCH v3 04/16] drm/i915/gen9: Allow calculation of data rate for in-flight state (v2) Matt Roper
2016-04-21 23:16 ` [PATCH v3 05/16] drm/i915/gen9: Store plane minimum blocks in CRTC wm " Matt Roper
2016-04-21 23:17 ` [PATCH v3 06/16] drm/i915: Track whether an atomic transaction changes the active CRTC's Matt Roper
2016-04-21 23:17 ` [PATCH v3 07/16] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state (v3) Matt Roper
2016-04-21 23:17 ` [PATCH v3 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time (v2) Matt Roper
2016-05-02 12:42   ` [PATCH v3.1 08/16] drm/i915/gen9: Compute DDB allocation at atomic check time (v3) Maarten Lankhorst
2016-05-03 20:44     ` Matt Roper [this message]
2016-05-05  3:08       ` Sripada, Radhakrishna
2016-04-21 23:17 ` [PATCH v3 09/16] drm/i915/gen9: Drop re-allocation of DDB at atomic commit (v2) Matt Roper
2016-05-06 18:12   ` Lyude Paul
2016-05-06 18:42     ` Lyude Paul
2016-05-10  1:06       ` Matt Roper
2016-04-21 23:17 ` [PATCH v3 10/16] drm/i915/gen9: Calculate plane WM's from state Matt Roper
2016-04-21 23:17 ` [PATCH v3 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state (v3) Matt Roper
2016-04-21 23:17 ` [PATCH v3 12/16] drm/i915/gen9: Use a bitmask to track dirty pipe watermarks Matt Roper
2016-04-21 23:17 ` [PATCH v3 13/16] drm/i915/gen9: Propagate watermark calculation failures up the call chain Matt Roper
2016-04-21 23:17 ` [PATCH v3 14/16] drm/i915/gen9: Calculate watermarks during atomic 'check' Matt Roper
2016-04-25 16:31   ` Jani Nikula
2016-04-21 23:17 ` [PATCH v3 15/16] drm/i915/gen9: Reject display updates that exceed wm limitations (v2) Matt Roper
2016-04-21 23:17 ` [PATCH v3 16/16] drm/i915: Remove wm_config from dev_priv/intel_atomic_state Matt Roper
2016-04-22  7:53 ` ✗ Fi.CI.BAT: warning for Pre-calculate SKL-style atomic watermarks (rev3) Patchwork
2016-05-07 16:46 ` [PATCH v3 00/16] Pre-calculate SKL-style atomic watermarks Daniel Stone

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=20160503204429.GB28377@intel.com \
    --to=matthew.d.roper@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=maarten.lankhorst@linux.intel.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.