From patchwork Wed May 29 15:52:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 2631051 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 05CFB40077 for ; Wed, 29 May 2013 15:52:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 03CE0E649D for ; Wed, 29 May 2013 08:52:41 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ee0-f41.google.com (mail-ee0-f41.google.com [74.125.83.41]) by gabe.freedesktop.org (Postfix) with ESMTP id 28611E5CB1 for ; Wed, 29 May 2013 08:52:32 -0700 (PDT) Received: by mail-ee0-f41.google.com with SMTP id d4so5412912eek.14 for ; Wed, 29 May 2013 08:52:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=rRjokKXnoR6DMHUorGGIvSnrOX4V34sM4SOtus5G2sE=; b=fJJ0YQr49/Bdb+f7AWm9Rcjy5EVO48//zZpC4ckL2w1/2oogjiZgmXGCUGAzJOQQQ5 +v++rOSmuozzU6159uYNKYObLORbyUFbIiA5oRS5lc1kkN+BNAVZAeIIHFvD0NhwvWl6 e6Qo1Am7RBpXfHIGPnaB3WWO5YS0ceFZ0rJ5M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=rRjokKXnoR6DMHUorGGIvSnrOX4V34sM4SOtus5G2sE=; b=fdKk2Xkirv5xj8fPqbCmbqLdyIu0wCoLdCoTdHvIAcjAEsCyfSZO3eYtnkPU9rTCN1 IgtIetsR5YdrrA8Hu1E7rVe4zU3u9bDls74JRZ2drk8qEeecY7SrRwldkPprkykkgRLG Jmch0sq3gVd5Q1WmrKtUsqpjXUG20ZT0y0TFASJDSO7ULJ4W2rThaGgTdosj7/Kx82xo Td70GU5zXExzXp8a0Tls55BKo4d2QJPsyv6peX1UEYfz71pO9cJKJ/iqTc8GGpgpBeD/ YBo/R5l9OP5uezYLyquEpNk80mUZQdbPl1hS9N/Zifil9VurSVyf9XeHkVcl1ahXUWnn qqyQ== X-Received: by 10.14.209.135 with SMTP id s7mr4372354eeo.57.1369842751093; Wed, 29 May 2013 08:52:31 -0700 (PDT) Received: from bremse.ffwll.local (178-83-130-250.dynamic.hispeed.ch. [178.83.130.250]) by mx.google.com with ESMTPSA id s8sm54792488eeo.4.2013.05.29.08.52.29 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 29 May 2013 08:52:30 -0700 (PDT) From: Daniel Vetter To: Intel Graphics Development Date: Wed, 29 May 2013 17:52:24 +0200 Message-Id: <1369842744-22820-1-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1369749619-15890-1-git-send-email-daniel.vetter@ffwll.ch> References: <1369749619-15890-1-git-send-email-daniel.vetter@ffwll.ch> X-Gm-Message-State: ALoCoQmauQiYAIw/PmtJjvX+u0zhFPzexvJdoVclY4R78yCFPAtn+PFbwjGjI8ILMjFLvovqa4RP Cc: Daniel Vetter , stable@vger.kernel.org Subject: [Intel-gfx] [PATCH] drm/i915: consolidate and tighten encoder cloning checks X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org 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. Cc: Chris Wilson Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 65 ++++++++++++++---------------------- 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, 25 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 14bb844..4cfce96 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); @@ -8834,6 +8818,7 @@ static void intel_setup_outputs(struct drm_device *dev) encoder->base.possible_crtcs = encoder->crtc_mask; encoder->base.possible_clones = intel_encoder_clones(encoder); + printk("possible encoder clones 0x%08x\n", encoder->base.possible_clones); } intel_init_pch_refclk(dev); 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;