drm/i915/skl: Adjust the port PLL selection code
authorSatheeshakrishna M <satheeshakrishna.m@intel.com>
Thu, 13 Nov 2014 14:55:19 +0000 (14:55 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 14 Nov 2014 10:18:46 +0000 (11:18 +0100)
Skylake deprecates the usage of PORT_CLK_SEL and we are advised to use
the new DPLL_CRTL2 for the DDI->PLL mapping.

v2: Modified as per review comments

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_ddi.c

index 5391c1e19ec75365c7333087f7b965d6ff5edbb7..5f786b476a394e964bafd34f8a5ad13a10225831 100644 (file)
@@ -1243,7 +1243,8 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 {
        struct drm_encoder *encoder = &intel_encoder->base;
-       struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+       struct drm_device *dev = encoder->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
        enum port port = intel_ddi_get_encoder_port(intel_encoder);
        int type = intel_encoder->type;
@@ -1253,8 +1254,22 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
                intel_edp_panel_on(intel_dp);
        }
 
-       WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
-       I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
+       if (IS_SKYLAKE(dev)) {
+               uint32_t dpll = crtc->config.ddi_pll_sel;
+               uint32_t val;
+
+               val = I915_READ(DPLL_CTRL2);
+
+               val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
+                       DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
+               val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
+                       DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
+
+               I915_WRITE(DPLL_CTRL2, val);
+       } else {
+               WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
+               I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
+       }
 
        if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -1278,7 +1293,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
 {
        struct drm_encoder *encoder = &intel_encoder->base;
-       struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+       struct drm_device *dev = encoder->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        enum port port = intel_ddi_get_encoder_port(intel_encoder);
        int type = intel_encoder->type;
        uint32_t val;
@@ -1306,7 +1322,11 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
                intel_edp_panel_off(intel_dp);
        }
 
-       I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+       if (IS_SKYLAKE(dev))
+               I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
+                                       DPLL_CTRL2_DDI_CLK_OFF(port)));
+       else
+               I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
 }
 
 static void intel_enable_ddi(struct intel_encoder *intel_encoder)