Skip to content

Commit

Permalink
i915: fix ironlake edp panel setup (v4)
Browse files Browse the repository at this point in the history
The eDP spec claims a 20% overhead for the 8:10 encoding scheme used
on the wire. Take this into account when picking the lane/clock speed
for the panel.

v3: some panels are out of spec, try our best to deal with them, don't
refuse modes on eDP panels, and try the largest allowed settings if
all else fails on eDP.
v4: fix stupid typo, forgot to git add before amending.

Fixes several reports in bugzilla:

      https://bugs.freedesktop.org/show_bug.cgi?id=28070

Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
  • Loading branch information
Dave Airlie authored and Eric Anholt committed Jul 1, 2010
1 parent adcdbc6 commit fe27d53
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ intel_dp_link_required(struct drm_device *dev,
return pixel_clock * 3;
}

static int
intel_dp_max_data_rate(int max_link_clock, int max_lanes)
{
return (max_link_clock * max_lanes * 8) / 10;
}

static int
intel_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
Expand All @@ -144,8 +150,11 @@ intel_dp_mode_valid(struct drm_connector *connector,
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
int max_lanes = intel_dp_max_lane_count(intel_encoder);

if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
> max_link_clock * max_lanes)
/* only refuse the mode on non eDP since we have seen some wierd eDP panels
which are outside spec tolerances but somehow work by magic */
if (!IS_eDP(intel_encoder) &&
(intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
> intel_dp_max_data_rate(max_link_clock, max_lanes)))
return MODE_CLOCK_HIGH;

if (mode->clock < 10000)
Expand Down Expand Up @@ -506,7 +515,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,

for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);

if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
<= link_avail) {
Expand All @@ -521,6 +530,18 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
}
}
}

if (IS_eDP(intel_encoder)) {
/* okay we failed just pick the highest */
dp_priv->lane_count = max_lane_count;
dp_priv->link_bw = bws[max_clock];
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
"count %d clock %d\n",
dp_priv->link_bw, dp_priv->lane_count,
adjusted_mode->clock);
return true;
}
return false;
}

Expand Down

0 comments on commit fe27d53

Please sign in to comment.