drm/i915: Parse the eDP link configuration from the vBIOS

First step, lets have a look at the values for troublesome panels and
see if they may be used to improve our link training.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6aa3431..cbfb99d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -338,9 +338,18 @@
 	unsigned int lvds_vbt:1;
 	unsigned int int_crt_support:1;
 	unsigned int lvds_use_ssc:1;
-	unsigned int edp_support:1;
 	int lvds_ssc_freq;
-	int edp_bpp;
+
+	struct {
+		u8 rate:4;
+		u8 lanes:4;
+		u8 preemphasis:4;
+		u8 vswing:4;
+
+		u8 initialized:1;
+		u8 support:1;
+		u8 bpp:6;
+	} edp;
 
 	struct notifier_block lid_notifier;
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 123e31d..42a7a5b 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -401,14 +401,11 @@
 	if (!driver)
 		return;
 
-	if (driver && SUPPORTS_EDP(dev) &&
-	    driver->lvds_config == BDB_DRIVER_FEATURE_EDP) {
-		dev_priv->edp_support = 1;
-	} else {
-		dev_priv->edp_support = 0;
-	}
+	if (SUPPORTS_EDP(dev) &&
+	    driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+		dev_priv->edp.support = 1;
 
-	if (driver && driver->dual_frequency)
+	if (driver->dual_frequency)
 		dev_priv->render_reclock_avail = true;
 }
 
@@ -417,28 +414,44 @@
 {
 	struct bdb_edp *edp;
 
+	dev_priv->edp.bpp = 18;
+
 	edp = find_section(bdb, BDB_EDP);
 	if (!edp) {
-		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) {
+		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) {
 			DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
-				      "supported, assume 18bpp panel color "
-				      "depth.\n");
-			dev_priv->edp_bpp = 18;
+				      "supported, assume %dbpp panel color "
+				      "depth.\n",
+				      dev_priv->edp.bpp);
 		}
 		return;
 	}
 
 	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
 	case EDP_18BPP:
-		dev_priv->edp_bpp = 18;
+		dev_priv->edp.bpp = 18;
 		break;
 	case EDP_24BPP:
-		dev_priv->edp_bpp = 24;
+		dev_priv->edp.bpp = 24;
 		break;
 	case EDP_30BPP:
-		dev_priv->edp_bpp = 30;
+		dev_priv->edp.bpp = 30;
 		break;
 	}
+
+	dev_priv->edp.rate = edp->link_params[panel_type].rate;
+	dev_priv->edp.lanes = edp->link_params[panel_type].lanes;
+	dev_priv->edp.preemphasis = edp->link_params[panel_type].preemphasis;
+	dev_priv->edp.vswing = edp->link_params[panel_type].vswing;
+
+	DRM_DEBUG_KMS("eDP vBIOS settings: bpp=%d, rate=%d, lanes=%d, preemphasis=%d, vswing=%d\n",
+		      dev_priv->edp.bpp,
+		      dev_priv->edp.rate,
+		      dev_priv->edp.lanes,
+		      dev_priv->edp.preemphasis,
+		      dev_priv->edp.vswing);
+
+	dev_priv->edp.initialized = true;
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6fbaa63..4843d02 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3705,7 +3705,7 @@
 			else
 				temp |= PIPE_6BPC;
 		} else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) {
-			switch (dev_priv->edp_bpp/3) {
+			switch (dev_priv->edp.bpp/3) {
 			case 8:
 				temp |= PIPE_8BPC;
 				break;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ec26ee7..117eb99 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -139,7 +139,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
-		return (pixel_clock * dev_priv->edp_bpp) / 8;
+		return (pixel_clock * dev_priv->edp.bpp + 7) / 8;
 	else
 		return pixel_clock * 3;
 }
@@ -653,7 +653,7 @@
 		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
 			lane_count = intel_dp->lane_count;
 			if (IS_PCH_eDP(intel_dp))
-				bpp = dev_priv->edp_bpp;
+				bpp = dev_priv->edp.bpp;
 			break;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 95e035a..98172bc 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -864,7 +864,7 @@
 	if (HAS_PCH_SPLIT(dev)) {
 		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
 			return;
-		if (dev_priv->edp_support) {
+		if (dev_priv->edp.support) {
 			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
 			return;
 		}