Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Intel Graphics Development <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 15/15] drm/i915: implement fdi auto-dithering
Date: Mon, 29 Apr 2013 17:02:20 +0300	[thread overview]
Message-ID: <1367244140.6390.66.camel@intelbox> (raw)
In-Reply-To: <1366363487-15926-16-git-send-email-daniel.vetter@ffwll.ch>

On Fri, 2013-04-19 at 11:24 +0200, Daniel Vetter wrote:
> So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw
> VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit
> into this, among them the default 1080p mode.
> 
> The solution is to dither down the pipe a bit so that everything fits,
> which this patch implements.
> 
> But ports compute their state under the assumption that the bpp they
> pick will be the one selected, e.g. the display port bw computations
> won't work otherwise. Now we could adjust our code to again up-dither
> to the computed DP link parameters, but that's pointless.
> 
> So instead when the pipe needs to adjust parameters we need to retry
> the pipe_config computation at the encoder stage. Furthermore we need
> to inform encoders that they should not increase bandwidth
> requirements if possible. This is required for the hdmi code, which
> prefers the pipe to up-dither to either of the two possible hdmi bpc
> values.
> 
> LVDS has a similar requirement, although that's probably only
> theoretical in nature: It's unlikely that we'll ever see an 8bpc
> high-res lvds panel (which is required to hit the 2 fdi lane limit).
> 
> v2: Rebased on top of a bikeshed from Paulo.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 56 ++++++++++++++++++++++++++++--------
>  drivers/gpu/drm/i915/intel_drv.h     |  7 +++++
>  drivers/gpu/drm/i915/intel_hdmi.c    | 14 ++++++---
>  drivers/gpu/drm/i915/intel_lvds.c    |  2 +-
>  4 files changed, 62 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c25dbdd..6d35ccd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4021,13 +4021,16 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
>  	}
>  }
>  
> -static bool ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> -					struct intel_crtc_config *pipe_config)
> +#define RETRY 1
> +static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> +				       struct intel_crtc_config *pipe_config)
>  {
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>  	int target_clock, lane, link_bw;
> +	bool setup_ok, needs_recompute = false;
>  
> +retry:
>  	/* FDI is a binary signal running at ~2.7GHz, encoding
>  	 * each output octet as 10 bits. The actual frequency
>  	 * is stored as a divider into a 100MHz clock, and the
> @@ -4052,12 +4055,26 @@ static bool ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, target_clock,
>  			       link_bw, &pipe_config->fdi_m_n);
>  
> -	return ironlake_check_fdi_lanes(intel_crtc->base.dev,
> -					intel_crtc->pipe, pipe_config);
> +	setup_ok = ironlake_check_fdi_lanes(intel_crtc->base.dev,
> +					    intel_crtc->pipe, pipe_config);
> +	if (!setup_ok && pipe_config->pipe_bpp > 6*3) {
> +		pipe_config->pipe_bpp -= 2*3;
> +		DRM_DEBUG_KMS("fdi link bw constraint, reducing pipe bpp to %i\n",
> +			      pipe_config->pipe_bpp);
> +		needs_recompute = true;
> +		pipe_config->bw_constrained = true;
> +
> +		goto retry;
> +	}
> +
> +	if (needs_recompute)
> +		return RETRY;
> +
> +	return setup_ok ? 0 : -EINVAL;
>  }
>  
> -static bool intel_crtc_compute_config(struct drm_crtc *crtc,
> -				      struct intel_crtc_config *pipe_config)
> +static int intel_crtc_compute_config(struct drm_crtc *crtc,
> +				     struct intel_crtc_config *pipe_config)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> @@ -4066,7 +4083,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
>  		/* FDI link clock is fixed at 2.7G */
>  		if (pipe_config->requested_mode.clock * 3
>  		    > IRONLAKE_FDI_FREQ * 4)
> -			return false;
> +			return -EINVAL;
>  	}
>  
>  	/* All interlaced capable intel hw wants timings in frames. Note though
> @@ -4080,7 +4097,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
>  	 */
>  	if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
>  		adjusted_mode->hsync_start == adjusted_mode->hdisplay)
> -		return false;
> +		return -EINVAL;
>  
>  	if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && pipe_config->pipe_bpp > 10*3) {
>  		pipe_config->pipe_bpp = 10*3; /* 12bpc is gen5+ */
> @@ -4093,7 +4110,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
>  	if (pipe_config->has_pch_encoder)
>  		return ironlake_fdi_compute_config(to_intel_crtc(crtc), pipe_config);
>  
> -	return true;
> +	return 0;
>  }
>  
>  static int valleyview_get_display_clock_speed(struct drm_device *dev)
> @@ -7673,7 +7690,8 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>  	struct drm_encoder_helper_funcs *encoder_funcs;
>  	struct intel_encoder *encoder;
>  	struct intel_crtc_config *pipe_config;
> -	int plane_bpp;
> +	int plane_bpp, ret = -EINVAL;
> +	bool retry = true;
>  
>  	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
>  	if (!pipe_config)
> @@ -7686,6 +7704,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>  	if (plane_bpp < 0)
>  		goto fail;
>  
> +encoder_retry:
>  	/* Pass our mode to the connectors and the CRTC to give them a chance to
>  	 * adjust it according to limitations or connector properties, and also
>  	 * a chance to reject the mode entirely.
> @@ -7714,10 +7733,23 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>  		}
>  	}
>  
> -	if (!(intel_crtc_compute_config(crtc, pipe_config))) {
> +	ret = intel_crtc_compute_config(crtc, pipe_config);
> +	if (ret < 0) {
>  		DRM_DEBUG_KMS("CRTC fixup failed\n");
>  		goto fail;
>  	}
> +
> +	if (ret == RETRY) {
> +		if (WARN(!retry, "loop in pipe configuration computation\n")) {
> +			ret = -EINVAL;
> +			goto fail;

Isn't it possible that intel_dp_compute_config increases pipe_bpp when
it forces pipe_bpp to what the firmware has set? In that case could hit
this WARN.

> +		}
> +
> +		DRM_DEBUG_KMS("CRTC bw constrained, retrying\n");
> +		retry = false;
> +		goto encoder_retry;
> +	}
> +
>  	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
>  
>  	pipe_config->dither = pipe_config->pipe_bpp != plane_bpp;
> @@ -7727,7 +7759,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>  	return pipe_config;
>  fail:
>  	kfree(pipe_config);
> -	return ERR_PTR(-EINVAL);
> +	return ERR_PTR(ret);
>  }
>  
>  /* Computes which crtcs are affected and sets the relevant bits in the mask. For
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index f40b43f..c14afc6 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -211,6 +211,13 @@ struct intel_crtc_config {
>  	/* Controls for the clock computation, to override various stages. */
>  	bool clock_set;
>  
> +	/*
> +	 * crtc bandwidth limit, don't increase pipe bpp or clock if not really
> +	 * required. This is set in the 2nd loop of calling encoder's
> +	 * ->compute_config if the first pick doesn't work out.
> +	 */
> +	bool bw_constrained;
> +
>  	/* Settings for the intel dpll used on pretty much everything but
>  	 * haswell. */
>  	struct dpll {
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index a8273c7..3942041 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -784,6 +784,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>  	int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2;
> +	int desired_bpp;
>  
>  	if (intel_hdmi->color_range_auto) {
>  		/* See CEA-861-E - 5.1 Default Encoding Parameters */
> @@ -808,16 +809,21 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>  	 */
>  	if (pipe_config->pipe_bpp > 8*3 && clock_12bpc < 225000
>  	    && HAS_PCH_SPLIT(dev)) {
> -		DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
> -		pipe_config->pipe_bpp = 12*3;
> +		DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
> +		desired_bpp = 12*3;
>  
>  		/* Need to adjust the port link by 1.5x for 12bpc. */
>  		adjusted_mode->clock = clock_12bpc;
>  		pipe_config->pixel_target_clock =
>  			pipe_config->requested_mode.clock;
>  	} else {
> -		DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
> -		pipe_config->pipe_bpp = 8*3;
> +		DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
> +		desired_bpp = 8*3;
> +	}
> +
> +	if (!pipe_config->bw_constrained) {
> +		DRM_DEBUG_KMS("forcing pipe bpc to %i for HDMI\n", desired_bpp);
> +		pipe_config->pipe_bpp = desired_bpp;
>  	}
>  
>  	if (adjusted_mode->clock > 225000) {
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 094f3c5..c426581 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -331,7 +331,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
>  	else
>  		lvds_bpp = 6*3;
>  
> -	if (lvds_bpp != pipe_config->pipe_bpp) {
> +	if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) {
>  		DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
>  			      pipe_config->pipe_bpp, lvds_bpp);
>  		pipe_config->pipe_bpp = lvds_bpp;

  reply	other threads:[~2013-04-29 14:02 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-19  9:24 [PATCH 00/15] high-bpp fixes and fdi auto dithering Daniel Vetter
2013-04-19  9:24 ` [PATCH 01/15] drm/i915: fixup 12bpc hdmi dotclock handling Daniel Vetter
2013-04-23 15:02   ` Ville Syrjälä
2013-04-23 15:37     ` Daniel Vetter
2013-04-19  9:24 ` [PATCH 02/15] drm/i915: Disable high-bpc on pre-1.4 EDID screens Daniel Vetter
2013-04-23 15:07   ` Ville Syrjälä
2013-04-24 10:54     ` Daniel Vetter
2013-04-19  9:24 ` [PATCH 03/15] drm/i915: force bpp for eDP panels Daniel Vetter
2013-04-19 20:31   ` [PATCH] " Daniel Vetter
2013-04-19  9:24 ` [PATCH 04/15] drm/i915: drop adjusted_mode from *_set_pipeconf functions Daniel Vetter
2013-04-23 15:12   ` Ville Syrjälä
2013-04-19  9:24 ` [PATCH 05/15] drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv Daniel Vetter
2013-04-19 16:39   ` Jesse Barnes
2013-04-19 18:17     ` [PATCH] " Daniel Vetter
2013-04-19 18:39       ` Jesse Barnes
2013-04-19 19:29         ` Daniel Vetter
2013-04-23 15:27       ` Ville Syrjälä
2013-04-23 20:39         ` Daniel Vetter
2013-04-23 22:27           ` Daniel Vetter
2013-04-24 11:07             ` Ville Syrjälä
2013-04-23 22:30         ` Daniel Vetter
2013-04-24 11:11           ` Ville Syrjälä
2013-04-24 12:57             ` Daniel Vetter
2013-04-24 13:07               ` Ville Syrjälä
2013-04-19  9:24 ` [PATCH 06/15] drm/i915: allow high-bpc modes on DP Daniel Vetter
2013-04-29 10:16   ` Imre Deak
2013-04-19  9:24 ` [PATCH 07/15] drm/i915: Fixup non-24bpp support for VGA screens on Haswell Daniel Vetter
2013-04-24 11:12   ` Ville Syrjälä
2013-04-24 12:50     ` Daniel Vetter
2013-04-19  9:24 ` [PATCH 08/15] drm/i915: move intel_crtc->fdi_lanes to pipe_config Daniel Vetter
2013-04-29 10:17   ` Imre Deak
2013-04-19  9:24 ` [PATCH 09/15] drm/i915: hw state readout support for pipe_config->fdi_lanes Daniel Vetter
2013-04-24 11:23   ` Ville Syrjälä
2013-04-24 12:49     ` Daniel Vetter
2013-04-24 13:30     ` [PATCH] " Daniel Vetter
2013-04-29 10:22       ` Imre Deak
2013-04-29 17:33         ` [PATCH] drm/i915: put the right cpu_transcoder into pipe_config for hw state readout Daniel Vetter
2013-04-29 17:33         ` [PATCH] drm/i915: hw state readout support for pipe_config->fdi_lanes Daniel Vetter
2013-04-19  9:24 ` [PATCH 10/15] drm/i915: split up fdi_set_m_n into computation and hw setup Daniel Vetter
2013-04-24 11:26   ` Ville Syrjälä
2013-04-19  9:24 ` [PATCH 11/15] drm/i915: compute fdi lane config earlier Daniel Vetter
2013-04-29 12:13   ` Imre Deak
2013-04-19  9:24 ` [PATCH 12/15] drm/i915: Split up ironlake_check_fdi_lanes Daniel Vetter
2013-04-29 12:19   ` Imre Deak
2013-04-19  9:24 ` [PATCH 13/15] drm/i915: move fdi lane configuration checks ahead Daniel Vetter
2013-04-22 10:32   ` Ville Syrjälä
2013-04-22 15:13     ` [PATCH] " Daniel Vetter
2013-04-29 12:31       ` Imre Deak
2013-04-29 17:34         ` Daniel Vetter
2013-04-19  9:24 ` [PATCH 14/15] drm/i915: don't count cpu ports for fdi B/C lane sharing Daniel Vetter
2013-04-29 13:00   ` Imre Deak
2013-04-19  9:24 ` [PATCH 15/15] drm/i915: implement fdi auto-dithering Daniel Vetter
2013-04-29 14:02   ` Imre Deak [this message]
2013-04-29 14:43     ` Daniel Vetter
2013-04-29 14:59       ` Imre Deak
2013-04-29 19:35         ` Daniel Vetter
2013-04-19 15:05 ` [PATCH 00/15] high-bpp fixes and fdi auto dithering Chris Wilson
2013-04-25 10:28 ` Jani Nikula
2013-04-29 19:51   ` Daniel Vetter

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=1367244140.6390.66.camel@intelbox \
    --to=imre.deak@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=intel-gfx@lists.freedesktop.org \
    /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