From patchwork Tue Jan 4 23:09:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barnes X-Patchwork-Id: 451971 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p04NERKF029304 for ; Tue, 4 Jan 2011 23:14:48 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 876279EEDE for ; Tue, 4 Jan 2011 15:14:27 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from cpoproxy3-pub.bluehost.com (cpoproxy3-pub.bluehost.com [67.222.54.6]) by gabe.freedesktop.org (Postfix) with SMTP id 979BB9E9E5 for ; Tue, 4 Jan 2011 15:09:49 -0800 (PST) Received: (qmail 7278 invoked by uid 0); 4 Jan 2011 23:09:49 -0000 Received: from unknown (HELO box514.bluehost.com) (74.220.219.114) by cpoproxy3.bluehost.com with SMTP; 4 Jan 2011 23:09:49 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=virtuousgeek.org; h=Received:From:To:Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References:X-Identified-User; b=OZtF/SmFitEP+cKCFnjR+lCrEQCYLmdyszIiuz/yvkXy3BlaIqxfthbOwanhWNLsHHFkPoeBBvbx2MfkW3Ut/vm2bzIg2gv0smlwCgyOwBdnXLb8am7GIsG3b+x0fTJS; Received: from c-67-174-193-198.hsd1.ca.comcast.net ([67.174.193.198] helo=localhost.localdomain) by box514.bluehost.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1PaG0g-0002nM-Cf; Tue, 04 Jan 2011 16:09:46 -0700 From: Jesse Barnes To: intel-gfx@lists.freedesktop.org Date: Tue, 4 Jan 2011 15:09:36 -0800 Message-Id: <1294182579-6643-9-git-send-email-jbarnes@virtuousgeek.org> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1294182579-6643-1-git-send-email-jbarnes@virtuousgeek.org> References: <1294182579-6643-1-git-send-email-jbarnes@virtuousgeek.org> X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 67.174.193.198 authed with jbarnes@virtuousgeek.org} Subject: [Intel-gfx] [PATCH 09/12] drm/i915: add transcoder enable/disable functions X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 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 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 04 Jan 2011 23:14:48 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 17005c3..e68c9be 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1086,6 +1086,84 @@ static void assert_pll(struct drm_i915_private *dev_priv, enum pipe pipe, #define assert_pll_enabled(d, p) assert_pll(d, p, on) #define assert_pll_disabled(d, p) assert_pll(d, p, off) +/* For ILK+ */ +static void assert_pch_pll(struct drm_i915_private *dev_priv, enum pipe pipe, + enum state state) +{ + int reg; + u32 val; + bool cur_state; + + reg = PCH_DPLL(pipe); + val = I915_READ(reg); + cur_state = !!(val & DPLL_VCO_ENABLE); + WARN(cur_state != state, + "PCH PLL state assertion failure (expected %s, current %s)\n", + state_string(state), state_string(cur_state)); +} +#define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, on) +#define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, off) + +static void assert_fdi_tx(struct drm_i915_private *dev_priv, enum pipe pipe, + enum state state) +{ + int reg; + u32 val; + bool cur_state; + + reg = FDI_TX_CTL(pipe); + val = I915_READ(reg); + cur_state = !!(val & FDI_TX_ENABLE); + WARN(cur_state != state, + "FDI TX state assertion failure (expected %s, current %s)\n", + state_string(state), state_string(cur_state)); +} +#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, on) +#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, off) + +static void assert_fdi_rx(struct drm_i915_private *dev_priv, enum pipe pipe, + enum state state) +{ + int reg; + u32 val; + bool cur_state; + + reg = FDI_RX_CTL(pipe); + val = I915_READ(reg); + cur_state = !!(val & FDI_RX_ENABLE); + WARN(cur_state != state, + "FDI RX state assertion failure (expected %s, current %s)\n", + state_string(state), state_string(cur_state)); +} +#define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, on) +#define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, off) + +static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + int reg; + u32 val; + + /* ILK FDI PLL is always enabled */ + if (dev_priv->info->gen == 5) + return; + + reg = FDI_TX_CTL(pipe); + val = I915_READ(reg); + WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); +} + +static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + int reg; + u32 val; + + reg = FDI_RX_CTL(pipe); + val = I915_READ(reg); + WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); +} + static void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -1303,10 +1381,59 @@ static void intel_disable_pch_pll(struct drm_i915_private *dev_priv, udelay(200); } +static void intel_enable_transcoder(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + int reg; + u32 val; + + /* PCH only available on ILK+ */ + BUG_ON(dev_priv->info->gen < 5); + + /* Make sure PCH DPLL is enabled */ + assert_pch_pll_enabled(dev_priv, pipe); + + /* FDI must be feeding us bits for PCH ports */ + assert_fdi_tx_enabled(dev_priv, pipe); + assert_fdi_rx_enabled(dev_priv, pipe); + + reg = TRANSCONF(pipe); + val = I915_READ(reg); + /* + * make the BPC in transcoder be consistent with + * that in pipeconf reg. + */ + val &= ~PIPE_BPC_MASK; + val |= I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK; + I915_WRITE(reg, val | TRANS_ENABLE); + if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) + DRM_ERROR("failed to enable transcoder %d\n", pipe); +} + +static void intel_disable_transcoder(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + int reg; + u32 val; + + /* FDI relies on the transcoder */ + assert_fdi_tx_disabled(dev_priv, pipe); + assert_fdi_rx_disabled(dev_priv, pipe); + + reg = TRANSCONF(pipe); + val = I915_READ(reg); + val &= ~TRANS_ENABLE; + I915_WRITE(reg, val); + /* wait for PCH transcoder off, transcoder state */ + if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) + DRM_ERROR("failed to disable transcoder\n"); +} + /** * intel_enable_pipe - enable a pipe, assertiing requirements * @dev_priv: i915 private structure * @pipe: pipe to enable + * @pch_port: on ILK+, is this pipe driving a PCH port or not * * Enable @pipe, making sure that various hardware specific requirements * are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc. @@ -1316,7 +1443,8 @@ static void intel_disable_pch_pll(struct drm_i915_private *dev_priv, * Will wait until the pipe is actually running (i.e. first vblank) before * returning. */ -static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, + bool pch_port) { int reg; u32 val; @@ -1328,6 +1456,14 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) */ if (!HAS_PCH_SPLIT(dev_priv->dev)) assert_pll_enabled(dev_priv, pipe); + else { + if (pch_port) { + /* if driving the PCH, we need FDI enabled */ + assert_fdi_rx_pll_enabled(dev_priv, pipe); + assert_fdi_tx_pll_enabled(dev_priv, pipe); + } + /* FIXME: assert CPU port conditions for SNB+ */ + } reg = PIPECONF(pipe); val = I915_READ(reg); @@ -2390,6 +2526,31 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) atomic_read(&obj->pending_flip) == 0); } +static bool intel_crtc_driving_pch(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; + + /* + * If there's a non-PCH eDP on this crtc, it must be DP_A, and that + * must be driven by its own crtc; no sharing is possible. + */ + list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { + if (encoder->base.crtc != crtc) + continue; + + switch (encoder->type) { + case INTEL_OUTPUT_EDP: + if (!intel_encoder_is_pch_edp(&encoder->base)) + return false; + continue; + } + } + + return true; +} + static void ironlake_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -2398,6 +2559,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; u32 reg, temp; + bool is_pch_port; if (intel_crtc->active) return; @@ -2428,7 +2590,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) dev_priv->pch_pf_size); } - intel_enable_pipe(dev_priv, pipe); + is_pch_port = intel_crtc_driving_pch(crtc); + + intel_enable_pipe(dev_priv, pipe, is_pch_port); intel_enable_plane(dev_priv, plane, pipe); /* For PCH output, training FDI link */ @@ -2497,18 +2661,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(reg, temp); } - /* enable PCH transcoder */ - reg = TRANSCONF(pipe); - temp = I915_READ(reg); - /* - * make the BPC in transcoder be consistent with - * that in pipeconf reg. - */ - temp &= ~PIPE_BPC_MASK; - temp |= I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK; - I915_WRITE(reg, temp | TRANS_ENABLE); - if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) - DRM_ERROR("failed to enable transcoder %d\n", pipe); + intel_enable_transcoder(dev_priv, pipe); intel_crtc_load_lut(crtc); intel_update_fbc(dev); @@ -2597,15 +2750,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) } } - /* disable PCH transcoder */ - reg = TRANSCONF(plane); - temp = I915_READ(reg); - if (temp & TRANS_ENABLE) { - I915_WRITE(reg, temp & ~TRANS_ENABLE); - /* wait for PCH transcoder off, transcoder state */ - if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) - DRM_ERROR("failed to disable transcoder\n"); - } + intel_disable_transcoder(dev_priv, pipe); if (HAS_PCH_CPT(dev)) { /* disable TRANS_DP_CTL */ @@ -2707,7 +2852,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_update_watermarks(dev); intel_enable_pll(dev_priv, pipe); - intel_enable_pipe(dev_priv, pipe); + intel_enable_pipe(dev_priv, pipe, false); intel_enable_plane(dev_priv, plane, pipe); intel_crtc_load_lut(crtc); @@ -4681,7 +4826,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(PIPECONF(pipe), pipeconf); POSTING_READ(PIPECONF(pipe)); if (!HAS_PCH_SPLIT(dev)) - intel_enable_pipe(dev_priv, pipe); + intel_enable_pipe(dev_priv, pipe, false); intel_wait_for_vblank(dev, pipe);