drm/i915: add lpt_pch_enable
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Wed, 31 Oct 2012 20:12:22 +0000 (18:12 -0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 11 Nov 2012 22:51:17 +0000 (23:51 +0100)
For now it's just a fork of ironlake_pch_enable. The next commits will
change this.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c

index 34d24bd7a36a795975877b58e72b0fb5327bdbe8..ac65d1aaf3c2452fdfab504c392fb0fe2dcc4de1 100644 (file)
@@ -3168,6 +3168,115 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
        intel_enable_transcoder(dev_priv, pipe);
 }
 
+static void lpt_pch_enable(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;
+       u32 reg, temp;
+
+       assert_transcoder_disabled(dev_priv, pipe);
+
+       /* Write the TU size bits before fdi link training, so that error
+        * detection works. */
+       I915_WRITE(FDI_RX_TUSIZE1(pipe),
+                  I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+
+       /* For PCH output, training FDI link */
+       dev_priv->display.fdi_link_train(crtc);
+
+       /* XXX: pch pll's can be enabled any time before we enable the PCH
+        * transcoder, and we actually should do this to not upset any PCH
+        * transcoder that already use the clock when we share it.
+        *
+        * Note that enable_pch_pll tries to do the right thing, but get_pch_pll
+        * unconditionally resets the pll - we need that to have the right LVDS
+        * enable sequence. */
+       intel_enable_pch_pll(intel_crtc);
+
+       if (HAS_PCH_LPT(dev)) {
+               DRM_DEBUG_KMS("LPT detected: programming iCLKIP\n");
+               lpt_program_iclkip(crtc);
+       } else if (HAS_PCH_CPT(dev)) {
+               u32 sel;
+
+               temp = I915_READ(PCH_DPLL_SEL);
+               switch (pipe) {
+               default:
+               case 0:
+                       temp |= TRANSA_DPLL_ENABLE;
+                       sel = TRANSA_DPLLB_SEL;
+                       break;
+               case 1:
+                       temp |= TRANSB_DPLL_ENABLE;
+                       sel = TRANSB_DPLLB_SEL;
+                       break;
+               case 2:
+                       temp |= TRANSC_DPLL_ENABLE;
+                       sel = TRANSC_DPLLB_SEL;
+                       break;
+               }
+               if (intel_crtc->pch_pll->pll_reg == _PCH_DPLL_B)
+                       temp |= sel;
+               else
+                       temp &= ~sel;
+               I915_WRITE(PCH_DPLL_SEL, temp);
+       }
+
+       /* set transcoder timing, panel must allow it */
+       assert_panel_unlocked(dev_priv, pipe);
+       I915_WRITE(TRANS_HTOTAL(pipe), I915_READ(HTOTAL(pipe)));
+       I915_WRITE(TRANS_HBLANK(pipe), I915_READ(HBLANK(pipe)));
+       I915_WRITE(TRANS_HSYNC(pipe),  I915_READ(HSYNC(pipe)));
+
+       I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe)));
+       I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe)));
+       I915_WRITE(TRANS_VSYNC(pipe),  I915_READ(VSYNC(pipe)));
+       I915_WRITE(TRANS_VSYNCSHIFT(pipe),  I915_READ(VSYNCSHIFT(pipe)));
+
+       if (!IS_HASWELL(dev))
+               intel_fdi_normal_train(crtc);
+
+       /* For PCH DP, enable TRANS_DP_CTL */
+       if (HAS_PCH_CPT(dev) &&
+           (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+            intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
+               u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5;
+               reg = TRANS_DP_CTL(pipe);
+               temp = I915_READ(reg);
+               temp &= ~(TRANS_DP_PORT_SEL_MASK |
+                         TRANS_DP_SYNC_MASK |
+                         TRANS_DP_BPC_MASK);
+               temp |= (TRANS_DP_OUTPUT_ENABLE |
+                        TRANS_DP_ENH_FRAMING);
+               temp |= bpc << 9; /* same format but at 11:9 */
+
+               if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
+                       temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
+               if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
+                       temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
+
+               switch (intel_trans_dp_port_sel(crtc)) {
+               case PCH_DP_B:
+                       temp |= TRANS_DP_PORT_SEL_B;
+                       break;
+               case PCH_DP_C:
+                       temp |= TRANS_DP_PORT_SEL_C;
+                       break;
+               case PCH_DP_D:
+                       temp |= TRANS_DP_PORT_SEL_D;
+                       break;
+               default:
+                       BUG();
+               }
+
+               I915_WRITE(reg, temp);
+       }
+
+       intel_enable_transcoder(dev_priv, pipe);
+}
+
 static void intel_put_pch_pll(struct intel_crtc *intel_crtc)
 {
        struct intel_pch_pll *pll = intel_crtc->pch_pll;
@@ -3414,7 +3523,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
        intel_enable_plane(dev_priv, plane, pipe);
 
        if (is_pch_port)
-               ironlake_pch_enable(crtc);
+               lpt_pch_enable(crtc);
 
        mutex_lock(&dev->struct_mutex);
        intel_update_fbc(dev);