tracing: Truncated output is better than nothing
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / intel_ddi.c
index 5db0b5552e39a5005f1c9e1dde74fe7216bb5037..b63d4fa204a32b540529b9e49d72cb7108839190 100644 (file)
 #include "i915_drv.h"
 #include "intel_drv.h"
 
+struct ddi_buf_trans {
+       u32 trans1;     /* balance leg enable, de-emph level */
+       u32 trans2;     /* vref sel, vswing */
+};
+
 /* HDMI/DVI modes ignore everything but the last 2 items. So we share
  * them for both DP and FDI transports, allowing those ports to
  * automatically adapt to HDMI connections as well
  */
-static const u32 hsw_ddi_translations_dp[] = {
-       0x00FFFFFF, 0x0006000E,         /* DP parameters */
-       0x00D75FFF, 0x0005000A,
-       0x00C30FFF, 0x00040006,
-       0x80AAAFFF, 0x000B0000,
-       0x00FFFFFF, 0x0005000A,
-       0x00D75FFF, 0x000C0004,
-       0x80C30FFF, 0x000B0000,
-       0x00FFFFFF, 0x00040006,
-       0x80D75FFF, 0x000B0000,
+static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
+       { 0x00FFFFFF, 0x0006000E },
+       { 0x00D75FFF, 0x0005000A },
+       { 0x00C30FFF, 0x00040006 },
+       { 0x80AAAFFF, 0x000B0000 },
+       { 0x00FFFFFF, 0x0005000A },
+       { 0x00D75FFF, 0x000C0004 },
+       { 0x80C30FFF, 0x000B0000 },
+       { 0x00FFFFFF, 0x00040006 },
+       { 0x80D75FFF, 0x000B0000 },
 };
 
-static const u32 hsw_ddi_translations_fdi[] = {
-       0x00FFFFFF, 0x0007000E,         /* FDI parameters */
-       0x00D75FFF, 0x000F000A,
-       0x00C30FFF, 0x00060006,
-       0x00AAAFFF, 0x001E0000,
-       0x00FFFFFF, 0x000F000A,
-       0x00D75FFF, 0x00160004,
-       0x00C30FFF, 0x001E0000,
-       0x00FFFFFF, 0x00060006,
-       0x00D75FFF, 0x001E0000,
+static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
+       { 0x00FFFFFF, 0x0007000E },
+       { 0x00D75FFF, 0x000F000A },
+       { 0x00C30FFF, 0x00060006 },
+       { 0x00AAAFFF, 0x001E0000 },
+       { 0x00FFFFFF, 0x000F000A },
+       { 0x00D75FFF, 0x00160004 },
+       { 0x00C30FFF, 0x001E0000 },
+       { 0x00FFFFFF, 0x00060006 },
+       { 0x00D75FFF, 0x001E0000 },
 };
 
-static const u32 hsw_ddi_translations_hdmi[] = {
-                               /* Idx  NT mV diff      T mV diff       db  */
-       0x00FFFFFF, 0x0006000E, /* 0:   400             400             0   */
-       0x00E79FFF, 0x000E000C, /* 1:   400             500             2   */
-       0x00D75FFF, 0x0005000A, /* 2:   400             600             3.5 */
-       0x00FFFFFF, 0x0005000A, /* 3:   600             600             0   */
-       0x00E79FFF, 0x001D0007, /* 4:   600             750             2   */
-       0x00D75FFF, 0x000C0004, /* 5:   600             900             3.5 */
-       0x00FFFFFF, 0x00040006, /* 6:   800             800             0   */
-       0x80E79FFF, 0x00030002, /* 7:   800             1000            2   */
-       0x00FFFFFF, 0x00140005, /* 8:   850             850             0   */
-       0x00FFFFFF, 0x000C0004, /* 9:   900             900             0   */
-       0x00FFFFFF, 0x001C0003, /* 10:  950             950             0   */
-       0x80FFFFFF, 0x00030002, /* 11:  1000            1000            0   */
+static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
+                                       /* Idx  NT mV d T mV d  db      */
+       { 0x00FFFFFF, 0x0006000E },     /* 0:   400     400     0       */
+       { 0x00E79FFF, 0x000E000C },     /* 1:   400     500     2       */
+       { 0x00D75FFF, 0x0005000A },     /* 2:   400     600     3.5     */
+       { 0x00FFFFFF, 0x0005000A },     /* 3:   600     600     0       */
+       { 0x00E79FFF, 0x001D0007 },     /* 4:   600     750     2       */
+       { 0x00D75FFF, 0x000C0004 },     /* 5:   600     900     3.5     */
+       { 0x00FFFFFF, 0x00040006 },     /* 6:   800     800     0       */
+       { 0x80E79FFF, 0x00030002 },     /* 7:   800     1000    2       */
+       { 0x00FFFFFF, 0x00140005 },     /* 8:   850     850     0       */
+       { 0x00FFFFFF, 0x000C0004 },     /* 9:   900     900     0       */
+       { 0x00FFFFFF, 0x001C0003 },     /* 10:  950     950     0       */
+       { 0x80FFFFFF, 0x00030002 },     /* 11:  1000    1000    0       */
 };
 
-static const u32 bdw_ddi_translations_edp[] = {
-       0x00FFFFFF, 0x00000012,         /* eDP parameters */
-       0x00EBAFFF, 0x00020011,
-       0x00C71FFF, 0x0006000F,
-       0x00AAAFFF, 0x000E000A,
-       0x00FFFFFF, 0x00020011,
-       0x00DB6FFF, 0x0005000F,
-       0x00BEEFFF, 0x000A000C,
-       0x00FFFFFF, 0x0005000F,
-       0x00DB6FFF, 0x000A000C,
-       0x00FFFFFF, 0x00140006          /* HDMI parameters 800mV 0dB*/
+static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
+       { 0x00FFFFFF, 0x00000012 },
+       { 0x00EBAFFF, 0x00020011 },
+       { 0x00C71FFF, 0x0006000F },
+       { 0x00AAAFFF, 0x000E000A },
+       { 0x00FFFFFF, 0x00020011 },
+       { 0x00DB6FFF, 0x0005000F },
+       { 0x00BEEFFF, 0x000A000C },
+       { 0x00FFFFFF, 0x0005000F },
+       { 0x00DB6FFF, 0x000A000C },
 };
 
-static const u32 bdw_ddi_translations_dp[] = {
-       0x00FFFFFF, 0x0007000E,         /* DP parameters */
-       0x00D75FFF, 0x000E000A,
-       0x00BEFFFF, 0x00140006,
-       0x80B2CFFF, 0x001B0002,
-       0x00FFFFFF, 0x000E000A,
-       0x00D75FFF, 0x00180004,
-       0x80CB2FFF, 0x001B0002,
-       0x00F7DFFF, 0x00180004,
-       0x80D75FFF, 0x001B0002,
-       0x00FFFFFF, 0x00140006          /* HDMI parameters 800mV 0dB*/
+static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
+       { 0x00FFFFFF, 0x0007000E },
+       { 0x00D75FFF, 0x000E000A },
+       { 0x00BEFFFF, 0x00140006 },
+       { 0x80B2CFFF, 0x001B0002 },
+       { 0x00FFFFFF, 0x000E000A },
+       { 0x00D75FFF, 0x00180004 },
+       { 0x80CB2FFF, 0x001B0002 },
+       { 0x00F7DFFF, 0x00180004 },
+       { 0x80D75FFF, 0x001B0002 },
 };
 
-static const u32 bdw_ddi_translations_fdi[] = {
-       0x00FFFFFF, 0x0001000E,         /* FDI parameters */
-       0x00D75FFF, 0x0004000A,
-       0x00C30FFF, 0x00070006,
-       0x00AAAFFF, 0x000C0000,
-       0x00FFFFFF, 0x0004000A,
-       0x00D75FFF, 0x00090004,
-       0x00C30FFF, 0x000C0000,
-       0x00FFFFFF, 0x00070006,
-       0x00D75FFF, 0x000C0000,
-       0x00FFFFFF, 0x00140006          /* HDMI parameters 800mV 0dB*/
+static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
+       { 0x00FFFFFF, 0x0001000E },
+       { 0x00D75FFF, 0x0004000A },
+       { 0x00C30FFF, 0x00070006 },
+       { 0x00AAAFFF, 0x000C0000 },
+       { 0x00FFFFFF, 0x0004000A },
+       { 0x00D75FFF, 0x00090004 },
+       { 0x00C30FFF, 0x000C0000 },
+       { 0x00FFFFFF, 0x00070006 },
+       { 0x00D75FFF, 0x000C0000 },
+};
+
+static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
+                                       /* Idx  NT mV d T mV df db      */
+       { 0x00FFFFFF, 0x0007000E },     /* 0:   400     400     0       */
+       { 0x00D75FFF, 0x000E000A },     /* 1:   400     600     3.5     */
+       { 0x00BEFFFF, 0x00140006 },     /* 2:   400     800     6       */
+       { 0x00FFFFFF, 0x0009000D },     /* 3:   450     450     0       */
+       { 0x00FFFFFF, 0x000E000A },     /* 4:   600     600     0       */
+       { 0x00D7FFFF, 0x00140006 },     /* 5:   600     800     2.5     */
+       { 0x80CB2FFF, 0x001B0002 },     /* 6:   600     1000    4.5     */
+       { 0x00FFFFFF, 0x00140006 },     /* 7:   800     800     0       */
+       { 0x80E79FFF, 0x001B0002 },     /* 8:   800     1000    2       */
+       { 0x80FFFFFF, 0x001B0002 },     /* 9:   1000    1000    0       */
 };
 
 enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
@@ -145,26 +161,36 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 reg;
-       int i;
+       int i, n_hdmi_entries, hdmi_800mV_0dB;
        int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
-       const u32 *ddi_translations_fdi;
-       const u32 *ddi_translations_dp;
-       const u32 *ddi_translations_edp;
-       const u32 *ddi_translations;
+       const struct ddi_buf_trans *ddi_translations_fdi;
+       const struct ddi_buf_trans *ddi_translations_dp;
+       const struct ddi_buf_trans *ddi_translations_edp;
+       const struct ddi_buf_trans *ddi_translations_hdmi;
+       const struct ddi_buf_trans *ddi_translations;
 
        if (IS_BROADWELL(dev)) {
                ddi_translations_fdi = bdw_ddi_translations_fdi;
                ddi_translations_dp = bdw_ddi_translations_dp;
                ddi_translations_edp = bdw_ddi_translations_edp;
+               ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+               n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
+               hdmi_800mV_0dB = 7;
        } else if (IS_HASWELL(dev)) {
                ddi_translations_fdi = hsw_ddi_translations_fdi;
                ddi_translations_dp = hsw_ddi_translations_dp;
                ddi_translations_edp = hsw_ddi_translations_dp;
+               ddi_translations_hdmi = hsw_ddi_translations_hdmi;
+               n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
+               hdmi_800mV_0dB = 6;
        } else {
                WARN(1, "ddi translation table missing\n");
                ddi_translations_edp = bdw_ddi_translations_dp;
                ddi_translations_fdi = bdw_ddi_translations_fdi;
                ddi_translations_dp = bdw_ddi_translations_dp;
+               ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+               n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
+               hdmi_800mV_0dB = 7;
        }
 
        switch (port) {
@@ -190,14 +216,22 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
 
        for (i = 0, reg = DDI_BUF_TRANS(port);
             i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) {
-               I915_WRITE(reg, ddi_translations[i]);
+               I915_WRITE(reg, ddi_translations[i].trans1);
                reg += 4;
-       }
-       /* Entry 9 is for HDMI: */
-       for (i = 0; i < 2; i++) {
-               I915_WRITE(reg, hsw_ddi_translations_hdmi[hdmi_level * 2 + i]);
+               I915_WRITE(reg, ddi_translations[i].trans2);
                reg += 4;
        }
+
+       /* Choose a good default if VBT is badly populated */
+       if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
+           hdmi_level >= n_hdmi_entries)
+               hdmi_level = hdmi_800mV_0dB;
+
+       /* Entry 9 is for HDMI: */
+       I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
+       reg += 4;
+       I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
+       reg += 4;
 }
 
 /* Program DDI buffers translations for DP. By default, program ports A-D in DP
@@ -214,18 +248,6 @@ void intel_prepare_ddi(struct drm_device *dev)
                intel_prepare_ddi_buffers(dev, port);
 }
 
-static const long hsw_ddi_buf_ctl_values[] = {
-       DDI_BUF_EMP_400MV_0DB_HSW,
-       DDI_BUF_EMP_400MV_3_5DB_HSW,
-       DDI_BUF_EMP_400MV_6DB_HSW,
-       DDI_BUF_EMP_400MV_9_5DB_HSW,
-       DDI_BUF_EMP_600MV_0DB_HSW,
-       DDI_BUF_EMP_600MV_3_5DB_HSW,
-       DDI_BUF_EMP_600MV_6DB_HSW,
-       DDI_BUF_EMP_800MV_0DB_HSW,
-       DDI_BUF_EMP_800MV_3_5DB_HSW
-};
-
 static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
                                    enum port port)
 {
@@ -285,7 +307,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 
        /* Start the training iterating through available voltages and emphasis,
         * testing each value twice. */
-       for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) {
+       for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
                /* Configure DP_TP_CTL with auto-training */
                I915_WRITE(DP_TP_CTL(PORT_E),
                                        DP_TP_CTL_FDI_AUTOTRAIN |
@@ -300,7 +322,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
                I915_WRITE(DDI_BUF_CTL(PORT_E),
                           DDI_BUF_CTL_ENABLE |
                           ((intel_crtc->config.fdi_lanes - 1) << 1) |
-                          hsw_ddi_buf_ctl_values[i / 2]);
+                          DDI_BUF_TRANS_SELECT(i / 2));
                POSTING_READ(DDI_BUF_CTL(PORT_E));
 
                udelay(600);
@@ -375,7 +397,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
                enc_to_dig_port(&encoder->base);
 
        intel_dp->DP = intel_dig_port->saved_port_bits |
-               DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
+               DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
        intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
 
 }
@@ -402,7 +424,7 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
 }
 
 #define LC_FREQ 2700
-#define LC_FREQ_2K (LC_FREQ * 2000)
+#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
 
 #define P_MIN 2
 #define P_MAX 64
@@ -414,7 +436,11 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
 #define VCO_MIN 2400
 #define VCO_MAX 4800
 
-#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
+#define abs_diff(a, b) ({                      \
+       typeof(a) __a = (a);                    \
+       typeof(b) __b = (b);                    \
+       (void) (&__a == &__b);                  \
+       __a > __b ? (__a - __b) : (__b - __a); })
 
 struct wrpll_rnp {
        unsigned p, n2, r2;
@@ -524,9 +550,9 @@ static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
         */
        a = freq2k * budget * p * r2;
        b = freq2k * budget * best->p * best->r2;
-       diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
-       diff_best = ABS_DIFF((freq2k * best->p * best->r2),
-                            (LC_FREQ_2K * best->n2));
+       diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
+       diff_best = abs_diff(freq2k * best->p * best->r2,
+                            LC_FREQ_2K * best->n2);
        c = 1000000 * diff;
        d = 1000000 * diff_best;
 
@@ -587,8 +613,8 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
        return (refclk * n * 100) / (p * r);
 }
 
-void intel_ddi_clock_get(struct intel_encoder *encoder,
-                        struct intel_crtc_config *pipe_config)
+static void hsw_ddi_clock_get(struct intel_encoder *encoder,
+                             struct intel_crtc_config *pipe_config)
 {
        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
        int link_clock = 0;
@@ -643,9 +669,15 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
                pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
 }
 
+void intel_ddi_clock_get(struct intel_encoder *encoder,
+                        struct intel_crtc_config *pipe_config)
+{
+       hsw_ddi_clock_get(encoder, pipe_config);
+}
+
 static void
-intel_ddi_calculate_wrpll(int clock /* in Hz */,
-                         unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
+hsw_ddi_calculate_wrpll(int clock /* in Hz */,
+                       unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
 {
        uint64_t freq2k;
        unsigned p, n2, r2;
@@ -708,27 +740,17 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
        *r2_out = best.r2;
 }
 
-/*
- * Tries to find a PLL for the CRTC. If it finds, it increases the refcount and
- * stores it in intel_crtc->ddi_pll_sel, so other mode sets won't be able to
- * steal the selected PLL. You need to call intel_ddi_pll_enable to actually
- * enable the PLL.
- */
-bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
+static bool
+hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
+                  struct intel_encoder *intel_encoder,
+                  int clock)
 {
-       struct drm_crtc *crtc = &intel_crtc->base;
-       struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
-       int type = intel_encoder->type;
-       int clock = intel_crtc->config.port_clock;
-
-       intel_put_shared_dpll(intel_crtc);
-
-       if (type == INTEL_OUTPUT_HDMI) {
+       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
                struct intel_shared_dpll *pll;
                uint32_t val;
                unsigned p, n2, r2;
 
-               intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
+               hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
 
                val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
                      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
@@ -749,6 +771,25 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
        return true;
 }
 
+
+/*
+ * Tries to find a *shared* PLL for the CRTC and store it in
+ * intel_crtc->ddi_pll_sel.
+ *
+ * For private DPLLs, compute_config() should do the selection for us. This
+ * function should be folded into compute_config() eventually.
+ */
+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);
+       int clock = intel_crtc->config.port_clock;
+
+       intel_put_shared_dpll(intel_crtc);
+
+       return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
+}
+
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = crtc->dev->dev_private;
@@ -1183,31 +1224,52 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
        }
 }
 
-int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
+static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
+{
+       uint32_t lcpll = I915_READ(LCPLL_CTL);
+       uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
+
+       if (lcpll & LCPLL_CD_SOURCE_FCLK)
+               return 800000;
+       else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
+               return 450000;
+       else if (freq == LCPLL_CLK_FREQ_450)
+               return 450000;
+       else if (freq == LCPLL_CLK_FREQ_54O_BDW)
+               return 540000;
+       else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
+               return 337500;
+       else
+               return 675000;
+}
+
+static int hsw_get_cdclk_freq(struct drm_i915_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
        uint32_t lcpll = I915_READ(LCPLL_CTL);
        uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
 
-       if (lcpll & LCPLL_CD_SOURCE_FCLK) {
+       if (lcpll & LCPLL_CD_SOURCE_FCLK)
                return 800000;
-       } else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT) {
+       else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
                return 450000;
-       } else if (freq == LCPLL_CLK_FREQ_450) {
+       else if (freq == LCPLL_CLK_FREQ_450)
                return 450000;
-       } else if (IS_HASWELL(dev)) {
-               if (IS_ULT(dev))
-                       return 337500;
-               else
-                       return 540000;
-       } else {
-               if (freq == LCPLL_CLK_FREQ_54O_BDW)
-                       return 540000;
-               else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
-                       return 337500;
-               else
-                       return 675000;
-       }
+       else if (IS_ULT(dev))
+               return 337500;
+       else
+               return 540000;
+}
+
+int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
+{
+       struct drm_device *dev = dev_priv->dev;
+
+       if (IS_BROADWELL(dev))
+               return bdw_get_cdclk_freq(dev_priv);
+
+       /* Haswell */
+       return hsw_get_cdclk_freq(dev_priv);
 }
 
 static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
@@ -1248,10 +1310,8 @@ static const char * const hsw_ddi_pll_names[] = {
        "WRPLL 2",
 };
 
-void intel_ddi_pll_init(struct drm_device *dev)
+static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t val = I915_READ(LCPLL_CTL);
        int i;
 
        dev_priv->num_shared_dpll = 2;
@@ -1264,6 +1324,14 @@ void intel_ddi_pll_init(struct drm_device *dev)
                dev_priv->shared_dplls[i].get_hw_state =
                        hsw_ddi_pll_get_hw_state;
        }
+}
+
+void intel_ddi_pll_init(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       uint32_t val = I915_READ(LCPLL_CTL);
+
+       hsw_shared_dplls_init(dev_priv);
 
        /* The LCPLL register should be turned on by the BIOS. For now let's
         * just check its state and print errors in case something is wrong.
@@ -1444,7 +1512,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
                dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
        }
 
-       intel_ddi_clock_get(encoder, pipe_config);
+       hsw_ddi_clock_get(encoder, pipe_config);
 }
 
 static void intel_ddi_destroy(struct drm_encoder *encoder)