[Intel-gfx] [PATCH] drm/i915: Increase WM memory latency values on SNB with high pixel clock

Chris Wilson chris at chris-wilson.co.uk
Fri Mar 21 10:29:43 CET 2014


On Fri, Mar 21, 2014 at 11:00:48AM +0200, Jani Nikula wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> On SNB the BIOS provided WM memory latency values seem insufficient to
> handle high resolution displays.
> 
> In this particular case the display mode was a 2560x1440 at 60Hz, which
> makes the pixel clock 241.5 MHz. It was empirically found that a memory
> latency value if 1.2 usec is enough to avoid underruns, whereas the BIOS
> provided value of 0.7 usec was clearly too low. Incidentally 1.2 usec
> is what the typical BIOS provided values are on IVB systems.
> 
> Increase the WM memory latency values to 1.2 usec when encountering a
> display mode with pixel clock exceeding 225 MHz. 225 MHz was chosen as
> the threshold simply because that's the documented limit of SNB with
> HDMI, so one might surmise that the hardware may have been tested up
> to that frequency. In theory the latency shouldn't depend on the pixel
> clock at all. So it may be that we should just increase the latency
> values across the board for all SNB systems. But for now I'm inclined
> to limit this quirk to only those cases that are proven to need it,
> as doing otherwise might cause some increase in power consumption for
> everyone.
> 
> Cc: Robert N <crshman at gmail.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70254
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> ---
> 
> I'm just relaying the patch from bugzilla to the list as it seems to fix
> the bug. Don't ask me anything about it.
> 
> BR,
> Jani.
> ---
>  drivers/gpu/drm/i915/intel_display.c |   10 ++++++++++
>  drivers/gpu/drm/i915/intel_drv.h     |    1 +
>  drivers/gpu/drm/i915/intel_pm.c      |   33 +++++++++++++++++++++++++++++++++
>  3 files changed, 44 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 0b19afdfbaa7..b0ac92d8f461 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9933,6 +9933,16 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>  		 */
>  		drm_calc_timestamping_constants(crtc,
>  						&pipe_config->adjusted_mode);
> +
> +
> +		/*
> +		 * The BIOS provided WM memory latency values are often
> +		 * inadequate for high resolution displays. Adjust them.
> +		 *
> +		 * FIXME not sure 225MHz is a good threshold.
> +		 */
> +		if (IS_GEN6(dev) && pipe_config->adjusted_mode.crtc_clock > 225000)
> +			snb_wm_latency_quirk(dev);
>  	}
>  
>  	/* Only after disabling all output pipelines that will be changed can we
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 60ffad376390..b1d631c9dfa5 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -903,6 +903,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
>  void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
>  void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
>  void ilk_wm_get_hw_state(struct drm_device *dev);
> +void snb_wm_latency_quirk(struct drm_device *dev);
>  
>  
>  /* intel_sdvo.c */
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 39f3238bf1c3..226750452637 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2104,6 +2104,39 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
>  	intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
>  }
>  
> +static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv,
> +				    uint16_t wm[5], uint16_t min)
> +{
> +	int level, max_level = ilk_wm_max_level(dev_priv->dev);
> +
> +	if (wm[0] >= min)
> +		return false;
> +
> +	wm[0] = max(wm[0], min);
> +	for (level = 1; level <= max_level; level++)
> +		wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5));
> +
> +	return true;
> +}
> +
> +void snb_wm_latency_quirk(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	bool changed;
> +
> +	changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) |
> +		ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) |
> +		ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12);

Unless I missed something this hereafter permanently bumps the latency
for computations.

At the 225MHz pixel clock, what are the differences in final WM values?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre



More information about the Intel-gfx mailing list