diff mbox

drm/i915/edp: Use fixed panel timing information from VBT

Message ID 1273678193-4697-2-git-send-email-ajax@redhat.com (mailing list archive)
State Deferred, archived
Headers show

Commit Message

Adam Jackson May 12, 2010, 3:29 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7f797ef..78212c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -326,6 +326,8 @@  typedef struct drm_i915_private {
 	unsigned int edp_support:1;
 	int lvds_ssc_freq;
 	int edp_bpp;
+	int edp_link_bw;
+	int edp_lane_count;
 
 	struct notifier_block lid_notifier;
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4c748d8..ac60a6f 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -26,6 +26,7 @@ 
  */
 #include "drmP.h"
 #include "drm.h"
+#include "drm_dp_helper.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "intel_bios.h"
@@ -437,6 +438,23 @@  parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 		dev_priv->edp_bpp = 30;
 		break;
 	}
+
+	if (edp->link_params[panel_type].rate == EDP_RATE_1_62)
+	    dev_priv->edp_link_bw = DP_LINK_BW_1_62;
+	else
+	    dev_priv->edp_link_bw = DP_LINK_BW_2_7;
+
+	switch (edp->link_params[panel_type].lanes) {
+	case EDP_LANE_1:
+	    dev_priv->edp_lane_count = 1;
+	    break;
+	case EDP_LANE_2:
+	    dev_priv->edp_lane_count = 2;
+	    break;
+	case EDP_LANE_4:
+	    dev_priv->edp_lane_count = 4;
+	    break;
+	}
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f6299bb..c77c567 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -494,6 +494,31 @@  intel_dp_i2c_init(struct intel_encoder *intel_encoder,
 }
 
 static bool
+intel_edp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		     struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+
+	/* the VBT tells us what the panel demands. hopefully it exists. */
+	if (dev_priv->edp_lane_count == 0) {
+		DRM_DEBUG_KMS("no eDP block found, guessing parameters\n");
+		return false;
+	}
+
+	dp_priv->link_bw = dev_priv->edp_link_bw;
+	dp_priv->lane_count = dev_priv->edp_lane_count;
+	adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
+
+	DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n",
+		      dp_priv->link_bw, dp_priv->lane_count,
+		      adjusted_mode->clock);
+
+	return true;
+}
+
+static bool
 intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		    struct drm_display_mode *adjusted_mode)
 {
@@ -504,6 +529,10 @@  intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
+	if (IS_eDP(intel_encoder))
+	    if (intel_edp_mode_fixup(encoder, mode, adjusted_mode))
+		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_link_clock(bws[clock]) * lane_count;