[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