@@ -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;
@@ -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
@@ -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;