Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218300
b: refs/heads/master
c: 869184a
h: refs/heads/master
v: v3
  • Loading branch information
Jesse Barnes authored and Chris Wilson committed Oct 8, 2010
1 parent 3d42cac commit fab3fb5
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 896673836b8c55b75e7d7d2741aaaadff0c6a038
refs/heads/master: 869184a675662bddcdf76c5b95665272facff2b8
146 changes: 89 additions & 57 deletions trunk/drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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)
{
uint32_t signal_levels = 0;
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;

switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
if (is_edp(intel_dp)) {
vswing = dev_priv->edp.vswing;
preemphasis = dev_priv->edp.preemphasis;
}

switch (vswing) {
case DP_TRAIN_VOLTAGE_SWING_400:
default:
signal_levels |= DP_VOLTAGE_0_4;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -1237,10 +1260,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
POSTING_READ(intel_dp->output_reg);
intel_wait_for_vblank(dev, intel_crtc->pipe);

/* Write the link configuration data */
intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
intel_dp->link_configuration,
DP_LINK_CONFIGURATION_SIZE);
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,
DP_LINK_CONFIGURATION_SIZE);

DP |= DP_PORT_EN;
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
Expand All @@ -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;
}

Expand All @@ -1272,33 +1296,37 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
break;
/* Set training pattern 1 */

udelay(100);
if (!intel_dp_get_link_status(intel_dp))
udelay(500);
if (intel_dp_aux_handshake_required(intel_dp)) {
break;
} else {
if (!intel_dp_get_link_status(intel_dp))
break;

if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
clock_recovery = true;
break;
}

/* Check to see if we've tried the max voltage */
for (i = 0; i < intel_dp->lane_count; i++)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
clock_recovery = true;
break;
if (i == intel_dp->lane_count)
break;
}

/* Check to see if we've tried the same voltage 5 times */
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
++tries;
if (tries == 5)
/* Check to see if we've tried the max voltage */
for (i = 0; i < intel_dp->lane_count; i++)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
if (i == intel_dp->lane_count)
break;
} else
tries = 0;
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;

/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp);
/* Check to see if we've tried the same voltage 5 times */
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
++tries;
if (tries == 5)
break;
} else
tries = 0;
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;

/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp);
}
}

intel_dp->DP = DP;
Expand All @@ -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;
}

Expand All @@ -1339,24 +1367,28 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
DP_TRAINING_PATTERN_2))
break;

udelay(400);
if (!intel_dp_get_link_status(intel_dp))
break;
udelay(500);

if (intel_channel_eq_ok(intel_dp)) {
channel_eq = true;
if (!intel_dp_aux_handshake_required(intel_dp)) {
break;
}
} else {
if (!intel_dp_get_link_status(intel_dp))
break;

/* Try 5 times */
if (tries > 5)
break;
if (intel_channel_eq_ok(intel_dp)) {
channel_eq = true;
break;
}

/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp);
++tries;
}
/* Try 5 times */
if (tries > 5)
break;

/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp);
++tries;
}
}
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
reg = DP | DP_LINK_TRAIN_OFF_CPT;
else
Expand Down

0 comments on commit fab3fb5

Please sign in to comment.