[Intel-gfx] [PATCH] drm/i915: consolidate and tighten encoder cloning checks
Daniel Vetter
daniel at ffwll.ch
Wed Jun 5 12:37:46 CEST 2013
On Thu, May 30, 2013 at 03:04:25PM +0200, Daniel Vetter wrote:
> Only lvds/tv did actually check for cloning or not, but many more
> places should.
>
> Notices because my ivb tried to enable both cpu edp and vga on the
> first crtc - the resulting confusion between has_pch_encoder,
> has_dp_encoder but not actually being a pch dp encoder resulting in
> hilarity (hitting a BUG).
>
> We _really_ need an igt to random-walk our modeset space more
> exhaustively.
>
> I haven't figured out yet why exactly we see this configuration
> request from the setcrtc ioctl, but I can reliably reproduce it by
> unplugging a bunch of connectors and restarting X.
>
> Strangely restarting X again fixes things ...
>
> v2: Kill intel_encoder_check_is_cloned, spotted by Paulo.
>
> v3: Drop the now unused pipe param.
>
> v4: Kill the stray printk Chris spotted.
>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
Patch merged to dinq (imo a bit late for -fixes) with Chris' r-b.
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 64 ++++++++++++++----------------------
> drivers/gpu/drm/i915/intel_drv.h | 1 -
> drivers/gpu/drm/i915/intel_lvds.c | 3 --
> drivers/gpu/drm/i915/intel_tv.c | 3 --
> 4 files changed, 24 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 14bb844..ba33a82 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5843,27 +5843,9 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
> struct drm_device *dev = crtc->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> - int pipe = intel_crtc->pipe;
> int plane = intel_crtc->plane;
> - int num_connectors = 0;
> - bool is_cpu_edp = false;
> - struct intel_encoder *encoder;
> int ret;
>
> - for_each_encoder_on_crtc(dev, crtc, encoder) {
> - switch (encoder->type) {
> - case INTEL_OUTPUT_EDP:
> - if (enc_to_dig_port(&encoder->base)->port == PORT_A)
> - is_cpu_edp = true;
> - break;
> - }
> -
> - num_connectors++;
> - }
> -
> - WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
> - num_connectors, pipe_name(pipe));
> -
> if (!intel_ddi_pll_mode_set(crtc))
> return -EINVAL;
>
> @@ -7523,28 +7505,6 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = {
> .load_lut = intel_crtc_load_lut,
> };
>
> -bool intel_encoder_check_is_cloned(struct intel_encoder *encoder)
> -{
> - struct intel_encoder *other_encoder;
> - struct drm_crtc *crtc = &encoder->new_crtc->base;
> -
> - if (WARN_ON(!crtc))
> - return false;
> -
> - list_for_each_entry(other_encoder,
> - &crtc->dev->mode_config.encoder_list,
> - base.head) {
> -
> - if (&other_encoder->new_crtc->base != crtc ||
> - encoder == other_encoder)
> - continue;
> - else
> - return true;
> - }
> -
> - return false;
> -}
> -
> static bool intel_encoder_crtc_ok(struct drm_encoder *encoder,
> struct drm_crtc *crtc)
> {
> @@ -7713,6 +7673,25 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
> pipe_config->pch_pfit.size);
> }
>
> +static bool check_encoder_cloning(struct drm_crtc *crtc)
> +{
> + int num_encoders = 0;
> + bool uncloneable_encoders = false;
> + struct intel_encoder *encoder;
> +
> + list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list,
> + base.head) {
> + if (&encoder->new_crtc->base != crtc)
> + continue;
> +
> + num_encoders++;
> + if (!encoder->cloneable)
> + uncloneable_encoders = true;
> + }
> +
> + return !(num_encoders > 1 && uncloneable_encoders);
> +}
> +
> static struct intel_crtc_config *
> intel_modeset_pipe_config(struct drm_crtc *crtc,
> struct drm_framebuffer *fb,
> @@ -7725,6 +7704,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> int plane_bpp, ret = -EINVAL;
> bool retry = true;
>
> + if (!check_encoder_cloning(crtc)) {
> + DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> if (!pipe_config)
> return ERR_PTR(-ENOMEM);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 3db4b14..a844a05 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -627,7 +627,6 @@ extern void intel_crtc_load_lut(struct drm_crtc *crtc);
> extern void intel_crtc_update_dpms(struct drm_crtc *crtc);
> extern void intel_encoder_destroy(struct drm_encoder *encoder);
> extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode);
> -extern bool intel_encoder_check_is_cloned(struct intel_encoder *encoder);
> extern void intel_connector_dpms(struct drm_connector *, int mode);
> extern bool intel_connector_get_hw_state(struct intel_connector *connector);
> extern void intel_modeset_check_state(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 6554860..10c3d56 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -264,9 +264,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
> return false;
> }
>
> - if (intel_encoder_check_is_cloned(&lvds_encoder->base))
> - return false;
> -
> if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) ==
> LVDS_A3_POWER_UP)
> lvds_bpp = 8*3;
> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> index 7d11a5a..39debd8 100644
> --- a/drivers/gpu/drm/i915/intel_tv.c
> +++ b/drivers/gpu/drm/i915/intel_tv.c
> @@ -914,9 +914,6 @@ intel_tv_compute_config(struct intel_encoder *encoder,
> if (!tv_mode)
> return false;
>
> - if (intel_encoder_check_is_cloned(&intel_tv->base))
> - return false;
> -
> pipe_config->adjusted_mode.clock = tv_mode->clock;
> DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
> pipe_config->pipe_bpp = 8*3;
> --
> 1.7.11.7
>
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
More information about the Intel-gfx
mailing list