diff mbox

[stable] i915: fix ironlake edp panel setup (v4)

Message ID alpine.DEB.2.00.1008111504510.865@hungry
State Awaiting Upstream
Delegated to: Steve Conklin
Headers show

Commit Message

Manoj Iyer Aug. 11, 2010, 8:13 p.m. UTC
Please consider the following upstream commits to stable 2.6.34.y

1. i915: fix ironlake edp panel setup (v4)
    SHAID: fe27d53e5c597ee5ba5d72a29d517091f244e974

These patches fix video issues on Dell Latitude E6410. Reported in bug:

http://launchpad.net/bugs/561802

The patch apply cleanly to 2.6.34.y. They were tested by James Ferguson @ 
canonical and his test results can be found at the bottom of the bug 
report. The stable kernel was tested on E6410 & E6510 Dell systems and 
reported to solve display issues. Please find attached the patch that was 
applied to the 2.6.34.y stable tree.


Cheers
--- manjo

Comments

Greg KH Aug. 11, 2010, 8:29 p.m. UTC | #1
On Wed, Aug 11, 2010 at 03:13:59PM -0500, Manoj Iyer wrote:
> 
> Please consider the following upstream commits to stable 2.6.34.y
> 
> 1. i915: fix ironlake edp panel setup (v4)
>    SHAID: fe27d53e5c597ee5ba5d72a29d517091f244e974
> 
> These patches fix video issues on Dell Latitude E6410. Reported in bug:
> 
> http://launchpad.net/bugs/561802
> 
> The patch apply cleanly to 2.6.34.y. They were tested by James
> Ferguson @ canonical and his test results can be found at the bottom
> of the bug report. The stable kernel was tested on E6410 & E6510
> Dell systems and reported to solve display issues. Please find
> attached the patch that was applied to the 2.6.34.y stable tree.

Now queued up.

thanks,

greg k-h
diff mbox

Patch

From 2d7593023c89c046fea7dd0c10accec63afd0482 Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@redhat.com>
Date: Wed, 30 Jun 2010 11:46:17 +1000
Subject: [PATCH] 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>
(cherry picked from commit fe27d53e5c597ee5ba5d72a29d517091f244e974)

Signed-off-by: Manoj Iyer <manoj.iyer@canonical.com>

Buglink: http://launchpad.net/bugs/561802
---
 drivers/gpu/drm/i915/intel_dp.c |   27 ++++++++++++++++++++++++---
 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 a9ec41d..f3902d3 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -138,6 +138,12 @@  intel_dp_link_required(struct drm_device *dev,
 }
 
 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)
 {
@@ -145,8 +151,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)
@@ -498,7 +507,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) {
@@ -513,6 +522,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;
 }
 
-- 
1.7.0.4