Loading drivers/gpu/drm/i915/intel_dp.c +89 −57 Original line number Diff line number Diff line Loading @@ -581,6 +581,17 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, mode->clock = dev_priv->panel_fixed_mode->clock; } /* Just use VBT values for eDP */ if (is_edp(intel_dp)) { intel_dp->lane_count = dev_priv->edp.lanes; intel_dp->link_bw = dev_priv->edp.rate; adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n", intel_dp->link_bw, intel_dp->lane_count, adjusted_mode->clock); return true; } for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); Loading @@ -599,19 +610,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, } } if (is_edp(intel_dp)) { /* okay we failed just pick the highest */ intel_dp->lane_count = max_lane_count; intel_dp->link_bw = bws[max_clock]; adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); DRM_DEBUG_KMS("Force picking display port link bw %02x lane " "count %d clock %d\n", intel_dp->link_bw, intel_dp->lane_count, adjusted_mode->clock); return true; } return false; } Loading Loading @@ -1088,11 +1086,21 @@ intel_get_adjust_train(struct intel_dp *intel_dp) } static uint32_t intel_dp_signal_levels(uint8_t train_set, int lane_count) intel_dp_signal_levels(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t signal_levels = 0; u8 train_set = intel_dp->train_set[0]; u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK; u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK; if (is_edp(intel_dp)) { vswing = dev_priv->edp.vswing; preemphasis = dev_priv->edp.preemphasis; } switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { switch (vswing) { case DP_TRAIN_VOLTAGE_SWING_400: default: signal_levels |= DP_VOLTAGE_0_4; Loading @@ -1107,7 +1115,7 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count) signal_levels |= DP_VOLTAGE_1_2; break; } switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { switch (preemphasis) { case DP_TRAIN_PRE_EMPHASIS_0: default: signal_levels |= DP_PRE_EMPHASIS_0; Loading Loading @@ -1193,6 +1201,18 @@ intel_channel_eq_ok(struct intel_dp *intel_dp) return true; } static bool intel_dp_aux_handshake_required(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; if (is_edp(intel_dp) && dev_priv->no_aux_handshake) return false; return true; } static bool intel_dp_set_link_train(struct intel_dp *intel_dp, uint32_t dp_reg_value, Loading @@ -1205,6 +1225,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, I915_WRITE(intel_dp->output_reg, dp_reg_value); POSTING_READ(intel_dp->output_reg); if (!intel_dp_aux_handshake_required(intel_dp)) return true; intel_dp_aux_native_write_1(intel_dp, DP_TRAINING_PATTERN_SET, dp_train_pat); Loading Loading @@ -1237,6 +1260,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) POSTING_READ(intel_dp->output_reg); intel_wait_for_vblank(dev, intel_crtc->pipe); if (intel_dp_aux_handshake_required(intel_dp)) /* Write the link configuration data */ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, intel_dp->link_configuration, Loading @@ -1258,7 +1282,7 @@ intel_dp_start_link_train(struct intel_dp *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 { signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); signal_levels = intel_dp_signal_levels(intel_dp); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; } Loading @@ -1272,7 +1296,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) break; /* Set training pattern 1 */ udelay(100); udelay(500); if (intel_dp_aux_handshake_required(intel_dp)) { break; } else { if (!intel_dp_get_link_status(intel_dp)) break; Loading Loading @@ -1300,6 +1327,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) /* Compute new intel_dp->train_set as requested by target */ intel_get_adjust_train(intel_dp); } } intel_dp->DP = DP; } Loading @@ -1325,7 +1353,7 @@ intel_dp_complete_link_train(struct intel_dp *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 { signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); signal_levels = intel_dp_signal_levels(intel_dp); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; } Loading @@ -1339,7 +1367,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) DP_TRAINING_PATTERN_2)) break; udelay(400); udelay(500); if (!intel_dp_aux_handshake_required(intel_dp)) { break; } else { if (!intel_dp_get_link_status(intel_dp)) break; Loading @@ -1356,7 +1388,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) intel_get_adjust_train(intel_dp); ++tries; } } if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) reg = DP | DP_LINK_TRAIN_OFF_CPT; else Loading Loading
drivers/gpu/drm/i915/intel_dp.c +89 −57 Original line number Diff line number Diff line Loading @@ -581,6 +581,17 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, mode->clock = dev_priv->panel_fixed_mode->clock; } /* Just use VBT values for eDP */ if (is_edp(intel_dp)) { intel_dp->lane_count = dev_priv->edp.lanes; intel_dp->link_bw = dev_priv->edp.rate; adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n", intel_dp->link_bw, intel_dp->lane_count, adjusted_mode->clock); return true; } for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); Loading @@ -599,19 +610,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, } } if (is_edp(intel_dp)) { /* okay we failed just pick the highest */ intel_dp->lane_count = max_lane_count; intel_dp->link_bw = bws[max_clock]; adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); DRM_DEBUG_KMS("Force picking display port link bw %02x lane " "count %d clock %d\n", intel_dp->link_bw, intel_dp->lane_count, adjusted_mode->clock); return true; } return false; } Loading Loading @@ -1088,11 +1086,21 @@ intel_get_adjust_train(struct intel_dp *intel_dp) } static uint32_t intel_dp_signal_levels(uint8_t train_set, int lane_count) intel_dp_signal_levels(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t signal_levels = 0; u8 train_set = intel_dp->train_set[0]; u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK; u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK; if (is_edp(intel_dp)) { vswing = dev_priv->edp.vswing; preemphasis = dev_priv->edp.preemphasis; } switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { switch (vswing) { case DP_TRAIN_VOLTAGE_SWING_400: default: signal_levels |= DP_VOLTAGE_0_4; Loading @@ -1107,7 +1115,7 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count) signal_levels |= DP_VOLTAGE_1_2; break; } switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { switch (preemphasis) { case DP_TRAIN_PRE_EMPHASIS_0: default: signal_levels |= DP_PRE_EMPHASIS_0; Loading Loading @@ -1193,6 +1201,18 @@ intel_channel_eq_ok(struct intel_dp *intel_dp) return true; } static bool intel_dp_aux_handshake_required(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; if (is_edp(intel_dp) && dev_priv->no_aux_handshake) return false; return true; } static bool intel_dp_set_link_train(struct intel_dp *intel_dp, uint32_t dp_reg_value, Loading @@ -1205,6 +1225,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, I915_WRITE(intel_dp->output_reg, dp_reg_value); POSTING_READ(intel_dp->output_reg); if (!intel_dp_aux_handshake_required(intel_dp)) return true; intel_dp_aux_native_write_1(intel_dp, DP_TRAINING_PATTERN_SET, dp_train_pat); Loading Loading @@ -1237,6 +1260,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) POSTING_READ(intel_dp->output_reg); intel_wait_for_vblank(dev, intel_crtc->pipe); if (intel_dp_aux_handshake_required(intel_dp)) /* Write the link configuration data */ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, intel_dp->link_configuration, Loading @@ -1258,7 +1282,7 @@ intel_dp_start_link_train(struct intel_dp *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 { signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); signal_levels = intel_dp_signal_levels(intel_dp); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; } Loading @@ -1272,7 +1296,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) break; /* Set training pattern 1 */ udelay(100); udelay(500); if (intel_dp_aux_handshake_required(intel_dp)) { break; } else { if (!intel_dp_get_link_status(intel_dp)) break; Loading Loading @@ -1300,6 +1327,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) /* Compute new intel_dp->train_set as requested by target */ intel_get_adjust_train(intel_dp); } } intel_dp->DP = DP; } Loading @@ -1325,7 +1353,7 @@ intel_dp_complete_link_train(struct intel_dp *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 { signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); signal_levels = intel_dp_signal_levels(intel_dp); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; } Loading @@ -1339,7 +1367,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) DP_TRAINING_PATTERN_2)) break; udelay(400); udelay(500); if (!intel_dp_aux_handshake_required(intel_dp)) { break; } else { if (!intel_dp_get_link_status(intel_dp)) break; Loading @@ -1356,7 +1388,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) intel_get_adjust_train(intel_dp); ++tries; } } if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) reg = DP | DP_LINK_TRAIN_OFF_CPT; else Loading