pandora: defconfig: update
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_dp.c
index 4d0358f..ca75076 100644 (file)
@@ -208,15 +208,8 @@ intel_dp_link_clock(uint8_t link_bw)
  */
 
 static int
-intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock)
+intel_dp_link_required(int pixel_clock, int bpp)
 {
-       struct drm_crtc *crtc = intel_dp->base.base.crtc;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int bpp = 24;
-
-       if (intel_crtc)
-               bpp = intel_crtc->bpp;
-
        return (pixel_clock * bpp + 9) / 10;
 }
 
@@ -226,13 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return (max_link_clock * max_lanes * 8) / 10;
 }
 
+static bool
+intel_dp_adjust_dithering(struct intel_dp *intel_dp,
+                         struct drm_display_mode *mode,
+                         struct drm_display_mode *adjusted_mode)
+{
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
+       int max_lanes = intel_dp_max_lane_count(intel_dp);
+       int max_rate, mode_rate;
+
+       mode_rate = intel_dp_link_required(mode->clock, 24);
+       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+
+       if (mode_rate > max_rate) {
+               mode_rate = intel_dp_link_required(mode->clock, 18);
+               if (mode_rate > max_rate)
+                       return false;
+
+               if (adjusted_mode)
+                       adjusted_mode->private_flags
+                               |= INTEL_MODE_DP_FORCE_6BPC;
+
+               return true;
+       }
+
+       return true;
+}
+
 static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
-       int max_lanes = intel_dp_max_lane_count(intel_dp);
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
                if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
@@ -242,8 +260,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
                        return MODE_PANEL;
        }
 
-       if (intel_dp_link_required(intel_dp, mode->clock)
-           > intel_dp_max_data_rate(max_link_clock, max_lanes))
+       if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
                return MODE_CLOCK_HIGH;
 
        if (mode->clock < 10000)
@@ -362,8 +379,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
         * clock divider.
         */
        if (is_cpu_edp(intel_dp)) {
-               if (IS_GEN6(dev))
-                       aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */
+               if (IS_GEN6(dev) || IS_GEN7(dev))
+                       aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */
                else
                        aux_clock_divider = 225; /* eDP input clock at 450Mhz */
        } else if (HAS_PCH_SPLIT(dev))
@@ -466,6 +483,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
        uint8_t msg[20];
        int msg_bytes;
        uint8_t ack;
+       int retry;
 
        intel_dp_check_edp(intel_dp);
        if (send_bytes > 16)
@@ -476,18 +494,20 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
        msg[3] = send_bytes - 1;
        memcpy(&msg[4], send, send_bytes);
        msg_bytes = send_bytes + 4;
-       for (;;) {
+       for (retry = 0; retry < 7; retry++) {
                ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
                if (ret < 0)
                        return ret;
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
-                       break;
+                       return send_bytes;
                else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
-                       udelay(100);
+                       usleep_range(400, 500);
                else
                        return -EIO;
        }
-       return send_bytes;
+
+       DRM_ERROR("too many retries, giving up\n");
+       return -EIO;
 }
 
 /* Write a single byte to the aux channel in native mode */
@@ -509,6 +529,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp,
        int reply_bytes;
        uint8_t ack;
        int ret;
+       int retry;
 
        intel_dp_check_edp(intel_dp);
        msg[0] = AUX_NATIVE_READ << 4;
@@ -519,7 +540,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp,
        msg_bytes = 4;
        reply_bytes = recv_bytes + 1;
 
-       for (;;) {
+       for (retry = 0; retry < 7; retry++) {
                ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes,
                                      reply, reply_bytes);
                if (ret == 0)
@@ -532,10 +553,13 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp,
                        return ret - 1;
                }
                else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
-                       udelay(100);
+                       usleep_range(400, 500);
                else
                        return -EIO;
        }
+
+       DRM_ERROR("too many retries, giving up\n");
+       return -EIO;
 }
 
 static int
@@ -604,7 +628,18 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
                        DRM_DEBUG_KMS("aux_ch native nack\n");
                        return -EREMOTEIO;
                case AUX_NATIVE_REPLY_DEFER:
-                       udelay(100);
+                       /*
+                        * For now, just give more slack to branch devices. We
+                        * could check the DPCD for I2C bit rate capabilities,
+                        * and if available, adjust the interval. We could also
+                        * be more careful with DP-to-Legacy adapters where a
+                        * long legacy cable may force very low I2C bit rates.
+                        */
+                       if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
+                           DP_DWN_STRM_PORT_PRESENT)
+                               usleep_range(500, 600);
+                       else
+                               usleep_range(300, 400);
                        continue;
                default:
                        DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
@@ -672,6 +707,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
        int lane_count, clock;
        int max_lane_count = intel_dp_max_lane_count(intel_dp);
        int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
+       int bpp;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -685,11 +721,16 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = intel_dp->panel_fixed_mode->clock;
        }
 
-       for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
-               for (clock = 0; clock <= max_clock; clock++) {
+       if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
+               return false;
+
+       bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+
+       for (clock = 0; clock <= max_clock; clock++) {
+               for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
 
-                       if (intel_dp_link_required(intel_dp, mode->clock)
+                       if (intel_dp_link_required(mode->clock, bpp)
                                        <= link_avail) {
                                intel_dp->link_bw = bws[clock];
                                intel_dp->lane_count = lane_count;
@@ -817,10 +858,11 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        }
 
        /*
-        * There are three kinds of DP registers:
+        * There are four kinds of DP registers:
         *
         *      IBX PCH
-        *      CPU
+        *      SNB CPU
+        *      IVB CPU
         *      CPT PCH
         *
         * IBX PCH and CPU are the same for almost everything,
@@ -873,7 +915,25 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 
        /* Split out the IBX/CPU vs CPT settings */
 
-       if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+       if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) {
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+                       intel_dp->DP |= DP_SYNC_HS_HIGH;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+                       intel_dp->DP |= DP_SYNC_VS_HIGH;
+               intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
+
+               if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+                       intel_dp->DP |= DP_ENHANCED_FRAMING;
+
+               intel_dp->DP |= intel_crtc->pipe << 29;
+
+               /* don't miss out required setting for eDP */
+               intel_dp->DP |= DP_PLL_ENABLE;
+               if (adjusted_mode->clock < 200000)
+                       intel_dp->DP |= DP_PLL_FREQ_160MHZ;
+               else
+                       intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+       } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
                intel_dp->DP |= intel_dp->color_range;
 
                if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
@@ -1107,13 +1167,17 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
        DRM_DEBUG_KMS("Turn eDP power off\n");
 
-       WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
+       WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
 
        pp = ironlake_get_pp_control(dev_priv);
+       /* We need to switch off panel power _and_ force vdd, for otherwise some
+        * panels get very unhappy and cease to work. */
        pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
 
+       intel_dp->want_panel_vdd = false;
+
        ironlake_wait_panel_off(intel_dp);
 }
 
@@ -1218,18 +1282,14 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-       ironlake_edp_backlight_off(intel_dp);
-       ironlake_edp_panel_off(intel_dp);
 
-       /* Wake up the sink first */
+       /* Make sure the panel is off before trying to change the mode. But also
+        * ensure that we have vdd while we switch off the panel. */
        ironlake_edp_panel_vdd_on(intel_dp);
+       ironlake_edp_backlight_off(intel_dp);
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       ironlake_edp_panel_off(intel_dp);
        intel_dp_link_down(intel_dp);
-       ironlake_edp_panel_vdd_off(intel_dp, false);
-
-       /* Make sure the panel is off before trying to
-        * change the mode
-        */
 }
 
 static void intel_dp_commit(struct drm_encoder *encoder)
@@ -1261,13 +1321,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
-               ironlake_edp_backlight_off(intel_dp);
-               ironlake_edp_panel_off(intel_dp);
-
+               /* Switching the panel off requires vdd. */
                ironlake_edp_panel_vdd_on(intel_dp);
+               ironlake_edp_backlight_off(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
+               ironlake_edp_panel_off(intel_dp);
                intel_dp_link_down(intel_dp);
-               ironlake_edp_panel_vdd_off(intel_dp, false);
 
                if (is_cpu_edp(intel_dp))
                        ironlake_edp_pll_off(encoder);
@@ -1375,34 +1434,59 @@ static char     *link_train_names[] = {
  * These are source-specific values; current Intel hardware supports
  * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
  */
-#define I830_DP_VOLTAGE_MAX        DP_TRAIN_VOLTAGE_SWING_800
-#define I830_DP_VOLTAGE_MAX_CPT            DP_TRAIN_VOLTAGE_SWING_1200
 
 static uint8_t
-intel_dp_pre_emphasis_max(uint8_t voltage_swing)
+intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
-       switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-       case DP_TRAIN_VOLTAGE_SWING_400:
-               return DP_TRAIN_PRE_EMPHASIS_6;
-       case DP_TRAIN_VOLTAGE_SWING_600:
-               return DP_TRAIN_PRE_EMPHASIS_6;
-       case DP_TRAIN_VOLTAGE_SWING_800:
-               return DP_TRAIN_PRE_EMPHASIS_3_5;
-       case DP_TRAIN_VOLTAGE_SWING_1200:
-       default:
-               return DP_TRAIN_PRE_EMPHASIS_0;
+       struct drm_device *dev = intel_dp->base.base.dev;
+
+       if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
+               return DP_TRAIN_VOLTAGE_SWING_800;
+       else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+               return DP_TRAIN_VOLTAGE_SWING_1200;
+       else
+               return DP_TRAIN_VOLTAGE_SWING_800;
+}
+
+static uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+{
+       struct drm_device *dev = intel_dp->base.base.dev;
+
+       if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
+               switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+               case DP_TRAIN_VOLTAGE_SWING_400:
+                       return DP_TRAIN_PRE_EMPHASIS_6;
+               case DP_TRAIN_VOLTAGE_SWING_600:
+               case DP_TRAIN_VOLTAGE_SWING_800:
+                       return DP_TRAIN_PRE_EMPHASIS_3_5;
+               default:
+                       return DP_TRAIN_PRE_EMPHASIS_0;
+               }
+       } else {
+               switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+               case DP_TRAIN_VOLTAGE_SWING_400:
+                       return DP_TRAIN_PRE_EMPHASIS_6;
+               case DP_TRAIN_VOLTAGE_SWING_600:
+                       return DP_TRAIN_PRE_EMPHASIS_6;
+               case DP_TRAIN_VOLTAGE_SWING_800:
+                       return DP_TRAIN_PRE_EMPHASIS_3_5;
+               case DP_TRAIN_VOLTAGE_SWING_1200:
+               default:
+                       return DP_TRAIN_PRE_EMPHASIS_0;
+               }
        }
 }
 
 static void
 intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
-       struct drm_device *dev = intel_dp->base.base.dev;
        uint8_t v = 0;
        uint8_t p = 0;
        int lane;
        uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS);
-       int voltage_max;
+       uint8_t voltage_max;
+       uint8_t preemph_max;
 
        for (lane = 0; lane < intel_dp->lane_count; lane++) {
                uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane);
@@ -1414,15 +1498,13 @@ intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_ST
                        p = this_p;
        }
 
-       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
-               voltage_max = I830_DP_VOLTAGE_MAX_CPT;
-       else
-               voltage_max = I830_DP_VOLTAGE_MAX;
+       voltage_max = intel_dp_voltage_max(intel_dp);
        if (v >= voltage_max)
                v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
-       if (p >= intel_dp_pre_emphasis_max(v))
-               p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+       preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
+       if (p >= preemph_max)
+               p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
        for (lane = 0; lane < 4; lane++)
                intel_dp->train_set[lane] = v | p;
@@ -1494,6 +1576,37 @@ intel_gen6_edp_signal_levels(uint8_t train_set)
        }
 }
 
+/* Gen7's DP voltage swing and pre-emphasis control */
+static uint32_t
+intel_gen7_edp_signal_levels(uint8_t train_set)
+{
+       int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+                                        DP_TRAIN_PRE_EMPHASIS_MASK);
+       switch (signal_levels) {
+       case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
+               return EDP_LINK_TRAIN_400MV_0DB_IVB;
+       case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
+               return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+       case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
+               return EDP_LINK_TRAIN_400MV_6DB_IVB;
+
+       case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
+               return EDP_LINK_TRAIN_600MV_0DB_IVB;
+       case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
+               return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+
+       case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
+               return EDP_LINK_TRAIN_800MV_0DB_IVB;
+       case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
+               return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+
+       default:
+               DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+                             "0x%x\n", signal_levels);
+               return EDP_LINK_TRAIN_500MV_0DB_IVB;
+       }
+}
+
 static uint8_t
 intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
                      int lane)
@@ -1599,7 +1712,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                                  DP_LINK_CONFIGURATION_SIZE);
 
        DP |= DP_PORT_EN;
-       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+
+       if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
                DP &= ~DP_LINK_TRAIN_MASK_CPT;
        else
                DP &= ~DP_LINK_TRAIN_MASK;
@@ -1613,7 +1727,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                uint8_t     link_status[DP_LINK_STATUS_SIZE];
                uint32_t    signal_levels;
 
-               if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
+
+               if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
+                       signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]);
+                       DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels;
+               } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
@@ -1622,7 +1740,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
-               if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+               if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
                        reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
                else
                        reg = DP | DP_LINK_TRAIN_PAT_1;
@@ -1703,7 +1821,10 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        break;
                }
 
-               if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
+               if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
+                       signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]);
+                       DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels;
+               } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
@@ -1711,7 +1832,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
-               if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+               if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
                        reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
                else
                        reg = DP | DP_LINK_TRAIN_PAT_2;
@@ -1752,7 +1873,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                ++tries;
        }
 
-       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+       if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
                reg = DP | DP_LINK_TRAIN_OFF_CPT;
        else
                reg = DP | DP_LINK_TRAIN_OFF;
@@ -1782,7 +1903,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
                udelay(100);
        }
 
-       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) {
+       if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
                DP &= ~DP_LINK_TRAIN_MASK_CPT;
                I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
        } else {
@@ -1794,7 +1915,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        msleep(17);
 
        if (is_edp(intel_dp)) {
-               if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+               if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
                        DP |= DP_LINK_TRAIN_OFF_CPT;
                else
                        DP |= DP_LINK_TRAIN_OFF;
@@ -1833,6 +1954,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
                        intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
        }
 
+       DP &= ~DP_AUDIO_OUTPUT_ENABLE;
        I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(intel_dp->output_reg);
        msleep(intel_dp->panel_power_down_delay);
@@ -2170,11 +2292,6 @@ done:
 static void
 intel_dp_destroy(struct drm_connector *connector)
 {
-       struct drm_device *dev = connector->dev;
-
-       if (intel_dpd_is_edp(dev))
-               intel_panel_destroy_backlight(dev);
-
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
        kfree(connector);