All of lore.kernel.org
 help / color / mirror / Atom feed
* eDP fixes
@ 2010-09-08 19:41 Jesse Barnes
  2010-09-08 19:41 ` [PATCH 1/7] drm/i915: fix eDP detection Jesse Barnes
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:41 UTC (permalink / raw)
  To: intel-gfx

Here's the set of eDP changes I've been running with locally.  With
these fixes applied, my Dell E6510 test machine is solid from boot
through suspend/resume, though it appears other users haven't been so
fortunate, so there's still more work to do.

Thanks,
Jesse

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

* [PATCH 1/7] drm/i915: fix eDP detection
  2010-09-08 19:41 eDP fixes Jesse Barnes
@ 2010-09-08 19:41 ` Jesse Barnes
  2010-09-08 19:42 ` [PATCH 2/7] drm/i915: use 125MHz reference clock for PCH attached eDP Jesse Barnes
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:41 UTC (permalink / raw)
  To: intel-gfx

Panel needs to be powered up.
---
 drivers/gpu/drm/i915/intel_dp.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 51d1429..625b480 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -754,13 +754,14 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	}
 }
 
-static void ironlake_edp_panel_on (struct drm_device *dev)
+/* Returns true if the panel was already on when called */
+static bool ironlake_edp_panel_on (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
 	if (I915_READ(PCH_PP_STATUS) & PP_ON)
-		return;
+		return true;
 
 	pp = I915_READ(PCH_PP_CONTROL);
 
@@ -780,6 +781,8 @@ static void ironlake_edp_panel_on (struct drm_device *dev)
 	pp |= PANEL_POWER_RESET; /* restore panel reset bit */
 	I915_WRITE(PCH_PP_CONTROL, pp);
 	POSTING_READ(PCH_PP_CONTROL);
+
+	return false;
 }
 
 static void ironlake_edp_panel_off (struct drm_device *dev)
@@ -860,7 +863,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)) {
+	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
 		ironlake_edp_backlight_off(dev);
 		ironlake_edp_panel_on(dev);
 		ironlake_edp_pll_on(encoder);
@@ -1365,7 +1368,11 @@ ironlake_dp_detect(struct drm_connector *connector)
 	struct drm_encoder *encoder = intel_attached_encoder(connector);
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	enum drm_connector_status status;
+	bool was_on = false;
 
+	/* Panel needs power for AUX to work */
+	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+		was_on = ironlake_edp_panel_on(connector->dev);
 	status = connector_status_disconnected;
 	if (intel_dp_aux_native_read(intel_dp,
 				     0x000, intel_dp->dpcd,
@@ -1376,6 +1383,8 @@ 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)) && !was_on)
+		ironlake_edp_panel_off(connector->dev);
 	return status;
 }
 
-- 
1.6.3.3

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

* [PATCH 2/7] drm/i915: use 125MHz reference clock for PCH attached eDP
  2010-09-08 19:41 eDP fixes Jesse Barnes
  2010-09-08 19:41 ` [PATCH 1/7] drm/i915: fix eDP detection Jesse Barnes
@ 2010-09-08 19:42 ` Jesse Barnes
  2010-09-08 19:42 ` [PATCH 3/7] drm/i915: use VDD AUX for panel power around detection and in prepare Jesse Barnes
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:42 UTC (permalink / raw)
  To: intel-gfx

Fix the test so we don't try to use the 450MHz refclk on PCH attached
eDP.

References:
  https://bugs.freedesktop.org/show_bug.cgi?id=29141

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

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 625b480..47eac03 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -246,8 +246,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 	/* The clock divider is based off the hrawclk,
 	 * and would like to run at 2MHz. So, take the
 	 * hrawclk value and divide by 2 and use that
+	 *
+	 * Note that PCH attached eDP panels should use a 125MHz input
+	 * clock divider.
 	 */
-	if (IS_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
-- 
1.6.3.3

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

* [PATCH 3/7] drm/i915: use VDD AUX for panel power around detection and in prepare
  2010-09-08 19:41 eDP fixes Jesse Barnes
  2010-09-08 19:41 ` [PATCH 1/7] drm/i915: fix eDP detection Jesse Barnes
  2010-09-08 19:42 ` [PATCH 2/7] drm/i915: use 125MHz reference clock for PCH attached eDP Jesse Barnes
@ 2010-09-08 19:42 ` Jesse Barnes
  2010-09-08 19:42 ` [PATCH 4/7] drm/i915: split DP link training across panel power sequencing Jesse Barnes
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:42 UTC (permalink / raw)
  To: intel-gfx

Mode setting sequence specifies that we use VDD AUX for configuration
and detection, and early in the mode set sequence.  Only later (after
DP_A has started training) should we actually enable panel power.

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

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 47eac03..d7a854f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -813,6 +813,28 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
 	POSTING_READ(PCH_PP_CONTROL);
 }
 
+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);
+}
+
+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);
+}
+
 static void ironlake_edp_backlight_on (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -868,7 +890,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 
 	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
 		ironlake_edp_backlight_off(dev);
-		ironlake_edp_panel_on(dev);
+		ironlake_edp_panel_vdd_on(dev);
 		ironlake_edp_pll_on(encoder);
 	}
 	if (dp_reg & DP_PORT_EN)
@@ -885,8 +907,10 @@ static void intel_dp_commit(struct drm_encoder *encoder)
 	if (!(dp_reg & DP_PORT_EN)) {
 		intel_dp_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);
 		ironlake_edp_backlight_on(dev);
+	}
 }
 
 static void
@@ -1371,11 +1395,10 @@ ironlake_dp_detect(struct drm_connector *connector)
 	struct drm_encoder *encoder = intel_attached_encoder(connector);
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	enum drm_connector_status status;
-	bool was_on = false;
 
 	/* Panel needs power for AUX to work */
 	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
-		was_on = ironlake_edp_panel_on(connector->dev);
+		ironlake_edp_panel_vdd_on(connector->dev);
 	status = connector_status_disconnected;
 	if (intel_dp_aux_native_read(intel_dp,
 				     0x000, intel_dp->dpcd,
@@ -1386,8 +1409,8 @@ 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)) && !was_on)
-		ironlake_edp_panel_off(connector->dev);
+	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+		ironlake_edp_panel_vdd_off(connector->dev);
 	return status;
 }
 
-- 
1.6.3.3

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

* [PATCH 4/7] drm/i915: split DP link training across panel power sequencing
  2010-09-08 19:41 eDP fixes Jesse Barnes
                   ` (2 preceding siblings ...)
  2010-09-08 19:42 ` [PATCH 3/7] drm/i915: use VDD AUX for panel power around detection and in prepare Jesse Barnes
@ 2010-09-08 19:42 ` Jesse Barnes
  2010-09-08 19:42 ` [PATCH 5/7] drm/i915: don't change VDD AUX status in panel power functions Jesse Barnes
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:42 UTC (permalink / raw)
  To: intel-gfx

Mode set sequence requires that we start training, then enable the
panel, then complete training.  So split the DP training function into
two parts; the first enables the DP port and sets training pattern 1 and
the second completes the training.

As part of this, remove some redundant function args from the various DP
handling functions and use the intel_dp fields everywhere we can.

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

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d7a854f..5053391 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -58,6 +58,8 @@ struct intel_dp {
 	struct i2c_adapter adapter;
 	struct i2c_algo_dp_aux_data algo;
 	bool is_pch_edp;
+	uint8_t	train_set[4];
+	uint8_t link_status[DP_LINK_STATUS_SIZE];
 };
 
 static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
@@ -65,7 +67,8 @@ static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
 	return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base);
 }
 
-static void intel_dp_link_train(struct intel_dp *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);
 
 void
@@ -902,15 +905,15 @@ static void intel_dp_commit(struct drm_encoder *encoder)
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
-	if (!(dp_reg & DP_PORT_EN)) {
-		intel_dp_link_train(intel_dp);
-	}
+	intel_dp_start_link_train(intel_dp);
 	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
 		ironlake_edp_panel_on(dev);
 		ironlake_edp_backlight_on(dev);
 	}
+	intel_dp_complete_link_train(intel_dp);
+	if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+		ironlake_edp_backlight_on(encoder->dev);
 }
 
 static void
@@ -932,9 +935,10 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
 			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))
 				ironlake_edp_panel_on(dev);
-			intel_dp_link_train(intel_dp);
+			intel_dp_complete_link_train(intel_dp);
 			if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
 				ironlake_edp_backlight_on(dev);
 		}
@@ -947,14 +951,13 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_dp *intel_dp,
-			 uint8_t link_status[DP_LINK_STATUS_SIZE])
+intel_dp_get_link_status(struct intel_dp *intel_dp)
 {
 	int ret;
 
 	ret = intel_dp_aux_native_read(intel_dp,
 				       DP_LANE0_1_STATUS,
-				       link_status, DP_LINK_STATUS_SIZE);
+				       intel_dp->link_status, DP_LINK_STATUS_SIZE);
 	if (ret != DP_LINK_STATUS_SIZE)
 		return false;
 	return true;
@@ -1029,18 +1032,15 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
 }
 
 static void
-intel_get_adjust_train(struct intel_dp *intel_dp,
-		       uint8_t link_status[DP_LINK_STATUS_SIZE],
-		       int lane_count,
-		       uint8_t train_set[4])
+intel_get_adjust_train(struct intel_dp *intel_dp)
 {
 	uint8_t v = 0;
 	uint8_t p = 0;
 	int lane;
 
-	for (lane = 0; lane < lane_count; lane++) {
-		uint8_t this_v = intel_get_adjust_request_voltage(link_status, lane);
-		uint8_t this_p = intel_get_adjust_request_pre_emphasis(link_status, lane);
+	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+		uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane);
+		uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane);
 
 		if (this_v > v)
 			v = this_v;
@@ -1055,7 +1055,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp,
 		p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
 	for (lane = 0; lane < 4; lane++)
-		train_set[lane] = v | p;
+		intel_dp->train_set[lane] = v | p;
 }
 
 static uint32_t
@@ -1146,18 +1146,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count
 			 DP_LANE_CHANNEL_EQ_DONE|\
 			 DP_LANE_SYMBOL_LOCKED)
 static bool
-intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
+intel_channel_eq_ok(struct intel_dp *intel_dp)
 {
 	uint8_t lane_align;
 	uint8_t lane_status;
 	int lane;
 
-	lane_align = intel_dp_link_status(link_status,
+	lane_align = intel_dp_link_status(intel_dp->link_status,
 					  DP_LANE_ALIGN_STATUS_UPDATED);
 	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
 		return false;
-	for (lane = 0; lane < lane_count; lane++) {
-		lane_status = intel_get_lane_status(link_status, lane);
+	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+		lane_status = intel_get_lane_status(intel_dp->link_status, lane);
 		if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
 			return false;
 	}
@@ -1168,7 +1168,6 @@ static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
 			uint32_t dp_reg_value,
 			uint8_t dp_train_pat,
-			uint8_t train_set[4],
 			bool first)
 {
 	struct drm_device *dev = intel_dp->base.enc.dev;
@@ -1186,24 +1185,21 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 				    dp_train_pat);
 
 	ret = intel_dp_aux_native_write(intel_dp,
-					DP_TRAINING_LANE0_SET, train_set, 4);
+					DP_TRAINING_LANE0_SET, intel_dp->train_set, 4);
 	if (ret != 4)
 		return false;
 
 	return true;
 }
 
+/* Enable corresponding port and start training pattern 1 */
 static void
-intel_dp_link_train(struct intel_dp *intel_dp)
+intel_dp_start_link_train(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp->base.enc.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	uint8_t	train_set[4];
-	uint8_t link_status[DP_LINK_STATUS_SIZE];
 	int i;
 	uint8_t voltage;
 	bool clock_recovery = false;
-	bool channel_eq = false;
 	bool first = true;
 	int tries;
 	u32 reg;
@@ -1219,18 +1215,18 @@ intel_dp_link_train(struct intel_dp *intel_dp)
 		DP &= ~DP_LINK_TRAIN_MASK_CPT;
 	else
 		DP &= ~DP_LINK_TRAIN_MASK;
-	memset(train_set, 0, 4);
+	memset(intel_dp->train_set, 0, 4);
 	voltage = 0xff;
 	tries = 0;
 	clock_recovery = false;
 	for (;;) {
-		/* Use train_set[0] to set the voltage and pre emphasis values */
+		/* 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)) {
-			signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
+			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(train_set[0], intel_dp->lane_count);
+			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
 			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 		}
 
@@ -1240,52 +1236,65 @@ intel_dp_link_train(struct intel_dp *intel_dp)
 			reg = DP | DP_LINK_TRAIN_PAT_1;
 
 		if (!intel_dp_set_link_train(intel_dp, reg,
-					     DP_TRAINING_PATTERN_1, train_set, first))
+					     DP_TRAINING_PATTERN_1, first))
 			break;
 		first = false;
 		/* Set training pattern 1 */
 
 		udelay(100);
-		if (!intel_dp_get_link_status(intel_dp, link_status))
+		if (!intel_dp_get_link_status(intel_dp))
 			break;
 
-		if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+		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 ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 				break;
 		if (i == intel_dp->lane_count)
 			break;
 
 		/* Check to see if we've tried the same voltage 5 times */
-		if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
 			++tries;
 			if (tries == 5)
 				break;
 		} else
 			tries = 0;
-		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
-		/* Compute new train_set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set);
+		/* Compute new intel_dp->train_set as requested by target */
+		intel_get_adjust_train(intel_dp);
 	}
 
+	intel_dp->DP = DP;
+}
+
+static void
+intel_dp_complete_link_train(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp->base.enc.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool channel_eq = false;
+	int tries;
+	u32 reg;
+	uint32_t DP = intel_dp->DP;
+
 	/* channel equalization */
 	tries = 0;
 	channel_eq = false;
 	for (;;) {
-		/* Use train_set[0] to set the voltage and pre emphasis values */
+		/* 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)) {
-			signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
+			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(train_set[0], intel_dp->lane_count);
+			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
 			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 		}
 
@@ -1296,15 +1305,15 @@ intel_dp_link_train(struct intel_dp *intel_dp)
 
 		/* channel eq pattern */
 		if (!intel_dp_set_link_train(intel_dp, reg,
-					     DP_TRAINING_PATTERN_2, train_set,
+					     DP_TRAINING_PATTERN_2,
 					     false))
 			break;
 
 		udelay(400);
-		if (!intel_dp_get_link_status(intel_dp, link_status))
+		if (!intel_dp_get_link_status(intel_dp))
 			break;
 
-		if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) {
+		if (intel_channel_eq_ok(intel_dp)) {
 			channel_eq = true;
 			break;
 		}
@@ -1313,8 +1322,8 @@ intel_dp_link_train(struct intel_dp *intel_dp)
 		if (tries > 5)
 			break;
 
-		/* Compute new train_set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set);
+		/* Compute new intel_dp->train_set as requested by target */
+		intel_get_adjust_train(intel_dp);
 		++tries;
 	}
 
@@ -1375,18 +1384,18 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
-	uint8_t link_status[DP_LINK_STATUS_SIZE];
-
 	if (!intel_dp->base.enc.crtc)
 		return;
 
-	if (!intel_dp_get_link_status(intel_dp, link_status)) {
+	if (!intel_dp_get_link_status(intel_dp)) {
 		intel_dp_link_down(intel_dp);
 		return;
 	}
 
-	if (!intel_channel_eq_ok(link_status, intel_dp->lane_count))
-		intel_dp_link_train(intel_dp);
+	if (!intel_channel_eq_ok(intel_dp)) {
+		intel_dp_start_link_train(intel_dp);
+		intel_dp_complete_link_train(intel_dp);
+	}
 }
 
 static enum drm_connector_status
-- 
1.6.3.3

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

* [PATCH 5/7] drm/i915: don't change VDD AUX status in panel power functions
  2010-09-08 19:41 eDP fixes Jesse Barnes
                   ` (3 preceding siblings ...)
  2010-09-08 19:42 ` [PATCH 4/7] drm/i915: split DP link training across panel power sequencing Jesse Barnes
@ 2010-09-08 19:42 ` Jesse Barnes
  2010-09-08 19:42 ` [PATCH 6/7] drm/i915: make sure VDD AUX power has time to settle Jesse Barnes
  2010-09-08 19:42 ` [PATCH 7/7] drm/i915: make sure panel is sequenced off when starting a mode set Jesse Barnes
  6 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:42 UTC (permalink / raw)
  To: intel-gfx

Mode set sequence outlines when the AUX VDD bit should be set and
cleared, and it's separate from the panel power sequence.

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

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5053391..2f7eb5d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -783,7 +783,7 @@ static bool ironlake_edp_panel_on (struct drm_device *dev)
 		DRM_ERROR("panel on wait timed out: 0x%08x\n",
 			  I915_READ(PCH_PP_STATUS));
 
-	pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD);
+	pp &= ~(PANEL_UNLOCK_REGS);
 	pp |= PANEL_POWER_RESET; /* restore panel reset bit */
 	I915_WRITE(PCH_PP_CONTROL, pp);
 	POSTING_READ(PCH_PP_CONTROL);
@@ -811,7 +811,7 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
 			  I915_READ(PCH_PP_STATUS));
 
 	/* Make sure VDD is enabled so DP AUX will work */
-	pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */
+	pp |= PANEL_POWER_RESET; /* restore panel reset bit */
 	I915_WRITE(PCH_PP_CONTROL, pp);
 	POSTING_READ(PCH_PP_CONTROL);
 }
-- 
1.6.3.3

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

* [PATCH 6/7] drm/i915: make sure VDD AUX power has time to settle
  2010-09-08 19:41 eDP fixes Jesse Barnes
                   ` (4 preceding siblings ...)
  2010-09-08 19:42 ` [PATCH 5/7] drm/i915: don't change VDD AUX status in panel power functions Jesse Barnes
@ 2010-09-08 19:42 ` Jesse Barnes
  2010-09-08 19:42 ` [PATCH 7/7] drm/i915: make sure panel is sequenced off when starting a mode set Jesse Barnes
  6 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:42 UTC (permalink / raw)
  To: intel-gfx

When turning on or off the VDD AUX bit, we need to give the panel time
to start or stop or AUX transactions may fail.

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

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2f7eb5d..3836f1f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -825,6 +825,7 @@ static void ironlake_edp_panel_vdd_on (struct drm_device *dev)
 	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)
@@ -836,6 +837,7 @@ static void ironlake_edp_panel_vdd_off (struct drm_device *dev)
 	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)
-- 
1.6.3.3

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

* [PATCH 7/7] drm/i915: make sure panel is sequenced off when starting a mode set
  2010-09-08 19:41 eDP fixes Jesse Barnes
                   ` (5 preceding siblings ...)
  2010-09-08 19:42 ` [PATCH 6/7] drm/i915: make sure VDD AUX power has time to settle Jesse Barnes
@ 2010-09-08 19:42 ` Jesse Barnes
  2010-09-08 20:11   ` Chris Wilson
  6 siblings, 1 reply; 9+ messages in thread
From: Jesse Barnes @ 2010-09-08 19:42 UTC (permalink / raw)
  To: intel-gfx

Otherwise we may not be able to train the DP link.

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

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3836f1f..0115039 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -894,6 +894,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
 	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);
 		ironlake_edp_pll_on(encoder);
-- 
1.6.3.3

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

* Re: [PATCH 7/7] drm/i915: make sure panel is sequenced off when starting a mode set
  2010-09-08 19:42 ` [PATCH 7/7] drm/i915: make sure panel is sequenced off when starting a mode set Jesse Barnes
@ 2010-09-08 20:11   ` Chris Wilson
  0 siblings, 0 replies; 9+ messages in thread
From: Chris Wilson @ 2010-09-08 20:11 UTC (permalink / raw)
  To: Jesse Barnes, intel-gfx

With a couple of tweaks as discussed on IRC, applied to -next.
Thanks,
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

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

end of thread, other threads:[~2010-09-08 20:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-08 19:41 eDP fixes Jesse Barnes
2010-09-08 19:41 ` [PATCH 1/7] drm/i915: fix eDP detection Jesse Barnes
2010-09-08 19:42 ` [PATCH 2/7] drm/i915: use 125MHz reference clock for PCH attached eDP Jesse Barnes
2010-09-08 19:42 ` [PATCH 3/7] drm/i915: use VDD AUX for panel power around detection and in prepare Jesse Barnes
2010-09-08 19:42 ` [PATCH 4/7] drm/i915: split DP link training across panel power sequencing Jesse Barnes
2010-09-08 19:42 ` [PATCH 5/7] drm/i915: don't change VDD AUX status in panel power functions Jesse Barnes
2010-09-08 19:42 ` [PATCH 6/7] drm/i915: make sure VDD AUX power has time to settle Jesse Barnes
2010-09-08 19:42 ` [PATCH 7/7] drm/i915: make sure panel is sequenced off when starting a mode set Jesse Barnes
2010-09-08 20:11   ` Chris Wilson

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.