eDP panels are often fixed-rate. Grab the link speed and lane count from the VBT and use those instead of trying to compute them.
Signed-off-by: Adam Jackson <a...@redhat.com> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_bios.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 0 deletions(-) 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; -- 1.7.0.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx