On Wed, 5 Oct 2011 10:25:21 -0700 Jesse Barnes <jbar...@virtuousgeek.org> wrote:
> Handle PLL allocation and transcoder select bits on CPT+. Updated patch that fixes the bug with VGA plus two HDMI. Was missing the composite sync bits in the FDI TX side (setting them everywhere here just to be safe). -- Jesse Barnes, Intel Open Source Technology Center From 3efb84701437f2d1eae3fb68c1259c2bb5a0c518 Mon Sep 17 00:00:00 2001 From: Jesse Barnes <jbar...@virtuousgeek.org> Date: Fri, 2 Sep 2011 15:28:39 -0700 Subject: [PATCH] drm/i915: more 3 pipe support Handle PLL allocation and transcoder select bits on CPT+. Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org> --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_crt.c | 13 +--- drivers/gpu/drm/i915/intel_display.c | 101 +++++++++++++++++++++------------- drivers/gpu/drm/i915/intel_drv.h | 3 + drivers/gpu/drm/i915/intel_hdmi.c | 10 +-- 5 files changed, 74 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7659075..b31f253 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3167,6 +3167,7 @@ #define FDI_LINK_TRAIN_NONE_IVB (3<<8) /* both Tx and Rx */ +#define FDI_COMPOSITE_SYNC (1<<11) #define FDI_LINK_TRAIN_AUTO (1<<10) #define FDI_SCRAMBLING_ENABLE (0<<7) #define FDI_SCRAMBLING_DISABLE (1<<7) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0979d88..da769e6 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -152,17 +152,12 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) adpa |= ADPA_VSYNC_ACTIVE_HIGH; - if (intel_crtc->pipe == 0) { - if (HAS_PCH_CPT(dev)) - adpa |= PORT_TRANS_A_SEL_CPT; - else + if (HAS_PCH_CPT(dev)) + adpa |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); + else if (intel_crtc->pipe == 0) adpa |= ADPA_PIPE_A_SELECT; - } else { - if (HAS_PCH_CPT(dev)) - adpa |= PORT_TRANS_B_SEL_CPT; - else + else adpa |= ADPA_PIPE_B_SELECT; - } if (!HAS_PCH_SPLIT(dev)) I915_WRITE(BCLRPAT(intel_crtc->pipe), 0); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 058dc05..e63a187 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -802,6 +802,9 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv, u32 val; bool cur_state; + if (pipe > 1) + return; + reg = PCH_DPLL(pipe); val = I915_READ(reg); cur_state = !!(val & DPLL_VCO_ENABLE); @@ -2366,6 +2369,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) temp = I915_READ(reg); temp &= ~FDI_RX_SYMBOL_LOCK; temp &= ~FDI_RX_BIT_LOCK; + temp |= FDI_COMPOSITE_SYNC; I915_WRITE(reg, temp); I915_READ(reg); udelay(150); @@ -2377,6 +2381,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) temp |= (intel_crtc->fdi_lanes - 1) << 19; temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_1; + temp |= FDI_COMPOSITE_SYNC; I915_WRITE(reg, temp | FDI_TX_ENABLE); reg = FDI_RX_CTL(pipe); @@ -2704,6 +2709,8 @@ static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) temp &= ~((0x7 << 19) | (0x7 << 16)); temp |= (intel_crtc->fdi_lanes - 1) << 19; temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; + if (HAS_PCH_CPT(dev)) + temp |= 1<<11; I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE); POSTING_READ(reg); @@ -2869,7 +2876,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; - u32 reg, temp; + u32 reg, temp, transc_sel; /* For PCH output, training FDI link */ dev_priv->display.fdi_link_train(crtc); @@ -2877,6 +2884,9 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) intel_enable_pch_pll(dev_priv, pipe); if (HAS_PCH_CPT(dev)) { + transc_sel = intel_crtc->use_pll_a ? TRANSC_DPLLA_SEL : + TRANSC_DPLLB_SEL; + /* Be sure PCH DPLL SEL is set */ temp = I915_READ(PCH_DPLL_SEL); if (pipe == 0 && (temp & TRANSA_DPLL_ENABLE) == 0) @@ -2884,7 +2894,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0) temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); else if (pipe == 2 && (temp & TRANSC_DPLL_ENABLE) == 0) - temp |= (TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL); + temp |= (TRANSC_DPLL_ENABLE | transc_sel); I915_WRITE(PCH_DPLL_SEL, temp); } @@ -3056,8 +3066,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); break; case 2: - /* FIXME: manage transcoder PLLs? */ - temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL); + /* C shares PLL A or B */ + temp &= ~(TRANSC_DPLL_ENABLE | TRANSB_DPLLB_SEL); break; default: BUG(); /* wtf */ @@ -3066,7 +3076,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) } /* disable PCH DPLL */ - intel_disable_pch_pll(dev_priv, pipe); + if (!intel_crtc->no_pll) + intel_disable_pch_pll(dev_priv, pipe); /* Switch from PCDclk to Rawclk */ reg = FDI_RX_CTL(pipe); @@ -5216,11 +5227,7 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) return dev_priv->lvds_ssc_freq * 1000; } - /* PCH ports use a 120 MHz refclk */ - if (!edp_encoder || intel_encoder_is_pch_edp(&edp_encoder->base)) - return 120000; - else - return 96000; + return 120000; } static int ironlake_crtc_mode_set(struct drm_crtc *crtc, @@ -5486,16 +5493,32 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, drm_mode_debug_printmodeline(mode); /* PCH eDP needs FDI, but CPU eDP does not */ - if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + if (!intel_crtc->no_pll && + (!has_edp_encoder || + intel_encoder_is_pch_edp(&has_edp_encoder->base))) { I915_WRITE(PCH_FP0(pipe), fp); I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); POSTING_READ(PCH_DPLL(pipe)); udelay(150); + } else { + if (dpll == (I915_READ(PCH_DPLL(0)) & 0x7fffffff) && + fp == I915_READ(PCH_FP0(0))) { + intel_crtc->use_pll_a = true; + DRM_DEBUG_KMS("using pipe a dpll\n"); + } else if (dpll == (I915_READ(PCH_DPLL(1)) & 0x7fffffff) && + fp == I915_READ(PCH_FP0(1))) { + intel_crtc->use_pll_a = false; + DRM_DEBUG_KMS("using pipe b dpll\n"); + } else + DRM_DEBUG_KMS("no matching PLL configuration for pipe 2\n"); } /* enable transcoder DPLL */ +#if 1 if (HAS_PCH_CPT(dev)) { + u32 transc_sel = intel_crtc->use_pll_a ? TRANSC_DPLLA_SEL : + TRANSC_DPLLB_SEL; temp = I915_READ(PCH_DPLL_SEL); switch (pipe) { case 0: @@ -5505,8 +5528,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, temp |= TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL; break; case 2: - /* FIXME: manage transcoder PLLs? */ - temp |= TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL; + temp |= TRANSC_DPLL_ENABLE | transc_sel; break; default: BUG(); @@ -5516,7 +5538,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, POSTING_READ(PCH_DPLL_SEL); udelay(150); } - +#endif /* The LVDS pin pair needs to be on before the DPLLs are enabled. * This is an exception to the general rule that mode_set doesn't turn * things on. @@ -5524,17 +5546,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, if (is_lvds) { temp = I915_READ(PCH_LVDS); temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (pipe == 1) { - if (HAS_PCH_CPT(dev)) - temp |= PORT_TRANS_B_SEL_CPT; - else - temp |= LVDS_PIPEB_SELECT; - } else { - if (HAS_PCH_CPT(dev)) - temp &= ~PORT_TRANS_SEL_MASK; - else - temp &= ~LVDS_PIPEB_SELECT; - } + if (HAS_PCH_CPT(dev)) + temp |= PORT_TRANS_SEL_CPT(pipe); + else if (pipe == 1) + temp |= LVDS_PIPEB_SELECT; + else + temp &= ~LVDS_PIPEB_SELECT; + /* set the corresponsding LVDS_BORDER bit */ temp |= dev_priv->lvds_border_bits; /* Set the B0-B3 data pairs corresponding to whether we're going to @@ -5584,8 +5602,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(TRANSDPLINK_N1(pipe), 0); } - if (!has_edp_encoder || - intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + if (!intel_crtc->no_pll && + (!has_edp_encoder || + intel_encoder_is_pch_edp(&has_edp_encoder->base))) { I915_WRITE(PCH_DPLL(pipe), dpll); /* Wait for the clocks to stabilize. */ @@ -5601,18 +5620,20 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, } intel_crtc->lowfreq_avail = false; - if (is_lvds && has_reduced_clock && i915_powersave) { - I915_WRITE(PCH_FP1(pipe), fp2); - intel_crtc->lowfreq_avail = true; - if (HAS_PIPE_CXSR(dev)) { - DRM_DEBUG_KMS("enabling CxSR downclocking\n"); - pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } - } else { - I915_WRITE(PCH_FP1(pipe), fp); - if (HAS_PIPE_CXSR(dev)) { - DRM_DEBUG_KMS("disabling CxSR downclocking\n"); - pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; + if (!intel_crtc->no_pll) { + if (is_lvds && has_reduced_clock && i915_powersave) { + I915_WRITE(PCH_FP1(pipe), fp2); + intel_crtc->lowfreq_avail = true; + if (HAS_PIPE_CXSR(dev)) { + DRM_DEBUG_KMS("enabling CxSR downclocking\n"); + pipeconf |= PIPECONF_CXSR_DOWNCLOCK; + } + } else { + I915_WRITE(PCH_FP1(pipe), fp); + if (HAS_PIPE_CXSR(dev)) { + DRM_DEBUG_KMS("disabling CxSR downclocking\n"); + pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; + } } } @@ -7103,6 +7124,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc->bpp = 24; /* default for pre-Ironlake */ if (HAS_PCH_SPLIT(dev)) { + if (pipe == 2 && IS_IVYBRIDGE(dev)) + intel_crtc->no_pll = true; intel_helper_funcs.prepare = ironlake_crtc_prepare; intel_helper_funcs.commit = ironlake_crtc_commit; } else { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0b2ee9d..4b5f543 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -171,6 +171,9 @@ struct intel_crtc { int16_t cursor_width, cursor_height; bool cursor_visible; unsigned int bpp; + + bool no_pll; /* tertiary pipe for IVB */ + bool use_pll_a; }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 11883c9..ac621dd 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -249,12 +249,10 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC; } - if (intel_crtc->pipe == 1) { - if (HAS_PCH_CPT(dev)) - sdvox |= PORT_TRANS_B_SEL_CPT; - else - sdvox |= SDVO_PIPE_B_SELECT; - } + if (HAS_PCH_CPT(dev)) + sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); + else if (intel_crtc->pipe == 1) + sdvox |= SDVO_PIPE_B_SELECT; I915_WRITE(intel_hdmi->sdvox_reg, sdvox); POSTING_READ(intel_hdmi->sdvox_reg); -- 1.7.4.1
signature.asc
Description: PGP signature
_______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx