drm/i915: ->disable hook for WRPLLs
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_ddi.c
index 0ad4e96..7c6e8d5 100644 (file)
@@ -76,12 +76,12 @@ 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, 0x000A000C,
        0x00FFFFFF, 0x00140006          /* HDMI parameters 800mV 0dB*/
 };
 
@@ -89,12 +89,12 @@ 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,
-       0x80FFFFFF, 0x001B0002,
        0x00FFFFFF, 0x00140006          /* HDMI parameters 800mV 0dB*/
 };
 
@@ -277,7 +277,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
        I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
 
        /* Configure Port Clock Select */
-       I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel);
+       I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config.ddi_pll_sel);
+       WARN_ON(intel_crtc->config.ddi_pll_sel != PORT_CLK_SEL_SPLL);
 
        /* Start the training iterating through available voltages and emphasis,
         * testing each value twice. */
@@ -364,55 +365,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
        DRM_ERROR("FDI link training failed!\n");
 }
 
-static void intel_ddi_mode_set(struct intel_encoder *encoder)
-{
-       struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
-       int port = intel_ddi_get_encoder_port(encoder);
-       int pipe = crtc->pipe;
-       int type = encoder->type;
-       struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
-
-       DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n",
-                     port_name(port), pipe_name(pipe));
-
-       crtc->eld_vld = false;
-       if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
-               struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-               struct intel_digital_port *intel_dig_port =
-                       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;
-               intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
-
-               if (intel_dp->has_audio) {
-                       DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n",
-                                        pipe_name(crtc->pipe));
-
-                       /* write eld */
-                       DRM_DEBUG_DRIVER("DP audio: write eld information\n");
-                       intel_write_eld(&encoder->base, adjusted_mode);
-               }
-       } else if (type == INTEL_OUTPUT_HDMI) {
-               struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
-
-               if (intel_hdmi->has_audio) {
-                       /* Proper support for digital audio needs a new logic
-                        * and a new set of registers, so we leave it for future
-                        * patch bombing.
-                        */
-                       DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n",
-                                        pipe_name(crtc->pipe));
-
-                       /* write eld */
-                       DRM_DEBUG_DRIVER("HDMI audio: write eld information\n");
-                       intel_write_eld(&encoder->base, adjusted_mode);
-               }
-
-               intel_hdmi->set_infoframes(&encoder->base, adjusted_mode);
-       }
-}
-
 static struct intel_encoder *
 intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
 {
@@ -439,46 +391,27 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
        struct drm_i915_private *dev_priv = crtc->dev->dev_private;
        struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       uint32_t val;
+       struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(intel_crtc);
 
-       switch (intel_crtc->ddi_pll_sel) {
-       case PORT_CLK_SEL_SPLL:
-               plls->spll_refcount--;
-               if (plls->spll_refcount == 0) {
-                       DRM_DEBUG_KMS("Disabling SPLL\n");
-                       val = I915_READ(SPLL_CTL);
-                       WARN_ON(!(val & SPLL_PLL_ENABLE));
-                       I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
-                       POSTING_READ(SPLL_CTL);
-               }
-               break;
+       switch (intel_crtc->config.ddi_pll_sel) {
        case PORT_CLK_SEL_WRPLL1:
                plls->wrpll1_refcount--;
                if (plls->wrpll1_refcount == 0) {
-                       DRM_DEBUG_KMS("Disabling WRPLL 1\n");
-                       val = I915_READ(WRPLL_CTL1);
-                       WARN_ON(!(val & WRPLL_PLL_ENABLE));
-                       I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE);
-                       POSTING_READ(WRPLL_CTL1);
+                       pll->disable(dev_priv, pll);
                }
+               intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
                break;
        case PORT_CLK_SEL_WRPLL2:
                plls->wrpll2_refcount--;
                if (plls->wrpll2_refcount == 0) {
-                       DRM_DEBUG_KMS("Disabling WRPLL 2\n");
-                       val = I915_READ(WRPLL_CTL2);
-                       WARN_ON(!(val & WRPLL_PLL_ENABLE));
-                       I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE);
-                       POSTING_READ(WRPLL_CTL2);
+                       pll->disable(dev_priv, pll);
                }
+               intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
                break;
        }
 
-       WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n");
        WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n");
        WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
-
-       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
 }
 
 #define LC_FREQ 2700
@@ -641,9 +574,9 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
        u32 wrpll;
 
        wrpll = I915_READ(reg);
-       switch (wrpll & SPLL_PLL_REF_MASK) {
-       case SPLL_PLL_SSC:
-       case SPLL_PLL_NON_SSC:
+       switch (wrpll & WRPLL_PLL_REF_MASK) {
+       case WRPLL_PLL_SSC:
+       case WRPLL_PLL_NON_SSC:
                /*
                 * We could calculate spread here, but our checking
                 * code only cares about 5% accuracy, and spread is a max of
@@ -651,7 +584,7 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
                 */
                refclk = 135;
                break;
-       case SPLL_PLL_LCPLL:
+       case WRPLL_PLL_LCPLL:
                refclk = LC_FREQ;
                break;
        default:
@@ -671,11 +604,10 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
                                struct intel_crtc_config *pipe_config)
 {
        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-       enum port port = intel_ddi_get_encoder_port(encoder);
        int link_clock = 0;
        u32 val, pll;
 
-       val = I915_READ(PORT_CLK_SEL(port));
+       val = pipe_config->ddi_pll_sel;
        switch (val & PORT_CLK_SEL_MASK) {
        case PORT_CLK_SEL_LCPLL_810:
                link_clock = 81000;
@@ -799,7 +731,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;
@@ -808,32 +739,13 @@ 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->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
-                       break;
-               case DP_LINK_BW_2_7:
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
-                       break;
-               case DP_LINK_BW_5_4:
-                       intel_crtc->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;
 
                intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
 
-               val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
+               val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
                      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
                      WRPLL_DIVIDER_POST(p);
 
@@ -863,26 +775,15 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
 
                if (reg == WRPLL_CTL1) {
                        plls->wrpll1_refcount++;
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
+                       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
+                       intel_crtc->config.shared_dpll = DPLL_ID_WRPLL1;
                } else {
                        plls->wrpll2_refcount++;
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
-               }
-
-       } else if (type == INTEL_OUTPUT_ANALOG) {
-               if (plls->spll_refcount == 0) {
-                       DRM_DEBUG_KMS("Using SPLL on pipe %c\n",
-                                     pipe_name(pipe));
-                       plls->spll_refcount++;
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL;
-               } else {
-                       DRM_ERROR("SPLL already in use\n");
-                       return false;
+                       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
+                       intel_crtc->config.shared_dpll = DPLL_ID_WRPLL2;
                }
 
-       } else {
-               WARN(1, "Invalid DDI encoder type %d\n", type);
-               return false;
+               intel_crtc->config.dpll_hw_state.wrpll = val;
        }
 
        return true;
@@ -907,27 +808,10 @@ void intel_ddi_pll_enable(struct intel_crtc *crtc)
        BUILD_BUG_ON(enable_bit != SPLL_PLL_ENABLE);
        BUILD_BUG_ON(enable_bit != WRPLL_PLL_ENABLE);
 
-       switch (crtc->ddi_pll_sel) {
-       case PORT_CLK_SEL_LCPLL_2700:
-       case PORT_CLK_SEL_LCPLL_1350:
-       case PORT_CLK_SEL_LCPLL_810:
-               /*
-                * LCPLL should always be enabled at this point of the mode set
-                * sequence, so nothing to do.
-                */
-               return;
-
-       case PORT_CLK_SEL_SPLL:
-               pll_name = "SPLL";
-               reg = SPLL_CTL;
-               refcount = plls->spll_refcount;
-               new_val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz |
-                         SPLL_PLL_SSC;
-               break;
-
+       switch (crtc->config.ddi_pll_sel) {
        case PORT_CLK_SEL_WRPLL1:
        case PORT_CLK_SEL_WRPLL2:
-               if (crtc->ddi_pll_sel == PORT_CLK_SEL_WRPLL1) {
+               if (crtc->config.ddi_pll_sel == PORT_CLK_SEL_WRPLL1) {
                        pll_name = "WRPLL1";
                        reg = WRPLL_CTL1;
                        refcount = plls->wrpll1_refcount;
@@ -939,7 +823,7 @@ void intel_ddi_pll_enable(struct intel_crtc *crtc)
 
                intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
 
-               new_val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
+               new_val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
                          WRPLL_DIVIDER_REFERENCE(r2) |
                          WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p);
 
@@ -949,7 +833,6 @@ void intel_ddi_pll_enable(struct intel_crtc *crtc)
                WARN(1, "Bad selected pll: PORT_CLK_SEL_NONE\n");
                return;
        default:
-               WARN(1, "Bad selected pll: 0x%08x\n", crtc->ddi_pll_sel);
                return;
        }
 
@@ -1044,7 +927,9 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
                         * eDP when not using the panel fitter, and when not
                         * using motion blur mitigation (which we don't
                         * support). */
-                       if (IS_HASWELL(dev) && intel_crtc->config.pch_pfit.enabled)
+                       if (IS_HASWELL(dev) &&
+                           (intel_crtc->config.pch_pfit.enabled ||
+                            intel_crtc->config.pch_pfit.force_thru))
                                temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
                        else
                                temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1062,9 +947,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
        }
 
        if (type == INTEL_OUTPUT_HDMI) {
-               struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
-
-               if (intel_hdmi->has_hdmi_sink)
+               if (intel_crtc->config.has_hdmi_sink)
                        temp |= TRANS_DDI_MODE_SELECT_HDMI;
                else
                        temp |= TRANS_DDI_MODE_SELECT_DVI;
@@ -1197,47 +1080,12 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
        return false;
 }
 
-static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv,
-                                      enum pipe pipe)
-{
-       uint32_t temp, ret;
-       enum port port = I915_MAX_PORTS;
-       enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
-                                                                     pipe);
-       int i;
-
-       if (cpu_transcoder == TRANSCODER_EDP) {
-               port = PORT_A;
-       } else {
-               temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
-               temp &= TRANS_DDI_PORT_MASK;
-
-               for (i = PORT_B; i <= PORT_E; i++)
-                       if (temp == TRANS_DDI_SELECT_PORT(i))
-                               port = i;
-       }
-
-       if (port == I915_MAX_PORTS) {
-               WARN(1, "Pipe %c enabled on an unknown port\n",
-                    pipe_name(pipe));
-               ret = PORT_CLK_SEL_NONE;
-       } else {
-               ret = I915_READ(PORT_CLK_SEL(port));
-               DRM_DEBUG_KMS("Pipe %c connected to port %c using clock "
-                             "0x%08x\n", pipe_name(pipe), port_name(port),
-                             ret);
-       }
-
-       return ret;
-}
-
 void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe;
        struct intel_crtc *intel_crtc;
 
-       dev_priv->ddi_plls.spll_refcount = 0;
        dev_priv->ddi_plls.wrpll1_refcount = 0;
        dev_priv->ddi_plls.wrpll2_refcount = 0;
 
@@ -1246,17 +1094,11 @@ void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
                        to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
 
                if (!intel_crtc->active) {
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
+                       intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
                        continue;
                }
 
-               intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv,
-                                                                pipe);
-
-               switch (intel_crtc->ddi_pll_sel) {
-               case PORT_CLK_SEL_SPLL:
-                       dev_priv->ddi_plls.spll_refcount++;
-                       break;
+               switch (intel_crtc->config.ddi_pll_sel) {
                case PORT_CLK_SEL_WRPLL1:
                        dev_priv->ddi_plls.wrpll1_refcount++;
                        break;
@@ -1293,28 +1135,48 @@ 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_crtc *crtc = encoder->crtc;
        struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
        enum port port = intel_ddi_get_encoder_port(intel_encoder);
        int type = intel_encoder->type;
 
+       if (crtc->config.has_audio) {
+               DRM_DEBUG_DRIVER("Audio on pipe %c on DDI\n",
+                                pipe_name(crtc->pipe));
+
+               /* write eld */
+               DRM_DEBUG_DRIVER("DDI audio: write eld information\n");
+               intel_write_eld(encoder, &crtc->config.adjusted_mode);
+       }
+
        if (type == INTEL_OUTPUT_EDP) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
                intel_edp_panel_on(intel_dp);
        }
 
-       WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE);
-       I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel);
+       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);
+               struct intel_digital_port *intel_dig_port =
+                       enc_to_dig_port(encoder);
+
+               intel_dp->DP = intel_dig_port->saved_port_bits |
+                              DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
+               intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
 
                intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
                intel_dp_start_link_train(intel_dp);
                intel_dp_complete_link_train(intel_dp);
                if (port != PORT_A)
                        intel_dp_stop_link_train(intel_dp);
+       } else if (type == INTEL_OUTPUT_HDMI) {
+               struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+
+               intel_hdmi->set_infoframes(encoder,
+                                          crtc->config.has_hdmi_sink,
+                                          &crtc->config.adjusted_mode);
        }
 }
 
@@ -1385,7 +1247,8 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
                intel_edp_psr_enable(intel_dp);
        }
 
-       if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
+       if (intel_crtc->config.has_audio) {
+               intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
                tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
                tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
                I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
@@ -1403,11 +1266,14 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t tmp;
 
-       if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
+       /* We can't touch HSW_AUD_PIN_ELD_CP_VLD uncionditionally because this
+        * register is part of the power well on Haswell. */
+       if (intel_crtc->config.has_audio) {
                tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
                tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) <<
                         (pipe * 4));
                I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+               intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
        }
 
        if (type == INTEL_OUTPUT_EDP) {
@@ -1445,10 +1311,54 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
        }
 }
 
+static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
+                               struct intel_shared_dpll *pll)
+{
+       uint32_t val;
+
+       val = I915_READ(WRPLL_CTL(pll->id));
+       WARN_ON(!(val & WRPLL_PLL_ENABLE));
+       I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
+       POSTING_READ(WRPLL_CTL(pll->id));
+}
+
+static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+                                    struct intel_shared_dpll *pll,
+                                    struct intel_dpll_hw_state *hw_state)
+{
+       uint32_t val;
+
+       if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
+               return false;
+
+       val = I915_READ(WRPLL_CTL(pll->id));
+       hw_state->wrpll = val;
+
+       return val & WRPLL_PLL_ENABLE;
+}
+
+static char *hsw_ddi_pll_names[] = {
+       "WRPLL 1",
+       "WRPLL 2",
+};
+
 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);
+       int i;
+
+       /* Dummy setup until everything is moved over to avoid upsetting the hw
+        * state cross checker. */
+       dev_priv->num_shared_dpll = 0;
+
+       for (i = 0; i < 2; i++) {
+               dev_priv->shared_dplls[i].id = i;
+               dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
+               dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
+               dev_priv->shared_dplls[i].get_hw_state =
+                       hsw_ddi_pll_get_hw_state;
+       }
 
        /* 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.
@@ -1580,6 +1490,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 
        switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
        case TRANS_DDI_MODE_SELECT_HDMI:
+               pipe_config->has_hdmi_sink = true;
        case TRANS_DDI_MODE_SELECT_DVI:
        case TRANS_DDI_MODE_SELECT_FDI:
                break;
@@ -1592,6 +1503,12 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
                break;
        }
 
+       if (intel_display_power_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
+               temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+               if (temp & (AUDIO_OUTPUT_ENABLE_A << (intel_crtc->pipe * 4)))
+                       pipe_config->has_audio = true;
+       }
+
        if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
            pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
                /*
@@ -1708,7 +1625,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
                         DRM_MODE_ENCODER_TMDS);
 
        intel_encoder->compute_config = intel_ddi_compute_config;
-       intel_encoder->mode_set = intel_ddi_mode_set;
        intel_encoder->enable = intel_enable_ddi;
        intel_encoder->pre_enable = intel_ddi_pre_enable;
        intel_encoder->disable = intel_disable_ddi;
@@ -1726,6 +1642,9 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
        intel_encoder->cloneable = 0;
        intel_encoder->hot_plug = intel_ddi_hot_plug;
 
+       intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+       dev_priv->hpd_irq_port[port] = intel_dig_port;
+
        if (init_dp)
                dp_connector = intel_ddi_init_dp_connector(intel_dig_port);