|
@@ -1379,6 +1379,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
|
|
|
ironlake_edp_panel_on(intel_dp);
|
|
|
ironlake_edp_panel_vdd_off(intel_dp, true);
|
|
|
intel_dp_complete_link_train(intel_dp);
|
|
|
+ intel_dp_stop_link_train(intel_dp);
|
|
|
ironlake_edp_backlight_on(intel_dp);
|
|
|
}
|
|
|
|
|
@@ -1701,10 +1702,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
enum port port = intel_dig_port->port;
|
|
|
int ret;
|
|
|
- uint32_t temp;
|
|
|
|
|
|
if (HAS_DDI(dev)) {
|
|
|
- temp = I915_READ(DP_TP_CTL(port));
|
|
|
+ uint32_t temp = I915_READ(DP_TP_CTL(port));
|
|
|
|
|
|
if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
|
|
|
temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
|
|
@@ -1714,18 +1714,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|
|
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
|
|
switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
|
|
|
case DP_TRAINING_PATTERN_DISABLE:
|
|
|
-
|
|
|
- if (port != PORT_A) {
|
|
|
- temp |= DP_TP_CTL_LINK_TRAIN_IDLE;
|
|
|
- I915_WRITE(DP_TP_CTL(port), temp);
|
|
|
-
|
|
|
- if (wait_for((I915_READ(DP_TP_STATUS(port)) &
|
|
|
- DP_TP_STATUS_IDLE_DONE), 1))
|
|
|
- DRM_ERROR("Timed out waiting for DP idle patterns\n");
|
|
|
-
|
|
|
- temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
|
|
- }
|
|
|
-
|
|
|
temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
|
|
|
|
|
|
break;
|
|
@@ -1801,6 +1789,37 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
|
|
|
+{
|
|
|
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
|
|
+ struct drm_device *dev = intel_dig_port->base.base.dev;
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ enum port port = intel_dig_port->port;
|
|
|
+ uint32_t val;
|
|
|
+
|
|
|
+ if (!HAS_DDI(dev))
|
|
|
+ return;
|
|
|
+
|
|
|
+ val = I915_READ(DP_TP_CTL(port));
|
|
|
+ val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
|
|
+ val |= DP_TP_CTL_LINK_TRAIN_IDLE;
|
|
|
+ I915_WRITE(DP_TP_CTL(port), val);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * On PORT_A we can have only eDP in SST mode. There the only reason
|
|
|
+ * we need to set idle transmission mode is to work around a HW issue
|
|
|
+ * where we enable the pipe while not in idle link-training mode.
|
|
|
+ * In this case there is requirement to wait for a minimum number of
|
|
|
+ * idle patterns to be sent.
|
|
|
+ */
|
|
|
+ if (port == PORT_A)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE),
|
|
|
+ 1))
|
|
|
+ DRM_ERROR("Timed out waiting for DP idle patterns\n");
|
|
|
+}
|
|
|
+
|
|
|
/* Enable corresponding port and start training pattern 1 */
|
|
|
void
|
|
|
intel_dp_start_link_train(struct intel_dp *intel_dp)
|
|
@@ -1943,10 +1962,19 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
|
|
|
++tries;
|
|
|
}
|
|
|
|
|
|
+ intel_dp_set_idle_link_train(intel_dp);
|
|
|
+
|
|
|
+ intel_dp->DP = DP;
|
|
|
+
|
|
|
if (channel_eq)
|
|
|
DRM_DEBUG_KMS("Channel EQ done. DP Training successfull\n");
|
|
|
|
|
|
- intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE);
|
|
|
+}
|
|
|
+
|
|
|
+void intel_dp_stop_link_train(struct intel_dp *intel_dp)
|
|
|
+{
|
|
|
+ intel_dp_set_link_train(intel_dp, intel_dp->DP,
|
|
|
+ DP_TRAINING_PATTERN_DISABLE);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -2154,6 +2182,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
|
|
|
drm_get_encoder_name(&intel_encoder->base));
|
|
|
intel_dp_start_link_train(intel_dp);
|
|
|
intel_dp_complete_link_train(intel_dp);
|
|
|
+ intel_dp_stop_link_train(intel_dp);
|
|
|
}
|
|
|
}
|
|
|
|