Commit 5ceb0f9b authored by Chris Wilson's avatar Chris Wilson

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 270eea0f
...@@ -338,9 +338,18 @@ typedef struct drm_i915_private { ...@@ -338,9 +338,18 @@ typedef struct drm_i915_private {
unsigned int lvds_vbt:1; unsigned int lvds_vbt:1;
unsigned int int_crt_support:1; unsigned int int_crt_support:1;
unsigned int lvds_use_ssc:1; unsigned int lvds_use_ssc:1;
unsigned int edp_support:1;
int lvds_ssc_freq; 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; struct notifier_block lid_notifier;
......
...@@ -401,14 +401,11 @@ parse_driver_features(struct drm_i915_private *dev_priv, ...@@ -401,14 +401,11 @@ parse_driver_features(struct drm_i915_private *dev_priv,
if (!driver) if (!driver)
return; return;
if (driver && SUPPORTS_EDP(dev) && if (SUPPORTS_EDP(dev) &&
driver->lvds_config == BDB_DRIVER_FEATURE_EDP) { driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
dev_priv->edp_support = 1; dev_priv->edp.support = 1;
} else {
dev_priv->edp_support = 0;
}
if (driver && driver->dual_frequency) if (driver->dual_frequency)
dev_priv->render_reclock_avail = true; dev_priv->render_reclock_avail = true;
} }
...@@ -417,28 +414,44 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) ...@@ -417,28 +414,44 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
{ {
struct bdb_edp *edp; struct bdb_edp *edp;
dev_priv->edp.bpp = 18;
edp = find_section(bdb, BDB_EDP); edp = find_section(bdb, BDB_EDP);
if (!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 " DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
"supported, assume 18bpp panel color " "supported, assume %dbpp panel color "
"depth.\n"); "depth.\n",
dev_priv->edp_bpp = 18; dev_priv->edp.bpp);
} }
return; return;
} }
switch ((edp->color_depth >> (panel_type * 2)) & 3) { switch ((edp->color_depth >> (panel_type * 2)) & 3) {
case EDP_18BPP: case EDP_18BPP:
dev_priv->edp_bpp = 18; dev_priv->edp.bpp = 18;
break; break;
case EDP_24BPP: case EDP_24BPP:
dev_priv->edp_bpp = 24; dev_priv->edp.bpp = 24;
break; break;
case EDP_30BPP: case EDP_30BPP:
dev_priv->edp_bpp = 30; dev_priv->edp.bpp = 30;
break; 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 static void
......
...@@ -3705,7 +3705,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, ...@@ -3705,7 +3705,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
else else
temp |= PIPE_6BPC; temp |= PIPE_6BPC;
} else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) { } 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: case 8:
temp |= PIPE_8BPC; temp |= PIPE_8BPC;
break; break;
......
...@@ -139,7 +139,7 @@ intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pi ...@@ -139,7 +139,7 @@ intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pi
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) 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 else
return pixel_clock * 3; return pixel_clock * 3;
} }
...@@ -653,7 +653,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, ...@@ -653,7 +653,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
lane_count = intel_dp->lane_count; lane_count = intel_dp->lane_count;
if (IS_PCH_eDP(intel_dp)) if (IS_PCH_eDP(intel_dp))
bpp = dev_priv->edp_bpp; bpp = dev_priv->edp.bpp;
break; break;
} }
} }
......
...@@ -864,7 +864,7 @@ void intel_lvds_init(struct drm_device *dev) ...@@ -864,7 +864,7 @@ void intel_lvds_init(struct drm_device *dev)
if (HAS_PCH_SPLIT(dev)) { if (HAS_PCH_SPLIT(dev)) {
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
return; return;
if (dev_priv->edp_support) { if (dev_priv->edp.support) {
DRM_DEBUG_KMS("disable LVDS for eDP support\n"); DRM_DEBUG_KMS("disable LVDS for eDP support\n");
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment