All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored
@ 2015-10-12  6:25 Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 1/9] drm/i915: Merge intel_dp_update_signal_levels() with set_signal_levels() Ander Conselvan de Oliveira
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

(I'm resending this due to a typo on intel-gfx@ mailing list address,
sorry for duplications.)

Hi,

This patch series reorganizes how the limits for DP voltage swing and pre
emphasis are stored. It moves that information into a struct that holds
the data for a given platform or a set of platforms. The if ladder to
chose the right value is then restrict to one function that sets up a
pointer in intel_dp.

I smoke-tested this in a haswell laptop. To verify that the values are
unchanged, I also wrote a small program that exercises the code and
prints the values for different platforms. I then ran it with the old
and new code and verified that there are no differences. The code for
that program is in the link below:

https://github.com/anderco/linux/commit/36268e777effefb3e906b35e2052d5488271b3ff

This patch series applies on top of the link training series I sent earlier
this week.

Thanks,
Ander

Ander Conselvan de Oliveira (9):
  drm/i915: Merge intel_dp_update_signal_levels() with
    set_signal_levels()
  drm/i915: Split setting of vswing and pre_emph levels to separate file
  drm/i915: Introduce struct intel_dp_signal_levels
  drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB
  drm/i915: Use struct intel_dp_signal_levels for VLV
  drm/i915: Use struct intel_dp_signal_levels for CHV
  drm/i915: Use struct intel_dp_signal_levels for DDI platforms
  drm/i915: Remove old functions for maximum DP vswing and pre-emph
    levels
  drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c

 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/intel_ddi.c              |  78 +--
 drivers/gpu/drm/i915/intel_dp.c               | 534 +-------------------
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 694 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h              |  24 +-
 5 files changed, 724 insertions(+), 607 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dp_signal_levels.c

-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 1/9] drm/i915: Merge intel_dp_update_signal_levels() with set_signal_levels()
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 2/9] drm/i915: Split setting of vswing and pre_emph levels to separate file Ander Conselvan de Oliveira
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Merge intel_dp_update_signal_levels() and intel_dp_set_signal_levels(),
since the former is the only user of the latter and doing so allow us to
not pass a pointer to intel_dp->DP around.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b785f1f..05374a7 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3526,13 +3526,13 @@ gen7_edp_signal_levels(uint8_t train_set)
 	}
 }
 
-/* Properly updates "DP" with the correct signal levels. */
-static void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
+void
+intel_dp_update_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	uint32_t signal_levels, mask = 0;
 	uint8_t train_set = intel_dp->train_set[0];
 
@@ -3567,31 +3567,22 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
 			DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
-	*DP = (*DP & ~mask) | signal_levels;
-}
-
-void
-intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
-				       uint8_t dp_train_pat)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct drm_i915_private *dev_priv =
-		to_i915(intel_dig_port->base.base.dev);
-
-	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
+	intel_dp->DP &= ~mask;
+	intel_dp->DP |= signal_levels;
 
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
 }
 
 void
-intel_dp_update_signal_levels(struct intel_dp *intel_dp)
+intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       uint8_t dp_train_pat)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv =
 		to_i915(intel_dig_port->base.base.dev);
 
-	intel_dp_set_signal_levels(intel_dp, &intel_dp->DP);
+	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
 
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 2/9] drm/i915: Split setting of vswing and pre_emph levels to separate file
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 1/9] drm/i915: Merge intel_dp_update_signal_levels() with set_signal_levels() Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 3/9] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

No functional changes, just moving code around.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/intel_dp.c               | 523 -------------------------
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 542 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h              |   7 +
 4 files changed, 550 insertions(+), 523 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dp_signal_levels.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..9cf9978 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -79,6 +79,7 @@ i915-y += dvo_ch7017.o \
 	  intel_ddi.o \
 	  intel_dp_link_training.o \
 	  intel_dp_mst.o \
+	  intel_dp_signal_levels.o \
 	  intel_dp.o \
 	  intel_dsi.o \
 	  intel_dsi_panel_vbt.o \
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 05374a7..9a159c0 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -111,13 +111,6 @@ static bool is_edp(struct intel_dp *intel_dp)
 	return intel_dig_port->base.type == INTEL_OUTPUT_EDP;
 }
 
-static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-
-	return intel_dig_port->base.base.dev;
-}
-
 static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
 {
 	return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
@@ -3058,522 +3051,6 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
 				       DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
 }
 
-/* These are source-specific values. */
-uint8_t
-intel_dp_voltage_max(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (IS_BROXTON(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (INTEL_INFO(dev)->gen >= 9) {
-		if (dev_priv->edp_low_vswing && port == PORT_A)
-			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	} else if (IS_VALLEYVIEW(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (IS_GEN7(dev) && port == PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	else if (HAS_PCH_CPT(dev) && port != PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-}
-
-uint8_t
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (INTEL_INFO(dev)->gen >= 9) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_VALLEYVIEW(dev)) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_GEN7(dev) && port == PORT_A) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	}
-}
-
-static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct intel_crtc *intel_crtc =
-		to_intel_crtc(dport->base.base.crtc);
-	unsigned long demph_reg_value, preemph_reg_value,
-		uniqtranscale_reg_value;
-	uint8_t train_set = intel_dp->train_set[0];
-	enum dpio_channel port = vlv_dport_to_channel(dport);
-	int pipe = intel_crtc->pipe;
-
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
-	case DP_TRAIN_PRE_EMPH_LEVEL_0:
-		preemph_reg_value = 0x0004000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x2B405555;
-			uniqtranscale_reg_value = 0x552AB83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			demph_reg_value = 0x2B404040;
-			uniqtranscale_reg_value = 0x5548B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			demph_reg_value = 0x2B245555;
-			uniqtranscale_reg_value = 0x5560B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-			demph_reg_value = 0x2B405555;
-			uniqtranscale_reg_value = 0x5598DA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_1:
-		preemph_reg_value = 0x0002000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x2B404040;
-			uniqtranscale_reg_value = 0x5552B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			demph_reg_value = 0x2B404848;
-			uniqtranscale_reg_value = 0x5580B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			demph_reg_value = 0x2B404040;
-			uniqtranscale_reg_value = 0x55ADDA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_2:
-		preemph_reg_value = 0x0000000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x2B305555;
-			uniqtranscale_reg_value = 0x5570B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			demph_reg_value = 0x2B2B4040;
-			uniqtranscale_reg_value = 0x55ADDA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_3:
-		preemph_reg_value = 0x0006000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x1B405555;
-			uniqtranscale_reg_value = 0x55ADDA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	default:
-		return 0;
-	}
-
-	mutex_lock(&dev_priv->sb_lock);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
-			 uniqtranscale_reg_value);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
-	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
-}
-
-static bool chv_need_uniq_trans_scale(uint8_t train_set)
-{
-	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
-		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-}
-
-static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
-	u32 deemph_reg_value, margin_reg_value, val;
-	uint8_t train_set = intel_dp->train_set[0];
-	enum dpio_channel ch = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
-	int i;
-
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
-	case DP_TRAIN_PRE_EMPH_LEVEL_0:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 128;
-			margin_reg_value = 52;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			deemph_reg_value = 128;
-			margin_reg_value = 77;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			deemph_reg_value = 128;
-			margin_reg_value = 102;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-			deemph_reg_value = 128;
-			margin_reg_value = 154;
-			/* FIXME extra to set for 1200 */
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_1:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 85;
-			margin_reg_value = 78;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			deemph_reg_value = 85;
-			margin_reg_value = 116;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			deemph_reg_value = 85;
-			margin_reg_value = 154;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_2:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 64;
-			margin_reg_value = 104;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			deemph_reg_value = 64;
-			margin_reg_value = 154;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_3:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 43;
-			margin_reg_value = 154;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	default:
-		return 0;
-	}
-
-	mutex_lock(&dev_priv->sb_lock);
-
-	/* Clear calc init */
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
-	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
-	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
-	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
-
-	if (intel_crtc->config->lane_count > 2) {
-		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
-		val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
-		val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
-		val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
-	}
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
-	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
-	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
-
-	if (intel_crtc->config->lane_count > 2) {
-		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
-		val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
-		val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
-	}
-
-	/* Program swing deemph */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
-		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
-		val &= ~DPIO_SWING_DEEMPH9P5_MASK;
-		val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
-		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
-	}
-
-	/* Program swing margin */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
-		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
-
-		val &= ~DPIO_SWING_MARGIN000_MASK;
-		val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
-
-		/*
-		 * Supposedly this value shouldn't matter when unique transition
-		 * scale is disabled, but in fact it does matter. Let's just
-		 * always program the same value and hope it's OK.
-		 */
-		val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
-		val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
-
-		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
-	}
-
-	/*
-	 * The document said it needs to set bit 27 for ch0 and bit 26
-	 * for ch1. Might be a typo in the doc.
-	 * For now, for this unique transition scale selection, set bit
-	 * 27 for ch0 and ch1.
-	 */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
-		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
-		if (chv_need_uniq_trans_scale(train_set))
-			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
-		else
-			val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
-		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
-	}
-
-	/* Start swing calculation */
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
-	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
-
-	if (intel_crtc->config->lane_count > 2) {
-		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
-		val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
-	}
-
-	/* LRC Bypass */
-	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30);
-	val |= DPIO_LRC_BYPASS;
-	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val);
-
-	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
-}
-
-static uint32_t
-gen4_signal_levels(uint8_t train_set)
-{
-	uint32_t	signal_levels = 0;
-
-	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-	default:
-		signal_levels |= DP_VOLTAGE_0_4;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		signal_levels |= DP_VOLTAGE_0_6;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-		signal_levels |= DP_VOLTAGE_0_8;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		signal_levels |= DP_VOLTAGE_1_2;
-		break;
-	}
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
-	case DP_TRAIN_PRE_EMPH_LEVEL_0:
-	default:
-		signal_levels |= DP_PRE_EMPHASIS_0;
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_1:
-		signal_levels |= DP_PRE_EMPHASIS_3_5;
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_2:
-		signal_levels |= DP_PRE_EMPHASIS_6;
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_3:
-		signal_levels |= DP_PRE_EMPHASIS_9_5;
-		break;
-	}
-	return signal_levels;
-}
-
-/* Gen6's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen6_edp_signal_levels(uint8_t train_set)
-{
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
-	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
-	}
-}
-
-/* Gen7's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen7_edp_signal_levels(uint8_t train_set)
-{
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400MV_0DB_IVB;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		return EDP_LINK_TRAIN_400MV_6DB_IVB;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_600MV_0DB_IVB;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800MV_0DB_IVB;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
-
-	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_500MV_0DB_IVB;
-	}
-}
-
-void
-intel_dp_update_signal_levels(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	enum port port = intel_dig_port->port;
-	struct drm_device *dev = intel_dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	uint32_t signal_levels, mask = 0;
-	uint8_t train_set = intel_dp->train_set[0];
-
-	if (HAS_DDI(dev)) {
-		signal_levels = ddi_signal_levels(intel_dp);
-
-		if (IS_BROXTON(dev))
-			signal_levels = 0;
-		else
-			mask = DDI_BUF_EMP_MASK;
-	} else if (IS_CHERRYVIEW(dev)) {
-		signal_levels = chv_signal_levels(intel_dp);
-	} else if (IS_VALLEYVIEW(dev)) {
-		signal_levels = vlv_signal_levels(intel_dp);
-	} else if (IS_GEN7(dev) && port == PORT_A) {
-		signal_levels = gen7_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
-	} else if (IS_GEN6(dev) && port == PORT_A) {
-		signal_levels = gen6_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
-	} else {
-		signal_levels = gen4_signal_levels(train_set);
-		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
-	}
-
-	if (mask)
-		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
-
-	DRM_DEBUG_KMS("Using vswing level %d\n",
-		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
-	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
-		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
-			DP_TRAIN_PRE_EMPHASIS_SHIFT);
-
-	intel_dp->DP &= ~mask;
-	intel_dp->DP |= signal_levels;
-
-	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
-	POSTING_READ(intel_dp->output_reg);
-}
-
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 				       uint8_t dp_train_pat)
diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
new file mode 100644
index 0000000..6d21638
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "intel_drv.h"
+
+/* These are source-specific values. */
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	if (IS_BROXTON(dev))
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else if (INTEL_INFO(dev)->gen >= 9) {
+		if (dev_priv->edp_low_vswing && port == PORT_A)
+			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	} else if (IS_VALLEYVIEW(dev))
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else if (IS_GEN7(dev) && port == PORT_A)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	else if (HAS_PCH_CPT(dev) && port != PORT_A)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+}
+
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_VALLEYVIEW(dev)) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_GEN7(dev) && port == PORT_A) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	}
+}
+
+static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dport->base.base.crtc);
+	unsigned long demph_reg_value, preemph_reg_value,
+		uniqtranscale_reg_value;
+	uint8_t train_set = intel_dp->train_set[0];
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		preemph_reg_value = 0x0004000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x552AB83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5548B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			demph_reg_value = 0x2B245555;
+			uniqtranscale_reg_value = 0x5560B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x5598DA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		preemph_reg_value = 0x0002000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5552B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B404848;
+			uniqtranscale_reg_value = 0x5580B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		preemph_reg_value = 0x0000000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B305555;
+			uniqtranscale_reg_value = 0x5570B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B2B4040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		preemph_reg_value = 0x0006000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x1B405555;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
+			 uniqtranscale_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return 0;
+}
+
+static bool chv_need_uniq_trans_scale(uint8_t train_set)
+{
+	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
+		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+}
+
+static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
+	u32 deemph_reg_value, margin_reg_value, val;
+	uint8_t train_set = intel_dp->train_set[0];
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	enum pipe pipe = intel_crtc->pipe;
+	int i;
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 128;
+			margin_reg_value = 52;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 128;
+			margin_reg_value = 77;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			deemph_reg_value = 128;
+			margin_reg_value = 102;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			deemph_reg_value = 128;
+			margin_reg_value = 154;
+			/* FIXME extra to set for 1200 */
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 85;
+			margin_reg_value = 78;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 85;
+			margin_reg_value = 116;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			deemph_reg_value = 85;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 64;
+			margin_reg_value = 104;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 64;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 43;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Clear calc init */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
+		val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+		val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+		val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+	}
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
+	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
+		val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+		val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
+	}
+
+	/* Program swing deemph */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
+		val &= ~DPIO_SWING_DEEMPH9P5_MASK;
+		val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
+	}
+
+	/* Program swing margin */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+
+		val &= ~DPIO_SWING_MARGIN000_MASK;
+		val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
+
+		/*
+		 * Supposedly this value shouldn't matter when unique transition
+		 * scale is disabled, but in fact it does matter. Let's just
+		 * always program the same value and hope it's OK.
+		 */
+		val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
+		val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
+
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+	}
+
+	/*
+	 * The document said it needs to set bit 27 for ch0 and bit 26
+	 * for ch1. Might be a typo in the doc.
+	 * For now, for this unique transition scale selection, set bit
+	 * 27 for ch0 and ch1.
+	 */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+		if (chv_need_uniq_trans_scale(train_set))
+			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		else
+			val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+	}
+
+	/* Start swing calculation */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
+		val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+	}
+
+	/* LRC Bypass */
+	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30);
+	val |= DPIO_LRC_BYPASS;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return 0;
+}
+
+static uint32_t
+gen4_signal_levels(uint8_t train_set)
+{
+	uint32_t	signal_levels = 0;
+
+	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+	default:
+		signal_levels |= DP_VOLTAGE_0_4;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		signal_levels |= DP_VOLTAGE_0_6;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+		signal_levels |= DP_VOLTAGE_0_8;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		signal_levels |= DP_VOLTAGE_1_2;
+		break;
+	}
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+	default:
+		signal_levels |= DP_PRE_EMPHASIS_0;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		signal_levels |= DP_PRE_EMPHASIS_3_5;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		signal_levels |= DP_PRE_EMPHASIS_6;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		signal_levels |= DP_PRE_EMPHASIS_9_5;
+		break;
+	}
+	return signal_levels;
+}
+
+/* Gen6's DP voltage swing and pre-emphasis control */
+static uint32_t
+gen6_edp_signal_levels(uint8_t train_set)
+{
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	}
+}
+
+/* Gen7's DP voltage swing and pre-emphasis control */
+static uint32_t
+gen7_edp_signal_levels(uint8_t train_set)
+{
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_400MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		return EDP_LINK_TRAIN_400MV_6DB_IVB;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_600MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_800MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_500MV_0DB_IVB;
+	}
+}
+
+void
+intel_dp_update_signal_levels(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint32_t signal_levels, mask = 0;
+	uint8_t train_set = intel_dp->train_set[0];
+
+	if (HAS_DDI(dev)) {
+		signal_levels = ddi_signal_levels(intel_dp);
+
+		if (IS_BROXTON(dev))
+			signal_levels = 0;
+		else
+			mask = DDI_BUF_EMP_MASK;
+	} else if (IS_CHERRYVIEW(dev)) {
+		signal_levels = chv_signal_levels(intel_dp);
+	} else if (IS_VALLEYVIEW(dev)) {
+		signal_levels = vlv_signal_levels(intel_dp);
+	} else if (IS_GEN7(dev) && port == PORT_A) {
+		signal_levels = gen7_edp_signal_levels(train_set);
+		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
+	} else if (IS_GEN6(dev) && port == PORT_A) {
+		signal_levels = gen6_edp_signal_levels(train_set);
+		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
+	} else {
+		signal_levels = gen4_signal_levels(train_set);
+		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
+	}
+
+	if (mask)
+		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	DRM_DEBUG_KMS("Using vswing level %d\n",
+		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
+		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+	intel_dp->DP &= ~mask;
+	intel_dp->DP |= signal_levels;
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
+}
+
+
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 298050f..d341210 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -936,6 +936,13 @@ dp_to_dig_port(struct intel_dp *intel_dp)
 	return container_of(intel_dp, struct intel_digital_port, dp);
 }
 
+static inline struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+
+	return intel_dig_port->base.base.dev;
+}
+
 static inline struct intel_digital_port *
 hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 {
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 3/9] drm/i915: Introduce struct intel_dp_signal_levels
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 1/9] drm/i915: Merge intel_dp_update_signal_levels() with set_signal_levels() Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 2/9] drm/i915: Split setting of vswing and pre_emph levels to separate file Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 4/9] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB Ander Conselvan de Oliveira
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

In order to clarify which platforms support which combination of voltage
swing and pre emphasis level, introduce struct intel_dp_signal_levels.
With the new struct, the if ladder to determine the values used is put
in one place, intel_dp_init_signal_levels().

This also wires gens 4, 5 and non-eDP ports on gen 6 and 7 to use the
new struct.
---
 drivers/gpu/drm/i915/intel_dp.c               |   2 +
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 103 ++++++++++++++++++++++----
 drivers/gpu/drm/i915/intel_drv.h              |  11 +++
 3 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9a159c0..2321b7e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5220,6 +5220,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	if (HAS_DDI(dev))
 		intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
 
+	intel_dp_init_signal_levels(intel_dp);
+
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
 	intel_dp->attached_connector = intel_connector;
diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 6d21638..317a2b4 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -24,8 +24,8 @@
 #include "intel_drv.h"
 
 /* These are source-specific values. */
-uint8_t
-intel_dp_voltage_max(struct intel_dp *intel_dp)
+static uint8_t
+_dp_voltage_max(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -47,8 +47,8 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
 
-uint8_t
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+static uint8_t
+_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	enum port port = dp_to_dig_port(intel_dp)->port;
@@ -394,10 +394,10 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 	return 0;
 }
 
-static uint32_t
-gen4_signal_levels(uint8_t train_set)
+static void
+gen4_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	uint32_t	signal_levels = 0;
+	uint32_t signal_levels = 0;
 
 	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
@@ -429,9 +429,38 @@ gen4_signal_levels(uint8_t train_set)
 		signal_levels |= DP_PRE_EMPHASIS_9_5;
 		break;
 	}
-	return signal_levels;
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
+	intel_dp->DP |= signal_levels;
 }
 
+static const struct signal_levels gen4_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = gen4_set_signal_levels,
+};
+
+/* Not for eDP */
+static const struct signal_levels snb_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = gen4_set_signal_levels,
+};
+
 /* Gen6's DP voltage swing and pre-emphasis control */
 static uint32_t
 gen6_edp_signal_levels(uint8_t train_set)
@@ -491,13 +520,12 @@ gen7_edp_signal_levels(uint8_t train_set)
 	}
 }
 
-void
-intel_dp_update_signal_levels(struct intel_dp *intel_dp)
+static void
+_update_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	uint32_t signal_levels, mask = 0;
 	uint8_t train_set = intel_dp->train_set[0];
 
@@ -519,24 +547,67 @@ intel_dp_update_signal_levels(struct intel_dp *intel_dp)
 		signal_levels = gen6_edp_signal_levels(train_set);
 		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
 	} else {
-		signal_levels = gen4_signal_levels(train_set);
-		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
+		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
+		return;
 	}
 
 	if (mask)
 		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
 
+	intel_dp->DP &= ~mask;
+	intel_dp->DP |= signal_levels;
+}
+
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp)
+{
+	if (intel_dp->signal_levels)
+		return intel_dp->signal_levels->max_voltage;
+	else
+		return _dp_voltage_max(intel_dp);
+}
+
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+{
+	if (intel_dp->signal_levels)
+		return intel_dp->signal_levels->max_pre_emph[voltage_swing];
+	else
+		return _dp_pre_emphasis_max(intel_dp, voltage_swing);
+}
+
+void
+intel_dp_update_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint8_t train_set = intel_dp->train_set[0];
+
+	if (intel_dp->signal_levels)
+		intel_dp->signal_levels->set(intel_dp, train_set);
+	else
+		_update_signal_levels(intel_dp);
+
 	DRM_DEBUG_KMS("Using vswing level %d\n",
 		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
 	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
 		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
 			DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
-	intel_dp->DP &= ~mask;
-	intel_dp->DP |= signal_levels;
-
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
 }
 
+void
+intel_dp_init_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
 
+	if (port != PORT_A && (IS_IVYBRIDGE(dev) || IS_GEN6(dev)))
+		intel_dp->signal_levels = &snb_signal_levels;
+
+	if (INTEL_INFO(dev)->gen <= 5)
+		intel_dp->signal_levels = &gen4_signal_levels;
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d341210..2b7cac9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -740,6 +740,14 @@ struct sink_crc {
 	int last_count;
 };
 
+struct intel_dp;
+struct signal_levels {
+	uint8_t max_voltage;
+	uint8_t max_pre_emph[4];
+
+	void (*set)(struct intel_dp *intel_dp, uint8_t train_set);
+};
+
 struct intel_dp {
 	uint32_t output_reg;
 	uint32_t aux_ch_ctl_reg;
@@ -758,6 +766,7 @@ struct intel_dp {
 	int sink_rates[DP_MAX_SUPPORTED_RATES];
 	struct sink_crc sink_crc;
 	struct drm_dp_aux aux;
+	const struct signal_levels *signal_levels;
 	uint8_t train_set[4];
 	int panel_power_up_delay;
 	int panel_power_down_delay;
@@ -1274,6 +1283,8 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
 
+void intel_dp_init_signal_levels(struct intel_dp *intel_dp);
+
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 4/9] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
                   ` (2 preceding siblings ...)
  2015-10-12  6:25 ` [PATCH 3/9] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 5/9] drm/i915: Use struct intel_dp_signal_levels for VLV Ander Conselvan de Oliveira
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for eDP on SNB and IVB.
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 132 ++++++++++++++++++--------
 1 file changed, 91 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 317a2b4..7e74f8c 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -448,7 +448,6 @@ static const struct signal_levels gen4_signal_levels = {
 	.set = gen4_set_signal_levels,
 };
 
-/* Not for eDP */
 static const struct signal_levels snb_signal_levels = {
 	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
 	.max_pre_emph = {
@@ -461,73 +460,123 @@ static const struct signal_levels snb_signal_levels = {
 	.set = gen4_set_signal_levels,
 };
 
-/* Gen6's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen6_edp_signal_levels(uint8_t train_set)
+/* SNB's DP voltage swing and pre-emphasis control */
+static void
+snb_edp_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
+	uint32_t signal_levels;
+
+	train_set &=
+		(DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK);
+
+	switch (train_set) {
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+		signal_levels =  EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+		break;
 	default:
 		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+			      "0x%x\n", train_set);
+		signal_levels = EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
 	}
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
+	intel_dp->DP |= signal_levels;
 }
 
-/* Gen7's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen7_edp_signal_levels(uint8_t train_set)
+static const struct signal_levels snb_edp_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = snb_edp_set_signal_levels,
+};
+
+/* IVB's DP voltage swing and pre-emphasis control */
+static void
+ivb_edp_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
+	uint32_t signal_levels;
+
+	train_set &=
+		(DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK);
+
+	switch (train_set) {
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400MV_0DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_400MV_0DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		return EDP_LINK_TRAIN_400MV_6DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_400MV_6DB_IVB;
+		break;
 
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_600MV_0DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_600MV_0DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+		break;
 
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800MV_0DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_800MV_0DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+		break;
 
 	default:
 		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_500MV_0DB_IVB;
+			      "0x%x\n", train_set);
+		signal_levels = EDP_LINK_TRAIN_500MV_0DB_IVB;
 	}
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
+	intel_dp->DP |= signal_levels;
 }
 
+static const struct signal_levels ivb_edp_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = ivb_edp_set_signal_levels,
+};
+
 static void
 _update_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	uint32_t signal_levels, mask = 0;
-	uint8_t train_set = intel_dp->train_set[0];
 
 	if (HAS_DDI(dev)) {
 		signal_levels = ddi_signal_levels(intel_dp);
@@ -540,12 +589,6 @@ _update_signal_levels(struct intel_dp *intel_dp)
 		signal_levels = chv_signal_levels(intel_dp);
 	} else if (IS_VALLEYVIEW(dev)) {
 		signal_levels = vlv_signal_levels(intel_dp);
-	} else if (IS_GEN7(dev) && port == PORT_A) {
-		signal_levels = gen7_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
-	} else if (IS_GEN6(dev) && port == PORT_A) {
-		signal_levels = gen6_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
 	} else {
 		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
 		return;
@@ -605,9 +648,16 @@ intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (port != PORT_A && (IS_IVYBRIDGE(dev) || IS_GEN6(dev)))
-		intel_dp->signal_levels = &snb_signal_levels;
-
-	if (INTEL_INFO(dev)->gen <= 5)
+	if (IS_IVYBRIDGE(dev)) {
+		if (port == PORT_A)
+			intel_dp->signal_levels = &ivb_edp_signal_levels;
+		else
+			intel_dp->signal_levels = &snb_signal_levels;
+	} else if (IS_GEN6(dev)) {
+		if (port == PORT_A)
+			intel_dp->signal_levels = &snb_edp_signal_levels;
+		else
+			intel_dp->signal_levels = &snb_signal_levels;
+	} else if (INTEL_INFO(dev)->gen <= 5)
 		intel_dp->signal_levels = &gen4_signal_levels;
 }
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 5/9] drm/i915: Use struct intel_dp_signal_levels for VLV
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
                   ` (3 preceding siblings ...)
  2015-10-12  6:25 ` [PATCH 4/9] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 6/9] drm/i915: Use struct intel_dp_signal_levels for CHV Ander Conselvan de Oliveira
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for VLV.
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 38 ++++++++++++++++++---------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 7e74f8c..824eead 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -115,7 +115,7 @@ _dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 	}
 }
 
-static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
+static void vlv_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -124,7 +124,6 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 		to_intel_crtc(dport->base.base.crtc);
 	unsigned long demph_reg_value, preemph_reg_value,
 		uniqtranscale_reg_value;
-	uint8_t train_set = intel_dp->train_set[0];
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	int pipe = intel_crtc->pipe;
 
@@ -149,7 +148,8 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x5598DA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
@@ -168,7 +168,8 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x55ADDA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
@@ -183,7 +184,8 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x55ADDA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
@@ -194,11 +196,13 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x55ADDA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	default:
-		return 0;
+		MISSING_CASE(train_set & DP_TRAIN_PRE_EMPHASIS_MASK);
+		return;
 	}
 
 	mutex_lock(&dev_priv->sb_lock);
@@ -211,10 +215,20 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
 	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
 }
 
+static const struct signal_levels vlv_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = vlv_set_signal_levels,
+};
+
 static bool chv_need_uniq_trans_scale(uint8_t train_set)
 {
 	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
@@ -587,8 +601,6 @@ _update_signal_levels(struct intel_dp *intel_dp)
 			mask = DDI_BUF_EMP_MASK;
 	} else if (IS_CHERRYVIEW(dev)) {
 		signal_levels = chv_signal_levels(intel_dp);
-	} else if (IS_VALLEYVIEW(dev)) {
-		signal_levels = vlv_signal_levels(intel_dp);
 	} else {
 		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
 		return;
@@ -648,7 +660,9 @@ intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (IS_IVYBRIDGE(dev)) {
+	if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+		intel_dp->signal_levels = &vlv_signal_levels;
+	} else if (IS_IVYBRIDGE(dev)) {
 		if (port == PORT_A)
 			intel_dp->signal_levels = &ivb_edp_signal_levels;
 		else
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 6/9] drm/i915: Use struct intel_dp_signal_levels for CHV
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
                   ` (4 preceding siblings ...)
  2015-10-12  6:25 ` [PATCH 5/9] drm/i915: Use struct intel_dp_signal_levels for VLV Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 7/9] drm/i915: Use struct intel_dp_signal_levels for DDI platforms Ander Conselvan de Oliveira
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for CHV.
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 38 ++++++++++++++++++---------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 824eead..60bdbe0 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -235,14 +235,13 @@ static bool chv_need_uniq_trans_scale(uint8_t train_set)
 		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 }
 
-static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
+static void chv_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
 	u32 deemph_reg_value, margin_reg_value, val;
-	uint8_t train_set = intel_dp->train_set[0];
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
 	enum pipe pipe = intel_crtc->pipe;
 	int i;
@@ -268,7 +267,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			/* FIXME extra to set for 1200 */
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
@@ -286,7 +286,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			margin_reg_value = 154;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
@@ -300,7 +301,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			margin_reg_value = 154;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
@@ -310,11 +312,13 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			margin_reg_value = 154;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	default:
-		return 0;
+		MISSING_CASE(train_set & DP_TRAIN_PRE_EMPHASIS_MASK);
+		return;
 	}
 
 	mutex_lock(&dev_priv->sb_lock);
@@ -404,10 +408,20 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val);
 
 	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
 }
 
+static const struct signal_levels chv_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = chv_set_signal_levels,
+};
+
 static void
 gen4_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
@@ -599,8 +613,6 @@ _update_signal_levels(struct intel_dp *intel_dp)
 			signal_levels = 0;
 		else
 			mask = DDI_BUF_EMP_MASK;
-	} else if (IS_CHERRYVIEW(dev)) {
-		signal_levels = chv_signal_levels(intel_dp);
 	} else {
 		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
 		return;
@@ -660,7 +672,9 @@ intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+	if (IS_CHERRYVIEW(dev)) {
+		intel_dp->signal_levels = &chv_signal_levels;
+	} else if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
 		intel_dp->signal_levels = &vlv_signal_levels;
 	} else if (IS_IVYBRIDGE(dev)) {
 		if (port == PORT_A)
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 7/9] drm/i915: Use struct intel_dp_signal_levels for DDI platforms
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
                   ` (5 preceding siblings ...)
  2015-10-12  6:25 ` [PATCH 6/9] drm/i915: Use struct intel_dp_signal_levels for CHV Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 8/9] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 9/9] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c Ander Conselvan de Oliveira
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for DDI platforms.
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 63 ++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 60bdbe0..06ef3ec 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -115,6 +115,59 @@ _dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 	}
 }
 
+static void
+hsw_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
+{
+	uint32_t signal_levels = ddi_signal_levels(intel_dp);
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~DDI_BUF_EMP_MASK;
+	intel_dp->DP |= signal_levels;
+}
+
+static const struct signal_levels hsw_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = hsw_set_signal_levels,
+};
+
+static const struct signal_levels skl_edp_low_vswing_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = hsw_set_signal_levels,
+};
+
+static void
+bxt_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
+{
+	ddi_signal_levels(intel_dp);
+}
+
+static const struct signal_levels bxt_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = bxt_set_signal_levels,
+};
+
 static void vlv_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -669,10 +722,18 @@ void
 intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (IS_CHERRYVIEW(dev)) {
+	if (IS_BROXTON(dev)) {
+		intel_dp->signal_levels = &bxt_signal_levels;
+	} else if (IS_SKYLAKE(dev) &&
+		   port == PORT_A && dev_priv->edp_low_vswing) {
+		intel_dp->signal_levels = &skl_edp_low_vswing_signal_levels;
+	} else if (HAS_DDI(dev)) {
+		intel_dp->signal_levels = &hsw_signal_levels;
+	} else if (IS_CHERRYVIEW(dev)) {
 		intel_dp->signal_levels = &chv_signal_levels;
 	} else if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
 		intel_dp->signal_levels = &vlv_signal_levels;
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 8/9] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
                   ` (6 preceding siblings ...)
  2015-10-12  6:25 ` [PATCH 7/9] drm/i915: Use struct intel_dp_signal_levels for DDI platforms Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  2015-10-12  6:25 ` [PATCH 9/9] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c Ander Conselvan de Oliveira
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Remove the old functions for maximum DP voltage swing and pre-emphasis
levels, now that all platforms use the new intel_dp_signal_values
struct.
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 133 +-------------------------
 1 file changed, 3 insertions(+), 130 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 06ef3ec..716d073 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -23,98 +23,6 @@
 
 #include "intel_drv.h"
 
-/* These are source-specific values. */
-static uint8_t
-_dp_voltage_max(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (IS_BROXTON(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (INTEL_INFO(dev)->gen >= 9) {
-		if (dev_priv->edp_low_vswing && port == PORT_A)
-			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	} else if (IS_VALLEYVIEW(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (IS_GEN7(dev) && port == PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	else if (HAS_PCH_CPT(dev) && port != PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-}
-
-static uint8_t
-_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (INTEL_INFO(dev)->gen >= 9) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_VALLEYVIEW(dev)) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_GEN7(dev) && port == PORT_A) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	}
-}
-
 static void
 hsw_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
@@ -652,48 +560,16 @@ static const struct signal_levels ivb_edp_signal_levels = {
 	.set = ivb_edp_set_signal_levels,
 };
 
-static void
-_update_signal_levels(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = intel_dig_port->base.base.dev;
-	uint32_t signal_levels, mask = 0;
-
-	if (HAS_DDI(dev)) {
-		signal_levels = ddi_signal_levels(intel_dp);
-
-		if (IS_BROXTON(dev))
-			signal_levels = 0;
-		else
-			mask = DDI_BUF_EMP_MASK;
-	} else {
-		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
-		return;
-	}
-
-	if (mask)
-		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
-
-	intel_dp->DP &= ~mask;
-	intel_dp->DP |= signal_levels;
-}
-
 uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
-	if (intel_dp->signal_levels)
-		return intel_dp->signal_levels->max_voltage;
-	else
-		return _dp_voltage_max(intel_dp);
+	return intel_dp->signal_levels->max_voltage;
 }
 
 uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
-	if (intel_dp->signal_levels)
-		return intel_dp->signal_levels->max_pre_emph[voltage_swing];
-	else
-		return _dp_pre_emphasis_max(intel_dp, voltage_swing);
+	return intel_dp->signal_levels->max_pre_emph[voltage_swing];
 }
 
 void
@@ -703,10 +579,7 @@ intel_dp_update_signal_levels(struct intel_dp *intel_dp)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	uint8_t train_set = intel_dp->train_set[0];
 
-	if (intel_dp->signal_levels)
-		intel_dp->signal_levels->set(intel_dp, train_set);
-	else
-		_update_signal_levels(intel_dp);
+	intel_dp->signal_levels->set(intel_dp, train_set);
 
 	DRM_DEBUG_KMS("Using vswing level %d\n",
 		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 9/9] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c
  2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
                   ` (7 preceding siblings ...)
  2015-10-12  6:25 ` [PATCH 8/9] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels Ander Conselvan de Oliveira
@ 2015-10-12  6:25 ` Ander Conselvan de Oliveira
  8 siblings, 0 replies; 10+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-12  6:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

The logic for writing the DP register based on the vswing and pre emph
values is in that file for all other platforms, so follow suit and move
ddi_signal_levels() to intel_dp_signal_levels.c too.
---
 drivers/gpu/drm/i915/intel_ddi.c              | 78 ++-------------------------
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 73 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h              |  6 ++-
 3 files changed, 80 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index d9af009..ba32ed2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -301,9 +301,6 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
 	{ 154, 0x9A, 1, 128, true },	/* 9:	1200		0   */
 };
 
-static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
-				    enum port port, int type);
-
 static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
 				 struct intel_digital_port **dig_port,
 				 enum port *port)
@@ -2063,8 +2060,8 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 			   TRANS_CLK_SEL_DISABLED);
 }
 
-static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
-			       enum port port, int type)
+void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			enum port port, int type)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct ddi_buf_trans *ddi_translations;
@@ -2120,8 +2117,8 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
 	I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
 }
 
-static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
-				    enum port port, int type)
+void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
+			     enum port port, int type)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct bxt_ddi_buf_trans *ddi_translations;
@@ -2189,73 +2186,6 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 	I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
 }
 
-static uint32_t translate_signal_level(int signal_levels)
-{
-	uint32_t level;
-
-	switch (signal_levels) {
-	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
-			      signal_levels);
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 0;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		level = 1;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		level = 2;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
-		level = 3;
-		break;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 4;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		level = 5;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		level = 6;
-		break;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 7;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		level = 8;
-		break;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 9;
-		break;
-	}
-
-	return level;
-}
-
-uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dport->base.base.dev;
-	struct intel_encoder *encoder = &dport->base;
-	uint8_t train_set = intel_dp->train_set[0];
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	enum port port = dport->port;
-	uint32_t level;
-
-	level = translate_signal_level(signal_levels);
-
-	if (IS_SKYLAKE(dev))
-		skl_ddi_set_iboost(dev, level, port, encoder->type);
-	else if (IS_BROXTON(dev))
-		bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
-
-	return DDI_BUF_TRANS_SELECT(level);
-}
-
 static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 716d073..51e5005 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -23,10 +23,72 @@
 
 #include "intel_drv.h"
 
+static uint32_t ddi_translate_signal_level(uint8_t train_set)
+{
+	uint32_t level;
+
+	train_set &=
+		(DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK);
+
+	switch (train_set) {
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
+			      train_set);
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 0;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 1;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		level = 2;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
+		level = 3;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 4;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 5;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		level = 6;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 7;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 8;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 9;
+		break;
+	}
+
+	return level;
+}
+
 static void
 hsw_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	uint32_t signal_levels = ddi_signal_levels(intel_dp);
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	uint32_t ddi_level, signal_levels;
+
+	ddi_level = ddi_translate_signal_level(train_set);
+
+	if (IS_SKYLAKE(dev)) {
+		struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+		struct intel_encoder *encoder = &dport->base;
+		enum port port = dport->port;
+
+		skl_ddi_set_iboost(dev, ddi_level, port, encoder->type);
+	}
+
+	signal_levels = DDI_BUF_TRANS_SELECT(ddi_level);
 
 	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
 
@@ -61,7 +123,14 @@ static const struct signal_levels skl_edp_low_vswing_signal_levels = {
 static void
 bxt_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	ddi_signal_levels(intel_dp);
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dport->base.base.dev;
+	struct intel_encoder *encoder = &dport->base;
+	enum port port = dport->port;
+	uint32_t level;
+
+	level = ddi_translate_signal_level(train_set);
+	bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
 }
 
 static const struct signal_levels bxt_signal_levels = {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2b7cac9..4645998 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1034,7 +1034,11 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
 void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
-uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
+
+void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			enum port port, int type);
+void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
+			     enum port port, int type);
 
 /* intel_frontbuffer.c */
 void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2015-10-12  6:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-12  6:25 [PATCH 0/9] Reorganize how max DP vswing and pre-emph values are stored Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 1/9] drm/i915: Merge intel_dp_update_signal_levels() with set_signal_levels() Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 2/9] drm/i915: Split setting of vswing and pre_emph levels to separate file Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 3/9] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 4/9] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 5/9] drm/i915: Use struct intel_dp_signal_levels for VLV Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 6/9] drm/i915: Use struct intel_dp_signal_levels for CHV Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 7/9] drm/i915: Use struct intel_dp_signal_levels for DDI platforms Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 8/9] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels Ander Conselvan de Oliveira
2015-10-12  6:25 ` [PATCH 9/9] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c Ander Conselvan de Oliveira

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.