All of lore.kernel.org
 help / color / mirror / Atom feed
* PCH eDP fixes
@ 2010-10-07 23:01 Jesse Barnes
  2010-10-07 23:01 ` [PATCH 01/20] drm/i915/dp: convert eDP checks to functions and document Jesse Barnes
                   ` (21 more replies)
  0 siblings, 22 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Here's the set of PCH eDP fixes I came up with once I received my Sony
Vaio.  I found a few, non-PCH issues in the process, and took the
opportunity to enhance our eDP support to avoid most of the DP training
if the VBIOS gives us good data.

This patchset is against ickle's drm-intel-next branch as of a few hours
ago, and is working on my test machine.  Before I rebased, I had success
reports from several users on bug
https://bugs.freedesktop.org/show_bug.cgi?id=29141.  The key change
there was to work around a newly discovered Ironlake panel power
sequencing bug (need to disable clock gating for the panel power
sequencing unit); before that change, panel bringup was very
intermittent.

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/20] drm/i915/dp: convert eDP checks to functions and document
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 02/20] drm/i915/dp: remove redundant is_pch_edp checks Jesse Barnes
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Most of the PCH eDP checks are redundant, so document the functions in
preparation for removing most of the calls.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |   92 ++++++++++++++++++++++++---------------
 1 files changed, 57 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 152d945..f2810ad 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -42,9 +42,6 @@
 
 #define DP_LINK_CONFIGURATION_SIZE	9
 
-#define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP)
-#define IS_PCH_eDP(i) ((i)->is_pch_edp)
-
 struct intel_dp {
 	struct intel_encoder base;
 	uint32_t output_reg;
@@ -62,6 +59,31 @@ struct intel_dp {
 	uint8_t link_status[DP_LINK_STATUS_SIZE];
 };
 
+/**
+ * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
+ * @intel_dp: DP struct
+ *
+ * If a CPU or PCH DP output is attached to an eDP panel, this function
+ * will return true, and false otherwise.
+ */
+static bool is_edp(struct intel_dp *intel_dp)
+{
+	return intel_dp->base.type == INTEL_OUTPUT_EDP;
+}
+
+/**
+ * is_pch_edp - is the port on the PCH and attached to an eDP panel?
+ * @intel_dp: DP struct
+ *
+ * Returns true if the given DP struct corresponds to a PCH DP port attached
+ * to an eDP panel, false otherwise.  Helpful for determining whether we
+ * may need FDI resources for a given DP output or not.
+ */
+static bool is_pch_edp(struct intel_dp *intel_dp)
+{
+	return intel_dp->is_pch_edp;
+}
+
 static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
 {
 	return container_of(encoder, struct intel_dp, base.base);
@@ -138,7 +160,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;
 
-	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 + 7) / 8;
 	else
 		return pixel_clock * 3;
@@ -160,7 +182,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
 	int max_lanes = intel_dp_max_lane_count(intel_dp);
 
-	if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
+	if ((is_edp(intel_dp) || is_pch_edp(intel_dp)) &&
 	    dev_priv->panel_fixed_mode) {
 		if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
 			return MODE_PANEL;
@@ -171,7 +193,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
 
 	/* only refuse the mode on non eDP since we have seen some wierd eDP panels
 	   which are outside spec tolerances but somehow work by magic */
-	if (!IS_eDP(intel_dp) &&
+	if (!is_edp(intel_dp) &&
 	    (intel_dp_link_required(connector->dev, intel_dp, mode->clock)
 	     > intel_dp_max_data_rate(max_link_clock, max_lanes)))
 		return MODE_CLOCK_HIGH;
@@ -258,7 +280,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 	 * Note that PCH attached eDP panels should use a 125MHz input
 	 * clock divider.
 	 */
-	if (IS_eDP(intel_dp) && !IS_PCH_eDP(intel_dp)) {
+	if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) {
 		if (IS_GEN6(dev))
 			aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */
 		else
@@ -530,7 +552,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	int max_clock = intel_dp_max_link_bw(intel_dp) == 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_dp) || IS_PCH_eDP(intel_dp)) &&
+	if ((is_edp(intel_dp) || is_pch_edp(intel_dp)) &&
 	    dev_priv->panel_fixed_mode) {
 		intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode);
 		intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
@@ -560,7 +582,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		}
 	}
 
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
 		/* okay we failed just pick the highest */
 		intel_dp->lane_count = max_lane_count;
 		intel_dp->link_bw = bws[max_clock];
@@ -652,7 +674,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		intel_dp = enc_to_intel_dp(encoder);
 		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
 			lane_count = intel_dp->lane_count;
-			if (IS_PCH_eDP(intel_dp))
+			if (is_pch_edp(intel_dp))
 				bpp = dev_priv->edp.bpp;
 			break;
 		}
@@ -720,7 +742,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
 		intel_dp->DP |= DP_SYNC_VS_HIGH;
 
-	if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+	if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
 	else
 		intel_dp->DP |= DP_LINK_TRAIN_OFF;
@@ -755,7 +777,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
 		intel_dp->DP |= DP_PIPEB_SELECT;
 
-	if (IS_eDP(intel_dp)) {
+	if (is_edp(intel_dp)) {
 		/* don't miss out required setting for eDP */
 		intel_dp->DP |= DP_PLL_ENABLE;
 		if (adjusted_mode->clock < 200000)
@@ -909,7 +931,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
 		ironlake_edp_panel_off(dev);
 		ironlake_edp_backlight_off(dev);
 		ironlake_edp_panel_vdd_on(dev);
@@ -926,12 +948,12 @@ static void intel_dp_commit(struct drm_encoder *encoder)
 
 	intel_dp_start_link_train(intel_dp);
 
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 		ironlake_edp_panel_on(dev);
 
 	intel_dp_complete_link_train(intel_dp);
 
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 		ironlake_edp_backlight_on(dev);
 	intel_dp->dpms_mode = DRM_MODE_DPMS_ON;
 }
@@ -945,21 +967,21 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
 	if (mode != DRM_MODE_DPMS_ON) {
-		if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
+		if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
 			ironlake_edp_backlight_off(dev);
 			ironlake_edp_panel_off(dev);
 		}
 		if (dp_reg & DP_PORT_EN)
 			intel_dp_link_down(intel_dp);
-		if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+		if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 			ironlake_edp_pll_off(encoder);
 	} else {
 		if (!(dp_reg & DP_PORT_EN)) {
 			intel_dp_start_link_train(intel_dp);
-			if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+			if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 				ironlake_edp_panel_on(dev);
 			intel_dp_complete_link_train(intel_dp);
-			if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+			if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 				ironlake_edp_backlight_on(dev);
 		}
 	}
@@ -1234,7 +1256,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 				  DP_LINK_CONFIGURATION_SIZE);
 
 	DP |= DP_PORT_EN;
-	if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+	if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
 		DP &= ~DP_LINK_TRAIN_MASK_CPT;
 	else
 		DP &= ~DP_LINK_TRAIN_MASK;
@@ -1245,7 +1267,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 	for (;;) {
 		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
 		uint32_t    signal_levels;
-		if (IS_GEN6(dev) && IS_eDP(intel_dp)) {
+		if (IS_GEN6(dev) && is_edp(intel_dp)) {
 			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
 			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
 		} else {
@@ -1253,7 +1275,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 		}
 
-		if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+		if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
 			reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
 		else
 			reg = DP | DP_LINK_TRAIN_PAT_1;
@@ -1312,7 +1334,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
 		uint32_t    signal_levels;
 
-		if (IS_GEN6(dev) && IS_eDP(intel_dp)) {
+		if (IS_GEN6(dev) && is_edp(intel_dp)) {
 			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
 			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
 		} else {
@@ -1320,7 +1342,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 		}
 
-		if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+		if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
 			reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
 		else
 			reg = DP | DP_LINK_TRAIN_PAT_2;
@@ -1348,7 +1370,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		++tries;
 	}
 
-	if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+	if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
 		reg = DP | DP_LINK_TRAIN_OFF_CPT;
 	else
 		reg = DP | DP_LINK_TRAIN_OFF;
@@ -1368,14 +1390,14 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
 	DRM_DEBUG_KMS("\n");
 
-	if (IS_eDP(intel_dp)) {
+	if (is_edp(intel_dp)) {
 		DP &= ~DP_PLL_ENABLE;
 		I915_WRITE(intel_dp->output_reg, DP);
 		POSTING_READ(intel_dp->output_reg);
 		udelay(100);
 	}
 
-	if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) {
+	if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) {
 		DP &= ~DP_LINK_TRAIN_MASK_CPT;
 		I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
 	} else {
@@ -1386,7 +1408,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
 	msleep(17);
 
-	if (IS_eDP(intel_dp))
+	if (is_edp(intel_dp))
 		DP |= DP_LINK_TRAIN_OFF;
 	I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
 	POSTING_READ(intel_dp->output_reg);
@@ -1425,7 +1447,7 @@ ironlake_dp_detect(struct drm_connector *connector)
 	enum drm_connector_status status;
 
 	/* Panel needs power for AUX to work */
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 		ironlake_edp_panel_vdd_on(connector->dev);
 	status = connector_status_disconnected;
 	if (intel_dp_aux_native_read(intel_dp,
@@ -1437,7 +1459,7 @@ ironlake_dp_detect(struct drm_connector *connector)
 	}
 	DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
 		      intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
 		ironlake_edp_panel_vdd_off(connector->dev);
 	return status;
 }
@@ -1504,7 +1526,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 
 	ret = intel_ddc_get_modes(connector, &intel_dp->adapter);
 	if (ret) {
-		if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
+		if ((is_edp(intel_dp) || is_pch_edp(intel_dp)) &&
 		    !dev_priv->panel_fixed_mode) {
 			struct drm_display_mode *newmode;
 			list_for_each_entry(newmode, &connector->probed_modes,
@@ -1521,7 +1543,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	}
 
 	/* if eDP has no EDID, try to use fixed panel mode from VBT */
-	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
+	if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
 		if (dev_priv->panel_fixed_mode != NULL) {
 			struct drm_display_mode *mode;
 			mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1651,7 +1673,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 		if (intel_dpd_is_edp(dev))
 			intel_dp->is_pch_edp = true;
 
-	if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) {
+	if (output_reg == DP_A || is_pch_edp(intel_dp)) {
 		type = DRM_MODE_CONNECTOR_eDP;
 		intel_encoder->type = INTEL_OUTPUT_EDP;
 	} else {
@@ -1672,7 +1694,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 	else if (output_reg == DP_D || output_reg == PCH_DP_D)
 		intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
-	if (IS_eDP(intel_dp))
+	if (is_edp(intel_dp))
 		intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
 
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
@@ -1719,7 +1741,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
 	intel_encoder->hot_plug = intel_dp_hot_plug;
 
-	if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) {
+	if (output_reg == DP_A || is_pch_edp(intel_dp)) {
 		/* initialize panel mode from VBT if available for eDP */
 		if (dev_priv->lfp_lvds_vbt_mode) {
 			dev_priv->panel_fixed_mode =
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/20] drm/i915/dp: remove redundant is_pch_edp checks
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
  2010-10-07 23:01 ` [PATCH 01/20] drm/i915/dp: convert eDP checks to functions and document Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 03/20] drm/i915/dp: correct eDP lane count and bpp Jesse Barnes
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

If is_edp is true, is_pch_edp will always be true.  So limit the calls
to the latter function to places where the distinction actually matters.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |   36 ++++++++++++++++--------------------
 1 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f2810ad..1b73663 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -160,7 +160,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;
 
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+	if (is_edp(intel_dp))
 		return (pixel_clock * dev_priv->edp.bpp + 7) / 8;
 	else
 		return pixel_clock * 3;
@@ -182,8 +182,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
 	int max_lanes = intel_dp_max_lane_count(intel_dp);
 
-	if ((is_edp(intel_dp) || is_pch_edp(intel_dp)) &&
-	    dev_priv->panel_fixed_mode) {
+	if (is_edp(intel_dp) && dev_priv->panel_fixed_mode) {
 		if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
 			return MODE_PANEL;
 
@@ -552,8 +551,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	int max_clock = intel_dp_max_link_bw(intel_dp) == 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_dp) || is_pch_edp(intel_dp)) &&
-	    dev_priv->panel_fixed_mode) {
+	if (is_edp(intel_dp) && dev_priv->panel_fixed_mode) {
 		intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode);
 		intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
 					mode, adjusted_mode);
@@ -582,7 +580,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		}
 	}
 
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
+	if (is_edp(intel_dp)) {
 		/* okay we failed just pick the highest */
 		intel_dp->lane_count = max_lane_count;
 		intel_dp->link_bw = bws[max_clock];
@@ -931,7 +929,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
+	if (is_edp(intel_dp)) {
 		ironlake_edp_panel_off(dev);
 		ironlake_edp_backlight_off(dev);
 		ironlake_edp_panel_vdd_on(dev);
@@ -948,14 +946,13 @@ static void intel_dp_commit(struct drm_encoder *encoder)
 
 	intel_dp_start_link_train(intel_dp);
 
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+	if (is_edp(intel_dp))
 		ironlake_edp_panel_on(dev);
 
 	intel_dp_complete_link_train(intel_dp);
 
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+	if (is_edp(intel_dp))
 		ironlake_edp_backlight_on(dev);
-	intel_dp->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
 static void
@@ -967,21 +964,21 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
 	if (mode != DRM_MODE_DPMS_ON) {
-		if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
+		if (is_edp(intel_dp)) {
 			ironlake_edp_backlight_off(dev);
 			ironlake_edp_panel_off(dev);
 		}
 		if (dp_reg & DP_PORT_EN)
 			intel_dp_link_down(intel_dp);
-		if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+		if (is_edp(intel_dp))
 			ironlake_edp_pll_off(encoder);
 	} else {
 		if (!(dp_reg & DP_PORT_EN)) {
 			intel_dp_start_link_train(intel_dp);
-			if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+			if (is_edp(intel_dp))
 				ironlake_edp_panel_on(dev);
 			intel_dp_complete_link_train(intel_dp);
-			if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+			if (is_edp(intel_dp))
 				ironlake_edp_backlight_on(dev);
 		}
 	}
@@ -1447,7 +1444,7 @@ ironlake_dp_detect(struct drm_connector *connector)
 	enum drm_connector_status status;
 
 	/* Panel needs power for AUX to work */
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+	if (is_edp(intel_dp))
 		ironlake_edp_panel_vdd_on(connector->dev);
 	status = connector_status_disconnected;
 	if (intel_dp_aux_native_read(intel_dp,
@@ -1459,7 +1456,7 @@ ironlake_dp_detect(struct drm_connector *connector)
 	}
 	DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
 		      intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp))
+	if (is_edp(intel_dp))
 		ironlake_edp_panel_vdd_off(connector->dev);
 	return status;
 }
@@ -1526,8 +1523,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 
 	ret = intel_ddc_get_modes(connector, &intel_dp->adapter);
 	if (ret) {
-		if ((is_edp(intel_dp) || is_pch_edp(intel_dp)) &&
-		    !dev_priv->panel_fixed_mode) {
+		if (is_edp(intel_dp) && !dev_priv->panel_fixed_mode) {
 			struct drm_display_mode *newmode;
 			list_for_each_entry(newmode, &connector->probed_modes,
 					    head) {
@@ -1543,7 +1539,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	}
 
 	/* if eDP has no EDID, try to use fixed panel mode from VBT */
-	if (is_edp(intel_dp) || is_pch_edp(intel_dp)) {
+	if (is_edp(intel_dp)) {
 		if (dev_priv->panel_fixed_mode != NULL) {
 			struct drm_display_mode *mode;
 			mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1741,7 +1737,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
 	intel_encoder->hot_plug = intel_dp_hot_plug;
 
-	if (output_reg == DP_A || is_pch_edp(intel_dp)) {
+	if (is_edp(intel_dp)) {
 		/* initialize panel mode from VBT if available for eDP */
 		if (dev_priv->lfp_lvds_vbt_mode) {
 			dev_priv->panel_fixed_mode =
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/20] drm/i915/dp: correct eDP lane count and bpp
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
  2010-10-07 23:01 ` [PATCH 01/20] drm/i915/dp: convert eDP checks to functions and document Jesse Barnes
  2010-10-07 23:01 ` [PATCH 02/20] drm/i915/dp: remove redundant is_pch_edp checks Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 04/20] drm/i915: add eDP checking functions for the display code Jesse Barnes
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

With the old check we'd never set lane_count or bpp to different values
on PCH attached eDP panels.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1b73663..714e553 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -672,8 +672,10 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		intel_dp = enc_to_intel_dp(encoder);
 		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;
+			break;
+		} else if (is_edp(intel_dp)) {
+			lane_count = dev_priv->edp.lanes;
+			bpp = dev_priv->edp.bpp;
 			break;
 		}
 	}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/20] drm/i915: add eDP checking functions for the display code
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (2 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 03/20] drm/i915/dp: correct eDP lane count and bpp Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 05/20] drm/i915: remove broken intel_pch_has_edp function Jesse Barnes
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

The display code needs to distinguish between CPU and PCH attached eDP
panels, so add some helpers to handle that.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c  |   19 +++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |    1 +
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 714e553..da71263 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -95,6 +95,25 @@ static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
 			    struct intel_dp, base);
 }
 
+/**
+ * intel_encoder_is_pch_edp - is the given encoder a PCH attached eDP?
+ * @encoder: DRM encoder
+ *
+ * Return true if @encoder corresponds to a PCH attached eDP panel.  Needed
+ * by intel_display.c.
+ */
+bool intel_encoder_is_pch_edp(struct drm_encoder *encoder)
+{
+	struct intel_dp *intel_dp;
+
+	if (!encoder)
+		return false;
+
+	intel_dp = enc_to_intel_dp(encoder);
+
+	return is_pch_edp(intel_dp);
+}
+
 static void intel_dp_start_link_train(struct intel_dp *intel_dp);
 static void intel_dp_complete_link_train(struct intel_dp *intel_dp);
 static void intel_dp_link_down(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 40e99bf..c946c48 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -212,6 +212,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 extern bool intel_pch_has_edp(struct drm_crtc *crtc);
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
+extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
 
 /* intel_panel.c */
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/20] drm/i915: remove broken intel_pch_has_edp function
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (3 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 04/20] drm/i915: add eDP checking functions for the display code Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 06/20] drm/i915: fix CPU vs PCH eDP confusion Jesse Barnes
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Since we set the output type of PCH attached eDP panels to
INTEL_OUTPUT_eDP this function would never return true when it should.
It's been replaced by working functions.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |    5 ++---
 drivers/gpu/drm/i915/intel_dp.c      |   19 -------------------
 drivers/gpu/drm/i915/intel_drv.h     |    1 -
 3 files changed, 2 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9109c00..4bd0210 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2001,8 +2001,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 
 	/* Enable panel fitting for LVDS */
 	if (dev_priv->pch_pf_size &&
-	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
-	     || HAS_eDP || intel_pch_has_edp(crtc))) {
+	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP)) {
 		/* Force use of hard-coded filter coefficients
 		 * as some pre-programmed values are broken,
 		 * e.g. x201.
@@ -3717,7 +3716,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 				temp |= PIPE_8BPC;
 			else
 				temp |= PIPE_6BPC;
-		} else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) {
+		} else if (has_edp_encoder) {
 			switch (dev_priv->edp.bpp/3) {
 			case 8:
 				temp |= PIPE_8BPC;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index da71263..57bfc3e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -648,25 +648,6 @@ intel_dp_compute_m_n(int bpp,
 	intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
 }
 
-bool intel_pch_has_edp(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct drm_encoder *encoder;
-
-	list_for_each_entry(encoder, &mode_config->encoder_list, head) {
-		struct intel_dp *intel_dp;
-
-		if (encoder->crtc != crtc)
-			continue;
-
-		intel_dp = enc_to_intel_dp(encoder);
-		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
-			return intel_dp->is_pch_edp;
-	}
-	return false;
-}
-
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		 struct drm_display_mode *adjusted_mode)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c946c48..0581e5e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -209,7 +209,6 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		 struct drm_display_mode *adjusted_mode);
-extern bool intel_pch_has_edp(struct drm_crtc *crtc);
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/20] drm/i915: fix CPU vs PCH eDP confusion
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (4 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 05/20] drm/i915: remove broken intel_pch_has_edp function Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 07/20] drm/i915/dp: eDP power sequencing fixes Jesse Barnes
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

FDI training needs to done and idle for PCH eDP and before we turn the
pipes on, and various eDP checks need to account for PCH attached eDP.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   67 ++++++++++++++++------------------
 1 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4bd0210..6903341 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -932,10 +932,6 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	intel_clock_t clock;
 
-	/* return directly when it is eDP */
-	if (HAS_eDP)
-		return true;
-
 	if (target < 200000) {
 		clock.n = 1;
 		clock.p1 = 2;
@@ -1763,6 +1759,28 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 		DRM_ERROR("FDI train 2 fail!\n");
 
 	DRM_DEBUG_KMS("FDI train done\n");
+
+	/* enable normal train */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
+	I915_WRITE(reg, temp);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	if (HAS_PCH_CPT(dev)) {
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp |= FDI_LINK_TRAIN_NORMAL_CPT;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_NONE;
+	}
+	I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
+
+	/* wait one idle pattern time */
+	POSTING_READ(reg);
+	udelay(1000);
 }
 
 static const int const snb_b_fdi_train_param [] = {
@@ -2065,28 +2083,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe)));
 	I915_WRITE(TRANS_VSYNC(pipe),  I915_READ(VSYNC(pipe)));
 
-	/* enable normal train */
-	reg = FDI_TX_CTL(pipe);
-	temp = I915_READ(reg);
-	temp &= ~FDI_LINK_TRAIN_NONE;
-	temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
-	I915_WRITE(reg, temp);
-
-	reg = FDI_RX_CTL(pipe);
-	temp = I915_READ(reg);
-	if (HAS_PCH_CPT(dev)) {
-		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
-		temp |= FDI_LINK_TRAIN_NORMAL_CPT;
-	} else {
-		temp &= ~FDI_LINK_TRAIN_NONE;
-		temp |= FDI_LINK_TRAIN_NONE;
-	}
-	I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
-
-	/* wait one idle pattern time */
-	POSTING_READ(reg);
-	udelay(100);
-
 	/* For PCH DP, enable TRANS_DP_CTL */
 	if (HAS_PCH_CPT(dev) &&
 	    intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
@@ -3683,16 +3679,16 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 	/* FDI link */
 	if (HAS_PCH_SPLIT(dev)) {
 		int lane = 0, link_bw, bpp;
-		/* eDP doesn't require FDI link, so just set DP M/N
+		/* CPU eDP doesn't require FDI link, so just set DP M/N
 		   according to current link config */
-		if (has_edp_encoder) {
+		if (has_edp_encoder && !intel_encoder_is_pch_edp(&encoder->base)) {
 			target_clock = mode->clock;
 			intel_edp_link_config(has_edp_encoder,
 					      &lane, &link_bw);
 		} else {
-			/* DP over FDI requires target mode clock
+			/* [e]DP over FDI requires target mode clock
 			   instead of link clock */
-			if (is_dp)
+			if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base))
 				target_clock = mode->clock;
 			else
 				target_clock = adjusted_mode->clock;
@@ -3932,7 +3928,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		dpll_reg = DPLL(pipe);
 	}
 
-	if (!has_edp_encoder) {
+	/* PCH eDP needs FDI, but CPU eDP does not */
+	if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 		I915_WRITE(fp_reg, fp);
 		I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
 
@@ -4009,9 +4006,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		}
 	}
 
-	if (is_dp)
+	if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 		intel_dp_set_m_n(crtc, mode, adjusted_mode);
-	else if (HAS_PCH_SPLIT(dev)) {
+	} else if (HAS_PCH_SPLIT(dev)) {
 		/* For non-DP output, clear any trans DP clock recovery setting.*/
 		if (pipe == 0) {
 			I915_WRITE(TRANSA_DATA_M1, 0);
@@ -4026,7 +4023,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		}
 	}
 
-	if (!has_edp_encoder) {
+	if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 		I915_WRITE(fp_reg, fp);
 		I915_WRITE(dpll_reg, dpll);
 
@@ -4120,7 +4117,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
 		I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
 
-		if (has_edp_encoder) {
+		if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 			ironlake_set_pll_edp(crtc, adjusted_mode->clock);
 		} else {
 			/* enable FDI RX PLL too */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/20] drm/i915/dp: eDP power sequencing fixes
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (5 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 06/20] drm/i915: fix CPU vs PCH eDP confusion Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 08/20] drm/i915: add _DSM support Jesse Barnes
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Enable the panel before adjusting eDP link params, make sure the panel
is idle after powering it on before proceeding with other activity,
delay backlight enable to avoid visible flicker.

Also avoid using VDD per hw team recommendation; it can conflict with
the builtin panel power sequencing logic and lead to panel power
sequencing failures.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h |    3 +
 drivers/gpu/drm/i915/intel_dp.c |   80 ++++++++++++++++----------------------
 2 files changed, 37 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d02de21..a72335e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1373,6 +1373,9 @@
 #define   PP_SEQUENCE_ON	(1 << 28)
 #define   PP_SEQUENCE_OFF	(2 << 28)
 #define   PP_SEQUENCE_MASK	0x30000000
+#define   PP_CYCLE_DELAY_ACTIVE	(1 << 27)
+#define   PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
+#define   PP_SEQUENCE_STATE_MASK 0x0000000f
 #define PP_CONTROL	0x61204
 #define   POWER_TARGET_ON	(1 << 0)
 #define PP_ON_DELAYS	0x61208
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 57bfc3e..e5f183f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -788,10 +788,11 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 }
 
 /* Returns true if the panel was already on when called */
-static bool ironlake_edp_panel_on (struct drm_device *dev)
+static bool ironlake_edp_panel_on (struct intel_dp *intel_dp)
 {
+	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp;
+	u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;
 
 	if (I915_READ(PCH_PP_STATUS) & PP_ON)
 		return true;
@@ -803,19 +804,20 @@ static bool ironlake_edp_panel_on (struct drm_device *dev)
 	I915_WRITE(PCH_PP_CONTROL, pp);
 	POSTING_READ(PCH_PP_CONTROL);
 
-	pp |= POWER_TARGET_ON;
+	pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
 	I915_WRITE(PCH_PP_CONTROL, pp);
+	POSTING_READ(PCH_PP_CONTROL);
 
 	/* Ouch. We need to wait here for some panels, like Dell e6510
 	 * https://bugs.freedesktop.org/show_bug.cgi?id=29278i
 	 */
 	msleep(300);
 
-	if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000))
+	if (wait_for(I915_READ(PCH_PP_STATUS) == idle_on_mask,
+		     5000))
 		DRM_ERROR("panel on wait timed out: 0x%08x\n",
 			  I915_READ(PCH_PP_STATUS));
 
-	pp &= ~(PANEL_UNLOCK_REGS);
 	pp |= PANEL_POWER_RESET; /* restore panel reset bit */
 	I915_WRITE(PCH_PP_CONTROL, pp);
 	POSTING_READ(PCH_PP_CONTROL);
@@ -826,7 +828,8 @@ static bool ironlake_edp_panel_on (struct drm_device *dev)
 static void ironlake_edp_panel_off (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp;
+	u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK |
+		PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK;
 
 	pp = I915_READ(PCH_PP_CONTROL);
 
@@ -837,12 +840,12 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
 
 	pp &= ~POWER_TARGET_ON;
 	I915_WRITE(PCH_PP_CONTROL, pp);
+	POSTING_READ(PCH_PP_CONTROL);
 
-	if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000))
+	if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000))
 		DRM_ERROR("panel off wait timed out: 0x%08x\n",
 			  I915_READ(PCH_PP_STATUS));
 
-	/* Make sure VDD is enabled so DP AUX will work */
 	pp |= PANEL_POWER_RESET; /* restore panel reset bit */
 	I915_WRITE(PCH_PP_CONTROL, pp);
 	POSTING_READ(PCH_PP_CONTROL);
@@ -853,36 +856,19 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
 	msleep(300);
 }
 
-static void ironlake_edp_panel_vdd_on(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp;
-
-	pp = I915_READ(PCH_PP_CONTROL);
-	pp |= EDP_FORCE_VDD;
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
-	msleep(300);
-}
-
-static void ironlake_edp_panel_vdd_off(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp;
-
-	pp = I915_READ(PCH_PP_CONTROL);
-	pp &= ~EDP_FORCE_VDD;
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
-	msleep(300);
-}
-
 static void ironlake_edp_backlight_on (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
 	DRM_DEBUG_KMS("\n");
+	/*
+	 * If we enable the backlight right away following a panel power
+	 * on, we may see slight flicker as the panel syncs with the eDP
+	 * link.  So delay a bit to make sure the image is solid before
+	 * allowing it to appear.
+	 */
+	msleep(300);
 	pp = I915_READ(PCH_PP_CONTROL);
 	pp |= EDP_BLC_ENABLE;
 	I915_WRITE(PCH_PP_CONTROL, pp);
@@ -932,10 +918,12 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
 	if (is_edp(intel_dp)) {
-		ironlake_edp_panel_off(dev);
 		ironlake_edp_backlight_off(dev);
-		ironlake_edp_panel_vdd_on(dev);
-		ironlake_edp_pll_on(encoder);
+		ironlake_edp_panel_on(intel_dp);
+		if (!is_pch_edp(intel_dp))
+			ironlake_edp_pll_on(encoder);
+		else
+			ironlake_edp_pll_off(encoder);
 	}
 	if (dp_reg & DP_PORT_EN)
 		intel_dp_link_down(intel_dp);
@@ -949,7 +937,7 @@ static void intel_dp_commit(struct drm_encoder *encoder)
 	intel_dp_start_link_train(intel_dp);
 
 	if (is_edp(intel_dp))
-		ironlake_edp_panel_on(dev);
+		ironlake_edp_panel_on(intel_dp);
 
 	intel_dp_complete_link_train(intel_dp);
 
@@ -966,19 +954,20 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
 	if (mode != DRM_MODE_DPMS_ON) {
-		if (is_edp(intel_dp)) {
+		if (is_edp(intel_dp))
 			ironlake_edp_backlight_off(dev);
-			ironlake_edp_panel_off(dev);
-		}
-		if (dp_reg & DP_PORT_EN)
+		if (dp_reg & DP_PORT_EN) {
 			intel_dp_link_down(intel_dp);
+		}
 		if (is_edp(intel_dp))
+			ironlake_edp_panel_off(dev);
+		if (is_edp(intel_dp) && !is_pch_edp(intel_dp))
 			ironlake_edp_pll_off(encoder);
 	} else {
 		if (!(dp_reg & DP_PORT_EN)) {
-			intel_dp_start_link_train(intel_dp);
 			if (is_edp(intel_dp))
-				ironlake_edp_panel_on(dev);
+				ironlake_edp_panel_on(intel_dp);
+			intel_dp_start_link_train(intel_dp);
 			intel_dp_complete_link_train(intel_dp);
 			if (is_edp(intel_dp))
 				ironlake_edp_backlight_on(dev);
@@ -1445,9 +1434,10 @@ ironlake_dp_detect(struct drm_connector *connector)
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	enum drm_connector_status status;
 
-	/* Panel needs power for AUX to work */
+	/* Can't disconnect eDP */
 	if (is_edp(intel_dp))
-		ironlake_edp_panel_vdd_on(connector->dev);
+		return connector_status_connected;
+
 	status = connector_status_disconnected;
 	if (intel_dp_aux_native_read(intel_dp,
 				     0x000, intel_dp->dpcd,
@@ -1458,8 +1448,6 @@ ironlake_dp_detect(struct drm_connector *connector)
 	}
 	DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
 		      intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
-	if (is_edp(intel_dp))
-		ironlake_edp_panel_vdd_off(connector->dev);
 	return status;
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/20] drm/i915: add _DSM support
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (6 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 07/20] drm/i915/dp: eDP power sequencing fixes Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 09/20] drm/i915: fetch eDP configuration data from the VBT Jesse Barnes
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

The _DSM method on the integrated graphics device can tell us which
connectors are muxable, so add support for making the call and parsing
out the connector info.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/Makefile        |    2 +
 drivers/gpu/drm/i915/i915_dma.c      |    2 +
 drivers/gpu/drm/i915/i915_drv.h      |    9 +
 drivers/gpu/drm/i915/intel_acpi.c    |  290 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |    3 +
 5 files changed, 306 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_acpi.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index f6e98dd..fdc833d 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -35,6 +35,8 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
 
 i915-$(CONFIG_COMPAT)   += i915_ioc32.o
 
+i915-$(CONFIG_ACPI)	+= intel_acpi.o
+
 obj-$(CONFIG_DRM_I915)  += i915.o
 
 CFLAGS_i915_trace_points.o := -I$(src)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 726c373..778c01c 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1244,6 +1244,8 @@ static int i915_load_modeset_init(struct drm_device *dev,
 	if (ret)
 		goto cleanup_ringbuffer;
 
+	intel_register_dsm_handler();
+
 	ret = vga_switcheroo_register_client(dev->pdev,
 					     i915_switcheroo_set_state,
 					     i915_switcheroo_can_switch);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 73ad8bf..e4ffcd3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1136,6 +1136,15 @@ static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; }
 static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
 
+/* intel_acpi.c */
+#ifdef CONFIG_ACPI
+extern void intel_register_dsm_handler(void);
+extern void intel_unregister_dsm_handler(void);
+#else
+static inline void intel_register_dsm_handler(void) { return; }
+static inline void intel_unregister_dsm_handler(void) { return; }
+#endif /* CONFIG_ACPI */
+
 /* modesetting */
 extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
new file mode 100644
index 0000000..c68d496
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -0,0 +1,290 @@
+/*
+ * Intel ACPI functions
+ *
+ * _DSM related code stolen from nouveau_acpi.c.
+ */
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/vga_switcheroo.h>
+#include <acpi/acpi_drivers.h>
+
+#include "drmP.h"
+
+#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
+
+#define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */
+#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */
+
+static struct intel_dsm_priv {
+	bool dsm_detected;
+	acpi_handle dhandle;
+} intel_dsm_priv;
+
+static const u8 intel_dsm_guid[] = {
+	0xd3, 0x73, 0xd8, 0x7e,
+	0xd0, 0xc2,
+	0x4f, 0x4e,
+	0xa8, 0x54,
+	0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
+};
+
+static int intel_dsm(acpi_handle handle, int func, int arg, u32 *result)
+{
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_object_list input;
+	union acpi_object params[4];
+	union acpi_object *obj;
+	int ret = 0;
+
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = sizeof(intel_dsm_guid);
+	params[0].buffer.pointer = (char *)intel_dsm_guid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = INTEL_DSM_REVISION_ID;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = func;
+	params[3].type = ACPI_TYPE_INTEGER;
+	params[3].integer.value = arg;
+
+	ret = acpi_evaluate_object(handle, "_DSM", &input, &output);
+	if (ret) {
+		DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
+		goto out;
+	}
+
+	obj = (union acpi_object *)output.pointer;
+
+	if (obj->type == ACPI_TYPE_INTEGER)
+		if (obj->integer.value == 0x80000002) {
+			ret = -ENODEV;
+			goto out;
+		}
+
+	if (obj->type == ACPI_TYPE_BUFFER) {
+		if (obj->buffer.length == 4 && result) {
+			*result = 0;
+			*result |= obj->buffer.pointer[0];
+			*result |= (obj->buffer.pointer[1] << 8);
+			*result |= (obj->buffer.pointer[2] << 16);
+			*result |= (obj->buffer.pointer[3] << 24);
+		}
+	}
+
+	if (*result == 0x80000002)
+		ret = -ENODEV;
+
+out:
+	kfree(output.pointer);
+	return ret;
+}
+
+static char *intel_dsm_port_name(u8 id)
+{
+	switch (id) {
+	case 0:
+		return "Reserved";
+	case 1:
+		return "Analog VGA";
+	case 2:
+		return "LVDS";
+	case 3:
+		return "Reserved";
+	case 4:
+		return "HDMI/DVI_B";
+	case 5:
+		return "HDMI/DVI_C";
+	case 6:
+		return "HDMI/DVI_D";
+	case 7:
+		return "DisplayPort_A";
+	case 8:
+		return "DisplayPort_B";
+	case 9:
+		return "DisplayPort_C";
+	case 0xa:
+		return "DisplayPort_D";
+	case 0xb:
+	case 0xc:
+	case 0xd:
+		return "Reserved";
+	case 0xe:
+		return "WiDi";
+	default:
+		return "bad type";
+	}
+}
+
+static char *intel_dsm_mux_type(u8 type)
+{
+	switch (type) {
+	case 0:
+		return "unknown";
+	case 1:
+		return "No MUX, iGPU only";
+	case 2:
+		return "No MUX, dGPU only";
+	case 3:
+		return "MUXed between iGPU and dGPU";
+	default:
+		return "bad type";
+	}
+}
+
+static void intel_dsm_platform_mux_info(void)
+{
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_object_list input;
+	union acpi_object params[4];
+	union acpi_object *pkg;
+	int i, ret;
+
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = sizeof(intel_dsm_guid);
+	params[0].buffer.pointer = (char *)intel_dsm_guid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = INTEL_DSM_REVISION_ID;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO;
+	params[3].type = ACPI_TYPE_INTEGER;
+	params[3].integer.value = 0;
+
+	ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input,
+				   &output);
+	if (ret) {
+		DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
+		goto out;
+	}
+
+	pkg = (union acpi_object *)output.pointer;
+
+	if (pkg->type == ACPI_TYPE_PACKAGE) {
+		union acpi_object *connector_count = &pkg->package.elements[0];
+		DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
+			  (unsigned long long)connector_count->integer.value);
+		for (i = 1; i < pkg->package.count; i++) {
+			union acpi_object *obj = &pkg->package.elements[i];
+			union acpi_object *connector_id =
+				&obj->package.elements[0];
+			union acpi_object *info = &obj->package.elements[1];
+			DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
+				  (unsigned long long)connector_id->integer.value);
+			DRM_DEBUG_DRIVER("  port id: %s\n",
+			       intel_dsm_port_name(info->buffer.pointer[0]));
+			DRM_DEBUG_DRIVER("  display mux info: %s\n",
+			       intel_dsm_mux_type(info->buffer.pointer[1]));
+			DRM_DEBUG_DRIVER("  aux/dc mux info: %s\n",
+			       intel_dsm_mux_type(info->buffer.pointer[2]));
+			DRM_DEBUG_DRIVER("  hpd mux info: %s\n",
+			       intel_dsm_mux_type(info->buffer.pointer[3]));
+		}
+	} else {
+		DRM_ERROR("MUX INFO call failed\n");
+	}
+
+out:
+	kfree(output.pointer);
+}
+
+static int intel_dsm_switchto(enum vga_switcheroo_client_id id)
+{
+	return 0;
+}
+
+static int intel_dsm_power_state(enum vga_switcheroo_client_id id,
+				   enum vga_switcheroo_state state)
+{
+	return 0;
+}
+
+static int intel_dsm_init(void)
+{
+	return 0;
+}
+
+static int intel_dsm_get_client_id(struct pci_dev *pdev)
+{
+	if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
+		return VGA_SWITCHEROO_IGD;
+	else
+		return VGA_SWITCHEROO_DIS;
+}
+
+static struct vga_switcheroo_handler intel_dsm_handler = {
+	.switchto = intel_dsm_switchto,
+	.power_state = intel_dsm_power_state,
+	.init = intel_dsm_init,
+	.get_client_id = intel_dsm_get_client_id,
+};
+
+static bool intel_dsm_pci_probe(struct pci_dev *pdev)
+{
+	acpi_handle dhandle, intel_handle;
+	acpi_status status;
+	int ret;
+	u32 result;
+
+	dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+	if (!dhandle)
+		return false;
+
+	status = acpi_get_handle(dhandle, "_DSM", &intel_handle);
+	if (ACPI_FAILURE(status)) {
+		DRM_ERROR("no _DSM method for intel device\n");
+		return false;
+	}
+
+	ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0, &result);
+	if (ret < 0) {
+		DRM_ERROR("failed to get supported _DSM functions\n");
+		return false;
+	}
+
+	intel_dsm_priv.dhandle = dhandle;
+
+	intel_dsm_platform_mux_info();
+	return true;
+}
+
+static bool intel_dsm_detect(void)
+{
+	char acpi_method_name[255] = { 0 };
+	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
+	struct pci_dev *pdev = NULL;
+	int has_dsm = 0;
+	int vga_count = 0;
+
+	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+		vga_count++;
+
+		has_dsm |= (intel_dsm_pci_probe(pdev) == true);
+	}
+
+	if (vga_count == 2 && has_dsm) {
+		acpi_get_name(intel_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
+		DRM_DEBUG_DRIVER("VGA switcheroo: detected DSM switching method %s handle\n",
+		       acpi_method_name);
+		intel_dsm_priv.dsm_detected = true;
+		return true;
+	}
+	return false;
+}
+
+void intel_register_dsm_handler(void)
+{
+	bool r;
+
+	r = intel_dsm_detect();
+	if (!r)
+		return;
+
+	vga_switcheroo_register_handler(&intel_dsm_handler);
+}
+
+void intel_unregister_dsm_handler(void)
+{
+	vga_switcheroo_unregister_handler();
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6903341..8d7409e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6126,6 +6126,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
 	drm_kms_helper_poll_fini(dev);
 	mutex_lock(&dev->struct_mutex);
 
+	intel_unregister_dsm_handler();
+
+
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		/* Skip inactive CRTCs */
 		if (!crtc->fb)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/20] drm/i915: fetch eDP configuration data from the VBT
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (7 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 08/20] drm/i915: add _DSM support Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 10/20] drm/i915: add Ironlake clock gating workaround for FDI link training Jesse Barnes
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

We need to use some of these values in eDP configurations, so be sure to
fetch them and store them in the i915 private structure.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.h   |   18 +++++-----
 drivers/gpu/drm/i915/intel_bios.c |   60 ++++++++++++++++++++++++++++++-------
 include/drm/drm_dp_helper.h       |    3 ++
 3 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e4ffcd3..6d49a9f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -339,16 +339,16 @@ typedef struct drm_i915_private {
 	unsigned int int_crt_support:1;
 	unsigned int lvds_use_ssc:1;
 	int lvds_ssc_freq;
-
 	struct {
-		u8 rate:4;
-		u8 lanes:4;
-		u8 preemphasis:4;
-		u8 vswing:4;
-
-		u8 initialized:1;
-		u8 support:1;
-		u8 bpp:6;
+		int rate;
+		int lanes;
+		int preemphasis;
+		int vswing;
+
+		bool initialized;
+		bool support;
+		int bpp;
+		struct edp_power_seq pps;
 	} 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 b1f73ac..cc15447 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -24,6 +24,7 @@
  *    Eric Anholt <eric@anholt.net>
  *
  */
+#include <drm/drm_dp_helper.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -413,6 +414,8 @@ static void
 parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 {
 	struct bdb_edp *edp;
+	struct edp_power_seq *edp_pps;
+	struct edp_link_params *edp_link_params;
 
 	edp = find_section(bdb, BDB_EDP);
 	if (!edp) {
@@ -437,19 +440,54 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 		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;
+	/* Get the eDP sequencing and link info */
+	edp_pps = &edp->power_seqs[panel_type];
+	edp_link_params = &edp->link_params[panel_type];
 
-	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.pps = *edp_pps;
 
-	dev_priv->edp.initialized = true;
+	dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
+		DP_LINK_BW_1_62;
+	switch (edp_link_params->lanes) {
+	case 0:
+		dev_priv->edp.lanes = 1;
+		break;
+	case 1:
+		dev_priv->edp.lanes = 2;
+		break;
+	case 3:
+	default:
+		dev_priv->edp.lanes = 4;
+		break;
+	}
+	switch (edp_link_params->preemphasis) {
+	case 0:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
+		break;
+	case 1:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
+		break;
+	case 2:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
+		break;
+	case 3:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
+		break;
+	}
+	switch (edp_link_params->vswing) {
+	case 0:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
+		break;
+	case 1:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
+		break;
+	case 2:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
+		break;
+	case 3:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
+		break;
+	}
 }
 
 static void
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index a49e791..83a389e 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -23,6 +23,9 @@
 #ifndef _DRM_DP_HELPER_H_
 #define _DRM_DP_HELPER_H_
 
+#include <linux/types.h>
+#include <linux/i2c.h>
+
 /* From the VESA DisplayPort spec */
 
 #define AUX_NATIVE_WRITE	0x8
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/20] drm/i915: add Ironlake clock gating workaround for FDI link training
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (8 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 09/20] drm/i915: fetch eDP configuration data from the VBT Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 11/20] drm/i915: fix PCH eDP SSC support Jesse Barnes
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |    8 ++++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a72335e..5a22887 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2782,6 +2782,7 @@
 #define FDI_RXA_CHICKEN         0xc200c
 #define FDI_RXB_CHICKEN         0xc2010
 #define  FDI_RX_PHASE_SYNC_POINTER_ENABLE       (1)
+#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, FDI_RXA_CHICKEN, FDI_RXB_CHICKEN)
 
 /* CPU: FDI_TX */
 #define FDI_TXA_CTL             0x60100
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8d7409e..9614747 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1714,6 +1714,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 	POSTING_READ(reg);
 	udelay(150);
 
+	/* Ironlake workaround, enable clock pointer after FDI enable*/
+	I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_ENABLE);
+
 	reg = FDI_RX_IIR(pipe);
 	for (tries = 0; tries < 5; tries++) {
 		temp = I915_READ(reg);
@@ -2192,6 +2195,11 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 	POSTING_READ(reg);
 	udelay(100);
 
+	/* Ironlake workaround, disable clock pointer after downing FDI */
+	I915_WRITE(FDI_RX_CHICKEN(pipe),
+		   I915_READ(FDI_RX_CHICKEN(pipe) &
+			     ~FDI_RX_PHASE_SYNC_POINTER_ENABLE));
+
 	/* still set train pattern 1 */
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 11/20] drm/i915: fix PCH eDP SSC support
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (9 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 10/20] drm/i915: add Ironlake clock gating workaround for FDI link training Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 12/20] drm/i915: use 120MHz refclk in PCH eDP case too Jesse Barnes
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Enable SSC on PCH eDP if possible.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9614747..2d0c893 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3796,13 +3796,24 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
 				POSTING_READ(PCH_DREF_CONTROL);
 				udelay(200);
+			}
+			temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
 
-				temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
-				temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+			/* Enable CPU source on CPU attached eDP */
+			if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
+				if (dev_priv->lvds_use_ssc)
+					temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+				else
+					temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
 			} else {
-				temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+				/* Enable SSC on PCH eDP if needed */
+				if (dev_priv->lvds_use_ssc) {
+					DRM_ERROR("enabling SSC on PCH\n");
+					temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
+				}
 			}
 			I915_WRITE(PCH_DREF_CONTROL, temp);
+			udelay(200);
 		}
 	}
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 12/20] drm/i915: use 120MHz refclk in PCH eDP case too
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (10 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 11/20] drm/i915: fix PCH eDP SSC support Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 13/20] drm/i915: use DPLL_DVO_HIGH_SPEED for PCH eDP Jesse Barnes
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

CPU eDP needs a different reference clock than PCH eDP, which uses the
standard PCH refclk of 120MHz.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2d0c893..5fee124 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3625,7 +3625,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 			      refclk / 1000);
 	} else if (!IS_GEN2(dev)) {
 		refclk = 96000;
-		if (HAS_PCH_SPLIT(dev))
+		if (HAS_PCH_SPLIT(dev) &&
+		    (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)))
 			refclk = 120000; /* 120Mhz refclk */
 	} else {
 		refclk = 48000;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 13/20] drm/i915: use DPLL_DVO_HIGH_SPEED for PCH eDP
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (11 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 12/20] drm/i915: use 120MHz refclk in PCH eDP case too Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 14/20] drm/i915: fix ironlake CRTC enable/disable Jesse Barnes
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

As with other PCH DP connections.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5fee124..6135875 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3849,7 +3849,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 			}
 			dpll |= DPLL_DVO_HIGH_SPEED;
 		}
-		if (is_dp)
+		if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base))
 			dpll |= DPLL_DVO_HIGH_SPEED;
 
 		/* compute bitmask from p1 value */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 14/20] drm/i915: fix ironlake CRTC enable/disable
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (12 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 13/20] drm/i915: use DPLL_DVO_HIGH_SPEED for PCH eDP Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 15/20] drm/i915: don't program FDI RX/TX in mode_set Jesse Barnes
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Wait for vblank after enabling a pipe, make the error messages more
informative, and wait for the pipe to turn off when we disable it.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6135875..7133e7d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2041,7 +2041,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	if ((temp & PIPECONF_ENABLE) == 0) {
 		I915_WRITE(reg, temp | PIPECONF_ENABLE);
 		POSTING_READ(reg);
-		udelay(100);
+		intel_wait_for_vblank(dev, intel_crtc->pipe);
 	}
 
 	/* configure and enable CPU plane */
@@ -2131,7 +2131,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	temp |= I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK;
 	I915_WRITE(reg, temp | TRANS_ENABLE);
 	if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100))
-		DRM_ERROR("failed to enable transcoder\n");
+		DRM_ERROR("failed to enable transcoder %d\n", pipe);
 
 	intel_crtc_load_lut(crtc);
 	intel_update_fbc(dev);
@@ -2171,9 +2171,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 	temp = I915_READ(reg);
 	if (temp & PIPECONF_ENABLE) {
 		I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
+		POSTING_READ(reg);
 		/* wait for cpu pipe off, pipe state */
-		if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, 50))
-			DRM_ERROR("failed to turn off cpu pipe\n");
+		intel_wait_for_pipe_off(dev, intel_crtc->pipe);
 	}
 
 	/* Disable PF */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 15/20] drm/i915: don't program FDI RX/TX in mode_set
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (13 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 14/20] drm/i915: fix ironlake CRTC enable/disable Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 16/20] drm/i915/dp: cache eDP DPCD data Jesse Barnes
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

We do this later (and more properly) when we enable FDI, so we don't
need to do it here.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   21 ---------------------
 1 files changed, 0 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7133e7d..09bc613 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4139,27 +4139,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
 		if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 			ironlake_set_pll_edp(crtc, adjusted_mode->clock);
-		} else {
-			/* enable FDI RX PLL too */
-			reg = FDI_RX_CTL(pipe);
-			temp = I915_READ(reg);
-			I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
-
-			POSTING_READ(reg);
-			udelay(200);
-
-			/* enable FDI TX PLL too */
-			reg = FDI_TX_CTL(pipe);
-			temp = I915_READ(reg);
-			I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE);
-
-			/* enable FDI RX PCDCLK */
-			reg = FDI_RX_CTL(pipe);
-			temp = I915_READ(reg);
-			I915_WRITE(reg, temp | FDI_PCDCLK);
-
-			POSTING_READ(reg);
-			udelay(200);
 		}
 	}
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 16/20] drm/i915/dp: cache eDP DPCD data
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (14 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 15/20] drm/i915: don't program FDI RX/TX in mode_set Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 17/20] drm/i915/dp: use VBT provided eDP params if available Jesse Barnes
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Cache the first 4 bytes of DPCD data in the eDP case.  It's unlikely to
change and can save us some trouble at link training time.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.h |    1 +
 drivers/gpu/drm/i915/intel_dp.c |   20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6d49a9f..84e33ae 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -350,6 +350,7 @@ typedef struct drm_i915_private {
 		int bpp;
 		struct edp_power_seq pps;
 	} edp;
+	bool no_aux_handshake;
 
 	struct notifier_block lid_notifier;
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e5f183f..5ea1d8d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1725,6 +1725,26 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
 	intel_dp_i2c_init(intel_dp, intel_connector, name);
 
+	/* Cache some DPCD data in the eDP case */
+	if (is_edp(intel_dp)) {
+		int ret;
+		bool was_on;
+
+		was_on = ironlake_edp_panel_on(intel_dp);
+		ret = intel_dp_aux_native_read(intel_dp, DP_DPCD_REV,
+					       intel_dp->dpcd,
+					       sizeof (intel_dp->dpcd));
+		if (ret == sizeof (intel_dp->dpcd)) {
+			if (intel_dp->dpcd[0] >= 0x11)
+				dev_priv->no_aux_handshake = intel_dp->dpcd[3] &
+					DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
+		} else {
+			DRM_ERROR("failed to retrieve link info\n");
+		}
+		if (!was_on)
+			ironlake_edp_panel_off(dev);
+	}
+
 	intel_encoder->hot_plug = intel_dp_hot_plug;
 
 	if (is_edp(intel_dp)) {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 17/20] drm/i915/dp: use VBT provided eDP params if available
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (15 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 16/20] drm/i915/dp: cache eDP DPCD data Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 18/20] drm/i915/dp: don't bother with DP PLL for PCH attached eDP Jesse Barnes
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

We can skip most of the link training step if we use the VBT provided
values.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |  146 ++++++++++++++++++++++++---------------
 1 files changed, 89 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5ea1d8d..fa24d94 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -581,6 +581,17 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		mode->clock = dev_priv->panel_fixed_mode->clock;
 	}
 
+	/* Just use VBT values for eDP */
+	if (is_edp(intel_dp)) {
+		intel_dp->lane_count = dev_priv->edp.lanes;
+		intel_dp->link_bw = dev_priv->edp.rate;
+		adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+		DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n",
+			      intel_dp->link_bw, intel_dp->lane_count,
+			      adjusted_mode->clock);
+		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_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
@@ -599,19 +610,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		}
 	}
 
-	if (is_edp(intel_dp)) {
-		/* okay we failed just pick the highest */
-		intel_dp->lane_count = max_lane_count;
-		intel_dp->link_bw = bws[max_clock];
-		adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
-		DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
-			      "count %d clock %d\n",
-			      intel_dp->link_bw, intel_dp->lane_count,
-			      adjusted_mode->clock);
-
-		return true;
-	}
-
 	return false;
 }
 
@@ -1089,11 +1087,21 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
 }
 
 static uint32_t
-intel_dp_signal_levels(uint8_t train_set, int lane_count)
+intel_dp_signal_levels(struct intel_dp *intel_dp)
 {
-	uint32_t	signal_levels = 0;
+	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t signal_levels = 0;
+	u8 train_set = intel_dp->train_set[0];
+	u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK;
+	u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK;
 
-	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	if (is_edp(intel_dp)) {
+		vswing = dev_priv->edp.vswing;
+		preemphasis = dev_priv->edp.preemphasis;
+	}
+
+	switch (vswing) {
 	case DP_TRAIN_VOLTAGE_SWING_400:
 	default:
 		signal_levels |= DP_VOLTAGE_0_4;
@@ -1108,7 +1116,7 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count)
 		signal_levels |= DP_VOLTAGE_1_2;
 		break;
 	}
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	switch (preemphasis) {
 	case DP_TRAIN_PRE_EMPHASIS_0:
 	default:
 		signal_levels |= DP_PRE_EMPHASIS_0;
@@ -1195,6 +1203,18 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
 }
 
 static bool
+intel_dp_aux_handshake_required(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (is_edp(intel_dp) && dev_priv->no_aux_handshake)
+		return false;
+
+	return true;
+}
+
+static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
 			uint32_t dp_reg_value,
 			uint8_t dp_train_pat)
@@ -1206,6 +1226,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 	I915_WRITE(intel_dp->output_reg, dp_reg_value);
 	POSTING_READ(intel_dp->output_reg);
 
+	if (!intel_dp_aux_handshake_required(intel_dp))
+		return true;
+
 	intel_dp_aux_native_write_1(intel_dp,
 				    DP_TRAINING_PATTERN_SET,
 				    dp_train_pat);
@@ -1238,10 +1261,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 	POSTING_READ(intel_dp->output_reg);
 	intel_wait_for_vblank(dev, intel_crtc->pipe);
 
-	/* Write the link configuration data */
-	intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
-				  intel_dp->link_configuration,
-				  DP_LINK_CONFIGURATION_SIZE);
+	if (intel_dp_aux_handshake_required(intel_dp))
+		/* Write the link configuration data */
+		intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
+					  intel_dp->link_configuration,
+					  DP_LINK_CONFIGURATION_SIZE);
 
 	DP |= DP_PORT_EN;
 	if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
@@ -1259,7 +1283,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
 			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
 		} else {
-			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
+			signal_levels = intel_dp_signal_levels(intel_dp);
 			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 		}
 
@@ -1273,33 +1297,37 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 			break;
 		/* Set training pattern 1 */
 
-		udelay(100);
-		if (!intel_dp_get_link_status(intel_dp))
+		udelay(500);
+		if (intel_dp_aux_handshake_required(intel_dp)) {
 			break;
+		} else {
+			if (!intel_dp_get_link_status(intel_dp))
+				break;
 
-		if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
-			clock_recovery = true;
-			break;
-		}
-
-		/* Check to see if we've tried the max voltage */
-		for (i = 0; i < intel_dp->lane_count; i++)
-			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+			if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+				clock_recovery = true;
 				break;
-		if (i == intel_dp->lane_count)
-			break;
+			}
 
-		/* Check to see if we've tried the same voltage 5 times */
-		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-			++tries;
-			if (tries == 5)
+			/* Check to see if we've tried the max voltage */
+			for (i = 0; i < intel_dp->lane_count; i++)
+				if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+					break;
+			if (i == intel_dp->lane_count)
 				break;
-		} else
-			tries = 0;
-		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
-		/* Compute new intel_dp->train_set as requested by target */
-		intel_get_adjust_train(intel_dp);
+			/* Check to see if we've tried the same voltage 5 times */
+			if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+				++tries;
+				if (tries == 5)
+					break;
+			} else
+				tries = 0;
+			voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+			/* Compute new intel_dp->train_set as requested by target */
+			intel_get_adjust_train(intel_dp);
+		}
 	}
 
 	intel_dp->DP = DP;
@@ -1326,7 +1354,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
 			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
 		} else {
-			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
+			signal_levels = intel_dp_signal_levels(intel_dp);
 			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 		}
 
@@ -1340,24 +1368,28 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 					     DP_TRAINING_PATTERN_2))
 			break;
 
-		udelay(400);
-		if (!intel_dp_get_link_status(intel_dp))
-			break;
+		udelay(500);
 
-		if (intel_channel_eq_ok(intel_dp)) {
-			channel_eq = true;
+		if (!intel_dp_aux_handshake_required(intel_dp)) {
 			break;
-		}
+		} else {
+			if (!intel_dp_get_link_status(intel_dp))
+				break;
 
-		/* Try 5 times */
-		if (tries > 5)
-			break;
+			if (intel_channel_eq_ok(intel_dp)) {
+				channel_eq = true;
+				break;
+			}
 
-		/* Compute new intel_dp->train_set as requested by target */
-		intel_get_adjust_train(intel_dp);
-		++tries;
-	}
+			/* Try 5 times */
+			if (tries > 5)
+				break;
 
+			/* Compute new intel_dp->train_set as requested by target */
+			intel_get_adjust_train(intel_dp);
+			++tries;
+		}
+	}
 	if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
 		reg = DP | DP_LINK_TRAIN_OFF_CPT;
 	else
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 18/20] drm/i915/dp: don't bother with DP PLL for PCH attached eDP
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (16 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 17/20] drm/i915/dp: use VBT provided eDP params if available Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 19/20] drm/i915/dp: make eDP PLL functions work as advertised Jesse Barnes
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

We don't use the CPU DP PLL with PCH attached eDP panels, so don't
bother to enable it.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fa24d94..19e0d65 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -775,7 +775,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
 		intel_dp->DP |= DP_PIPEB_SELECT;
 
-	if (is_edp(intel_dp)) {
+	if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) {
 		/* don't miss out required setting for eDP */
 		intel_dp->DP |= DP_PLL_ENABLE;
 		if (adjusted_mode->clock < 200000)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 19/20] drm/i915/dp: make eDP PLL functions work as advertised
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (17 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 18/20] drm/i915/dp: don't bother with DP PLL for PCH attached eDP Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-07 23:01 ` [PATCH 20/20] drm/i915: diasable clock gating for the panel power sequencer Jesse Barnes
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 19e0d65..8e019c8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -891,8 +891,10 @@ static void ironlake_edp_pll_on(struct drm_encoder *encoder)
 
 	DRM_DEBUG_KMS("\n");
 	dpa_ctl = I915_READ(DP_A);
-	dpa_ctl &= ~DP_PLL_ENABLE;
+	dpa_ctl |= DP_PLL_ENABLE;
 	I915_WRITE(DP_A, dpa_ctl);
+	POSTING_READ(DP_A);
+	udelay(200);
 }
 
 static void ironlake_edp_pll_off(struct drm_encoder *encoder)
@@ -902,7 +904,7 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder)
 	u32 dpa_ctl;
 
 	dpa_ctl = I915_READ(DP_A);
-	dpa_ctl |= DP_PLL_ENABLE;
+	dpa_ctl &= ~DP_PLL_ENABLE;
 	I915_WRITE(DP_A, dpa_ctl);
 	POSTING_READ(DP_A);
 	udelay(200);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 20/20] drm/i915: diasable clock gating for the panel power sequencer
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (18 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 19/20] drm/i915/dp: make eDP PLL functions work as advertised Jesse Barnes
@ 2010-10-07 23:01 ` Jesse Barnes
  2010-10-08  9:50 ` PCH eDP fixes Jim Gettys
  2010-10-08 10:00 ` Chris Wilson
  21 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-07 23:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: stable

Needed on Ibex Peak and Cougar Point or the panel won't always come on.

Cc: stable@kernel.org
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h      |    3 +++
 drivers/gpu/drm/i915/intel_display.c |    7 +++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5a22887..8829289 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2784,6 +2784,9 @@
 #define  FDI_RX_PHASE_SYNC_POINTER_ENABLE       (1)
 #define FDI_RX_CHICKEN(pipe) _PIPE(pipe, FDI_RXA_CHICKEN, FDI_RXB_CHICKEN)
 
+#define SOUTH_DSPCLK_GATE_D	0xc2020
+#define  PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
+
 /* CPU: FDI_TX */
 #define FDI_TXA_CTL             0x60100
 #define FDI_TXB_CTL             0x61100
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 09bc613..159dd01 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5744,6 +5744,13 @@ void intel_init_clock_gating(struct drm_device *dev)
 		I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
 
 		/*
+		 * On Ibex Peak and Cougar Point, we need to disable clock
+		 * gating for the panel power sequencer or it will fail to
+		 * start up when no ports are active.
+		 */
+		I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+
+		/*
 		 * According to the spec the following bits should be set in
 		 * order to enable memory self-refresh
 		 * The bit 22/21 of 0x42004
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: PCH eDP fixes
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (19 preceding siblings ...)
  2010-10-07 23:01 ` [PATCH 20/20] drm/i915: diasable clock gating for the panel power sequencer Jesse Barnes
@ 2010-10-08  9:50 ` Jim Gettys
  2010-10-08 10:00 ` Chris Wilson
  21 siblings, 0 replies; 24+ messages in thread
From: Jim Gettys @ 2010-10-08  9:50 UTC (permalink / raw)
  To: intel-gfx

On 10/07/2010 07:01 PM, Jesse Barnes wrote:
> Here's the set of PCH eDP fixes I came up with once I received my Sony
> Vaio.  I found a few, non-PCH issues in the process, and took the
> opportunity to enhance our eDP support to avoid most of the DP training
> if the VBIOS gives us good data.
>
> This patchset is against ickle's drm-intel-next branch as of a few hours
> ago, and is working on my test machine.  Before I rebased, I had success
> reports from several users on bug
> https://bugs.freedesktop.org/show_bug.cgi?id=29141.  The key change
> there was to work around a newly discovered Ironlake panel power
> sequencing bug (need to disable clock gating for the panel power
> sequencing unit); before that change, panel bringup was very
> intermittent.
>

These patches work on my HP 2540p which has had the nasty flicker 
problem. https://bugs.freedesktop.org/show_bug.cgi?id=29821

Suspend does not work, however; much less resume: but at least this is 
the first thing I've been able to run in a very long time that works.
                 - Jim

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: PCH eDP fixes
  2010-10-07 23:01 PCH eDP fixes Jesse Barnes
                   ` (20 preceding siblings ...)
  2010-10-08  9:50 ` PCH eDP fixes Jim Gettys
@ 2010-10-08 10:00 ` Chris Wilson
  2010-10-08 16:24   ` Jesse Barnes
  21 siblings, 1 reply; 24+ messages in thread
From: Chris Wilson @ 2010-10-08 10:00 UTC (permalink / raw)
  To: Jesse Barnes, intel-gfx

On Thu,  7 Oct 2010 16:01:05 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> Here's the set of PCH eDP fixes I came up with once I received my Sony
> Vaio.  I found a few, non-PCH issues in the process, and took the
> opportunity to enhance our eDP support to avoid most of the DP training
> if the VBIOS gives us good data.

I didn't see how you confirmed that it was good data rather than just
conservative, power hungry values ;-) Nevertheless, getting eDP to light
up is a massive step forward on those machines.

Applied (after smoke testing on my non-eDP machines) to -next with some
minor amendments (style and compiler warnings).

Thanks Jesse, and to everyone who tested the various hacks, maybe there is
some light at the end of the eDP tunnel!
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: PCH eDP fixes
  2010-10-08 10:00 ` Chris Wilson
@ 2010-10-08 16:24   ` Jesse Barnes
  0 siblings, 0 replies; 24+ messages in thread
From: Jesse Barnes @ 2010-10-08 16:24 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Fri, 08 Oct 2010 11:00:11 +0100
Chris Wilson <chris@chris-wilson.co.uk> wrote:

> On Thu,  7 Oct 2010 16:01:05 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> > Here's the set of PCH eDP fixes I came up with once I received my Sony
> > Vaio.  I found a few, non-PCH issues in the process, and took the
> > opportunity to enhance our eDP support to avoid most of the DP training
> > if the VBIOS gives us good data.
> 
> I didn't see how you confirmed that it was good data rather than just
> conservative, power hungry values ;-) Nevertheless, getting eDP to light
> up is a massive step forward on those machines.

I saw you added a new 'valid' bit of some kind for the VBT provided eDP
data; we should check for that in the DP init function if needed.

As for power, the preemphasis and voltage swing levels are just for
training.  Using the VBT values is supposedly ideal from the panel and
board's perspective (i.e. the link will be most stable with the
provided values), so we really need to use them even if they cost
slightly more power than a different training scheme.  On my test
machine, these values are actually lower than the values arrived at via
full training, so hopefully they're better, power-wise, anyway.

The number of lanes definitely affects power though, but the VBT should
have the minimum number of lanes required to drive the panel at its
native mode (and in fact, some systems may be missing wires for lanes
above this number), so again it should be good from a power perspective.

> Thanks Jesse, and to everyone who tested the various hacks, maybe there is
> some light at the end of the eDP tunnel!

I hope so, sounds like there are still some suspend/resume issues, I'll
take a look at those.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2010-10-08 16:22 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-07 23:01 PCH eDP fixes Jesse Barnes
2010-10-07 23:01 ` [PATCH 01/20] drm/i915/dp: convert eDP checks to functions and document Jesse Barnes
2010-10-07 23:01 ` [PATCH 02/20] drm/i915/dp: remove redundant is_pch_edp checks Jesse Barnes
2010-10-07 23:01 ` [PATCH 03/20] drm/i915/dp: correct eDP lane count and bpp Jesse Barnes
2010-10-07 23:01 ` [PATCH 04/20] drm/i915: add eDP checking functions for the display code Jesse Barnes
2010-10-07 23:01 ` [PATCH 05/20] drm/i915: remove broken intel_pch_has_edp function Jesse Barnes
2010-10-07 23:01 ` [PATCH 06/20] drm/i915: fix CPU vs PCH eDP confusion Jesse Barnes
2010-10-07 23:01 ` [PATCH 07/20] drm/i915/dp: eDP power sequencing fixes Jesse Barnes
2010-10-07 23:01 ` [PATCH 08/20] drm/i915: add _DSM support Jesse Barnes
2010-10-07 23:01 ` [PATCH 09/20] drm/i915: fetch eDP configuration data from the VBT Jesse Barnes
2010-10-07 23:01 ` [PATCH 10/20] drm/i915: add Ironlake clock gating workaround for FDI link training Jesse Barnes
2010-10-07 23:01 ` [PATCH 11/20] drm/i915: fix PCH eDP SSC support Jesse Barnes
2010-10-07 23:01 ` [PATCH 12/20] drm/i915: use 120MHz refclk in PCH eDP case too Jesse Barnes
2010-10-07 23:01 ` [PATCH 13/20] drm/i915: use DPLL_DVO_HIGH_SPEED for PCH eDP Jesse Barnes
2010-10-07 23:01 ` [PATCH 14/20] drm/i915: fix ironlake CRTC enable/disable Jesse Barnes
2010-10-07 23:01 ` [PATCH 15/20] drm/i915: don't program FDI RX/TX in mode_set Jesse Barnes
2010-10-07 23:01 ` [PATCH 16/20] drm/i915/dp: cache eDP DPCD data Jesse Barnes
2010-10-07 23:01 ` [PATCH 17/20] drm/i915/dp: use VBT provided eDP params if available Jesse Barnes
2010-10-07 23:01 ` [PATCH 18/20] drm/i915/dp: don't bother with DP PLL for PCH attached eDP Jesse Barnes
2010-10-07 23:01 ` [PATCH 19/20] drm/i915/dp: make eDP PLL functions work as advertised Jesse Barnes
2010-10-07 23:01 ` [PATCH 20/20] drm/i915: diasable clock gating for the panel power sequencer Jesse Barnes
2010-10-08  9:50 ` PCH eDP fixes Jim Gettys
2010-10-08 10:00 ` Chris Wilson
2010-10-08 16:24   ` Jesse Barnes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.