[Intel-gfx] [PATCH 50/58] drm/i915: compute masks of crtcs affected in set_mode

Jesse Barnes jbarnes at virtuousgeek.org
Wed Sep 5 20:07:22 CEST 2012


On Sun, 19 Aug 2012 21:13:07 +0200
Daniel Vetter <daniel.vetter at ffwll.ch> wrote:

> This is definetely a bit more generic than currently required, but
> if we keep track of all crtcs that need to be disabled/enable (because
> they loose an encoder or something similar), crtcs that get completely
> disabled and those that we need to do an actual mode change on nicely
> prepares us for global modeset operations on multiple crtcs.
> 
> The only big thing missing here would be a global resource allocation
> step (for e.g. pch plls), which would equally frob these bitmasks if
> e.g. a crtc only needs a new pll.
> 
> These masks aren't yet put to use in this patch, this will follow in the
> next one.
> 
> v2-v5: Fix up the computations for good (hopefully).
> 
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 89 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 89 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c59569e..4334400 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6706,6 +6706,91 @@ fail:
>  	return ERR_PTR(-EINVAL);
>  }
>  
> +/* Computes which crtcs are affected and sets the relevant bits in the mask. For
> + * simplicity we use the crtc's pipe number (because it's easier to obtain). */
> +static void
> +intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
> +			     unsigned *prepare_pipes, unsigned *disable_pipes)
> +{
> +	struct intel_crtc *intel_crtc;
> +	struct drm_device *dev = crtc->dev;
> +	struct intel_encoder *encoder;
> +	struct intel_connector *connector;
> +	struct drm_crtc *tmp_crtc;
> +
> +	*disable_pipes = *modeset_pipes = *prepare_pipes = 0;
> +
> +	/* Check which crtcs have changed outputs connected to them, these need
> +	 * to be part of the prepare_pipes mask. We don't (yet) support global
> +	 * modeset across multiple crtcs, so modeset_pipes will only have one
> +	 * bit set at most. */
> +	list_for_each_entry(connector, &dev->mode_config.connector_list,
> +			    base.head) {
> +		if (connector->base.encoder == &connector->new_encoder->base)
> +			continue;
> +
> +		if (connector->base.encoder) {
> +			tmp_crtc = connector->base.encoder->crtc;
> +
> +			*prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe;
> +		}
> +
> +		if (connector->new_encoder)
> +			*prepare_pipes |=
> +				1 << connector->new_encoder->new_crtc->pipe;
> +	}
> +
> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> +			    base.head) {
> +		if (encoder->base.crtc == &encoder->new_crtc->base)
> +			continue;
> +
> +		if (encoder->base.crtc) {
> +			tmp_crtc = encoder->base.crtc;
> +
> +			*prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe;
> +		}
> +
> +		if (encoder->new_crtc)
> +			*prepare_pipes |= 1 << encoder->new_crtc->pipe;
> +	}
> +
> +	/* Check for any pipes that will be fully disabled ... */
> +	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
> +			    base.head) {
> +		bool used = false;
> +
> +		/* Don't try to disable disabled crtcs. */
> +		if (!intel_crtc->base.enabled)
> +			continue;
> +
> +		list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> +				    base.head) {
> +			if (encoder->new_crtc == intel_crtc)
> +				used = true;
> +		}
> +
> +		if (!used)
> +			*disable_pipes |= 1 << intel_crtc->pipe;
> +	}
> +
> +
> +	/* set_mode is also used to update properties on life display pipes. */
> +	intel_crtc = to_intel_crtc(crtc);
> +	if (!*disable_pipes && crtc->enabled)
> +		*prepare_pipes |= 1 << intel_crtc->pipe;
> +
> +	/* We only support modeset on one single crtc, hence we need to do that
> +	 * only for the passed in crtc iff we change anything else than just
> +	 * disable crtcs. */
> +	if (*prepare_pipes)
> +		*modeset_pipes |= 1 << intel_crtc->pipe;
> +
> +	/* ... and mask these out. */
> +	*modeset_pipes &= ~(*disable_pipes);
> +	*prepare_pipes &= ~(*disable_pipes);
> +}
> +
>  bool intel_set_mode(struct drm_crtc *crtc,
>  		    struct drm_display_mode *mode,
>  		    int x, int y, struct drm_framebuffer *fb)
> @@ -6715,8 +6800,12 @@ bool intel_set_mode(struct drm_crtc *crtc,
>  	struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
>  	struct drm_encoder_helper_funcs *encoder_funcs;
>  	struct drm_encoder *encoder;
> +	unsigned disable_pipe, prepare_pipes, modeset_pipes;
>  	bool ret = true;
>  
> +	intel_modeset_affected_pipes(crtc, &modeset_pipes,
> +				     &prepare_pipes, &disable_pipe);
> +
>  	intel_modeset_commit_output_state(dev);
>  
>  	crtc->enabled = drm_helper_crtc_in_use(crtc);

Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list