drm/i915: Precompute static ddi_pll_sel values in encoders
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 4 Jul 2014 14:26:04 +0000 (11:26 -0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 10 Jul 2014 20:11:18 +0000 (22:11 +0200)
This way only the dynamic WRPLL selection for hdmi ddi mode is
done in intel_ddi_pll_select.

v2: Don't clobber the precomputed values when selecting clocks fro
hdmi encoders.
v3 (from Paulo): Rebase on top of the s/IS_HASWELL/HAS_DDI/ patch.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Paulo Zanoni <przanoni@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_dp.c

index 30bfdc7..4b08561 100644 (file)
@@ -315,8 +315,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,
                pipe_config->pipe_bpp = 24;
 
        /* FDI must always be 2.7 GHz */
-       if (HAS_DDI(dev))
+       if (HAS_DDI(dev)) {
+               pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL;
                pipe_config->port_clock = 135000 * 2;
+       }
 
        return true;
 }
index 1b4748b..195d52e 100644 (file)
@@ -403,6 +403,7 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
                        I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE);
                        POSTING_READ(WRPLL_CTL1);
                }
+               intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
                break;
        case PORT_CLK_SEL_WRPLL2:
                plls->wrpll2_refcount--;
@@ -413,13 +414,12 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
                        I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE);
                        POSTING_READ(WRPLL_CTL2);
                }
+               intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
                break;
        }
 
        WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n");
        WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
-
-       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
 }
 
 #define LC_FREQ 2700
@@ -739,7 +739,6 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
 {
        struct drm_crtc *crtc = &intel_crtc->base;
        struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
-       struct drm_encoder *encoder = &intel_encoder->base;
        struct drm_i915_private *dev_priv = crtc->dev->dev_private;
        struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
        int type = intel_encoder->type;
@@ -748,26 +747,7 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
 
        intel_ddi_put_crtc_pll(crtc);
 
-       if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-               switch (intel_dp->link_bw) {
-               case DP_LINK_BW_1_62:
-                       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
-                       break;
-               case DP_LINK_BW_2_7:
-                       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
-                       break;
-               case DP_LINK_BW_5_4:
-                       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700;
-                       break;
-               default:
-                       DRM_ERROR("Link bandwidth %d unsupported\n",
-                                 intel_dp->link_bw);
-                       return false;
-               }
-
-       } else if (type == INTEL_OUTPUT_HDMI) {
+       if (type == INTEL_OUTPUT_HDMI) {
                uint32_t reg, val;
                unsigned p, n2, r2;
 
@@ -808,14 +788,6 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
                        plls->wrpll2_refcount++;
                        intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
                }
-
-       } else if (type == INTEL_OUTPUT_ANALOG) {
-               DRM_DEBUG_KMS("Using SPLL on pipe %c\n",
-                             pipe_name(pipe));
-               intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_SPLL;
-       } else {
-               WARN(1, "Invalid DDI encoder type %d\n", type);
-               return false;
        }
 
        return true;
index 568e532..ec080e5 100644 (file)
@@ -746,6 +746,22 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
 }
 
 static void
+hsw_dp_set_ddi_pll_sel(struct intel_crtc_config *pipe_config, int link_bw)
+{
+       switch (link_bw) {
+       case DP_LINK_BW_1_62:
+               pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
+               break;
+       case DP_LINK_BW_2_7:
+               pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
+               break;
+       case DP_LINK_BW_5_4:
+               pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700;
+               break;
+       }
+}
+
+static void
 intel_dp_set_clock(struct intel_encoder *encoder,
                   struct intel_crtc_config *pipe_config, int link_bw)
 {
@@ -756,8 +772,6 @@ intel_dp_set_clock(struct intel_encoder *encoder,
        if (IS_G4X(dev)) {
                divisor = gen4_dpll;
                count = ARRAY_SIZE(gen4_dpll);
-       } else if (HAS_DDI(dev)) {
-               /* Haswell has special-purpose DP DDI clocks. */
        } else if (HAS_PCH_SPLIT(dev)) {
                divisor = pch_dpll;
                count = ARRAY_SIZE(pch_dpll);
@@ -928,7 +942,10 @@ found:
                                &pipe_config->dp_m2_n2);
        }
 
-       intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
+       if (HAS_DDI(dev))
+               hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
+       else
+               intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
 
        return true;
 }