aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-06-29 21:46:17 -0400
committerEric Anholt <eric@anholt.net>2010-07-01 18:33:19 -0400
commitfe27d53e5c597ee5ba5d72a29d517091f244e974 (patch)
tree4c29d58dc8fa06ffbf12c35ea570328ffa4736d0 /drivers
parentadcdbc6651a7086b99827cf50623a02d941261f1 (diff)
i915: fix ironlake edp panel setup (v4)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 49b54f05d3cf..1aac59e83bff 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -136,6 +136,12 @@ intel_dp_link_required(struct drm_device *dev,
136} 136}
137 137
138static int 138static int
139intel_dp_max_data_rate(int max_link_clock, int max_lanes)
140{
141 return (max_link_clock * max_lanes * 8) / 10;
142}
143
144static int
139intel_dp_mode_valid(struct drm_connector *connector, 145intel_dp_mode_valid(struct drm_connector *connector,
140 struct drm_display_mode *mode) 146 struct drm_display_mode *mode)
141{ 147{
@@ -144,8 +150,11 @@ intel_dp_mode_valid(struct drm_connector *connector,
144 int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); 150 int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
145 int max_lanes = intel_dp_max_lane_count(intel_encoder); 151 int max_lanes = intel_dp_max_lane_count(intel_encoder);
146 152
147 if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) 153 /* only refuse the mode on non eDP since we have seen some wierd eDP panels
148 > max_link_clock * max_lanes) 154 which are outside spec tolerances but somehow work by magic */
155 if (!IS_eDP(intel_encoder) &&
156 (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
157 > intel_dp_max_data_rate(max_link_clock, max_lanes)))
149 return MODE_CLOCK_HIGH; 158 return MODE_CLOCK_HIGH;
150 159
151 if (mode->clock < 10000) 160 if (mode->clock < 10000)
@@ -506,7 +515,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
506 515
507 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { 516 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
508 for (clock = 0; clock <= max_clock; clock++) { 517 for (clock = 0; clock <= max_clock; clock++) {
509 int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; 518 int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
510 519
511 if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) 520 if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
512 <= link_avail) { 521 <= link_avail) {
@@ -521,6 +530,18 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
521 } 530 }
522 } 531 }
523 } 532 }
533
534 if (IS_eDP(intel_encoder)) {
535 /* okay we failed just pick the highest */
536 dp_priv->lane_count = max_lane_count;
537 dp_priv->link_bw = bws[max_clock];
538 adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
539 DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
540 "count %d clock %d\n",
541 dp_priv->link_bw, dp_priv->lane_count,
542 adjusted_mode->clock);
543 return true;
544 }
524 return false; 545 return false;
525} 546}
526 547