From 170583cfb7a04287b22e2ef6b8f2a0d2894d2f39 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 30 Jun 2010 11:46:17 +1000 Subject: [PATCH] --- yaml --- r: 200756 b: refs/heads/master c: fe27d53e5c597ee5ba5d72a29d517091f244e974 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index aab6738e28ce..1488ff1c4934 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: adcdbc6651a7086b99827cf50623a02d941261f1 +refs/heads/master: fe27d53e5c597ee5ba5d72a29d517091f244e974 diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 49b54f05d3cf..1aac59e83bff 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -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) @@ -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) @@ -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) { @@ -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; }