From patchwork Wed Jun 22 01:49:34 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keng-Yu Lin X-Patchwork-Id: 101450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 37707B6F54 for ; Wed, 22 Jun 2011 22:28:16 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1QZMXM-00026D-1x; Wed, 22 Jun 2011 12:28:04 +0000 Received: from mail-iw0-f177.google.com ([209.85.214.177]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1QZCZf-0007bq-I4 for kernel-team@lists.ubuntu.com; Wed, 22 Jun 2011 01:49:47 +0000 Received: by iwn35 with SMTP id 35so345651iwn.8 for ; Tue, 21 Jun 2011 18:49:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:cc:subject:date:message-id :x-mailer:in-reply-to:references; bh=b/PdGW1BDcwP+MQ0pgtAqQAWM2clROGPClTWllBxLfQ=; b=pvAuR5OhVF1g89G0No6GfZ1CiixxYYlktlfc1k/iiQDAalzJlIP8iweAKuHcabqbKb rMy1YZ3Fnmc5zEJGRTHCuE/en3Uke7P2Hgpb7bWbJxSSuUoWKJMUvcDhz7BYwZFxWCmg dU3AlGV1daFsa/YBqsVzgi7JQCYr6cp7Ab1JI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; b=eUYoAaEiarbcaBx52ZHEPK/xQiosYuKM1QYD5NDKxkxtoqsJ7eOiw8QpCHjkZ9pv1N SA5nGI7JgQ1V2Bd/0VPak988oDJZwR0cGeYs8wu4b2zcS7rYOxT5HJW8auOhPMZFEEdy zYnKVYvaG5sYUdOaxBiG/aoUUnmJdpQ0TJMhQ= Received: by 10.42.82.75 with SMTP id c11mr131657icl.92.1308707386575; Tue, 21 Jun 2011 18:49:46 -0700 (PDT) Received: from localhost (61-224-220-248.dynamic.hinet.net [61.224.220.248]) by mx.google.com with ESMTPS id v16sm54345ibe.0.2011.06.21.18.49.43 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 21 Jun 2011 18:49:45 -0700 (PDT) From: Keng-Yu Lin To: kernel-team@lists.ubuntu.com Subject: [PATCH] drm/i915: disable PCH ports if needed when disabling a CRTC Date: Wed, 22 Jun 2011 09:49:34 +0800 Message-Id: <1308707374-15692-2-git-send-email-kengyu@canonical.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1308707374-15692-1-git-send-email-kengyu@canonical.com> References: <1308707374-15692-1-git-send-email-kengyu@canonical.com> X-Mailman-Approved-At: Wed, 22 Jun 2011 12:28:02 +0000 Cc: rex.cc.tsai@canonical.com, sylee@canonical.com, kent.lin@canonical.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Keng-Yu Lin BugLink: http://bugs.launchpad.net/bugs/791752 This patch is tailored to apply on top of Ubuntu Natty kernel. commit 47a05eca72991039e788b25232061f9c9df9ec23 Author: Jesse Barnes Date: Mon Feb 7 13:46:40 2011 -0800 drm/i915: disable PCH ports if needed when disabling a CRTC Disable any PCH ports associated with a pipe when disabling it. This should prevent transcoder disable failures due to ports still being on. Signed-off-by: Jesse Barnes [ickle: introduce *_PIPE_ENABLED() macro] Signed-off-by: Chris Wilson Signed-off-by: Keng-Yu Lin Acked-by: Tim Gardner Acked-by: Seth Forshee Acked-by: Leann Ogasawara --- drivers/gpu/drm/i915/i915_reg.h | 15 ++++++++ drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 12c547a..e7cb5df 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1444,6 +1444,7 @@ #define LVDS_PORT_EN (1 << 31) /* Selects pipe B for LVDS data. Must be set on pre-965. */ #define LVDS_PIPEB_SELECT (1 << 30) +#define LVDS_PIPE_MASK (1 << 30) /* LVDS dithering flag on 965/g4x platform */ #define LVDS_ENABLE_DITHER (1 << 25) /* Enable border for unscaled (or aspect-scaled) display */ @@ -1479,6 +1480,9 @@ #define LVDS_B0B3_POWER_DOWN (0 << 2) #define LVDS_B0B3_POWER_UP (3 << 2) +#define LVDS_PIPE_ENABLED(V, P) \ + (((V) & (LVDS_PIPE_MASK | LVDS_PORT_EN)) == ((P) << 30 | LVDS_PORT_EN)) + /* Video Data Island Packet control */ #define VIDEO_DIP_DATA 0x61178 #define VIDEO_DIP_CTL 0x61170 @@ -2067,6 +2071,10 @@ #define DP_PORT_EN (1 << 31) #define DP_PIPEB_SELECT (1 << 30) +#define DP_PIPE_MASK (1 << 30) + +#define DP_PIPE_ENABLED(V, P) \ + (((V) & (DP_PIPE_MASK | DP_PORT_EN)) == ((P) << 30 | DP_PORT_EN)) /* Link training mode - select a suitable mode for each stage */ #define DP_LINK_TRAIN_PAT_1 (0 << 28) @@ -3148,11 +3156,15 @@ #define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) +#define ADPA_PIPE_ENABLED(V, P) \ + (((V) & (ADPA_TRANS_SELECT_MASK | ADPA_DAC_ENABLE)) == ((P) << 30 | ADPA_DAC_ENABLE)) + /* or SDVOB */ #define HDMIB 0xe1140 #define PORT_ENABLE (1 << 31) #define TRANSCODER_A (0) #define TRANSCODER_B (1 << 30) +#define TRANSCODER_MASK (1 << 30) #define COLOR_FORMAT_8bpc (0) #define COLOR_FORMAT_12bpc (3 << 26) #define SDVOB_HOTPLUG_ENABLE (1 << 23) @@ -3168,6 +3180,9 @@ #define HSYNC_ACTIVE_HIGH (1 << 3) #define PORT_DETECTED (1 << 2) +#define HDMI_PIPE_ENABLED(V, P) \ + (((V) & (TRANSCODER_MASK | PORT_ENABLE)) == ((P) << 30 | PORT_ENABLE)) + /* PCH SDVOB multiplex with HDMIB */ #define PCH_SDVOB HDMIB diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 841558b..88dc3fe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1058,6 +1058,53 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) } } +static void disable_pch_dp(struct drm_i915_private *dev_priv, + enum pipe pipe, int reg) +{ + u32 val = I915_READ(reg); + if (DP_PIPE_ENABLED(val, pipe)) + I915_WRITE(reg, val & ~DP_PORT_EN); +} + +static void disable_pch_hdmi(struct drm_i915_private *dev_priv, + enum pipe pipe, int reg) +{ + u32 val = I915_READ(reg); + if (HDMI_PIPE_ENABLED(val, pipe)) + I915_WRITE(reg, val & ~PORT_ENABLE); +} + +/* Disable any ports connected to this transcoder */ +static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + u32 reg, val; + + val = I915_READ(PCH_PP_CONTROL); + I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); + + disable_pch_dp(dev_priv, pipe, PCH_DP_B); + disable_pch_dp(dev_priv, pipe, PCH_DP_C); + disable_pch_dp(dev_priv, pipe, PCH_DP_D); + + reg = PCH_ADPA; + val = I915_READ(reg); + if (ADPA_PIPE_ENABLED(val, pipe)) + I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); + + reg = PCH_LVDS; + val = I915_READ(reg); + if (LVDS_PIPE_ENABLED(val, pipe)) { + I915_WRITE(reg, val & ~LVDS_PORT_EN); + POSTING_READ(reg); + udelay(100); + } + + disable_pch_hdmi(dev_priv, pipe, HDMIB); + disable_pch_hdmi(dev_priv, pipe, HDMIC); + disable_pch_hdmi(dev_priv, pipe, HDMID); +} + static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) { struct drm_device *dev = crtc->dev; @@ -2356,14 +2403,12 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) POSTING_READ(reg); udelay(100); - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - temp = I915_READ(PCH_LVDS); - if (temp & LVDS_PORT_EN) { - I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN); - POSTING_READ(PCH_LVDS); - udelay(100); - } - } + /* This is a horrible layering violation; we should be doing this in + * the connector/encoder ->prepare instead, but we don't always have + * enough information there about the config to know whether it will + * actually be necessary or just cause undesired flicker. + */ + intel_disable_pch_ports(dev_priv, pipe); /* disable PCH transcoder */ reg = TRANSCONF(plane);