All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder
@ 2015-12-08 17:59 ville.syrjala
  2015-12-08 17:59 ` [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST ville.syrjala
                   ` (15 more replies)
  0 siblings, 16 replies; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

While debugging problems on DDI platforms I got tired of the crap
caused by the the dual personality DDI encoders, so I went ahead
and split them into separate HDMI and DP encoders.

As usual, the hole got a bit deeper after I noticed that I had to
kill intel_prepare_ddi() as well.

This also needs the check_digital_port_conflicts() patch [1] because
otherwise kms_setmode results in a dead machine.

Series avaialbe there (with [1] included):
git://github.com/vsyrjala/linux.git ddi_encoder_split_3

[1] http://lists.freedesktop.org/archives/intel-gfx/2015-December/082284.html

Ville Syrjälä (15):
  drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST
  drm/i915: Check max number of lanes when registering DDI ports
  drm/i915: Store max lane count in intel_digital_port
  drm/i915: Remove pointless 'ddi_translations' local variable
  drm/i915: Eliminate duplicated skl_get_buf_trans_dp()
  drm/i915: Pass around dev_priv for ddi buffer programming
  drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes
  drm/i915: Reject >9 ddi translation entried if port != A/E on SKL
  drm/i915: Kill intel_prepare_ddi()
  drm/i915: Split the problematic dual-role DDI encoder into two
    encoders
  drm/i915: Explicitly use ddi bug trans entry 9 for hdmi
  drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart
  drm/i915: Add a sanity check for 'hdmi_default_entry'
  drm/i915: Get the iboost setting based on the port type
  drm/i915: Simplify intel_ddi_get_encoder_port()

 drivers/gpu/drm/i915/i915_drv.c         |   1 -
 drivers/gpu/drm/i915/intel_ddi.c        | 542 +++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_display.c    |  21 --
 drivers/gpu/drm/i915/intel_dp.c         |  36 +--
 drivers/gpu/drm/i915/intel_dp_mst.c     |   4 +-
 drivers/gpu/drm/i915/intel_drv.h        |   6 +-
 drivers/gpu/drm/i915/intel_hdmi.c       |   9 +
 drivers/gpu/drm/i915/intel_opregion.c   |   1 -
 drivers/gpu/drm/i915/intel_runtime_pm.c |  12 -
 9 files changed, 344 insertions(+), 288 deletions(-)

-- 
2.4.10

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

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

* [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:17   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 02/15] drm/i915: Check max number of lanes when registering DDI ports ville.syrjala
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We're supposed to pass the primary DP encoder to intel_ddi_clk_select(),
not the fake MST encoder. Do so.

There's no real bug here though, since intel_ddi_clk_select() only
checks if the encoder type is EDP (which it isn't for either the
primary DP encoder or the fake MST encoder), and it gets the DDI port
via intel_ddi_get_encoder_port() (which knows how to do the
fake->primary->port dance itself).

Fixes: e404ba8 ("drm/i915: Setup DDI clk for MST on SKL")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp_mst.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 8c4e7dfe304c..abfc171888b8 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -173,7 +173,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 	intel_mst->port = found->port;
 
 	if (intel_dp->active_mst_links == 0) {
-		intel_ddi_clk_select(encoder, intel_crtc->config);
+		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
 
 		intel_dp_set_link_params(intel_dp, intel_crtc->config);
 
-- 
2.4.10

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

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

* [PATCH 02/15] drm/i915: Check max number of lanes when registering DDI ports
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
  2015-12-08 17:59 ` [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:19   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port ville.syrjala
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

DDI A and E share some of the lanes, so check that we have enough
lanes for the purpose we need before registering the encoders.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b9d6b038ea0c..e903d9c87680 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3278,6 +3278,33 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 	struct intel_encoder *intel_encoder;
 	struct drm_encoder *encoder;
 	bool init_hdmi, init_dp;
+	int max_lanes;
+
+	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
+		switch (port) {
+		case PORT_A:
+			max_lanes = 4;
+			break;
+		case PORT_E:
+			max_lanes = 0;
+			break;
+		default:
+			max_lanes = 4;
+			break;
+		}
+	} else {
+		switch (port) {
+		case PORT_A:
+			max_lanes = 2;
+			break;
+		case PORT_E:
+			max_lanes = 2;
+			break;
+		default:
+			max_lanes = 4;
+			break;
+		}
+	}
 
 	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
 		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
@@ -3288,6 +3315,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 		return;
 	}
 
+	if (WARN(max_lanes == 0,
+		 "No lanes for port %c\n", port_name(port)))
+		return;
+
+	if (WARN(init_hdmi && max_lanes < 4,
+		 "Not enough lanes (%d) for HDMI on port %c\n",
+		 max_lanes, port_name(port)))
+		init_hdmi = false;
+
 	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
 	if (!intel_dig_port)
 		return;
-- 
2.4.10

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

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

* [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
  2015-12-08 17:59 ` [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST ville.syrjala
  2015-12-08 17:59 ` [PATCH 02/15] drm/i915: Check max number of lanes when registering DDI ports ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:22   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 04/15] drm/i915: Remove pointless 'ddi_translations' local variable ville.syrjala
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Rather than having open coded checks for the DDI A/E configuration,
just store the max supported lane count in intel_digital_port.

We had an open coded check for DDI A, but not for DDI E. So we may
have been vilating the DDI E max lane count.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 10 +---------
 drivers/gpu/drm/i915/intel_dp.c   | 13 +++++++------
 drivers/gpu/drm/i915/intel_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_hdmi.c |  6 ++++++
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e903d9c87680..fdb4aaa084d6 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3315,15 +3315,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 		return;
 	}
 
-	if (WARN(max_lanes == 0,
-		 "No lanes for port %c\n", port_name(port)))
-		return;
-
-	if (WARN(init_hdmi && max_lanes < 4,
-		 "Not enough lanes (%d) for HDMI on port %c\n",
-		 max_lanes, port_name(port)))
-		init_hdmi = false;
-
 	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
 	if (!intel_dig_port)
 		return;
@@ -3346,6 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
 					  (DDI_BUF_PORT_REVERSAL |
 					   DDI_A_4_LANES);
+	intel_dig_port->max_lanes = max_lanes;
 
 	/*
 	 * Bspec says that DDI_A_4_LANES is the only supported configuration
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f335c92b4fa7..7d354b1e5e5f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -157,14 +157,9 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
 static u8 intel_dp_max_lane_count(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;
 	u8 source_max, sink_max;
 
-	source_max = 4;
-	if (HAS_DDI(dev) && intel_dig_port->port == PORT_A &&
-	    (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0)
-		source_max = 2;
-
+	source_max = intel_dig_port->max_lanes;
 	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
 
 	return min(source_max, sink_max);
@@ -5820,6 +5815,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	enum port port = intel_dig_port->port;
 	int type, ret;
 
+	if (WARN(intel_dig_port->max_lanes < 1,
+		 "Not enough lanes (%d) for DP on port %c\n",
+		 intel_dig_port->max_lanes, port_name(port)))
+		return false;
+
 	intel_dp->pps_pipe = INVALID_PIPE;
 
 	/* intel_dp vfuncs */
@@ -6016,6 +6016,7 @@ intel_dp_init(struct drm_device *dev,
 
 	intel_dig_port->port = port;
 	intel_dig_port->dp.output_reg = output_reg;
+	intel_dig_port->max_lanes = 4;
 
 	intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 	if (IS_CHERRYVIEW(dev)) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8963a8a53b0b..43d451c7c366 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -818,6 +818,7 @@ struct intel_digital_port {
 	struct intel_hdmi hdmi;
 	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
 	bool release_cl2_override;
+	uint8_t max_lanes;
 };
 
 struct intel_dp_mst_encoder {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index c3978bad5ca0..895189abfd56 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2034,6 +2034,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	enum port port = intel_dig_port->port;
 	uint8_t alternate_ddc_pin;
 
+	if (WARN(intel_dig_port->max_lanes < 4,
+		 "Not enough lanes (%d) for HDMI on port %c\n",
+		 intel_dig_port->max_lanes, port_name(port)))
+		return;
+
 	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
@@ -2217,6 +2222,7 @@ void intel_hdmi_init(struct drm_device *dev,
 	intel_dig_port->port = port;
 	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
 	intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
+	intel_dig_port->max_lanes = 4;
 
 	intel_hdmi_init_connector(intel_dig_port, intel_connector);
 }
-- 
2.4.10

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

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

* [PATCH 04/15] drm/i915: Remove pointless 'ddi_translations' local variable
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (2 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:22   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 05/15] drm/i915: Eliminate duplicated skl_get_buf_trans_dp() ville.syrjala
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

skl_get_buf_trans_*() don't need the 'ddi_translations' local variable
since all they with is assign and return. Just return the right thing
directly and get rid of the local variable.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 44 +++++++++++++++-------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index fdb4aaa084d6..f8517ed4d636 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -348,75 +348,63 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
 	return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
 }
 
-static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
-							int *n_entries)
+static const struct ddi_buf_trans *
+skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
 {
-	const struct ddi_buf_trans *ddi_translations;
-
 	if (IS_SKL_ULX(dev)) {
-		ddi_translations = skl_y_ddi_translations_dp;
 		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
+		return skl_y_ddi_translations_dp;
 	} else if (IS_SKL_ULT(dev)) {
-		ddi_translations = skl_u_ddi_translations_dp;
 		*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
+		return skl_u_ddi_translations_dp;
 	} else {
-		ddi_translations = skl_ddi_translations_dp;
 		*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
+		return skl_ddi_translations_dp;
 	}
-
-	return ddi_translations;
 }
 
-static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
-							 int *n_entries)
+static const struct ddi_buf_trans *
+skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	const struct ddi_buf_trans *ddi_translations;
 
 	if (IS_SKL_ULX(dev)) {
 		if (dev_priv->edp_low_vswing) {
-			ddi_translations = skl_y_ddi_translations_edp;
 			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
+			return skl_y_ddi_translations_edp;
 		} else {
-			ddi_translations = skl_y_ddi_translations_dp;
 			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
+			return skl_y_ddi_translations_dp;
 		}
 	} else if (IS_SKL_ULT(dev)) {
 		if (dev_priv->edp_low_vswing) {
-			ddi_translations = skl_u_ddi_translations_edp;
 			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
+			return skl_u_ddi_translations_edp;
 		} else {
-			ddi_translations = skl_u_ddi_translations_dp;
 			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
+			return skl_u_ddi_translations_dp;
 		}
 	} else {
 		if (dev_priv->edp_low_vswing) {
-			ddi_translations = skl_ddi_translations_edp;
 			*n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
+			return skl_ddi_translations_edp;
 		} else {
-			ddi_translations = skl_ddi_translations_dp;
 			*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
+			return skl_ddi_translations_dp;
 		}
 	}
-
-	return ddi_translations;
 }
 
 static const struct ddi_buf_trans *
-skl_get_buf_trans_hdmi(struct drm_device *dev,
-		       int *n_entries)
+skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
 {
-	const struct ddi_buf_trans *ddi_translations;
-
 	if (IS_SKL_ULX(dev)) {
-		ddi_translations = skl_y_ddi_translations_hdmi;
 		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
+		return skl_y_ddi_translations_hdmi;
 	} else {
-		ddi_translations = skl_ddi_translations_hdmi;
 		*n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
+		return skl_ddi_translations_hdmi;
 	}
-
-	return ddi_translations;
 }
 
 /*
-- 
2.4.10

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

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

* [PATCH 05/15] drm/i915: Eliminate duplicated skl_get_buf_trans_dp()
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (3 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 04/15] drm/i915: Remove pointless 'ddi_translations' local variable ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:24   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 06/15] drm/i915: Pass around dev_priv for ddi buffer programming ville.syrjala
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

skl_get_buf_trans_edp() effectively contains another copy of
skl_get_buf_trans_dp(). Remove the duplication and just call
skl_get_buf_trans_dp() from  skl_get_buf_trans_edp().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f8517ed4d636..e281813cad82 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -368,31 +368,20 @@ skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_SKL_ULX(dev)) {
-		if (dev_priv->edp_low_vswing) {
+	if (dev_priv->edp_low_vswing) {
+		if (IS_SKL_ULX(dev)) {
 			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
 			return skl_y_ddi_translations_edp;
-		} else {
-			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
-			return skl_y_ddi_translations_dp;
-		}
-	} else if (IS_SKL_ULT(dev)) {
-		if (dev_priv->edp_low_vswing) {
+		} else if (IS_SKL_ULT(dev)) {
 			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
 			return skl_u_ddi_translations_edp;
 		} else {
-			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
-			return skl_u_ddi_translations_dp;
-		}
-	} else {
-		if (dev_priv->edp_low_vswing) {
 			*n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
 			return skl_ddi_translations_edp;
-		} else {
-			*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
-			return skl_ddi_translations_dp;
 		}
 	}
+
+	return skl_get_buf_trans_dp(dev, n_entries);
 }
 
 static const struct ddi_buf_trans *
-- 
2.4.10

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

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

* [PATCH 06/15] drm/i915: Pass around dev_priv for ddi buffer programming
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (4 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 05/15] drm/i915: Eliminate duplicated skl_get_buf_trans_dp() ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:25   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes ville.syrjala
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Make the ddi buffer programming code a bit more neat by passing
around dev_priv instead of dev.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 79 +++++++++++++++++++---------------------
 1 file changed, 37 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e281813cad82..5d0b03d6d388 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -301,8 +301,8 @@ 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 bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
+				    u32 level, enum port port, int type);
 
 static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
 				 struct intel_digital_port **dig_port,
@@ -349,12 +349,12 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
 }
 
 static const struct ddi_buf_trans *
-skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
+skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
 {
-	if (IS_SKL_ULX(dev)) {
+	if (IS_SKL_ULX(dev_priv)) {
 		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
 		return skl_y_ddi_translations_dp;
-	} else if (IS_SKL_ULT(dev)) {
+	} else if (IS_SKL_ULT(dev_priv)) {
 		*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
 		return skl_u_ddi_translations_dp;
 	} else {
@@ -364,15 +364,13 @@ skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
 }
 
 static const struct ddi_buf_trans *
-skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
+skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
 	if (dev_priv->edp_low_vswing) {
-		if (IS_SKL_ULX(dev)) {
+		if (IS_SKL_ULX(dev_priv)) {
 			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
 			return skl_y_ddi_translations_edp;
-		} else if (IS_SKL_ULT(dev)) {
+		} else if (IS_SKL_ULT(dev_priv)) {
 			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
 			return skl_u_ddi_translations_edp;
 		} else {
@@ -381,13 +379,13 @@ skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
 		}
 	}
 
-	return skl_get_buf_trans_dp(dev, n_entries);
+	return skl_get_buf_trans_dp(dev_priv, n_entries);
 }
 
 static const struct ddi_buf_trans *
-skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
+skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
 {
-	if (IS_SKL_ULX(dev)) {
+	if (IS_SKL_ULX(dev_priv)) {
 		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
 		return skl_y_ddi_translations_hdmi;
 	} else {
@@ -403,10 +401,9 @@ skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
  * in either FDI or DP modes only, as HDMI connections will work with both
  * of those
  */
-static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
-				      bool supports_hdmi)
+static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
+				      enum port port, bool supports_hdmi)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 iboost_bit = 0;
 	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
 	    size;
@@ -417,28 +414,28 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 	const struct ddi_buf_trans *ddi_translations_hdmi;
 	const struct ddi_buf_trans *ddi_translations;
 
-	if (IS_BROXTON(dev)) {
+	if (IS_BROXTON(dev_priv)) {
 		if (!supports_hdmi)
 			return;
 
 		/* Vswing programming for HDMI */
-		bxt_ddi_vswing_sequence(dev, hdmi_level, port,
+		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
 					INTEL_OUTPUT_HDMI);
 		return;
-	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
 		ddi_translations_fdi = NULL;
 		ddi_translations_dp =
-				skl_get_buf_trans_dp(dev, &n_dp_entries);
+				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
 		ddi_translations_edp =
-				skl_get_buf_trans_edp(dev, &n_edp_entries);
+				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
 		ddi_translations_hdmi =
-				skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
+				skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
 		hdmi_default_entry = 8;
 		/* If we're boosting the current, set bit 31 of trans1 */
 		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
 		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
 			iboost_bit = 1<<31;
-	} else if (IS_BROADWELL(dev)) {
+	} else if (IS_BROADWELL(dev_priv)) {
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
 		ddi_translations_edp = bdw_ddi_translations_edp;
@@ -447,7 +444,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
 		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
 		hdmi_default_entry = 7;
-	} else if (IS_HASWELL(dev)) {
+	} else if (IS_HASWELL(dev_priv)) {
 		ddi_translations_fdi = hsw_ddi_translations_fdi;
 		ddi_translations_dp = hsw_ddi_translations_dp;
 		ddi_translations_edp = hsw_ddi_translations_dp;
@@ -478,7 +475,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 		size = n_dp_entries;
 		break;
 	case PORT_D:
-		if (intel_dp_is_edp(dev, PORT_D)) {
+		if (intel_dp_is_edp(dev_priv->dev, PORT_D)) {
 			ddi_translations = ddi_translations_edp;
 			size = n_edp_entries;
 		} else {
@@ -545,7 +542,7 @@ void intel_prepare_ddi(struct drm_device *dev)
 		supports_hdmi = intel_dig_port &&
 				intel_dig_port_supports_hdmi(intel_dig_port);
 
-		intel_prepare_ddi_buffers(dev, port, supports_hdmi);
+		intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi);
 		visited[port] = true;
 	}
 }
@@ -2062,10 +2059,9 @@ 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)
+static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
+			       u32 level, enum port port, int type)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct ddi_buf_trans *ddi_translations;
 	uint8_t iboost;
 	uint8_t dp_iboost, hdmi_iboost;
@@ -2080,21 +2076,21 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
 		if (dp_iboost) {
 			iboost = dp_iboost;
 		} else {
-			ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
+			ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries);
 			iboost = ddi_translations[level].i_boost;
 		}
 	} else if (type == INTEL_OUTPUT_EDP) {
 		if (dp_iboost) {
 			iboost = dp_iboost;
 		} else {
-			ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
+			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
 			iboost = ddi_translations[level].i_boost;
 		}
 	} else if (type == INTEL_OUTPUT_HDMI) {
 		if (hdmi_iboost) {
 			iboost = hdmi_iboost;
 		} else {
-			ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
+			ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
 			iboost = ddi_translations[level].i_boost;
 		}
 	} else {
@@ -2119,10 +2115,9 @@ 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)
+static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
+				    u32 level, enum port port, int type)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct bxt_ddi_buf_trans *ddi_translations;
 	u32 n_entries, i;
 	uint32_t val;
@@ -2237,7 +2232,7 @@ static uint32_t translate_signal_level(int signal_levels)
 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 drm_i915_private *dev_priv = to_i915(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 |
@@ -2247,10 +2242,10 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
 
 	level = translate_signal_level(signal_levels);
 
-	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
-		skl_ddi_set_iboost(dev, level, port, encoder->type);
-	else if (IS_BROXTON(dev))
-		bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
+	else if (IS_BROXTON(dev_priv))
+		bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
 
 	return DDI_BUF_TRANS_SELECT(level);
 }
@@ -2333,8 +2328,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 		if (IS_BROXTON(dev)) {
 			hdmi_level = dev_priv->vbt.
 				ddi_port_info[port].hdmi_level_shift;
-			bxt_ddi_vswing_sequence(dev, hdmi_level, port,
-					INTEL_OUTPUT_HDMI);
+			bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
+						INTEL_OUTPUT_HDMI);
 		}
 		intel_hdmi->set_infoframes(encoder,
 					   crtc->config->has_hdmi_sink,
-- 
2.4.10

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

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

* [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (5 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 06/15] drm/i915: Pass around dev_priv for ddi buffer programming ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:28   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL ville.syrjala
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The DDI translation tables are supposed to be of certain size,
so let's add some compile time asserts to enforce that..

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 5d0b03d6d388..838cbbe33517 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -351,6 +351,10 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
 static const struct ddi_buf_trans *
 skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
 {
+	BUILD_BUG_ON(ARRAY_SIZE(skl_y_ddi_translations_dp) != 9);
+	BUILD_BUG_ON(ARRAY_SIZE(skl_u_ddi_translations_dp) != 9);
+	BUILD_BUG_ON(ARRAY_SIZE(skl_ddi_translations_dp) != 9);
+
 	if (IS_SKL_ULX(dev_priv)) {
 		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
 		return skl_y_ddi_translations_dp;
@@ -366,6 +370,10 @@ skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
 static const struct ddi_buf_trans *
 skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 {
+	BUILD_BUG_ON(ARRAY_SIZE(skl_y_ddi_translations_edp) != 10);
+	BUILD_BUG_ON(ARRAY_SIZE(skl_u_ddi_translations_edp) != 10);
+	BUILD_BUG_ON(ARRAY_SIZE(skl_ddi_translations_edp) != 10);
+
 	if (dev_priv->edp_low_vswing) {
 		if (IS_SKL_ULX(dev_priv)) {
 			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
@@ -436,6 +444,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
 		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
 			iboost_bit = 1<<31;
 	} else if (IS_BROADWELL(dev_priv)) {
+		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
+		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
+		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_edp) != 9);
+
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
 		ddi_translations_edp = bdw_ddi_translations_edp;
@@ -445,6 +457,9 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
 		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
 		hdmi_default_entry = 7;
 	} else if (IS_HASWELL(dev_priv)) {
+		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_fdi) != 9);
+		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_dp) != 9);
+
 		ddi_translations_fdi = hsw_ddi_translations_fdi;
 		ddi_translations_dp = hsw_ddi_translations_dp;
 		ddi_translations_edp = hsw_ddi_translations_dp;
-- 
2.4.10

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

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

* [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (6 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:30   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 09/15] drm/i915: Kill intel_prepare_ddi() ville.syrjala
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Only DDI A and E support 10 translation entries in DP mode. For the
other ports the tenth entry is reserved for HDMI..

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 838cbbe33517..152c813cc43e 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -443,6 +443,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
 		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
 		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
 			iboost_bit = 1<<31;
+
+		if (WARN_ON(port != PORT_A &&
+			    port != PORT_E && n_edp_entries > 9))
+			n_edp_entries = 9;
 	} else if (IS_BROADWELL(dev_priv)) {
 		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
 		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
@@ -2099,6 +2103,11 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
 			iboost = dp_iboost;
 		} else {
 			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
+
+			if (WARN_ON(port != PORT_A &&
+				    port != PORT_E && n_entries > 9))
+				n_entries = 9;
+
 			iboost = ddi_translations[level].i_boost;
 		}
 	} else if (type == INTEL_OUTPUT_HDMI) {
-- 
2.4.10

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

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

* [PATCH 09/15] drm/i915: Kill intel_prepare_ddi()
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (7 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:37   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders ville.syrjala
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Move the ddi buffer translation programming to occur from the encoder
.pre_enable() hook, for just the ddi port we are enabling. Previously
we used to reprogram the translations for all ddi ports during
init and during power well enabling.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c         |  1 -
 drivers/gpu/drm/i915/intel_ddi.c        | 99 ++++++++++-----------------------
 drivers/gpu/drm/i915/intel_display.c    |  3 -
 drivers/gpu/drm/i915/intel_dp_mst.c     |  2 +
 drivers/gpu/drm/i915/intel_drv.h        |  2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 12 ----
 6 files changed, 31 insertions(+), 88 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e6935f1cb689..4d8feff411bb 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1062,7 +1062,6 @@ static int bxt_resume_prepare(struct drm_i915_private *dev_priv)
 	 */
 	broxton_init_cdclk(dev);
 	broxton_ddi_phy_init(dev);
-	intel_prepare_ddi(dev);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 152c813cc43e..074121efb265 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -342,12 +342,6 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
 	return port;
 }
 
-static bool
-intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
-{
-	return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
-}
-
 static const struct ddi_buf_trans *
 skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
 {
@@ -409,28 +403,34 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
  * in either FDI or DP modes only, as HDMI connections will work with both
  * of those
  */
-static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
-				      enum port port, bool supports_hdmi)
+void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 {
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	u32 iboost_bit = 0;
 	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
 	    size;
-	int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
+	int hdmi_level;
+	enum port port;
 	const struct ddi_buf_trans *ddi_translations_fdi;
 	const struct ddi_buf_trans *ddi_translations_dp;
 	const struct ddi_buf_trans *ddi_translations_edp;
 	const struct ddi_buf_trans *ddi_translations_hdmi;
 	const struct ddi_buf_trans *ddi_translations;
 
+	port = intel_ddi_get_encoder_port(encoder);
+	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
+
 	if (IS_BROXTON(dev_priv)) {
-		if (!supports_hdmi)
+		if (encoder->type != INTEL_OUTPUT_HDMI)
 			return;
 
 		/* Vswing programming for HDMI */
 		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
 					INTEL_OUTPUT_HDMI);
 		return;
-	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+	}
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
 		ddi_translations_fdi = NULL;
 		ddi_translations_dp =
 				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
@@ -483,30 +483,18 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
 		hdmi_default_entry = 7;
 	}
 
-	switch (port) {
-	case PORT_A:
+	switch (encoder->type) {
+	case INTEL_OUTPUT_EDP:
 		ddi_translations = ddi_translations_edp;
 		size = n_edp_entries;
 		break;
-	case PORT_B:
-	case PORT_C:
+	case INTEL_OUTPUT_DISPLAYPORT:
+	case INTEL_OUTPUT_HDMI:
 		ddi_translations = ddi_translations_dp;
 		size = n_dp_entries;
 		break;
-	case PORT_D:
-		if (intel_dp_is_edp(dev_priv->dev, PORT_D)) {
-			ddi_translations = ddi_translations_edp;
-			size = n_edp_entries;
-		} else {
-			ddi_translations = ddi_translations_dp;
-			size = n_dp_entries;
-		}
-		break;
-	case PORT_E:
-		if (ddi_translations_fdi)
-			ddi_translations = ddi_translations_fdi;
-		else
-			ddi_translations = ddi_translations_dp;
+	case INTEL_OUTPUT_ANALOG:
+		ddi_translations = ddi_translations_fdi;
 		size = n_dp_entries;
 		break;
 	default:
@@ -520,7 +508,7 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
 			   ddi_translations[i].trans2);
 	}
 
-	if (!supports_hdmi)
+	if (encoder->type != INTEL_OUTPUT_HDMI)
 		return;
 
 	/* Choose a good default if VBT is badly populated */
@@ -535,37 +523,6 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
 		   ddi_translations_hdmi[hdmi_level].trans2);
 }
 
-/* Program DDI buffers translations for DP. By default, program ports A-D in DP
- * mode and port E for FDI.
- */
-void intel_prepare_ddi(struct drm_device *dev)
-{
-	struct intel_encoder *intel_encoder;
-	bool visited[I915_MAX_PORTS] = { 0, };
-
-	if (!HAS_DDI(dev))
-		return;
-
-	for_each_intel_encoder(dev, intel_encoder) {
-		struct intel_digital_port *intel_dig_port;
-		enum port port;
-		bool supports_hdmi;
-
-		if (intel_encoder->type == INTEL_OUTPUT_DSI)
-			continue;
-
-		ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
-		if (visited[port])
-			continue;
-
-		supports_hdmi = intel_dig_port &&
-				intel_dig_port_supports_hdmi(intel_dig_port);
-
-		intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi);
-		visited[port] = true;
-	}
-}
-
 static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
 				    enum port port)
 {
@@ -594,8 +551,14 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
 	u32 temp, i, rx_ctl_val;
 
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
+		intel_prepare_ddi_buffers(encoder);
+	}
+
 	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
 	 * mode set "sequence for CRT port" document:
 	 * - TP1 to TP2 time with the default value
@@ -2321,12 +2284,12 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
-	struct drm_device *dev = encoder->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
 	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
-	int hdmi_level;
+
+	intel_prepare_ddi_buffers(intel_encoder);
 
 	if (type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -2344,17 +2307,11 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 		intel_dp_start_link_train(intel_dp);
-		if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
+		if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
 			intel_dp_stop_link_train(intel_dp);
 	} else if (type == INTEL_OUTPUT_HDMI) {
 		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
 
-		if (IS_BROXTON(dev)) {
-			hdmi_level = dev_priv->vbt.
-				ddi_port_info[port].hdmi_level_shift;
-			bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
-						INTEL_OUTPUT_HDMI);
-		}
 		intel_hdmi->set_infoframes(encoder,
 					   crtc->config->has_hdmi_sink,
 					   &crtc->config->base.adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f1a5404728df..bc7aaa3c431e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9649,8 +9649,6 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
 		val |= PCH_LP_PARTITION_LEVEL_DISABLE;
 		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
 	}
-
-	intel_prepare_ddi(dev);
 }
 
 static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state)
@@ -15172,7 +15170,6 @@ static void i915_disable_vga(struct drm_device *dev)
 void intel_modeset_init_hw(struct drm_device *dev)
 {
 	intel_update_cdclk(dev);
-	intel_prepare_ddi(dev);
 	intel_init_clock_gating(dev);
 	intel_enable_gt_powersave(dev);
 }
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index abfc171888b8..73ac68e21b7e 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -173,6 +173,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 	intel_mst->port = found->port;
 
 	if (intel_dp->active_mst_links == 0) {
+		intel_prepare_ddi_buffers(&intel_dig_port->base);
+
 		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
 
 		intel_dp_set_link_params(intel_dp, intel_crtc->config);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 43d451c7c366..a8a84b8c2bac 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -996,7 +996,7 @@ void intel_crt_init(struct drm_device *dev);
 /* intel_ddi.c */
 void intel_ddi_clk_select(struct intel_encoder *encoder,
 			  const struct intel_crtc_state *pipe_config);
-void intel_prepare_ddi(struct drm_device *dev);
+void intel_prepare_ddi_buffers(struct intel_encoder *encoder);
 void hsw_fdi_link_train(struct drm_crtc *crtc);
 void intel_ddi_init(struct drm_device *dev, enum port port);
 enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 2c2151f1c47e..60a592d20402 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -625,7 +625,6 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
 static void skl_set_power_well(struct drm_i915_private *dev_priv,
 			struct i915_power_well *power_well, bool enable)
 {
-	struct drm_device *dev = dev_priv->dev;
 	uint32_t tmp, fuse_status;
 	uint32_t req_mask, state_mask;
 	bool is_enabled, enable_requested, check_fuse_status = false;
@@ -669,17 +668,6 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
 				!I915_READ(HSW_PWR_WELL_BIOS),
 				"Invalid for power well status to be enabled, unless done by the BIOS, \
 				when request is to disable!\n");
-			if (power_well->data == SKL_DISP_PW_2) {
-				/*
-				 * DDI buffer programming unnecessary during
-				 * driver-load/resume as it's already done
-				 * during modeset initialization then. It's
-				 * also invalid here as encoder list is still
-				 * uninitialized.
-				 */
-				if (!dev_priv->power_domains.initializing)
-					intel_prepare_ddi(dev);
-			}
 			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
 		}
 
-- 
2.4.10

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

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

* [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (8 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 09/15] drm/i915: Kill intel_prepare_ddi() ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-08 18:21   ` kbuild test robot
  2015-12-10 13:47   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi ville.syrjala
                   ` (5 subsequent siblings)
  15 siblings, 2 replies; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Eliminate the troublesome role switching DDI encoder, and just register
a separate encoder for each role (DP and HDMI).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 232 +++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_display.c  |  18 ---
 drivers/gpu/drm/i915/intel_dp.c       |  23 +---
 drivers/gpu/drm/i915/intel_drv.h      |   3 +-
 drivers/gpu/drm/i915/intel_hdmi.c     |   3 +
 drivers/gpu/drm/i915/intel_opregion.c |   1 -
 6 files changed, 180 insertions(+), 100 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 074121efb265..5f008f0fdc13 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -318,7 +318,6 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
 	case INTEL_OUTPUT_DISPLAYPORT:
 	case INTEL_OUTPUT_EDP:
 	case INTEL_OUTPUT_HDMI:
-	case INTEL_OUTPUT_UNKNOWN:
 		*dig_port = enc_to_dig_port(encoder);
 		*port = (*dig_port)->port;
 		break;
@@ -1942,19 +1941,19 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
 	switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
 	case TRANS_DDI_MODE_SELECT_HDMI:
 	case TRANS_DDI_MODE_SELECT_DVI:
-		return (type == DRM_MODE_CONNECTOR_HDMIA);
+		return type == DRM_MODE_CONNECTOR_HDMIA;
 
 	case TRANS_DDI_MODE_SELECT_DP_SST:
-		if (type == DRM_MODE_CONNECTOR_eDP)
-			return true;
-		return (type == DRM_MODE_CONNECTOR_DisplayPort);
+		return type == DRM_MODE_CONNECTOR_DisplayPort ||
+			type == DRM_MODE_CONNECTOR_eDP;
+
 	case TRANS_DDI_MODE_SELECT_DP_MST:
 		/* if the transcoder is in MST state then
 		 * connector isn't connected */
 		return false;
 
 	case TRANS_DDI_MODE_SELECT_FDI:
-		return (type == DRM_MODE_CONNECTOR_VGA);
+		return type == DRM_MODE_CONNECTOR_VGA;
 
 	default:
 		return false;
@@ -1981,8 +1980,23 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
 		return false;
 
 	if (port == PORT_A) {
+		WARN_ON(encoder->type != INTEL_OUTPUT_EDP);
+
 		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
 
+		if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
+			goto out;
+
+		switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
+		case TRANS_DDI_MODE_SELECT_DP_SST:
+			break;
+		default:
+			WARN(1,
+			     "Bad transcoder EDP DDI mode 0x%08x for port %c\n",
+			     tmp, port_name(port));
+			return false;
+		}
+
 		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
 		case TRANS_DDI_EDP_INPUT_A_ON:
 		case TRANS_DDI_EDP_INPUT_A_ONOFF:
@@ -1994,25 +2008,98 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
 		case TRANS_DDI_EDP_INPUT_C_ONOFF:
 			*pipe = PIPE_C;
 			break;
+		default:
+			WARN(1,
+			     "Bad transcoder EDP input select 0x%08x for port %c\n",
+			     tmp, port_name(port));
+			return false;
 		}
 
 		return true;
 	} else {
+		int num_mst_transcoders = 0;
+		int num_sst_transcoders = 0;
+		int num_fdi_transcoders = 0;
+		int num_hdmi_transcoders = 0;
+		int num_transcoders = 0;
+		bool enabled = false;
+
 		for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
 			tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
 
-			if ((tmp & TRANS_DDI_PORT_MASK)
-			    == TRANS_DDI_SELECT_PORT(port)) {
-				if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
-					return false;
+			if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
+				continue;
+
+			if ((tmp & TRANS_DDI_PORT_MASK) != TRANS_DDI_SELECT_PORT(port))
+				continue;
+
+			if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST) {
+				num_mst_transcoders++;
+				WARN_ON(port == PORT_E);
+				continue;
+			}
+
+
+			switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
+			case TRANS_DDI_MODE_SELECT_DP_SST:
+				WARN_ON(port == PORT_E && INTEL_INFO(dev_priv)->gen < 9);
+
+				num_sst_transcoders++;
+				if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+				    encoder->type == INTEL_OUTPUT_EDP) {
+					enabled = true;
+					*pipe = i;
+				}
+				break;
+			case TRANS_DDI_MODE_SELECT_HDMI:
+			case TRANS_DDI_MODE_SELECT_DVI:
+				WARN_ON(port == PORT_E);
+
+				num_hdmi_transcoders++;
+				if (encoder->type == INTEL_OUTPUT_HDMI) {
+					enabled = true;
+					*pipe = i;
+				}
+				break;
+
+			case TRANS_DDI_MODE_SELECT_FDI:
+				WARN_ON(port != PORT_E || INTEL_INFO(dev_priv)->gen >= 9);
+
+				num_fdi_transcoders++;
+				if (encoder->type == INTEL_OUTPUT_ANALOG) {
+					enabled = true;
+					*pipe = i;
+				}
+				break;
 
-				*pipe = i;
-				return true;
+			default:
+				WARN(1, "Bad transcoder %c DDI mode 0x%08x for port %c\n",
+				     transcoder_name(i), tmp, port_name(port));
+				return false;
 			}
 		}
+
+		num_transcoders = num_sst_transcoders +
+			num_fdi_transcoders + num_hdmi_transcoders;
+
+		if (WARN(num_transcoders && num_mst_transcoders,
+			 "MST and non-MST transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
+			 port_name(port), num_sst_transcoders, num_mst_transcoders,
+			 num_fdi_transcoders, num_hdmi_transcoders))
+			return false;
+
+		if (WARN(num_transcoders > 1,
+			 "Multiple transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
+			 port_name(port), num_sst_transcoders, num_mst_transcoders,
+			 num_fdi_transcoders, num_hdmi_transcoders))
+			return false;
+
+		if (enabled)
+			return true;
 	}
 
-	DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
+out:
+	DRM_DEBUG_KMS("No pipe for DDI port %c found\n", port_name(port));
 
 	return false;
 }
@@ -3174,8 +3261,6 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
 	int type = encoder->type;
 	int port = intel_ddi_get_encoder_port(encoder);
 
-	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
-
 	if (port == PORT_A)
 		pipe_config->cpu_transcoder = TRANSCODER_EDP;
 
@@ -3224,53 +3309,18 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
 	return connector;
 }
 
-void intel_ddi_init(struct drm_device *dev, enum port port)
+static int intel_ddi_init_role(struct drm_device *dev, enum port port,
+			       int encoder_type, uint32_t saved_port_bits,
+			       int max_lanes)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_digital_port *intel_dig_port;
 	struct intel_encoder *intel_encoder;
 	struct drm_encoder *encoder;
-	bool init_hdmi, init_dp;
-	int max_lanes;
-
-	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
-		switch (port) {
-		case PORT_A:
-			max_lanes = 4;
-			break;
-		case PORT_E:
-			max_lanes = 0;
-			break;
-		default:
-			max_lanes = 4;
-			break;
-		}
-	} else {
-		switch (port) {
-		case PORT_A:
-			max_lanes = 2;
-			break;
-		case PORT_E:
-			max_lanes = 2;
-			break;
-		default:
-			max_lanes = 4;
-			break;
-		}
-	}
-
-	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
-		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
-	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
-	if (!init_dp && !init_hdmi) {
-		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
-			      port_name(port));
-		return;
-	}
 
 	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
 	if (!intel_dig_port)
-		return;
+		return -ENOMEM;
 
 	intel_encoder = &intel_dig_port->base;
 	encoder = &intel_encoder->base;
@@ -3287,9 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 	intel_encoder->get_config = intel_ddi_get_config;
 
 	intel_dig_port->port = port;
-	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
-					  (DDI_BUF_PORT_REVERSAL |
-					   DDI_A_4_LANES);
+	intel_dig_port->saved_port_bits = saved_port_bits;
 	intel_dig_port->max_lanes = max_lanes;
 
 	/*
@@ -3306,11 +3354,11 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 		}
 	}
 
-	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
+	intel_encoder->type = encoder_type;
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
 	intel_encoder->cloneable = 0;
 
-	if (init_dp) {
+	if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
 		if (!intel_ddi_init_dp_connector(intel_dig_port))
 			goto err;
 
@@ -3327,14 +3375,74 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 
 	/* In theory we don't need the encoder->type check, but leave it just in
 	 * case we have some really bad VBTs... */
-	if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
+	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
 		if (!intel_ddi_init_hdmi_connector(intel_dig_port))
 			goto err;
 	}
 
-	return;
+	return intel_encoder->type;
 
 err:
 	drm_encoder_cleanup(encoder);
 	kfree(intel_dig_port);
+
+	return -ENODEV;
+}
+
+void intel_ddi_init(struct drm_device *dev, enum port port)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint32_t saved_port_bits;
+	bool init_hdmi, init_dp;
+	int max_lanes;
+
+	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
+		switch (port) {
+		case PORT_A:
+			max_lanes = 4;
+			break;
+		case PORT_E:
+			max_lanes = 0;
+			break;
+		default:
+			max_lanes = 4;
+			break;
+		}
+	} else {
+		switch (port) {
+		case PORT_A:
+			max_lanes = 2;
+			break;
+		case PORT_E:
+			max_lanes = 2;
+			break;
+		default:
+			max_lanes = 4;
+			break;
+		}
+	}
+
+	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
+		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
+	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
+	if (!init_dp && !init_hdmi) {
+		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
+			      port_name(port));
+		return;
+	}
+
+	saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
+		(DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES);
+
+	if (init_dp) {
+		int ret = intel_ddi_init_role(dev, port, INTEL_OUTPUT_DISPLAYPORT,
+					      saved_port_bits, max_lanes);
+		/* Don't register the HDMI connector/encoder when we have eDP */
+		if (ret == INTEL_OUTPUT_EDP)
+			init_hdmi = false;
+	}
+
+	if (init_hdmi)
+		intel_ddi_init_role(dev, port, INTEL_OUTPUT_HDMI,
+				    saved_port_bits, max_lanes);
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bc7aaa3c431e..fc1d7387eb12 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5252,13 +5252,9 @@ static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder)
 {
-	struct drm_device *dev = intel_encoder->base.dev;
 	struct intel_digital_port *intel_dig_port;
 
 	switch (intel_encoder->type) {
-	case INTEL_OUTPUT_UNKNOWN:
-		/* Only DDI platforms should ever use this output type */
-		WARN_ON_ONCE(!HAS_DDI(dev));
 	case INTEL_OUTPUT_DISPLAYPORT:
 	case INTEL_OUTPUT_HDMI:
 	case INTEL_OUTPUT_EDP:
@@ -5279,20 +5275,9 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
 enum intel_display_power_domain
 intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
 {
-	struct drm_device *dev = intel_encoder->base.dev;
 	struct intel_digital_port *intel_dig_port;
 
 	switch (intel_encoder->type) {
-	case INTEL_OUTPUT_UNKNOWN:
-	case INTEL_OUTPUT_HDMI:
-		/*
-		 * Only DDI platforms should ever use these output types.
-		 * We can get here after the HDMI detect code has already set
-		 * the type of the shared encoder. Since we can't be sure
-		 * what's the status of the given connectors, play safe and
-		 * run the DP detection too.
-		 */
-		WARN_ON_ONCE(!HAS_DDI(dev));
 	case INTEL_OUTPUT_DISPLAYPORT:
 	case INTEL_OUTPUT_EDP:
 		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
@@ -12283,9 +12268,6 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 
 		switch (encoder->type) {
 			unsigned int port_mask;
-		case INTEL_OUTPUT_UNKNOWN:
-			if (WARN_ON(!HAS_DDI(dev)))
-				break;
 		case INTEL_OUTPUT_DISPLAYPORT:
 		case INTEL_OUTPUT_HDMI:
 		case INTEL_OUTPUT_EDP:
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 7d354b1e5e5f..1d31aa296aaa 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4601,8 +4601,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 
 	if (intel_dp->is_mst) {
 		/* MST devices are disconnected from a monitor POV */
-		if (intel_encoder->type != INTEL_OUTPUT_EDP)
-			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 		return connector_status_disconnected;
 	}
 
@@ -4632,8 +4630,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 	if (ret) {
 		/* if we are in MST mode then this connector
 		   won't appear connected or have anything with EDID on it */
-		if (intel_encoder->type != INTEL_OUTPUT_EDP)
-			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 		status = connector_status_disconnected;
 		goto out;
 	}
@@ -4648,8 +4644,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 
 	intel_dp_set_edid(intel_dp);
 
-	if (intel_encoder->type != INTEL_OUTPUT_EDP)
-		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 	status = connector_status_connected;
 
 	/* Try to read the source of the interrupt */
@@ -4692,9 +4686,6 @@ intel_dp_force(struct drm_connector *connector)
 	intel_dp_set_edid(intel_dp);
 
 	intel_display_power_put(dev_priv, power_domain);
-
-	if (intel_encoder->type != INTEL_OUTPUT_EDP)
-		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 }
 
 static int intel_dp_get_modes(struct drm_connector *connector)
@@ -4969,9 +4960,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
 	enum intel_display_power_domain power_domain;
 	enum irqreturn ret = IRQ_NONE;
 
-	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
-	    intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
-		intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
+	if (WARN_ON_ONCE(intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
+			 intel_dig_port->base.type != INTEL_OUTPUT_DISPLAYPORT))
+		return IRQ_HANDLED;
 
 	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
 		/*
@@ -5815,6 +5806,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	enum port port = intel_dig_port->port;
 	int type, ret;
 
+	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT))
+		return false;
+
 	if (WARN(intel_dig_port->max_lanes < 1,
 		 "Not enough lanes (%d) for DP on port %c\n",
 		 intel_dig_port->max_lanes, port_name(port)))
@@ -5851,11 +5845,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	else
 		type = DRM_MODE_CONNECTOR_DisplayPort;
 
-	/*
-	 * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
-	 * for DP the encoder type can be set by the caller to
-	 * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it.
-	 */
 	if (type == DRM_MODE_CONNECTOR_eDP)
 		intel_encoder->type = INTEL_OUTPUT_EDP;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a8a84b8c2bac..9e5db3d71e12 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -103,8 +103,7 @@ enum intel_output_type {
 	INTEL_OUTPUT_DISPLAYPORT = 7,
 	INTEL_OUTPUT_EDP = 8,
 	INTEL_OUTPUT_DSI = 9,
-	INTEL_OUTPUT_UNKNOWN = 10,
-	INTEL_OUTPUT_DP_MST = 11,
+	INTEL_OUTPUT_DP_MST = 10,
 };
 
 #define INTEL_DVO_CHIP_NONE 0
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 895189abfd56..75ea9515a9ce 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2034,6 +2034,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	enum port port = intel_dig_port->port;
 	uint8_t alternate_ddc_pin;
 
+	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_HDMI))
+		return;
+
 	if (WARN(intel_dig_port->max_lanes < 4,
 		 "Not enough lanes (%d) for HDMI on port %c\n",
 		 intel_dig_port->max_lanes, port_name(port)))
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index e362a30776fa..a15459a451c2 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -360,7 +360,6 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
 	case INTEL_OUTPUT_ANALOG:
 		type = DISPLAY_TYPE_CRT;
 		break;
-	case INTEL_OUTPUT_UNKNOWN:
 	case INTEL_OUTPUT_DISPLAYPORT:
 	case INTEL_OUTPUT_HDMI:
 	case INTEL_OUTPUT_DP_MST:
-- 
2.4.10

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

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

* [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (9 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:48   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart ville.syrjala
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

When the DDI port is in HDMI/DVI mode, it automagically uses the buffer
translations values from entry 9. Let's make that explicit in the code.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 5f008f0fdc13..f812607045d6 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -516,9 +516,9 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 		hdmi_level = hdmi_default_entry;
 
 	/* Entry 9 is for HDMI: */
-	I915_WRITE(DDI_BUF_TRANS_LO(port, i),
+	I915_WRITE(DDI_BUF_TRANS_LO(port, 9),
 		   ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
-	I915_WRITE(DDI_BUF_TRANS_HI(port, i),
+	I915_WRITE(DDI_BUF_TRANS_HI(port, 9),
 		   ddi_translations_hdmi[hdmi_level].trans2);
 }
 
-- 
2.4.10

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

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

* [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (10 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:52   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 13/15] drm/i915: Add a sanity check for 'hdmi_default_entry' ville.syrjala
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

DDI buffer prorgramming works quite differently depending on
the mode of the DDI port (DP/eDP/FDI vs. HDMI/DVI). Let's split
the function that does the programming into two matching variants
as well.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c    | 94 ++++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_dp_mst.c |  4 +-
 drivers/gpu/drm/i915/intel_drv.h    |  2 +-
 3 files changed, 60 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f812607045d6..c47f45c0f4a2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -397,37 +397,22 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
 
 /*
  * Starting with Haswell, DDI port buffers must be programmed with correct
- * values in advance. The buffer values are different for FDI and DP modes,
- * but the HDMI/DVI fields are shared among those. So we program the DDI
- * in either FDI or DP modes only, as HDMI connections will work with both
- * of those
+ * values in advance. This function programs the correct values for
+ * DP/eDP/FDI use cases.
  */
-void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
+void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	u32 iboost_bit = 0;
-	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
-	    size;
-	int hdmi_level;
-	enum port port;
+	int i, n_dp_entries, n_edp_entries, size;
+	enum port port = intel_ddi_get_encoder_port(encoder);
 	const struct ddi_buf_trans *ddi_translations_fdi;
 	const struct ddi_buf_trans *ddi_translations_dp;
 	const struct ddi_buf_trans *ddi_translations_edp;
-	const struct ddi_buf_trans *ddi_translations_hdmi;
 	const struct ddi_buf_trans *ddi_translations;
 
-	port = intel_ddi_get_encoder_port(encoder);
-	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
-
-	if (IS_BROXTON(dev_priv)) {
-		if (encoder->type != INTEL_OUTPUT_HDMI)
-			return;
-
-		/* Vswing programming for HDMI */
-		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
-					INTEL_OUTPUT_HDMI);
+	if (IS_BROXTON(dev_priv))
 		return;
-	}
 
 	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
 		ddi_translations_fdi = NULL;
@@ -435,9 +420,6 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
 		ddi_translations_edp =
 				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
-		ddi_translations_hdmi =
-				skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
-		hdmi_default_entry = 8;
 		/* If we're boosting the current, set bit 31 of trans1 */
 		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
 		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
@@ -454,11 +436,8 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
 		ddi_translations_edp = bdw_ddi_translations_edp;
-		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
 		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
 		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
-		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
-		hdmi_default_entry = 7;
 	} else if (IS_HASWELL(dev_priv)) {
 		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_fdi) != 9);
 		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_dp) != 9);
@@ -466,20 +445,14 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 		ddi_translations_fdi = hsw_ddi_translations_fdi;
 		ddi_translations_dp = hsw_ddi_translations_dp;
 		ddi_translations_edp = hsw_ddi_translations_dp;
-		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
 		n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
-		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
-		hdmi_default_entry = 6;
 	} else {
 		WARN(1, "ddi translation table missing\n");
 		ddi_translations_edp = bdw_ddi_translations_dp;
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
-		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
 		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
 		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
-		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
-		hdmi_default_entry = 7;
 	}
 
 	switch (encoder->type) {
@@ -488,7 +461,6 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 		size = n_edp_entries;
 		break;
 	case INTEL_OUTPUT_DISPLAYPORT:
-	case INTEL_OUTPUT_HDMI:
 		ddi_translations = ddi_translations_dp;
 		size = n_dp_entries;
 		break;
@@ -506,10 +478,54 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
 		I915_WRITE(DDI_BUF_TRANS_HI(port, i),
 			   ddi_translations[i].trans2);
 	}
+}
+
+/*
+ * Starting with Haswell, DDI port buffers must be programmed with correct
+ * values in advance. This function programs the correct values for
+ * HDMI/DVI use cases.
+ */
+static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	u32 iboost_bit = 0;
+	int n_hdmi_entries, hdmi_default_entry, hdmi_level;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	const struct ddi_buf_trans *ddi_translations_hdmi;
 
 	if (encoder->type != INTEL_OUTPUT_HDMI)
 		return;
 
+	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
+
+	if (IS_BROXTON(dev_priv)) {
+		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
+					INTEL_OUTPUT_HDMI);
+		return;
+	}
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
+		hdmi_default_entry = 8;
+		/* If we're boosting the current, set bit 31 of trans1 */
+		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
+		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
+			iboost_bit = 1<<31;
+	} else if (IS_BROADWELL(dev_priv)) {
+		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
+		hdmi_default_entry = 7;
+	} else if (IS_HASWELL(dev_priv)) {
+		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
+		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
+		hdmi_default_entry = 6;
+	} else {
+		WARN(1, "ddi translation table missing\n");
+		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
+		hdmi_default_entry = 7;
+	}
+
 	/* Choose a good default if VBT is badly populated */
 	if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
 	    hdmi_level >= n_hdmi_entries)
@@ -555,7 +571,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
-		intel_prepare_ddi_buffers(encoder);
+		intel_prepare_dp_ddi_buffers(encoder);
 	}
 
 	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
@@ -2376,8 +2392,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
 
-	intel_prepare_ddi_buffers(intel_encoder);
-
 	if (type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 		intel_edp_panel_on(intel_dp);
@@ -2388,6 +2402,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
+		intel_prepare_dp_ddi_buffers(intel_encoder);
+
 		intel_dp_set_link_params(intel_dp, crtc->config);
 
 		intel_ddi_init_dp_buf_reg(intel_encoder);
@@ -2399,9 +2415,13 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	} else if (type == INTEL_OUTPUT_HDMI) {
 		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
 
+		intel_prepare_hdmi_ddi_buffers(intel_encoder);
+
 		intel_hdmi->set_infoframes(encoder,
 					   crtc->config->has_hdmi_sink,
 					   &crtc->config->base.adjusted_mode);
+	} else if (type == INTEL_OUTPUT_ANALOG) {
+		intel_prepare_dp_ddi_buffers(intel_encoder);
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 73ac68e21b7e..d8e9b28bb2e0 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -173,10 +173,10 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 	intel_mst->port = found->port;
 
 	if (intel_dp->active_mst_links == 0) {
-		intel_prepare_ddi_buffers(&intel_dig_port->base);
-
 		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
 
+		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
+
 		intel_dp_set_link_params(intel_dp, intel_crtc->config);
 
 		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9e5db3d71e12..f7ee4bc39b33 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -995,7 +995,7 @@ void intel_crt_init(struct drm_device *dev);
 /* intel_ddi.c */
 void intel_ddi_clk_select(struct intel_encoder *encoder,
 			  const struct intel_crtc_state *pipe_config);
-void intel_prepare_ddi_buffers(struct intel_encoder *encoder);
+void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder);
 void hsw_fdi_link_train(struct drm_crtc *crtc);
 void intel_ddi_init(struct drm_device *dev, enum port port);
 enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
-- 
2.4.10

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

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

* [PATCH 13/15] drm/i915: Add a sanity check for 'hdmi_default_entry'
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (11 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:54   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 14/15] drm/i915: Get the iboost setting based on the port type ville.syrjala
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c47f45c0f4a2..8d8f346a9615 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -526,6 +526,9 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
 		hdmi_default_entry = 7;
 	}
 
+	if (WARN_ON(hdmi_default_entry >= n_hdmi_entries))
+		hdmi_default_entry = 0;
+
 	/* Choose a good default if VBT is badly populated */
 	if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
 	    hdmi_level >= n_hdmi_entries)
-- 
2.4.10

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

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

* [PATCH 14/15] drm/i915: Get the iboost setting based on the port type
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (12 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 13/15] drm/i915: Add a sanity check for 'hdmi_default_entry' ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:55   ` Daniel Vetter
  2015-12-08 17:59 ` [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port() ville.syrjala
  2016-01-12 14:52 ` [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder Ville Syrjälä
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Program the 'iboost_bit' based on what the VBT says it should be for
the specific port type, rather than assume it's alwasy the same
for DP and HDMI.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8d8f346a9615..f4f5c52a116c 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -421,8 +421,7 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder)
 		ddi_translations_edp =
 				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
 		/* If we're boosting the current, set bit 31 of trans1 */
-		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
-		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
+		if (dev_priv->vbt.ddi_port_info[port].dp_boost_level)
 			iboost_bit = 1<<31;
 
 		if (WARN_ON(port != PORT_A &&
@@ -508,8 +507,7 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
 		ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
 		hdmi_default_entry = 8;
 		/* If we're boosting the current, set bit 31 of trans1 */
-		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
-		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
+		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level)
 			iboost_bit = 1<<31;
 	} else if (IS_BROADWELL(dev_priv)) {
 		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
-- 
2.4.10

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

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

* [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port()
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (13 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 14/15] drm/i915: Get the iboost setting based on the port type ville.syrjala
@ 2015-12-08 17:59 ` ville.syrjala
  2015-12-10 13:57   ` Daniel Vetter
  2016-01-12 14:52 ` [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder Ville Syrjälä
  15 siblings, 1 reply; 46+ messages in thread
From: ville.syrjala @ 2015-12-08 17:59 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We no longer have any need to look up the intel_digital_port based
on the passed in intel_encoder, but we still want to look up the port.
Let's just move that logic into intel_ddi_get_encoder_port() and drop
the dig_port stuff.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 34 +++++++---------------------------
 1 file changed, 7 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f4f5c52a116c..b4c3aad2d817 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -304,43 +304,23 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
 static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
 				    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)
+enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder)
 {
-	struct drm_encoder *encoder = &intel_encoder->base;
-
-	switch (intel_encoder->type) {
+	switch (encoder->type) {
 	case INTEL_OUTPUT_DP_MST:
-		*dig_port = enc_to_mst(encoder)->primary;
-		*port = (*dig_port)->port;
-		break;
+		return enc_to_mst(&encoder->base)->primary->port;
 	case INTEL_OUTPUT_DISPLAYPORT:
 	case INTEL_OUTPUT_EDP:
 	case INTEL_OUTPUT_HDMI:
-		*dig_port = enc_to_dig_port(encoder);
-		*port = (*dig_port)->port;
-		break;
+		return enc_to_dig_port(&encoder->base)->port;
 	case INTEL_OUTPUT_ANALOG:
-		*dig_port = NULL;
-		*port = PORT_E;
-		break;
+		return PORT_E;
 	default:
-		WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
-		break;
+		MISSING_CASE(encoder->type);
+		return PORT_A;
 	}
 }
 
-enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
-{
-	struct intel_digital_port *dig_port;
-	enum port port;
-
-	ddi_get_encoder_port(intel_encoder, &dig_port, &port);
-
-	return port;
-}
-
 static const struct ddi_buf_trans *
 skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
 {
-- 
2.4.10

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

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

* Re: [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders
  2015-12-08 17:59 ` [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders ville.syrjala
@ 2015-12-08 18:21   ` kbuild test robot
  2015-12-10 13:47   ` Daniel Vetter
  1 sibling, 0 replies; 46+ messages in thread
From: kbuild test robot @ 2015-12-08 18:21 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3544 bytes --]

Hi Ville,

[auto build test WARNING on next-20151208]
[cannot apply to drm-intel/for-linux-next v4.4-rc4 v4.4-rc3 v4.4-rc2 v4.4-rc4]

url:    https://github.com/0day-ci/linux/commits/ville-syrjala-linux-intel-com/drm-i915-Cure-DDI-from-multiple-personality-disorder/20151209-020401
config: i386-randconfig-x007-12070758 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/i915/intel_display.c: In function 'check_digital_port_conflicts':
>> drivers/gpu/drm/i915/intel_display.c:12176:21: warning: unused variable 'dev' [-Wunused-variable]
     struct drm_device *dev = state->dev;
                        ^

vim +/dev +12176 drivers/gpu/drm/i915/intel_display.c

6a60cd87 Chandra Konduru             2015-04-07  12160  			crtc->base.primary == plane ? 0 : intel_plane->plane + 1,
6a60cd87 Chandra Konduru             2015-04-07  12161  			drm_plane_index(plane));
6a60cd87 Chandra Konduru             2015-04-07  12162  		DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = 0x%x",
6a60cd87 Chandra Konduru             2015-04-07  12163  			fb->base.id, fb->width, fb->height, fb->pixel_format);
6a60cd87 Chandra Konduru             2015-04-07  12164  		DRM_DEBUG_KMS("\tscaler:%d src (%u, %u) %ux%u dst (%u, %u) %ux%u\n",
6a60cd87 Chandra Konduru             2015-04-07  12165  			state->scaler_id,
6a60cd87 Chandra Konduru             2015-04-07  12166  			state->src.x1 >> 16, state->src.y1 >> 16,
6a60cd87 Chandra Konduru             2015-04-07  12167  			drm_rect_width(&state->src) >> 16,
6a60cd87 Chandra Konduru             2015-04-07  12168  			drm_rect_height(&state->src) >> 16,
6a60cd87 Chandra Konduru             2015-04-07  12169  			state->dst.x1, state->dst.y1,
6a60cd87 Chandra Konduru             2015-04-07  12170  			drm_rect_width(&state->dst), drm_rect_height(&state->dst));
6a60cd87 Chandra Konduru             2015-04-07  12171  	}
c0b03411 Daniel Vetter               2013-05-28  12172  }
c0b03411 Daniel Vetter               2013-05-28  12173  
5448a00d Ander Conselvan de Oliveira 2015-04-02  12174  static bool check_digital_port_conflicts(struct drm_atomic_state *state)
00f0b378 Ville Syrjälä               2014-12-02  12175  {
5448a00d Ander Conselvan de Oliveira 2015-04-02 @12176  	struct drm_device *dev = state->dev;
5448a00d Ander Conselvan de Oliveira 2015-04-02  12177  	struct intel_encoder *encoder;
da3ced29 Ander Conselvan de Oliveira 2015-04-21  12178  	struct drm_connector *connector;
5448a00d Ander Conselvan de Oliveira 2015-04-02  12179  	struct drm_connector_state *connector_state;
00f0b378 Ville Syrjälä               2014-12-02  12180  	unsigned int used_ports = 0;
5448a00d Ander Conselvan de Oliveira 2015-04-02  12181  	int i;
00f0b378 Ville Syrjälä               2014-12-02  12182  
00f0b378 Ville Syrjälä               2014-12-02  12183  	/*
00f0b378 Ville Syrjälä               2014-12-02  12184  	 * Walk the connector list instead of the encoder

:::::: The code at line 12176 was first introduced by commit
:::::: 5448a00d3f0640949c2a9a4d16e163b0b40a3b2e drm/i915: Don't use staged config in check_digital_port_conflicts()

:::::: TO: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
:::::: CC: Daniel Vetter <daniel.vetter@ffwll.ch>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 26554 bytes --]

[-- Attachment #3: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST
  2015-12-08 17:59 ` [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST ville.syrjala
@ 2015-12-10 13:17   ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:17 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:36PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We're supposed to pass the primary DP encoder to intel_ddi_clk_select(),
> not the fake MST encoder. Do so.
> 
> There's no real bug here though, since intel_ddi_clk_select() only
> checks if the encoder type is EDP (which it isn't for either the
> primary DP encoder or the fake MST encoder), and it gets the DDI port
> via intel_ddi_get_encoder_port() (which knows how to do the
> fake->primary->port dance itself).
> 
> Fixes: e404ba8 ("drm/i915: Setup DDI clk for MST on SKL")
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Meh, just stumbled over found->encoder = encoder in this very function.
Ugh, another thing to fix up ...

Anyway, looks correct. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_dp_mst.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 8c4e7dfe304c..abfc171888b8 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -173,7 +173,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
>  	intel_mst->port = found->port;
>  
>  	if (intel_dp->active_mst_links == 0) {
> -		intel_ddi_clk_select(encoder, intel_crtc->config);
> +		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
>  
>  		intel_dp_set_link_params(intel_dp, intel_crtc->config);
>  
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 02/15] drm/i915: Check max number of lanes when registering DDI ports
  2015-12-08 17:59 ` [PATCH 02/15] drm/i915: Check max number of lanes when registering DDI ports ville.syrjala
@ 2015-12-10 13:19   ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:19 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:37PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> DDI A and E share some of the lanes, so check that we have enough
> lanes for the purpose we need before registering the encoders.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Oh, trusting the VBT. Indeed better to double-check.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index b9d6b038ea0c..e903d9c87680 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3278,6 +3278,33 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  	struct intel_encoder *intel_encoder;
>  	struct drm_encoder *encoder;
>  	bool init_hdmi, init_dp;
> +	int max_lanes;
> +
> +	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> +		switch (port) {
> +		case PORT_A:
> +			max_lanes = 4;
> +			break;
> +		case PORT_E:
> +			max_lanes = 0;
> +			break;
> +		default:
> +			max_lanes = 4;
> +			break;
> +		}
> +	} else {
> +		switch (port) {
> +		case PORT_A:
> +			max_lanes = 2;
> +			break;
> +		case PORT_E:
> +			max_lanes = 2;
> +			break;
> +		default:
> +			max_lanes = 4;
> +			break;
> +		}
> +	}
>  
>  	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
>  		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> @@ -3288,6 +3315,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  		return;
>  	}
>  
> +	if (WARN(max_lanes == 0,
> +		 "No lanes for port %c\n", port_name(port)))
> +		return;
> +
> +	if (WARN(init_hdmi && max_lanes < 4,
> +		 "Not enough lanes (%d) for HDMI on port %c\n",
> +		 max_lanes, port_name(port)))
> +		init_hdmi = false;
> +
>  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
>  	if (!intel_dig_port)
>  		return;
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port
  2015-12-08 17:59 ` [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port ville.syrjala
@ 2015-12-10 13:22   ` Daniel Vetter
  2015-12-10 13:31     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:22 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:38PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Rather than having open coded checks for the DDI A/E configuration,
> just store the max supported lane count in intel_digital_port.
> 
> We had an open coded check for DDI A, but not for DDI E. So we may
> have been vilating the DDI E max lane count.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Isn't this going to break on non-DDI platforms?
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_ddi.c  | 10 +---------
>  drivers/gpu/drm/i915/intel_dp.c   | 13 +++++++------
>  drivers/gpu/drm/i915/intel_drv.h  |  1 +
>  drivers/gpu/drm/i915/intel_hdmi.c |  6 ++++++
>  4 files changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index e903d9c87680..fdb4aaa084d6 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3315,15 +3315,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  		return;
>  	}
>  
> -	if (WARN(max_lanes == 0,
> -		 "No lanes for port %c\n", port_name(port)))
> -		return;
> -
> -	if (WARN(init_hdmi && max_lanes < 4,
> -		 "Not enough lanes (%d) for HDMI on port %c\n",
> -		 max_lanes, port_name(port)))
> -		init_hdmi = false;
> -
>  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
>  	if (!intel_dig_port)
>  		return;
> @@ -3346,6 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
>  					  (DDI_BUF_PORT_REVERSAL |
>  					   DDI_A_4_LANES);
> +	intel_dig_port->max_lanes = max_lanes;
>  
>  	/*
>  	 * Bspec says that DDI_A_4_LANES is the only supported configuration
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index f335c92b4fa7..7d354b1e5e5f 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -157,14 +157,9 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
>  static u8 intel_dp_max_lane_count(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;
>  	u8 source_max, sink_max;
>  
> -	source_max = 4;
> -	if (HAS_DDI(dev) && intel_dig_port->port == PORT_A &&
> -	    (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0)
> -		source_max = 2;
> -
> +	source_max = intel_dig_port->max_lanes;
>  	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
>  
>  	return min(source_max, sink_max);
> @@ -5820,6 +5815,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	enum port port = intel_dig_port->port;
>  	int type, ret;
>  
> +	if (WARN(intel_dig_port->max_lanes < 1,
> +		 "Not enough lanes (%d) for DP on port %c\n",
> +		 intel_dig_port->max_lanes, port_name(port)))
> +		return false;
> +
>  	intel_dp->pps_pipe = INVALID_PIPE;
>  
>  	/* intel_dp vfuncs */
> @@ -6016,6 +6016,7 @@ intel_dp_init(struct drm_device *dev,
>  
>  	intel_dig_port->port = port;
>  	intel_dig_port->dp.output_reg = output_reg;
> +	intel_dig_port->max_lanes = 4;
>  
>  	intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
>  	if (IS_CHERRYVIEW(dev)) {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 8963a8a53b0b..43d451c7c366 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -818,6 +818,7 @@ struct intel_digital_port {
>  	struct intel_hdmi hdmi;
>  	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
>  	bool release_cl2_override;
> +	uint8_t max_lanes;
>  };
>  
>  struct intel_dp_mst_encoder {
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index c3978bad5ca0..895189abfd56 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -2034,6 +2034,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	enum port port = intel_dig_port->port;
>  	uint8_t alternate_ddc_pin;
>  
> +	if (WARN(intel_dig_port->max_lanes < 4,
> +		 "Not enough lanes (%d) for HDMI on port %c\n",
> +		 intel_dig_port->max_lanes, port_name(port)))
> +		return;
> +
>  	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
>  			   DRM_MODE_CONNECTOR_HDMIA);
>  	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
> @@ -2217,6 +2222,7 @@ void intel_hdmi_init(struct drm_device *dev,
>  	intel_dig_port->port = port;
>  	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
>  	intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
> +	intel_dig_port->max_lanes = 4;
>  
>  	intel_hdmi_init_connector(intel_dig_port, intel_connector);
>  }
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/15] drm/i915: Remove pointless 'ddi_translations' local variable
  2015-12-08 17:59 ` [PATCH 04/15] drm/i915: Remove pointless 'ddi_translations' local variable ville.syrjala
@ 2015-12-10 13:22   ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:22 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:39PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> skl_get_buf_trans_*() don't need the 'ddi_translations' local variable
> since all they with is assign and return. Just return the right thing
> directly and get rid of the local variable.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 44 +++++++++++++++-------------------------
>  1 file changed, 16 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index fdb4aaa084d6..f8517ed4d636 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -348,75 +348,63 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
>  	return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
>  }
>  
> -static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
> -							int *n_entries)
> +static const struct ddi_buf_trans *
> +skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
>  {
> -	const struct ddi_buf_trans *ddi_translations;
> -
>  	if (IS_SKL_ULX(dev)) {
> -		ddi_translations = skl_y_ddi_translations_dp;
>  		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
> +		return skl_y_ddi_translations_dp;
>  	} else if (IS_SKL_ULT(dev)) {
> -		ddi_translations = skl_u_ddi_translations_dp;
>  		*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
> +		return skl_u_ddi_translations_dp;
>  	} else {
> -		ddi_translations = skl_ddi_translations_dp;
>  		*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
> +		return skl_ddi_translations_dp;
>  	}
> -
> -	return ddi_translations;
>  }
>  
> -static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
> -							 int *n_entries)
> +static const struct ddi_buf_trans *
> +skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	const struct ddi_buf_trans *ddi_translations;
>  
>  	if (IS_SKL_ULX(dev)) {
>  		if (dev_priv->edp_low_vswing) {
> -			ddi_translations = skl_y_ddi_translations_edp;
>  			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
> +			return skl_y_ddi_translations_edp;
>  		} else {
> -			ddi_translations = skl_y_ddi_translations_dp;
>  			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
> +			return skl_y_ddi_translations_dp;
>  		}
>  	} else if (IS_SKL_ULT(dev)) {
>  		if (dev_priv->edp_low_vswing) {
> -			ddi_translations = skl_u_ddi_translations_edp;
>  			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
> +			return skl_u_ddi_translations_edp;
>  		} else {
> -			ddi_translations = skl_u_ddi_translations_dp;
>  			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
> +			return skl_u_ddi_translations_dp;
>  		}
>  	} else {
>  		if (dev_priv->edp_low_vswing) {
> -			ddi_translations = skl_ddi_translations_edp;
>  			*n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
> +			return skl_ddi_translations_edp;
>  		} else {
> -			ddi_translations = skl_ddi_translations_dp;
>  			*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
> +			return skl_ddi_translations_dp;
>  		}
>  	}
> -
> -	return ddi_translations;
>  }
>  
>  static const struct ddi_buf_trans *
> -skl_get_buf_trans_hdmi(struct drm_device *dev,
> -		       int *n_entries)
> +skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
>  {
> -	const struct ddi_buf_trans *ddi_translations;
> -
>  	if (IS_SKL_ULX(dev)) {
> -		ddi_translations = skl_y_ddi_translations_hdmi;
>  		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
> +		return skl_y_ddi_translations_hdmi;
>  	} else {
> -		ddi_translations = skl_ddi_translations_hdmi;
>  		*n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
> +		return skl_ddi_translations_hdmi;
>  	}
> -
> -	return ddi_translations;
>  }
>  
>  /*
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/15] drm/i915: Eliminate duplicated skl_get_buf_trans_dp()
  2015-12-08 17:59 ` [PATCH 05/15] drm/i915: Eliminate duplicated skl_get_buf_trans_dp() ville.syrjala
@ 2015-12-10 13:24   ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:24 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:40PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> skl_get_buf_trans_edp() effectively contains another copy of
> skl_get_buf_trans_dp(). Remove the duplication and just call
> skl_get_buf_trans_dp() from  skl_get_buf_trans_edp().
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 21 +++++----------------
>  1 file changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index f8517ed4d636..e281813cad82 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -368,31 +368,20 @@ skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (IS_SKL_ULX(dev)) {
> -		if (dev_priv->edp_low_vswing) {
> +	if (dev_priv->edp_low_vswing) {
> +		if (IS_SKL_ULX(dev)) {
>  			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
>  			return skl_y_ddi_translations_edp;
> -		} else {
> -			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
> -			return skl_y_ddi_translations_dp;
> -		}
> -	} else if (IS_SKL_ULT(dev)) {
> -		if (dev_priv->edp_low_vswing) {
> +		} else if (IS_SKL_ULT(dev)) {
>  			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
>  			return skl_u_ddi_translations_edp;
>  		} else {
> -			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
> -			return skl_u_ddi_translations_dp;
> -		}
> -	} else {
> -		if (dev_priv->edp_low_vswing) {
>  			*n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
>  			return skl_ddi_translations_edp;
> -		} else {
> -			*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
> -			return skl_ddi_translations_dp;
>  		}
>  	}
> +
> +	return skl_get_buf_trans_dp(dev, n_entries);
>  }
>  
>  static const struct ddi_buf_trans *
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/15] drm/i915: Pass around dev_priv for ddi buffer programming
  2015-12-08 17:59 ` [PATCH 06/15] drm/i915: Pass around dev_priv for ddi buffer programming ville.syrjala
@ 2015-12-10 13:25   ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:25 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:41PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Make the ddi buffer programming code a bit more neat by passing
> around dev_priv instead of dev.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Too lazy to check you didn't upset the compiler here. Assuming gcc is
still happy:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 79 +++++++++++++++++++---------------------
>  1 file changed, 37 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index e281813cad82..5d0b03d6d388 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -301,8 +301,8 @@ 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 bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
> +				    u32 level, enum port port, int type);
>  
>  static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
>  				 struct intel_digital_port **dig_port,
> @@ -349,12 +349,12 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
>  }
>  
>  static const struct ddi_buf_trans *
> -skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
> +skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> -	if (IS_SKL_ULX(dev)) {
> +	if (IS_SKL_ULX(dev_priv)) {
>  		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
>  		return skl_y_ddi_translations_dp;
> -	} else if (IS_SKL_ULT(dev)) {
> +	} else if (IS_SKL_ULT(dev_priv)) {
>  		*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
>  		return skl_u_ddi_translations_dp;
>  	} else {
> @@ -364,15 +364,13 @@ skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
>  }
>  
>  static const struct ddi_buf_trans *
> -skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
> +skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
>  	if (dev_priv->edp_low_vswing) {
> -		if (IS_SKL_ULX(dev)) {
> +		if (IS_SKL_ULX(dev_priv)) {
>  			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
>  			return skl_y_ddi_translations_edp;
> -		} else if (IS_SKL_ULT(dev)) {
> +		} else if (IS_SKL_ULT(dev_priv)) {
>  			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
>  			return skl_u_ddi_translations_edp;
>  		} else {
> @@ -381,13 +379,13 @@ skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
>  		}
>  	}
>  
> -	return skl_get_buf_trans_dp(dev, n_entries);
> +	return skl_get_buf_trans_dp(dev_priv, n_entries);
>  }
>  
>  static const struct ddi_buf_trans *
> -skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
> +skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> -	if (IS_SKL_ULX(dev)) {
> +	if (IS_SKL_ULX(dev_priv)) {
>  		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
>  		return skl_y_ddi_translations_hdmi;
>  	} else {
> @@ -403,10 +401,9 @@ skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
>   * in either FDI or DP modes only, as HDMI connections will work with both
>   * of those
>   */
> -static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
> -				      bool supports_hdmi)
> +static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> +				      enum port port, bool supports_hdmi)
>  {
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 iboost_bit = 0;
>  	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
>  	    size;
> @@ -417,28 +414,28 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
>  	const struct ddi_buf_trans *ddi_translations_hdmi;
>  	const struct ddi_buf_trans *ddi_translations;
>  
> -	if (IS_BROXTON(dev)) {
> +	if (IS_BROXTON(dev_priv)) {
>  		if (!supports_hdmi)
>  			return;
>  
>  		/* Vswing programming for HDMI */
> -		bxt_ddi_vswing_sequence(dev, hdmi_level, port,
> +		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
>  					INTEL_OUTPUT_HDMI);
>  		return;
> -	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
> +	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
>  		ddi_translations_fdi = NULL;
>  		ddi_translations_dp =
> -				skl_get_buf_trans_dp(dev, &n_dp_entries);
> +				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
>  		ddi_translations_edp =
> -				skl_get_buf_trans_edp(dev, &n_edp_entries);
> +				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
>  		ddi_translations_hdmi =
> -				skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
> +				skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
>  		hdmi_default_entry = 8;
>  		/* If we're boosting the current, set bit 31 of trans1 */
>  		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
>  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
>  			iboost_bit = 1<<31;
> -	} else if (IS_BROADWELL(dev)) {
> +	} else if (IS_BROADWELL(dev_priv)) {
>  		ddi_translations_fdi = bdw_ddi_translations_fdi;
>  		ddi_translations_dp = bdw_ddi_translations_dp;
>  		ddi_translations_edp = bdw_ddi_translations_edp;
> @@ -447,7 +444,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
>  		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
>  		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
>  		hdmi_default_entry = 7;
> -	} else if (IS_HASWELL(dev)) {
> +	} else if (IS_HASWELL(dev_priv)) {
>  		ddi_translations_fdi = hsw_ddi_translations_fdi;
>  		ddi_translations_dp = hsw_ddi_translations_dp;
>  		ddi_translations_edp = hsw_ddi_translations_dp;
> @@ -478,7 +475,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
>  		size = n_dp_entries;
>  		break;
>  	case PORT_D:
> -		if (intel_dp_is_edp(dev, PORT_D)) {
> +		if (intel_dp_is_edp(dev_priv->dev, PORT_D)) {
>  			ddi_translations = ddi_translations_edp;
>  			size = n_edp_entries;
>  		} else {
> @@ -545,7 +542,7 @@ void intel_prepare_ddi(struct drm_device *dev)
>  		supports_hdmi = intel_dig_port &&
>  				intel_dig_port_supports_hdmi(intel_dig_port);
>  
> -		intel_prepare_ddi_buffers(dev, port, supports_hdmi);
> +		intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi);
>  		visited[port] = true;
>  	}
>  }
> @@ -2062,10 +2059,9 @@ 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)
> +static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
> +			       u32 level, enum port port, int type)
>  {
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	const struct ddi_buf_trans *ddi_translations;
>  	uint8_t iboost;
>  	uint8_t dp_iboost, hdmi_iboost;
> @@ -2080,21 +2076,21 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
>  		if (dp_iboost) {
>  			iboost = dp_iboost;
>  		} else {
> -			ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
> +			ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries);
>  			iboost = ddi_translations[level].i_boost;
>  		}
>  	} else if (type == INTEL_OUTPUT_EDP) {
>  		if (dp_iboost) {
>  			iboost = dp_iboost;
>  		} else {
> -			ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
> +			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
>  			iboost = ddi_translations[level].i_boost;
>  		}
>  	} else if (type == INTEL_OUTPUT_HDMI) {
>  		if (hdmi_iboost) {
>  			iboost = hdmi_iboost;
>  		} else {
> -			ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
> +			ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
>  			iboost = ddi_translations[level].i_boost;
>  		}
>  	} else {
> @@ -2119,10 +2115,9 @@ 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)
> +static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
> +				    u32 level, enum port port, int type)
>  {
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	const struct bxt_ddi_buf_trans *ddi_translations;
>  	u32 n_entries, i;
>  	uint32_t val;
> @@ -2237,7 +2232,7 @@ static uint32_t translate_signal_level(int signal_levels)
>  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 drm_i915_private *dev_priv = to_i915(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 |
> @@ -2247,10 +2242,10 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
>  
>  	level = translate_signal_level(signal_levels);
>  
> -	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
> -		skl_ddi_set_iboost(dev, level, port, encoder->type);
> -	else if (IS_BROXTON(dev))
> -		bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
> +	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
> +		skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
> +	else if (IS_BROXTON(dev_priv))
> +		bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
>  
>  	return DDI_BUF_TRANS_SELECT(level);
>  }
> @@ -2333,8 +2328,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  		if (IS_BROXTON(dev)) {
>  			hdmi_level = dev_priv->vbt.
>  				ddi_port_info[port].hdmi_level_shift;
> -			bxt_ddi_vswing_sequence(dev, hdmi_level, port,
> -					INTEL_OUTPUT_HDMI);
> +			bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> +						INTEL_OUTPUT_HDMI);
>  		}
>  		intel_hdmi->set_infoframes(encoder,
>  					   crtc->config->has_hdmi_sink,
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes
  2015-12-08 17:59 ` [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes ville.syrjala
@ 2015-12-10 13:28   ` Daniel Vetter
  2015-12-10 14:43     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:28 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:42PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> The DDI translation tables are supposed to be of certain size,
> so let's add some compile time asserts to enforce that..
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Not sure this is worth it really. Next patch seems more valuable. Not
against it, but imo needs someone to really rave about it.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 5d0b03d6d388..838cbbe33517 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -351,6 +351,10 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
>  static const struct ddi_buf_trans *
>  skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> +	BUILD_BUG_ON(ARRAY_SIZE(skl_y_ddi_translations_dp) != 9);
> +	BUILD_BUG_ON(ARRAY_SIZE(skl_u_ddi_translations_dp) != 9);
> +	BUILD_BUG_ON(ARRAY_SIZE(skl_ddi_translations_dp) != 9);
> +
>  	if (IS_SKL_ULX(dev_priv)) {
>  		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
>  		return skl_y_ddi_translations_dp;
> @@ -366,6 +370,10 @@ skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
>  static const struct ddi_buf_trans *
>  skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> +	BUILD_BUG_ON(ARRAY_SIZE(skl_y_ddi_translations_edp) != 10);
> +	BUILD_BUG_ON(ARRAY_SIZE(skl_u_ddi_translations_edp) != 10);
> +	BUILD_BUG_ON(ARRAY_SIZE(skl_ddi_translations_edp) != 10);
> +
>  	if (dev_priv->edp_low_vswing) {
>  		if (IS_SKL_ULX(dev_priv)) {
>  			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
> @@ -436,6 +444,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
>  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
>  			iboost_bit = 1<<31;
>  	} else if (IS_BROADWELL(dev_priv)) {
> +		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
> +		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
> +		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_edp) != 9);
> +
>  		ddi_translations_fdi = bdw_ddi_translations_fdi;
>  		ddi_translations_dp = bdw_ddi_translations_dp;
>  		ddi_translations_edp = bdw_ddi_translations_edp;
> @@ -445,6 +457,9 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
>  		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
>  		hdmi_default_entry = 7;
>  	} else if (IS_HASWELL(dev_priv)) {
> +		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_fdi) != 9);
> +		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_dp) != 9);
> +
>  		ddi_translations_fdi = hsw_ddi_translations_fdi;
>  		ddi_translations_dp = hsw_ddi_translations_dp;
>  		ddi_translations_edp = hsw_ddi_translations_dp;
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL
  2015-12-08 17:59 ` [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL ville.syrjala
@ 2015-12-10 13:30   ` Daniel Vetter
  2015-12-10 13:42     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:30 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:43PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Only DDI A and E support 10 translation entries in DP mode. For the
> other ports the tenth entry is reserved for HDMI..
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 838cbbe33517..152c813cc43e 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -443,6 +443,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
>  		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
>  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
>  			iboost_bit = 1<<31;
> +
> +		if (WARN_ON(port != PORT_A &&
> +			    port != PORT_E && n_edp_entries > 9))
> +			n_edp_entries = 9;

Imo WARN_ON just here is enough, set_iboost can only be hit if we pass
here. With that bikeshed Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

>  	} else if (IS_BROADWELL(dev_priv)) {
>  		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
>  		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
> @@ -2099,6 +2103,11 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
>  			iboost = dp_iboost;
>  		} else {
>  			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
> +
> +			if (WARN_ON(port != PORT_A &&
> +				    port != PORT_E && n_entries > 9))
> +				n_entries = 9;
> +
>  			iboost = ddi_translations[level].i_boost;
>  		}
>  	} else if (type == INTEL_OUTPUT_HDMI) {
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port
  2015-12-10 13:22   ` Daniel Vetter
@ 2015-12-10 13:31     ` Ville Syrjälä
  2015-12-10 14:08       ` Daniel Vetter
  0 siblings, 1 reply; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 13:31 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:22:01PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:38PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Rather than having open coded checks for the DDI A/E configuration,
> > just store the max supported lane count in intel_digital_port.
> > 
> > We had an open coded check for DDI A, but not for DDI E. So we may
> > have been vilating the DDI E max lane count.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Isn't this going to break on non-DDI platforms?

It always sets 'intel_dig_port->max_lanes = 4' for non-DDI encoders.

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c  | 10 +---------
> >  drivers/gpu/drm/i915/intel_dp.c   | 13 +++++++------
> >  drivers/gpu/drm/i915/intel_drv.h  |  1 +
> >  drivers/gpu/drm/i915/intel_hdmi.c |  6 ++++++
> >  4 files changed, 15 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index e903d9c87680..fdb4aaa084d6 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -3315,15 +3315,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> >  		return;
> >  	}
> >  
> > -	if (WARN(max_lanes == 0,
> > -		 "No lanes for port %c\n", port_name(port)))
> > -		return;
> > -
> > -	if (WARN(init_hdmi && max_lanes < 4,
> > -		 "Not enough lanes (%d) for HDMI on port %c\n",
> > -		 max_lanes, port_name(port)))
> > -		init_hdmi = false;
> > -
> >  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
> >  	if (!intel_dig_port)
> >  		return;
> > @@ -3346,6 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> >  	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> >  					  (DDI_BUF_PORT_REVERSAL |
> >  					   DDI_A_4_LANES);
> > +	intel_dig_port->max_lanes = max_lanes;
> >  
> >  	/*
> >  	 * Bspec says that DDI_A_4_LANES is the only supported configuration
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index f335c92b4fa7..7d354b1e5e5f 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -157,14 +157,9 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
> >  static u8 intel_dp_max_lane_count(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;
> >  	u8 source_max, sink_max;
> >  
> > -	source_max = 4;
> > -	if (HAS_DDI(dev) && intel_dig_port->port == PORT_A &&
> > -	    (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0)
> > -		source_max = 2;
> > -
> > +	source_max = intel_dig_port->max_lanes;
> >  	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
> >  
> >  	return min(source_max, sink_max);
> > @@ -5820,6 +5815,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> >  	enum port port = intel_dig_port->port;
> >  	int type, ret;
> >  
> > +	if (WARN(intel_dig_port->max_lanes < 1,
> > +		 "Not enough lanes (%d) for DP on port %c\n",
> > +		 intel_dig_port->max_lanes, port_name(port)))
> > +		return false;
> > +
> >  	intel_dp->pps_pipe = INVALID_PIPE;
> >  
> >  	/* intel_dp vfuncs */
> > @@ -6016,6 +6016,7 @@ intel_dp_init(struct drm_device *dev,
> >  
> >  	intel_dig_port->port = port;
> >  	intel_dig_port->dp.output_reg = output_reg;
> > +	intel_dig_port->max_lanes = 4;
> >  
> >  	intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> >  	if (IS_CHERRYVIEW(dev)) {
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 8963a8a53b0b..43d451c7c366 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -818,6 +818,7 @@ struct intel_digital_port {
> >  	struct intel_hdmi hdmi;
> >  	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
> >  	bool release_cl2_override;
> > +	uint8_t max_lanes;
> >  };
> >  
> >  struct intel_dp_mst_encoder {
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > index c3978bad5ca0..895189abfd56 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -2034,6 +2034,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> >  	enum port port = intel_dig_port->port;
> >  	uint8_t alternate_ddc_pin;
> >  
> > +	if (WARN(intel_dig_port->max_lanes < 4,
> > +		 "Not enough lanes (%d) for HDMI on port %c\n",
> > +		 intel_dig_port->max_lanes, port_name(port)))
> > +		return;
> > +
> >  	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
> >  			   DRM_MODE_CONNECTOR_HDMIA);
> >  	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
> > @@ -2217,6 +2222,7 @@ void intel_hdmi_init(struct drm_device *dev,
> >  	intel_dig_port->port = port;
> >  	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
> >  	intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
> > +	intel_dig_port->max_lanes = 4;
> >  
> >  	intel_hdmi_init_connector(intel_dig_port, intel_connector);
> >  }
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/15] drm/i915: Kill intel_prepare_ddi()
  2015-12-08 17:59 ` [PATCH 09/15] drm/i915: Kill intel_prepare_ddi() ville.syrjala
@ 2015-12-10 13:37   ` Daniel Vetter
  2015-12-10 14:00     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:37 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:44PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Move the ddi buffer translation programming to occur from the encoder
> .pre_enable() hook, for just the ddi port we are enabling. Previously
> we used to reprogram the translations for all ddi ports during
> init and during power well enabling.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c         |  1 -
>  drivers/gpu/drm/i915/intel_ddi.c        | 99 ++++++++++-----------------------
>  drivers/gpu/drm/i915/intel_display.c    |  3 -
>  drivers/gpu/drm/i915/intel_dp_mst.c     |  2 +
>  drivers/gpu/drm/i915/intel_drv.h        |  2 +-
>  drivers/gpu/drm/i915/intel_runtime_pm.c | 12 ----
>  6 files changed, 31 insertions(+), 88 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index e6935f1cb689..4d8feff411bb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1062,7 +1062,6 @@ static int bxt_resume_prepare(struct drm_i915_private *dev_priv)
>  	 */
>  	broxton_init_cdclk(dev);
>  	broxton_ddi_phy_init(dev);
> -	intel_prepare_ddi(dev);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 152c813cc43e..074121efb265 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -342,12 +342,6 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
>  	return port;
>  }
>  
> -static bool
> -intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
> -{
> -	return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
> -}
> -
>  static const struct ddi_buf_trans *
>  skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> @@ -409,28 +403,34 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
>   * in either FDI or DP modes only, as HDMI connections will work with both
>   * of those
>   */
> -static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> -				      enum port port, bool supports_hdmi)
> +void intel_prepare_ddi_buffers(struct intel_encoder *encoder)

s/buffers/buffer/ since it's not just for one encoder? Or do we have a
pile of buffers per encoder? Seems a bit confusing to me, but really just
a bikeshed and was there before.

>  {
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	u32 iboost_bit = 0;
>  	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
>  	    size;
> -	int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> +	int hdmi_level;
> +	enum port port;
>  	const struct ddi_buf_trans *ddi_translations_fdi;
>  	const struct ddi_buf_trans *ddi_translations_dp;
>  	const struct ddi_buf_trans *ddi_translations_edp;
>  	const struct ddi_buf_trans *ddi_translations_hdmi;
>  	const struct ddi_buf_trans *ddi_translations;
>  
> +	port = intel_ddi_get_encoder_port(encoder);
> +	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> +
>  	if (IS_BROXTON(dev_priv)) {
> -		if (!supports_hdmi)
> +		if (encoder->type != INTEL_OUTPUT_HDMI)
>  			return;
>  
>  		/* Vswing programming for HDMI */
>  		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
>  					INTEL_OUTPUT_HDMI);
>  		return;
> -	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> +	}
> +
> +	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
>  		ddi_translations_fdi = NULL;
>  		ddi_translations_dp =
>  				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
> @@ -483,30 +483,18 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
>  		hdmi_default_entry = 7;
>  	}
>  
> -	switch (port) {
> -	case PORT_A:
> +	switch (encoder->type) {
> +	case INTEL_OUTPUT_EDP:
>  		ddi_translations = ddi_translations_edp;
>  		size = n_edp_entries;
>  		break;
> -	case PORT_B:
> -	case PORT_C:
> +	case INTEL_OUTPUT_DISPLAYPORT:
> +	case INTEL_OUTPUT_HDMI:
>  		ddi_translations = ddi_translations_dp;
>  		size = n_dp_entries;
>  		break;
> -	case PORT_D:
> -		if (intel_dp_is_edp(dev_priv->dev, PORT_D)) {
> -			ddi_translations = ddi_translations_edp;
> -			size = n_edp_entries;
> -		} else {
> -			ddi_translations = ddi_translations_dp;
> -			size = n_dp_entries;
> -		}
> -		break;
> -	case PORT_E:
> -		if (ddi_translations_fdi)
> -			ddi_translations = ddi_translations_fdi;
> -		else
> -			ddi_translations = ddi_translations_dp;
> +	case INTEL_OUTPUT_ANALOG:
> +		ddi_translations = ddi_translations_fdi;
>  		size = n_dp_entries;
>  		break;
>  	default:
> @@ -520,7 +508,7 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
>  			   ddi_translations[i].trans2);
>  	}
>  
> -	if (!supports_hdmi)
> +	if (encoder->type != INTEL_OUTPUT_HDMI)
>  		return;
>  
>  	/* Choose a good default if VBT is badly populated */
> @@ -535,37 +523,6 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
>  		   ddi_translations_hdmi[hdmi_level].trans2);
>  }
>  
> -/* Program DDI buffers translations for DP. By default, program ports A-D in DP
> - * mode and port E for FDI.
> - */
> -void intel_prepare_ddi(struct drm_device *dev)
> -{
> -	struct intel_encoder *intel_encoder;
> -	bool visited[I915_MAX_PORTS] = { 0, };
> -
> -	if (!HAS_DDI(dev))
> -		return;
> -
> -	for_each_intel_encoder(dev, intel_encoder) {
> -		struct intel_digital_port *intel_dig_port;
> -		enum port port;
> -		bool supports_hdmi;
> -
> -		if (intel_encoder->type == INTEL_OUTPUT_DSI)
> -			continue;
> -
> -		ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
> -		if (visited[port])
> -			continue;
> -
> -		supports_hdmi = intel_dig_port &&
> -				intel_dig_port_supports_hdmi(intel_dig_port);
> -
> -		intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi);
> -		visited[port] = true;
> -	}
> -}
> -
>  static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
>  				    enum port port)
>  {
> @@ -594,8 +551,14 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_encoder *encoder;
>  	u32 temp, i, rx_ctl_val;
>  
> +	for_each_encoder_on_crtc(dev, crtc, encoder) {
> +		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
> +		intel_prepare_ddi_buffers(encoder);
> +	}

I still maintain that on hsw the entire fdi stuff really should all be
part of the encoder, since it's all behind the pipe/port crossbar. Would
avoid this little annoyance here.

> +
>  	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
>  	 * mode set "sequence for CRT port" document:
>  	 * - TP1 to TP2 time with the default value
> @@ -2321,12 +2284,12 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
>  static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
> -	struct drm_device *dev = encoder->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
>  	int type = intel_encoder->type;
> -	int hdmi_level;
> +
> +	intel_prepare_ddi_buffers(intel_encoder);
>  
>  	if (type == INTEL_OUTPUT_EDP) {
>  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> @@ -2344,17 +2307,11 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
>  		intel_dp_start_link_train(intel_dp);
> -		if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
> +		if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
>  			intel_dp_stop_link_train(intel_dp);
>  	} else if (type == INTEL_OUTPUT_HDMI) {
>  		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
>  
> -		if (IS_BROXTON(dev)) {
> -			hdmi_level = dev_priv->vbt.
> -				ddi_port_info[port].hdmi_level_shift;
> -			bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> -						INTEL_OUTPUT_HDMI);
> -		}
>  		intel_hdmi->set_infoframes(encoder,
>  					   crtc->config->has_hdmi_sink,
>  					   &crtc->config->base.adjusted_mode);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index f1a5404728df..bc7aaa3c431e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9649,8 +9649,6 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
>  		val |= PCH_LP_PARTITION_LEVEL_DISABLE;
>  		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
>  	}
> -
> -	intel_prepare_ddi(dev);
>  }
>  
>  static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state)
> @@ -15172,7 +15170,6 @@ static void i915_disable_vga(struct drm_device *dev)
>  void intel_modeset_init_hw(struct drm_device *dev)
>  {
>  	intel_update_cdclk(dev);
> -	intel_prepare_ddi(dev);

This patch is worth it just for this hunk here and the one below in the
skl dmc code.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

>  	intel_init_clock_gating(dev);
>  	intel_enable_gt_powersave(dev);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index abfc171888b8..73ac68e21b7e 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -173,6 +173,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
>  	intel_mst->port = found->port;
>  
>  	if (intel_dp->active_mst_links == 0) {
> +		intel_prepare_ddi_buffers(&intel_dig_port->base);
> +
>  		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
>  
>  		intel_dp_set_link_params(intel_dp, intel_crtc->config);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 43d451c7c366..a8a84b8c2bac 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -996,7 +996,7 @@ void intel_crt_init(struct drm_device *dev);
>  /* intel_ddi.c */
>  void intel_ddi_clk_select(struct intel_encoder *encoder,
>  			  const struct intel_crtc_state *pipe_config);
> -void intel_prepare_ddi(struct drm_device *dev);
> +void intel_prepare_ddi_buffers(struct intel_encoder *encoder);
>  void hsw_fdi_link_train(struct drm_crtc *crtc);
>  void intel_ddi_init(struct drm_device *dev, enum port port);
>  enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index 2c2151f1c47e..60a592d20402 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -625,7 +625,6 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
>  static void skl_set_power_well(struct drm_i915_private *dev_priv,
>  			struct i915_power_well *power_well, bool enable)
>  {
> -	struct drm_device *dev = dev_priv->dev;
>  	uint32_t tmp, fuse_status;
>  	uint32_t req_mask, state_mask;
>  	bool is_enabled, enable_requested, check_fuse_status = false;
> @@ -669,17 +668,6 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
>  				!I915_READ(HSW_PWR_WELL_BIOS),
>  				"Invalid for power well status to be enabled, unless done by the BIOS, \
>  				when request is to disable!\n");
> -			if (power_well->data == SKL_DISP_PW_2) {
> -				/*
> -				 * DDI buffer programming unnecessary during
> -				 * driver-load/resume as it's already done
> -				 * during modeset initialization then. It's
> -				 * also invalid here as encoder list is still
> -				 * uninitialized.
> -				 */
> -				if (!dev_priv->power_domains.initializing)
> -					intel_prepare_ddi(dev);
> -			}
>  			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
>  		}
>  
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL
  2015-12-10 13:30   ` Daniel Vetter
@ 2015-12-10 13:42     ` Ville Syrjälä
  2015-12-10 14:09       ` Daniel Vetter
  0 siblings, 1 reply; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 13:42 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:30:34PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:43PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Only DDI A and E support 10 translation entries in DP mode. For the
> > other ports the tenth entry is reserved for HDMI..
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 838cbbe33517..152c813cc43e 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -443,6 +443,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> >  		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> >  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> >  			iboost_bit = 1<<31;
> > +
> > +		if (WARN_ON(port != PORT_A &&
> > +			    port != PORT_E && n_edp_entries > 9))
> > +			n_edp_entries = 9;
> 
> Imo WARN_ON just here is enough, set_iboost can only be hit if we pass
> here. With that bikeshed Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

We would then access some unknown registers and memory.

> 
> >  	} else if (IS_BROADWELL(dev_priv)) {
> >  		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
> >  		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
> > @@ -2099,6 +2103,11 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
> >  			iboost = dp_iboost;
> >  		} else {
> >  			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
> > +
> > +			if (WARN_ON(port != PORT_A &&
> > +				    port != PORT_E && n_entries > 9))
> > +				n_entries = 9;
> > +
> >  			iboost = ddi_translations[level].i_boost;
> >  		}
> >  	} else if (type == INTEL_OUTPUT_HDMI) {
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders
  2015-12-08 17:59 ` [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders ville.syrjala
  2015-12-08 18:21   ` kbuild test robot
@ 2015-12-10 13:47   ` Daniel Vetter
  2015-12-10 14:10     ` Ville Syrjälä
  1 sibling, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:47 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:45PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Eliminate the troublesome role switching DDI encoder, and just register
> a separate encoder for each role (DP and HDMI).
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Caveat about max_lanes and pre-DDI platforms still apply.

> ---
>  drivers/gpu/drm/i915/intel_ddi.c      | 232 +++++++++++++++++++++++++---------
>  drivers/gpu/drm/i915/intel_display.c  |  18 ---
>  drivers/gpu/drm/i915/intel_dp.c       |  23 +---
>  drivers/gpu/drm/i915/intel_drv.h      |   3 +-
>  drivers/gpu/drm/i915/intel_hdmi.c     |   3 +
>  drivers/gpu/drm/i915/intel_opregion.c |   1 -
>  6 files changed, 180 insertions(+), 100 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 074121efb265..5f008f0fdc13 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -318,7 +318,6 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
>  	case INTEL_OUTPUT_DISPLAYPORT:
>  	case INTEL_OUTPUT_EDP:
>  	case INTEL_OUTPUT_HDMI:
> -	case INTEL_OUTPUT_UNKNOWN:
>  		*dig_port = enc_to_dig_port(encoder);
>  		*port = (*dig_port)->port;
>  		break;
> @@ -1942,19 +1941,19 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
>  	switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
>  	case TRANS_DDI_MODE_SELECT_HDMI:
>  	case TRANS_DDI_MODE_SELECT_DVI:
> -		return (type == DRM_MODE_CONNECTOR_HDMIA);
> +		return type == DRM_MODE_CONNECTOR_HDMIA;
>  
>  	case TRANS_DDI_MODE_SELECT_DP_SST:
> -		if (type == DRM_MODE_CONNECTOR_eDP)
> -			return true;
> -		return (type == DRM_MODE_CONNECTOR_DisplayPort);
> +		return type == DRM_MODE_CONNECTOR_DisplayPort ||
> +			type == DRM_MODE_CONNECTOR_eDP;
> +
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		/* if the transcoder is in MST state then
>  		 * connector isn't connected */
>  		return false;
>  
>  	case TRANS_DDI_MODE_SELECT_FDI:
> -		return (type == DRM_MODE_CONNECTOR_VGA);
> +		return type == DRM_MODE_CONNECTOR_VGA;
>  
>  	default:
>  		return false;
> @@ -1981,8 +1980,23 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
>  		return false;
>  
>  	if (port == PORT_A) {
> +		WARN_ON(encoder->type != INTEL_OUTPUT_EDP);
> +
>  		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
>  
> +		if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
> +			goto out;
> +
> +		switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> +		case TRANS_DDI_MODE_SELECT_DP_SST:
> +			break;
> +		default:
> +			WARN(1,
> +			     "Bad transcoder EDP DDI mode 0x%08x for port %c\n",
> +			     tmp, port_name(port));
> +			return false;
> +		}
> +
>  		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
>  		case TRANS_DDI_EDP_INPUT_A_ON:
>  		case TRANS_DDI_EDP_INPUT_A_ONOFF:
> @@ -1994,25 +2008,98 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
>  		case TRANS_DDI_EDP_INPUT_C_ONOFF:
>  			*pipe = PIPE_C;
>  			break;
> +		default:
> +			WARN(1,
> +			     "Bad transcoder EDP input select 0x%08x for port %c\n",
> +			     tmp, port_name(port));
> +			return false;
>  		}
>  
>  		return true;
>  	} else {
> +		int num_mst_transcoders = 0;
> +		int num_sst_transcoders = 0;
> +		int num_fdi_transcoders = 0;
> +		int num_hdmi_transcoders = 0;
> +		int num_transcoders = 0;
> +		bool enabled = false;
> +
>  		for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
>  			tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
>  
> -			if ((tmp & TRANS_DDI_PORT_MASK)
> -			    == TRANS_DDI_SELECT_PORT(port)) {
> -				if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
> -					return false;
> +			if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
> +				continue;
> +
> +			if ((tmp & TRANS_DDI_PORT_MASK) != TRANS_DDI_SELECT_PORT(port))
> +				continue;
> +
> +			if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST) {
> +				num_mst_transcoders++;
> +				WARN_ON(port == PORT_E);
> +				continue;
> +			}
> +
> +
> +			switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> +			case TRANS_DDI_MODE_SELECT_DP_SST:
> +				WARN_ON(port == PORT_E && INTEL_INFO(dev_priv)->gen < 9);
> +
> +				num_sst_transcoders++;
> +				if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
> +				    encoder->type == INTEL_OUTPUT_EDP) {
> +					enabled = true;
> +					*pipe = i;
> +				}
> +				break;
> +			case TRANS_DDI_MODE_SELECT_HDMI:
> +			case TRANS_DDI_MODE_SELECT_DVI:
> +				WARN_ON(port == PORT_E);

Hm, previous patches made it look like hdmi on port E is possible - at
least you added piles of checks to make sure we have at least 4 lanes
everywhere. Am I mistaken?

> +
> +				num_hdmi_transcoders++;
> +				if (encoder->type == INTEL_OUTPUT_HDMI) {
> +					enabled = true;
> +					*pipe = i;
> +				}
> +				break;
> +
> +			case TRANS_DDI_MODE_SELECT_FDI:
> +				WARN_ON(port != PORT_E || INTEL_INFO(dev_priv)->gen >= 9);
> +
> +				num_fdi_transcoders++;
> +				if (encoder->type == INTEL_OUTPUT_ANALOG) {
> +					enabled = true;
> +					*pipe = i;
> +				}
> +				break;
>  
> -				*pipe = i;
> -				return true;
> +			default:
> +				WARN(1, "Bad transcoder %c DDI mode 0x%08x for port %c\n",
> +				     transcoder_name(i), tmp, port_name(port));
> +				return false;
>  			}
>  		}
> +
> +		num_transcoders = num_sst_transcoders +
> +			num_fdi_transcoders + num_hdmi_transcoders;
> +
> +		if (WARN(num_transcoders && num_mst_transcoders,
> +			 "MST and non-MST transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
> +			 port_name(port), num_sst_transcoders, num_mst_transcoders,
> +			 num_fdi_transcoders, num_hdmi_transcoders))
> +			return false;
> +
> +		if (WARN(num_transcoders > 1,
> +			 "Multiple transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
> +			 port_name(port), num_sst_transcoders, num_mst_transcoders,
> +			 num_fdi_transcoders, num_hdmi_transcoders))
> +			return false;
> +
> +		if (enabled)
> +			return true;

This is too big and needs to be extracted into a static function.

Otherwise I didn't spot anything, and getting rid of OUTPUT_UNKNOWN is
really nice. I also wonder whether we should long term rework mst to use
the fake encoder as the real one. The fake encoder was just done to not
confuse the ddi encoder, but now that we have multiples of those we might
as well embrace that everywhere.

Cheers, Daniel

>  	}
>  
> -	DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
> +out:
> +	DRM_DEBUG_KMS("No pipe for DDI port %c found\n", port_name(port));
>  
>  	return false;
>  }
> @@ -3174,8 +3261,6 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
>  	int type = encoder->type;
>  	int port = intel_ddi_get_encoder_port(encoder);
>  
> -	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
> -
>  	if (port == PORT_A)
>  		pipe_config->cpu_transcoder = TRANSCODER_EDP;
>  
> @@ -3224,53 +3309,18 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
>  	return connector;
>  }
>  
> -void intel_ddi_init(struct drm_device *dev, enum port port)
> +static int intel_ddi_init_role(struct drm_device *dev, enum port port,
> +			       int encoder_type, uint32_t saved_port_bits,
> +			       int max_lanes)
>  {
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_digital_port *intel_dig_port;
>  	struct intel_encoder *intel_encoder;
>  	struct drm_encoder *encoder;
> -	bool init_hdmi, init_dp;
> -	int max_lanes;
> -
> -	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> -		switch (port) {
> -		case PORT_A:
> -			max_lanes = 4;
> -			break;
> -		case PORT_E:
> -			max_lanes = 0;
> -			break;
> -		default:
> -			max_lanes = 4;
> -			break;
> -		}
> -	} else {
> -		switch (port) {
> -		case PORT_A:
> -			max_lanes = 2;
> -			break;
> -		case PORT_E:
> -			max_lanes = 2;
> -			break;
> -		default:
> -			max_lanes = 4;
> -			break;
> -		}
> -	}
> -
> -	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
> -		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> -	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
> -	if (!init_dp && !init_hdmi) {
> -		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
> -			      port_name(port));
> -		return;
> -	}
>  
>  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
>  	if (!intel_dig_port)
> -		return;
> +		return -ENOMEM;
>  
>  	intel_encoder = &intel_dig_port->base;
>  	encoder = &intel_encoder->base;
> @@ -3287,9 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  	intel_encoder->get_config = intel_ddi_get_config;
>  
>  	intel_dig_port->port = port;
> -	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> -					  (DDI_BUF_PORT_REVERSAL |
> -					   DDI_A_4_LANES);
> +	intel_dig_port->saved_port_bits = saved_port_bits;
>  	intel_dig_port->max_lanes = max_lanes;
>  
>  	/*
> @@ -3306,11 +3354,11 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  		}
>  	}
>  
> -	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
> +	intel_encoder->type = encoder_type;
>  	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
>  	intel_encoder->cloneable = 0;
>  
> -	if (init_dp) {
> +	if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
>  		if (!intel_ddi_init_dp_connector(intel_dig_port))
>  			goto err;
>  
> @@ -3327,14 +3375,74 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>  
>  	/* In theory we don't need the encoder->type check, but leave it just in
>  	 * case we have some really bad VBTs... */
> -	if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
> +	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
>  		if (!intel_ddi_init_hdmi_connector(intel_dig_port))
>  			goto err;
>  	}
>  
> -	return;
> +	return intel_encoder->type;
>  
>  err:
>  	drm_encoder_cleanup(encoder);
>  	kfree(intel_dig_port);
> +
> +	return -ENODEV;
> +}
> +
> +void intel_ddi_init(struct drm_device *dev, enum port port)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	uint32_t saved_port_bits;
> +	bool init_hdmi, init_dp;
> +	int max_lanes;
> +
> +	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> +		switch (port) {
> +		case PORT_A:
> +			max_lanes = 4;
> +			break;
> +		case PORT_E:
> +			max_lanes = 0;
> +			break;
> +		default:
> +			max_lanes = 4;
> +			break;
> +		}
> +	} else {
> +		switch (port) {
> +		case PORT_A:
> +			max_lanes = 2;
> +			break;
> +		case PORT_E:
> +			max_lanes = 2;
> +			break;
> +		default:
> +			max_lanes = 4;
> +			break;
> +		}
> +	}
> +
> +	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
> +		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> +	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
> +	if (!init_dp && !init_hdmi) {
> +		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
> +			      port_name(port));
> +		return;
> +	}
> +
> +	saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> +		(DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES);
> +
> +	if (init_dp) {
> +		int ret = intel_ddi_init_role(dev, port, INTEL_OUTPUT_DISPLAYPORT,
> +					      saved_port_bits, max_lanes);
> +		/* Don't register the HDMI connector/encoder when we have eDP */
> +		if (ret == INTEL_OUTPUT_EDP)
> +			init_hdmi = false;
> +	}
> +
> +	if (init_hdmi)
> +		intel_ddi_init_role(dev, port, INTEL_OUTPUT_HDMI,
> +				    saved_port_bits, max_lanes);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index bc7aaa3c431e..fc1d7387eb12 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5252,13 +5252,9 @@ static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
>  enum intel_display_power_domain
>  intel_display_port_power_domain(struct intel_encoder *intel_encoder)
>  {
> -	struct drm_device *dev = intel_encoder->base.dev;
>  	struct intel_digital_port *intel_dig_port;
>  
>  	switch (intel_encoder->type) {
> -	case INTEL_OUTPUT_UNKNOWN:
> -		/* Only DDI platforms should ever use this output type */
> -		WARN_ON_ONCE(!HAS_DDI(dev));
>  	case INTEL_OUTPUT_DISPLAYPORT:
>  	case INTEL_OUTPUT_HDMI:
>  	case INTEL_OUTPUT_EDP:
> @@ -5279,20 +5275,9 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
>  enum intel_display_power_domain
>  intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
>  {
> -	struct drm_device *dev = intel_encoder->base.dev;
>  	struct intel_digital_port *intel_dig_port;
>  
>  	switch (intel_encoder->type) {
> -	case INTEL_OUTPUT_UNKNOWN:
> -	case INTEL_OUTPUT_HDMI:
> -		/*
> -		 * Only DDI platforms should ever use these output types.
> -		 * We can get here after the HDMI detect code has already set
> -		 * the type of the shared encoder. Since we can't be sure
> -		 * what's the status of the given connectors, play safe and
> -		 * run the DP detection too.
> -		 */
> -		WARN_ON_ONCE(!HAS_DDI(dev));
>  	case INTEL_OUTPUT_DISPLAYPORT:
>  	case INTEL_OUTPUT_EDP:
>  		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
> @@ -12283,9 +12268,6 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
>  
>  		switch (encoder->type) {
>  			unsigned int port_mask;
> -		case INTEL_OUTPUT_UNKNOWN:
> -			if (WARN_ON(!HAS_DDI(dev)))
> -				break;
>  		case INTEL_OUTPUT_DISPLAYPORT:
>  		case INTEL_OUTPUT_HDMI:
>  		case INTEL_OUTPUT_EDP:
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 7d354b1e5e5f..1d31aa296aaa 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4601,8 +4601,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
>  
>  	if (intel_dp->is_mst) {
>  		/* MST devices are disconnected from a monitor POV */
> -		if (intel_encoder->type != INTEL_OUTPUT_EDP)
> -			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
>  		return connector_status_disconnected;
>  	}
>  
> @@ -4632,8 +4630,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
>  	if (ret) {
>  		/* if we are in MST mode then this connector
>  		   won't appear connected or have anything with EDID on it */
> -		if (intel_encoder->type != INTEL_OUTPUT_EDP)
> -			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
>  		status = connector_status_disconnected;
>  		goto out;
>  	}
> @@ -4648,8 +4644,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
>  
>  	intel_dp_set_edid(intel_dp);
>  
> -	if (intel_encoder->type != INTEL_OUTPUT_EDP)
> -		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
>  	status = connector_status_connected;
>  
>  	/* Try to read the source of the interrupt */
> @@ -4692,9 +4686,6 @@ intel_dp_force(struct drm_connector *connector)
>  	intel_dp_set_edid(intel_dp);
>  
>  	intel_display_power_put(dev_priv, power_domain);
> -
> -	if (intel_encoder->type != INTEL_OUTPUT_EDP)
> -		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
>  }
>  
>  static int intel_dp_get_modes(struct drm_connector *connector)
> @@ -4969,9 +4960,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
>  	enum intel_display_power_domain power_domain;
>  	enum irqreturn ret = IRQ_NONE;
>  
> -	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
> -	    intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
> -		intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
> +	if (WARN_ON_ONCE(intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
> +			 intel_dig_port->base.type != INTEL_OUTPUT_DISPLAYPORT))
> +		return IRQ_HANDLED;
>  
>  	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
>  		/*
> @@ -5815,6 +5806,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	enum port port = intel_dig_port->port;
>  	int type, ret;
>  
> +	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT))
> +		return false;
> +
>  	if (WARN(intel_dig_port->max_lanes < 1,
>  		 "Not enough lanes (%d) for DP on port %c\n",
>  		 intel_dig_port->max_lanes, port_name(port)))
> @@ -5851,11 +5845,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	else
>  		type = DRM_MODE_CONNECTOR_DisplayPort;
>  
> -	/*
> -	 * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
> -	 * for DP the encoder type can be set by the caller to
> -	 * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it.
> -	 */
>  	if (type == DRM_MODE_CONNECTOR_eDP)
>  		intel_encoder->type = INTEL_OUTPUT_EDP;
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a8a84b8c2bac..9e5db3d71e12 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -103,8 +103,7 @@ enum intel_output_type {
>  	INTEL_OUTPUT_DISPLAYPORT = 7,
>  	INTEL_OUTPUT_EDP = 8,
>  	INTEL_OUTPUT_DSI = 9,
> -	INTEL_OUTPUT_UNKNOWN = 10,
> -	INTEL_OUTPUT_DP_MST = 11,
> +	INTEL_OUTPUT_DP_MST = 10,
>  };
>  
>  #define INTEL_DVO_CHIP_NONE 0
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 895189abfd56..75ea9515a9ce 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -2034,6 +2034,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	enum port port = intel_dig_port->port;
>  	uint8_t alternate_ddc_pin;
>  
> +	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_HDMI))
> +		return;
> +
>  	if (WARN(intel_dig_port->max_lanes < 4,
>  		 "Not enough lanes (%d) for HDMI on port %c\n",
>  		 intel_dig_port->max_lanes, port_name(port)))
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index e362a30776fa..a15459a451c2 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -360,7 +360,6 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
>  	case INTEL_OUTPUT_ANALOG:
>  		type = DISPLAY_TYPE_CRT;
>  		break;
> -	case INTEL_OUTPUT_UNKNOWN:
>  	case INTEL_OUTPUT_DISPLAYPORT:
>  	case INTEL_OUTPUT_HDMI:
>  	case INTEL_OUTPUT_DP_MST:
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi
  2015-12-08 17:59 ` [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi ville.syrjala
@ 2015-12-10 13:48   ` Daniel Vetter
  2015-12-10 14:41     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:48 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:46PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> When the DDI port is in HDMI/DVI mode, it automagically uses the buffer
> translations values from entry 9. Let's make that explicit in the code.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Or WARN_ON(i != 9); Either way don't see that much benefit, but I guess
won't hurt either. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 5f008f0fdc13..f812607045d6 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -516,9 +516,9 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
>  		hdmi_level = hdmi_default_entry;
>  
>  	/* Entry 9 is for HDMI: */
> -	I915_WRITE(DDI_BUF_TRANS_LO(port, i),
> +	I915_WRITE(DDI_BUF_TRANS_LO(port, 9),
>  		   ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
> -	I915_WRITE(DDI_BUF_TRANS_HI(port, i),
> +	I915_WRITE(DDI_BUF_TRANS_HI(port, 9),
>  		   ddi_translations_hdmi[hdmi_level].trans2);
>  }
>  
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart
  2015-12-08 17:59 ` [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart ville.syrjala
@ 2015-12-10 13:52   ` Daniel Vetter
  2015-12-10 14:15     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:52 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:47PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> DDI buffer prorgramming works quite differently depending on
> the mode of the DDI port (DP/eDP/FDI vs. HDMI/DVI). Let's split
> the function that does the programming into two matching variants
> as well.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c    | 94 ++++++++++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_dp_mst.c |  4 +-
>  drivers/gpu/drm/i915/intel_drv.h    |  2 +-
>  3 files changed, 60 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index f812607045d6..c47f45c0f4a2 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -397,37 +397,22 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
>  
>  /*
>   * Starting with Haswell, DDI port buffers must be programmed with correct
> - * values in advance. The buffer values are different for FDI and DP modes,
> - * but the HDMI/DVI fields are shared among those. So we program the DDI
> - * in either FDI or DP modes only, as HDMI connections will work with both
> - * of those
> + * values in advance. This function programs the correct values for
> + * DP/eDP/FDI use cases.
>   */
> -void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> +void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	u32 iboost_bit = 0;
> -	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
> -	    size;
> -	int hdmi_level;
> -	enum port port;
> +	int i, n_dp_entries, n_edp_entries, size;
> +	enum port port = intel_ddi_get_encoder_port(encoder);
>  	const struct ddi_buf_trans *ddi_translations_fdi;
>  	const struct ddi_buf_trans *ddi_translations_dp;
>  	const struct ddi_buf_trans *ddi_translations_edp;
> -	const struct ddi_buf_trans *ddi_translations_hdmi;
>  	const struct ddi_buf_trans *ddi_translations;
>  
> -	port = intel_ddi_get_encoder_port(encoder);
> -	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> -
> -	if (IS_BROXTON(dev_priv)) {
> -		if (encoder->type != INTEL_OUTPUT_HDMI)
> -			return;
> -
> -		/* Vswing programming for HDMI */
> -		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> -					INTEL_OUTPUT_HDMI);
> +	if (IS_BROXTON(dev_priv))
>  		return;
> -	}
>  
>  	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
>  		ddi_translations_fdi = NULL;
> @@ -435,9 +420,6 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
>  				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
>  		ddi_translations_edp =
>  				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
> -		ddi_translations_hdmi =
> -				skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
> -		hdmi_default_entry = 8;
>  		/* If we're boosting the current, set bit 31 of trans1 */
>  		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
>  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> @@ -454,11 +436,8 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
>  		ddi_translations_fdi = bdw_ddi_translations_fdi;
>  		ddi_translations_dp = bdw_ddi_translations_dp;
>  		ddi_translations_edp = bdw_ddi_translations_edp;
> -		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
>  		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
>  		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
> -		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> -		hdmi_default_entry = 7;
>  	} else if (IS_HASWELL(dev_priv)) {
>  		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_fdi) != 9);
>  		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_dp) != 9);
> @@ -466,20 +445,14 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
>  		ddi_translations_fdi = hsw_ddi_translations_fdi;
>  		ddi_translations_dp = hsw_ddi_translations_dp;
>  		ddi_translations_edp = hsw_ddi_translations_dp;
> -		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
>  		n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
> -		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
> -		hdmi_default_entry = 6;
>  	} else {
>  		WARN(1, "ddi translation table missing\n");
>  		ddi_translations_edp = bdw_ddi_translations_dp;
>  		ddi_translations_fdi = bdw_ddi_translations_fdi;
>  		ddi_translations_dp = bdw_ddi_translations_dp;
> -		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
>  		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
>  		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
> -		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> -		hdmi_default_entry = 7;
>  	}
>  
>  	switch (encoder->type) {
> @@ -488,7 +461,6 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
>  		size = n_edp_entries;
>  		break;
>  	case INTEL_OUTPUT_DISPLAYPORT:
> -	case INTEL_OUTPUT_HDMI:
>  		ddi_translations = ddi_translations_dp;
>  		size = n_dp_entries;
>  		break;
> @@ -506,10 +478,54 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
>  		I915_WRITE(DDI_BUF_TRANS_HI(port, i),
>  			   ddi_translations[i].trans2);
>  	}
> +}
> +
> +/*
> + * Starting with Haswell, DDI port buffers must be programmed with correct
> + * values in advance. This function programs the correct values for
> + * HDMI/DVI use cases.
> + */
> +static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	u32 iboost_bit = 0;
> +	int n_hdmi_entries, hdmi_default_entry, hdmi_level;
> +	enum port port = intel_ddi_get_encoder_port(encoder);
> +	const struct ddi_buf_trans *ddi_translations_hdmi;
>  
>  	if (encoder->type != INTEL_OUTPUT_HDMI)

WARN_ON?

>  		return;
>  
> +	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> +
> +	if (IS_BROXTON(dev_priv)) {
> +		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> +					INTEL_OUTPUT_HDMI);
> +		return;
> +	}
> +
> +	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> +		ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
> +		hdmi_default_entry = 8;
> +		/* If we're boosting the current, set bit 31 of trans1 */
> +		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> +		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> +			iboost_bit = 1<<31;
> +	} else if (IS_BROADWELL(dev_priv)) {
> +		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> +		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> +		hdmi_default_entry = 7;
> +	} else if (IS_HASWELL(dev_priv)) {
> +		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
> +		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
> +		hdmi_default_entry = 6;
> +	} else {
> +		WARN(1, "ddi translation table missing\n");
> +		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> +		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> +		hdmi_default_entry = 7;
> +	}
> +
>  	/* Choose a good default if VBT is badly populated */
>  	if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
>  	    hdmi_level >= n_hdmi_entries)
> @@ -555,7 +571,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder) {
>  		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
> -		intel_prepare_ddi_buffers(encoder);
> +		intel_prepare_dp_ddi_buffers(encoder);
>  	}
>  
>  	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
> @@ -2376,8 +2392,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
>  	int type = intel_encoder->type;
>  
> -	intel_prepare_ddi_buffers(intel_encoder);
> -
>  	if (type == INTEL_OUTPUT_EDP) {
>  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  		intel_edp_panel_on(intel_dp);
> @@ -2388,6 +2402,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
>  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  
> +		intel_prepare_dp_ddi_buffers(intel_encoder);
> +
>  		intel_dp_set_link_params(intel_dp, crtc->config);
>  
>  		intel_ddi_init_dp_buf_reg(intel_encoder);
> @@ -2399,9 +2415,13 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  	} else if (type == INTEL_OUTPUT_HDMI) {
>  		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
>  
> +		intel_prepare_hdmi_ddi_buffers(intel_encoder);
> +
>  		intel_hdmi->set_infoframes(encoder,
>  					   crtc->config->has_hdmi_sink,
>  					   &crtc->config->base.adjusted_mode);
> +	} else if (type == INTEL_OUTPUT_ANALOG) {
> +		intel_prepare_dp_ddi_buffers(intel_encoder);

Hm, I was hoping with an encoder split that we could use the vfunc hooks
instead of these massive if ladders everywhere ... too much trouble still?

Anyway, besides the WARN_ON request the patch looks correct, so with that
addressed Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 73ac68e21b7e..d8e9b28bb2e0 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -173,10 +173,10 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
>  	intel_mst->port = found->port;
>  
>  	if (intel_dp->active_mst_links == 0) {
> -		intel_prepare_ddi_buffers(&intel_dig_port->base);
> -
>  		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
>  
> +		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
> +
>  		intel_dp_set_link_params(intel_dp, intel_crtc->config);
>  
>  		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 9e5db3d71e12..f7ee4bc39b33 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -995,7 +995,7 @@ void intel_crt_init(struct drm_device *dev);
>  /* intel_ddi.c */
>  void intel_ddi_clk_select(struct intel_encoder *encoder,
>  			  const struct intel_crtc_state *pipe_config);
> -void intel_prepare_ddi_buffers(struct intel_encoder *encoder);
> +void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder);
>  void hsw_fdi_link_train(struct drm_crtc *crtc);
>  void intel_ddi_init(struct drm_device *dev, enum port port);
>  enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/15] drm/i915: Add a sanity check for 'hdmi_default_entry'
  2015-12-08 17:59 ` [PATCH 13/15] drm/i915: Add a sanity check for 'hdmi_default_entry' ville.syrjala
@ 2015-12-10 13:54   ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:54 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:48PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index c47f45c0f4a2..8d8f346a9615 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -526,6 +526,9 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
>  		hdmi_default_entry = 7;
>  	}
>  
> +	if (WARN_ON(hdmi_default_entry >= n_hdmi_entries))
> +		hdmi_default_entry = 0;
> +
>  	/* Choose a good default if VBT is badly populated */
>  	if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
>  	    hdmi_level >= n_hdmi_entries)
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/15] drm/i915: Get the iboost setting based on the port type
  2015-12-08 17:59 ` [PATCH 14/15] drm/i915: Get the iboost setting based on the port type ville.syrjala
@ 2015-12-10 13:55   ` Daniel Vetter
  2015-12-10 14:17     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:55 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:49PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Program the 'iboost_bit' based on what the VBT says it should be for
> the specific port type, rather than assume it's alwasy the same
> for DP and HDMI.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

I guess we don't have any indication that vbt would set this differently
depending upon port?

Anyway makes sense, and if it breaks something we'll know.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 8d8f346a9615..f4f5c52a116c 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -421,8 +421,7 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder)
>  		ddi_translations_edp =
>  				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
>  		/* If we're boosting the current, set bit 31 of trans1 */
> -		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> -		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> +		if (dev_priv->vbt.ddi_port_info[port].dp_boost_level)
>  			iboost_bit = 1<<31;
>  
>  		if (WARN_ON(port != PORT_A &&
> @@ -508,8 +507,7 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
>  		ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
>  		hdmi_default_entry = 8;
>  		/* If we're boosting the current, set bit 31 of trans1 */
> -		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> -		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> +		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level)
>  			iboost_bit = 1<<31;
>  	} else if (IS_BROADWELL(dev_priv)) {
>  		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port()
  2015-12-08 17:59 ` [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port() ville.syrjala
@ 2015-12-10 13:57   ` Daniel Vetter
  2015-12-10 14:19     ` Ville Syrjälä
  0 siblings, 1 reply; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 13:57 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, Dec 08, 2015 at 07:59:50PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We no longer have any need to look up the intel_digital_port based
> on the passed in intel_encoder, but we still want to look up the port.
> Let's just move that logic into intel_ddi_get_encoder_port() and drop
> the dig_port stuff.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

I wonder whether we shouldn't just add intel_encoder->port somewhere.

Anyway Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 34 +++++++---------------------------
>  1 file changed, 7 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index f4f5c52a116c..b4c3aad2d817 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -304,43 +304,23 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
>  static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
>  				    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)
> +enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder)
>  {
> -	struct drm_encoder *encoder = &intel_encoder->base;
> -
> -	switch (intel_encoder->type) {
> +	switch (encoder->type) {
>  	case INTEL_OUTPUT_DP_MST:
> -		*dig_port = enc_to_mst(encoder)->primary;
> -		*port = (*dig_port)->port;
> -		break;
> +		return enc_to_mst(&encoder->base)->primary->port;
>  	case INTEL_OUTPUT_DISPLAYPORT:
>  	case INTEL_OUTPUT_EDP:
>  	case INTEL_OUTPUT_HDMI:
> -		*dig_port = enc_to_dig_port(encoder);
> -		*port = (*dig_port)->port;
> -		break;
> +		return enc_to_dig_port(&encoder->base)->port;
>  	case INTEL_OUTPUT_ANALOG:
> -		*dig_port = NULL;
> -		*port = PORT_E;
> -		break;
> +		return PORT_E;
>  	default:
> -		WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
> -		break;
> +		MISSING_CASE(encoder->type);
> +		return PORT_A;
>  	}
>  }
>  
> -enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
> -{
> -	struct intel_digital_port *dig_port;
> -	enum port port;
> -
> -	ddi_get_encoder_port(intel_encoder, &dig_port, &port);
> -
> -	return port;
> -}
> -
>  static const struct ddi_buf_trans *
>  skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
>  {
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/15] drm/i915: Kill intel_prepare_ddi()
  2015-12-10 13:37   ` Daniel Vetter
@ 2015-12-10 14:00     ` Ville Syrjälä
  0 siblings, 0 replies; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:00 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:37:01PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:44PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Move the ddi buffer translation programming to occur from the encoder
> > .pre_enable() hook, for just the ddi port we are enabling. Previously
> > we used to reprogram the translations for all ddi ports during
> > init and during power well enabling.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.c         |  1 -
> >  drivers/gpu/drm/i915/intel_ddi.c        | 99 ++++++++++-----------------------
> >  drivers/gpu/drm/i915/intel_display.c    |  3 -
> >  drivers/gpu/drm/i915/intel_dp_mst.c     |  2 +
> >  drivers/gpu/drm/i915/intel_drv.h        |  2 +-
> >  drivers/gpu/drm/i915/intel_runtime_pm.c | 12 ----
> >  6 files changed, 31 insertions(+), 88 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> > index e6935f1cb689..4d8feff411bb 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.c
> > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > @@ -1062,7 +1062,6 @@ static int bxt_resume_prepare(struct drm_i915_private *dev_priv)
> >  	 */
> >  	broxton_init_cdclk(dev);
> >  	broxton_ddi_phy_init(dev);
> > -	intel_prepare_ddi(dev);
> >  
> >  	return 0;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 152c813cc43e..074121efb265 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -342,12 +342,6 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
> >  	return port;
> >  }
> >  
> > -static bool
> > -intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
> > -{
> > -	return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
> > -}
> > -
> >  static const struct ddi_buf_trans *
> >  skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
> >  {
> > @@ -409,28 +403,34 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
> >   * in either FDI or DP modes only, as HDMI connections will work with both
> >   * of those
> >   */
> > -static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> > -				      enum port port, bool supports_hdmi)
> > +void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> 
> s/buffers/buffer/ since it's not just for one encoder? Or do we have a
> pile of buffers per encoder? Seems a bit confusing to me, but really just
> a bikeshed and was there before.

Bspec seems to refer to it as a singular "DDI buffer" so yeah dropping
the 's' would seem to match. I suppose in reality there's a buffer on
each signal, but I guess it's common practice to refer to the whole
thing as a single buffer.

> 
> >  {
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >  	u32 iboost_bit = 0;
> >  	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
> >  	    size;
> > -	int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> > +	int hdmi_level;
> > +	enum port port;
> >  	const struct ddi_buf_trans *ddi_translations_fdi;
> >  	const struct ddi_buf_trans *ddi_translations_dp;
> >  	const struct ddi_buf_trans *ddi_translations_edp;
> >  	const struct ddi_buf_trans *ddi_translations_hdmi;
> >  	const struct ddi_buf_trans *ddi_translations;
> >  
> > +	port = intel_ddi_get_encoder_port(encoder);
> > +	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> > +
> >  	if (IS_BROXTON(dev_priv)) {
> > -		if (!supports_hdmi)
> > +		if (encoder->type != INTEL_OUTPUT_HDMI)
> >  			return;
> >  
> >  		/* Vswing programming for HDMI */
> >  		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> >  					INTEL_OUTPUT_HDMI);
> >  		return;
> > -	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> > +	}
> > +
> > +	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> >  		ddi_translations_fdi = NULL;
> >  		ddi_translations_dp =
> >  				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
> > @@ -483,30 +483,18 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> >  		hdmi_default_entry = 7;
> >  	}
> >  
> > -	switch (port) {
> > -	case PORT_A:
> > +	switch (encoder->type) {
> > +	case INTEL_OUTPUT_EDP:
> >  		ddi_translations = ddi_translations_edp;
> >  		size = n_edp_entries;
> >  		break;
> > -	case PORT_B:
> > -	case PORT_C:
> > +	case INTEL_OUTPUT_DISPLAYPORT:
> > +	case INTEL_OUTPUT_HDMI:
> >  		ddi_translations = ddi_translations_dp;
> >  		size = n_dp_entries;
> >  		break;
> > -	case PORT_D:
> > -		if (intel_dp_is_edp(dev_priv->dev, PORT_D)) {
> > -			ddi_translations = ddi_translations_edp;
> > -			size = n_edp_entries;
> > -		} else {
> > -			ddi_translations = ddi_translations_dp;
> > -			size = n_dp_entries;
> > -		}
> > -		break;
> > -	case PORT_E:
> > -		if (ddi_translations_fdi)
> > -			ddi_translations = ddi_translations_fdi;
> > -		else
> > -			ddi_translations = ddi_translations_dp;
> > +	case INTEL_OUTPUT_ANALOG:
> > +		ddi_translations = ddi_translations_fdi;
> >  		size = n_dp_entries;
> >  		break;
> >  	default:
> > @@ -520,7 +508,7 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> >  			   ddi_translations[i].trans2);
> >  	}
> >  
> > -	if (!supports_hdmi)
> > +	if (encoder->type != INTEL_OUTPUT_HDMI)
> >  		return;
> >  
> >  	/* Choose a good default if VBT is badly populated */
> > @@ -535,37 +523,6 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> >  		   ddi_translations_hdmi[hdmi_level].trans2);
> >  }
> >  
> > -/* Program DDI buffers translations for DP. By default, program ports A-D in DP
> > - * mode and port E for FDI.
> > - */
> > -void intel_prepare_ddi(struct drm_device *dev)
> > -{
> > -	struct intel_encoder *intel_encoder;
> > -	bool visited[I915_MAX_PORTS] = { 0, };
> > -
> > -	if (!HAS_DDI(dev))
> > -		return;
> > -
> > -	for_each_intel_encoder(dev, intel_encoder) {
> > -		struct intel_digital_port *intel_dig_port;
> > -		enum port port;
> > -		bool supports_hdmi;
> > -
> > -		if (intel_encoder->type == INTEL_OUTPUT_DSI)
> > -			continue;
> > -
> > -		ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
> > -		if (visited[port])
> > -			continue;
> > -
> > -		supports_hdmi = intel_dig_port &&
> > -				intel_dig_port_supports_hdmi(intel_dig_port);
> > -
> > -		intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi);
> > -		visited[port] = true;
> > -	}
> > -}
> > -
> >  static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
> >  				    enum port port)
> >  {
> > @@ -594,8 +551,14 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct intel_encoder *encoder;
> >  	u32 temp, i, rx_ctl_val;
> >  
> > +	for_each_encoder_on_crtc(dev, crtc, encoder) {
> > +		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
> > +		intel_prepare_ddi_buffers(encoder);
> > +	}
> 
> I still maintain that on hsw the entire fdi stuff really should all be
> part of the encoder, since it's all behind the pipe/port crossbar. Would
> avoid this little annoyance here.

Yeah, it's a bit unsightly. Actually I forgot to put this here
originally, and then I was wondering why FDI was acting up. I then put
it into the crt .pre_enable() hook but it looked too lonely there,
so in the end I figured it's better to have it next to the FDI setup
where it's actually needed, leading to the encoder loop.

> 
> > +
> >  	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
> >  	 * mode set "sequence for CRT port" document:
> >  	 * - TP1 to TP2 time with the default value
> > @@ -2321,12 +2284,12 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
> >  static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
> >  {
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> > -	struct drm_device *dev = encoder->dev;
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
> >  	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> >  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> >  	int type = intel_encoder->type;
> > -	int hdmi_level;
> > +
> > +	intel_prepare_ddi_buffers(intel_encoder);
> >  
> >  	if (type == INTEL_OUTPUT_EDP) {
> >  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > @@ -2344,17 +2307,11 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
> >  
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> >  		intel_dp_start_link_train(intel_dp);
> > -		if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
> > +		if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
> >  			intel_dp_stop_link_train(intel_dp);
> >  	} else if (type == INTEL_OUTPUT_HDMI) {
> >  		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> >  
> > -		if (IS_BROXTON(dev)) {
> > -			hdmi_level = dev_priv->vbt.
> > -				ddi_port_info[port].hdmi_level_shift;
> > -			bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> > -						INTEL_OUTPUT_HDMI);
> > -		}
> >  		intel_hdmi->set_infoframes(encoder,
> >  					   crtc->config->has_hdmi_sink,
> >  					   &crtc->config->base.adjusted_mode);
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index f1a5404728df..bc7aaa3c431e 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -9649,8 +9649,6 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
> >  		val |= PCH_LP_PARTITION_LEVEL_DISABLE;
> >  		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
> >  	}
> > -
> > -	intel_prepare_ddi(dev);
> >  }
> >  
> >  static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state)
> > @@ -15172,7 +15170,6 @@ static void i915_disable_vga(struct drm_device *dev)
> >  void intel_modeset_init_hw(struct drm_device *dev)
> >  {
> >  	intel_update_cdclk(dev);
> > -	intel_prepare_ddi(dev);
> 
> This patch is worth it just for this hunk here and the one below in the
> skl dmc code.
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> >  	intel_init_clock_gating(dev);
> >  	intel_enable_gt_powersave(dev);
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> > index abfc171888b8..73ac68e21b7e 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> > @@ -173,6 +173,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
> >  	intel_mst->port = found->port;
> >  
> >  	if (intel_dp->active_mst_links == 0) {
> > +		intel_prepare_ddi_buffers(&intel_dig_port->base);
> > +
> >  		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
> >  
> >  		intel_dp_set_link_params(intel_dp, intel_crtc->config);
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 43d451c7c366..a8a84b8c2bac 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -996,7 +996,7 @@ void intel_crt_init(struct drm_device *dev);
> >  /* intel_ddi.c */
> >  void intel_ddi_clk_select(struct intel_encoder *encoder,
> >  			  const struct intel_crtc_state *pipe_config);
> > -void intel_prepare_ddi(struct drm_device *dev);
> > +void intel_prepare_ddi_buffers(struct intel_encoder *encoder);
> >  void hsw_fdi_link_train(struct drm_crtc *crtc);
> >  void intel_ddi_init(struct drm_device *dev, enum port port);
> >  enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
> > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > index 2c2151f1c47e..60a592d20402 100644
> > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > @@ -625,7 +625,6 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
> >  static void skl_set_power_well(struct drm_i915_private *dev_priv,
> >  			struct i915_power_well *power_well, bool enable)
> >  {
> > -	struct drm_device *dev = dev_priv->dev;
> >  	uint32_t tmp, fuse_status;
> >  	uint32_t req_mask, state_mask;
> >  	bool is_enabled, enable_requested, check_fuse_status = false;
> > @@ -669,17 +668,6 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
> >  				!I915_READ(HSW_PWR_WELL_BIOS),
> >  				"Invalid for power well status to be enabled, unless done by the BIOS, \
> >  				when request is to disable!\n");
> > -			if (power_well->data == SKL_DISP_PW_2) {
> > -				/*
> > -				 * DDI buffer programming unnecessary during
> > -				 * driver-load/resume as it's already done
> > -				 * during modeset initialization then. It's
> > -				 * also invalid here as encoder list is still
> > -				 * uninitialized.
> > -				 */
> > -				if (!dev_priv->power_domains.initializing)
> > -					intel_prepare_ddi(dev);
> > -			}
> >  			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
> >  		}
> >  
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port
  2015-12-10 13:31     ` Ville Syrjälä
@ 2015-12-10 14:08       ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 14:08 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 03:31:10PM +0200, Ville Syrjälä wrote:
> On Thu, Dec 10, 2015 at 02:22:01PM +0100, Daniel Vetter wrote:
> > On Tue, Dec 08, 2015 at 07:59:38PM +0200, ville.syrjala@linux.intel.com wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Rather than having open coded checks for the DDI A/E configuration,
> > > just store the max supported lane count in intel_digital_port.
> > > 
> > > We had an open coded check for DDI A, but not for DDI E. So we may
> > > have been vilating the DDI E max lane count.
> > > 
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Isn't this going to break on non-DDI platforms?
> 
> It always sets 'intel_dig_port->max_lanes = 4' for non-DDI encoders.

Oh dear, must have been blind. Was looking for this line specifically,
didn't find it. With that resolved:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> 
> > -Daniel
> > 
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c  | 10 +---------
> > >  drivers/gpu/drm/i915/intel_dp.c   | 13 +++++++------
> > >  drivers/gpu/drm/i915/intel_drv.h  |  1 +
> > >  drivers/gpu/drm/i915/intel_hdmi.c |  6 ++++++
> > >  4 files changed, 15 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > > index e903d9c87680..fdb4aaa084d6 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -3315,15 +3315,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> > >  		return;
> > >  	}
> > >  
> > > -	if (WARN(max_lanes == 0,
> > > -		 "No lanes for port %c\n", port_name(port)))
> > > -		return;
> > > -
> > > -	if (WARN(init_hdmi && max_lanes < 4,
> > > -		 "Not enough lanes (%d) for HDMI on port %c\n",
> > > -		 max_lanes, port_name(port)))
> > > -		init_hdmi = false;
> > > -
> > >  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
> > >  	if (!intel_dig_port)
> > >  		return;
> > > @@ -3346,6 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> > >  	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> > >  					  (DDI_BUF_PORT_REVERSAL |
> > >  					   DDI_A_4_LANES);
> > > +	intel_dig_port->max_lanes = max_lanes;
> > >  
> > >  	/*
> > >  	 * Bspec says that DDI_A_4_LANES is the only supported configuration
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > > index f335c92b4fa7..7d354b1e5e5f 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -157,14 +157,9 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
> > >  static u8 intel_dp_max_lane_count(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;
> > >  	u8 source_max, sink_max;
> > >  
> > > -	source_max = 4;
> > > -	if (HAS_DDI(dev) && intel_dig_port->port == PORT_A &&
> > > -	    (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0)
> > > -		source_max = 2;
> > > -
> > > +	source_max = intel_dig_port->max_lanes;
> > >  	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
> > >  
> > >  	return min(source_max, sink_max);
> > > @@ -5820,6 +5815,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> > >  	enum port port = intel_dig_port->port;
> > >  	int type, ret;
> > >  
> > > +	if (WARN(intel_dig_port->max_lanes < 1,
> > > +		 "Not enough lanes (%d) for DP on port %c\n",
> > > +		 intel_dig_port->max_lanes, port_name(port)))
> > > +		return false;
> > > +
> > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > >  
> > >  	/* intel_dp vfuncs */
> > > @@ -6016,6 +6016,7 @@ intel_dp_init(struct drm_device *dev,
> > >  
> > >  	intel_dig_port->port = port;
> > >  	intel_dig_port->dp.output_reg = output_reg;
> > > +	intel_dig_port->max_lanes = 4;
> > >  
> > >  	intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> > >  	if (IS_CHERRYVIEW(dev)) {
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index 8963a8a53b0b..43d451c7c366 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -818,6 +818,7 @@ struct intel_digital_port {
> > >  	struct intel_hdmi hdmi;
> > >  	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
> > >  	bool release_cl2_override;
> > > +	uint8_t max_lanes;
> > >  };
> > >  
> > >  struct intel_dp_mst_encoder {
> > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > > index c3978bad5ca0..895189abfd56 100644
> > > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > > @@ -2034,6 +2034,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> > >  	enum port port = intel_dig_port->port;
> > >  	uint8_t alternate_ddc_pin;
> > >  
> > > +	if (WARN(intel_dig_port->max_lanes < 4,
> > > +		 "Not enough lanes (%d) for HDMI on port %c\n",
> > > +		 intel_dig_port->max_lanes, port_name(port)))
> > > +		return;
> > > +
> > >  	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
> > >  			   DRM_MODE_CONNECTOR_HDMIA);
> > >  	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
> > > @@ -2217,6 +2222,7 @@ void intel_hdmi_init(struct drm_device *dev,
> > >  	intel_dig_port->port = port;
> > >  	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
> > >  	intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
> > > +	intel_dig_port->max_lanes = 4;
> > >  
> > >  	intel_hdmi_init_connector(intel_dig_port, intel_connector);
> > >  }
> > > -- 
> > > 2.4.10
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL
  2015-12-10 13:42     ` Ville Syrjälä
@ 2015-12-10 14:09       ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 14:09 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 03:42:15PM +0200, Ville Syrjälä wrote:
> On Thu, Dec 10, 2015 at 02:30:34PM +0100, Daniel Vetter wrote:
> > On Tue, Dec 08, 2015 at 07:59:43PM +0200, ville.syrjala@linux.intel.com wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Only DDI A and E support 10 translation entries in DP mode. For the
> > > other ports the tenth entry is reserved for HDMI..
> > > 
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++++
> > >  1 file changed, 9 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > > index 838cbbe33517..152c813cc43e 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -443,6 +443,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> > >  		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> > >  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> > >  			iboost_bit = 1<<31;
> > > +
> > > +		if (WARN_ON(port != PORT_A &&
> > > +			    port != PORT_E && n_edp_entries > 9))
> > > +			n_edp_entries = 9;
> > 
> > Imo WARN_ON just here is enough, set_iboost can only be hit if we pass
> > here. With that bikeshed Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> We would then access some unknown registers and memory.

Well tbh I'm not too concerning about trampling over random registers.
Generally the chip survives, so one WARN to scream at you is enough.
Personally I wouldn't even bother with the if () return.

Anyway this is bikeshed, so if you feel this is useful you can extend the
r-b to the entire patch.
-Daniel

> 
> > 
> > >  	} else if (IS_BROADWELL(dev_priv)) {
> > >  		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
> > >  		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
> > > @@ -2099,6 +2103,11 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
> > >  			iboost = dp_iboost;
> > >  		} else {
> > >  			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
> > > +
> > > +			if (WARN_ON(port != PORT_A &&
> > > +				    port != PORT_E && n_entries > 9))
> > > +				n_entries = 9;
> > > +
> > >  			iboost = ddi_translations[level].i_boost;
> > >  		}
> > >  	} else if (type == INTEL_OUTPUT_HDMI) {
> > > -- 
> > > 2.4.10
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders
  2015-12-10 13:47   ` Daniel Vetter
@ 2015-12-10 14:10     ` Ville Syrjälä
  2015-12-10 14:20       ` Daniel Vetter
  0 siblings, 1 reply; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:10 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:47:12PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:45PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Eliminate the troublesome role switching DDI encoder, and just register
> > a separate encoder for each role (DP and HDMI).
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Caveat about max_lanes and pre-DDI platforms still apply.
> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c      | 232 +++++++++++++++++++++++++---------
> >  drivers/gpu/drm/i915/intel_display.c  |  18 ---
> >  drivers/gpu/drm/i915/intel_dp.c       |  23 +---
> >  drivers/gpu/drm/i915/intel_drv.h      |   3 +-
> >  drivers/gpu/drm/i915/intel_hdmi.c     |   3 +
> >  drivers/gpu/drm/i915/intel_opregion.c |   1 -
> >  6 files changed, 180 insertions(+), 100 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 074121efb265..5f008f0fdc13 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -318,7 +318,6 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
> >  	case INTEL_OUTPUT_DISPLAYPORT:
> >  	case INTEL_OUTPUT_EDP:
> >  	case INTEL_OUTPUT_HDMI:
> > -	case INTEL_OUTPUT_UNKNOWN:
> >  		*dig_port = enc_to_dig_port(encoder);
> >  		*port = (*dig_port)->port;
> >  		break;
> > @@ -1942,19 +1941,19 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
> >  	switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> >  	case TRANS_DDI_MODE_SELECT_HDMI:
> >  	case TRANS_DDI_MODE_SELECT_DVI:
> > -		return (type == DRM_MODE_CONNECTOR_HDMIA);
> > +		return type == DRM_MODE_CONNECTOR_HDMIA;
> >  
> >  	case TRANS_DDI_MODE_SELECT_DP_SST:
> > -		if (type == DRM_MODE_CONNECTOR_eDP)
> > -			return true;
> > -		return (type == DRM_MODE_CONNECTOR_DisplayPort);
> > +		return type == DRM_MODE_CONNECTOR_DisplayPort ||
> > +			type == DRM_MODE_CONNECTOR_eDP;
> > +
> >  	case TRANS_DDI_MODE_SELECT_DP_MST:
> >  		/* if the transcoder is in MST state then
> >  		 * connector isn't connected */
> >  		return false;
> >  
> >  	case TRANS_DDI_MODE_SELECT_FDI:
> > -		return (type == DRM_MODE_CONNECTOR_VGA);
> > +		return type == DRM_MODE_CONNECTOR_VGA;
> >  
> >  	default:
> >  		return false;
> > @@ -1981,8 +1980,23 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
> >  		return false;
> >  
> >  	if (port == PORT_A) {
> > +		WARN_ON(encoder->type != INTEL_OUTPUT_EDP);
> > +
> >  		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
> >  
> > +		if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
> > +			goto out;
> > +
> > +		switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> > +		case TRANS_DDI_MODE_SELECT_DP_SST:
> > +			break;
> > +		default:
> > +			WARN(1,
> > +			     "Bad transcoder EDP DDI mode 0x%08x for port %c\n",
> > +			     tmp, port_name(port));
> > +			return false;
> > +		}
> > +
> >  		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
> >  		case TRANS_DDI_EDP_INPUT_A_ON:
> >  		case TRANS_DDI_EDP_INPUT_A_ONOFF:
> > @@ -1994,25 +2008,98 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
> >  		case TRANS_DDI_EDP_INPUT_C_ONOFF:
> >  			*pipe = PIPE_C;
> >  			break;
> > +		default:
> > +			WARN(1,
> > +			     "Bad transcoder EDP input select 0x%08x for port %c\n",
> > +			     tmp, port_name(port));
> > +			return false;
> >  		}
> >  
> >  		return true;
> >  	} else {
> > +		int num_mst_transcoders = 0;
> > +		int num_sst_transcoders = 0;
> > +		int num_fdi_transcoders = 0;
> > +		int num_hdmi_transcoders = 0;
> > +		int num_transcoders = 0;
> > +		bool enabled = false;
> > +
> >  		for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
> >  			tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
> >  
> > -			if ((tmp & TRANS_DDI_PORT_MASK)
> > -			    == TRANS_DDI_SELECT_PORT(port)) {
> > -				if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
> > -					return false;
> > +			if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
> > +				continue;
> > +
> > +			if ((tmp & TRANS_DDI_PORT_MASK) != TRANS_DDI_SELECT_PORT(port))
> > +				continue;
> > +
> > +			if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST) {
> > +				num_mst_transcoders++;
> > +				WARN_ON(port == PORT_E);
> > +				continue;
> > +			}
> > +
> > +
> > +			switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> > +			case TRANS_DDI_MODE_SELECT_DP_SST:
> > +				WARN_ON(port == PORT_E && INTEL_INFO(dev_priv)->gen < 9);
> > +
> > +				num_sst_transcoders++;
> > +				if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
> > +				    encoder->type == INTEL_OUTPUT_EDP) {
> > +					enabled = true;
> > +					*pipe = i;
> > +				}
> > +				break;
> > +			case TRANS_DDI_MODE_SELECT_HDMI:
> > +			case TRANS_DDI_MODE_SELECT_DVI:
> > +				WARN_ON(port == PORT_E);
> 
> Hm, previous patches made it look like hdmi on port E is possible - at
> least you added piles of checks to make sure we have at least 4 lanes
> everywhere. Am I mistaken?

DDI E can only have two lanes at most. So it can't do HDMI. Actually
it's documented that it can only do FDI (or SST on SKL+). Now that I
think about it, I'm not sure an external DP port with < 4 lanes is
even legal, so perhaps in practice it can only be eDP or FDI?

> 
> > +
> > +				num_hdmi_transcoders++;
> > +				if (encoder->type == INTEL_OUTPUT_HDMI) {
> > +					enabled = true;
> > +					*pipe = i;
> > +				}
> > +				break;
> > +
> > +			case TRANS_DDI_MODE_SELECT_FDI:
> > +				WARN_ON(port != PORT_E || INTEL_INFO(dev_priv)->gen >= 9);
> > +
> > +				num_fdi_transcoders++;
> > +				if (encoder->type == INTEL_OUTPUT_ANALOG) {
> > +					enabled = true;
> > +					*pipe = i;
> > +				}
> > +				break;
> >  
> > -				*pipe = i;
> > -				return true;
> > +			default:
> > +				WARN(1, "Bad transcoder %c DDI mode 0x%08x for port %c\n",
> > +				     transcoder_name(i), tmp, port_name(port));
> > +				return false;
> >  			}
> >  		}
> > +
> > +		num_transcoders = num_sst_transcoders +
> > +			num_fdi_transcoders + num_hdmi_transcoders;
> > +
> > +		if (WARN(num_transcoders && num_mst_transcoders,
> > +			 "MST and non-MST transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
> > +			 port_name(port), num_sst_transcoders, num_mst_transcoders,
> > +			 num_fdi_transcoders, num_hdmi_transcoders))
> > +			return false;
> > +
> > +		if (WARN(num_transcoders > 1,
> > +			 "Multiple transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
> > +			 port_name(port), num_sst_transcoders, num_mst_transcoders,
> > +			 num_fdi_transcoders, num_hdmi_transcoders))
> > +			return false;
> > +
> > +		if (enabled)
> > +			return true;
> 
> This is too big and needs to be extracted into a static function.
> 
> Otherwise I didn't spot anything, and getting rid of OUTPUT_UNKNOWN is
> really nice. I also wonder whether we should long term rework mst to use
> the fake encoder as the real one. The fake encoder was just done to not
> confuse the ddi encoder, but now that we have multiples of those we might
> as well embrace that everywhere.

Hmm. One idea for MST I've had is that we'd pull out the main link
management from the mst code, and instead use atomic to set up the main
link as just another crtc (would need a fake crtc for that), and then
the streams would just deal with their fake encoders and not mess about
with the main encoder at all. But sounds like you've had pretty much the
opposite idea.

> 
> Cheers, Daniel
> 
> >  	}
> >  
> > -	DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
> > +out:
> > +	DRM_DEBUG_KMS("No pipe for DDI port %c found\n", port_name(port));
> >  
> >  	return false;
> >  }
> > @@ -3174,8 +3261,6 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> >  	int type = encoder->type;
> >  	int port = intel_ddi_get_encoder_port(encoder);
> >  
> > -	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
> > -
> >  	if (port == PORT_A)
> >  		pipe_config->cpu_transcoder = TRANSCODER_EDP;
> >  
> > @@ -3224,53 +3309,18 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
> >  	return connector;
> >  }
> >  
> > -void intel_ddi_init(struct drm_device *dev, enum port port)
> > +static int intel_ddi_init_role(struct drm_device *dev, enum port port,
> > +			       int encoder_type, uint32_t saved_port_bits,
> > +			       int max_lanes)
> >  {
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct drm_i915_private *dev_priv = to_i915(dev);
> >  	struct intel_digital_port *intel_dig_port;
> >  	struct intel_encoder *intel_encoder;
> >  	struct drm_encoder *encoder;
> > -	bool init_hdmi, init_dp;
> > -	int max_lanes;
> > -
> > -	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> > -		switch (port) {
> > -		case PORT_A:
> > -			max_lanes = 4;
> > -			break;
> > -		case PORT_E:
> > -			max_lanes = 0;
> > -			break;
> > -		default:
> > -			max_lanes = 4;
> > -			break;
> > -		}
> > -	} else {
> > -		switch (port) {
> > -		case PORT_A:
> > -			max_lanes = 2;
> > -			break;
> > -		case PORT_E:
> > -			max_lanes = 2;
> > -			break;
> > -		default:
> > -			max_lanes = 4;
> > -			break;
> > -		}
> > -	}
> > -
> > -	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
> > -		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> > -	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
> > -	if (!init_dp && !init_hdmi) {
> > -		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
> > -			      port_name(port));
> > -		return;
> > -	}
> >  
> >  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
> >  	if (!intel_dig_port)
> > -		return;
> > +		return -ENOMEM;
> >  
> >  	intel_encoder = &intel_dig_port->base;
> >  	encoder = &intel_encoder->base;
> > @@ -3287,9 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> >  	intel_encoder->get_config = intel_ddi_get_config;
> >  
> >  	intel_dig_port->port = port;
> > -	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> > -					  (DDI_BUF_PORT_REVERSAL |
> > -					   DDI_A_4_LANES);
> > +	intel_dig_port->saved_port_bits = saved_port_bits;
> >  	intel_dig_port->max_lanes = max_lanes;
> >  
> >  	/*
> > @@ -3306,11 +3354,11 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> >  		}
> >  	}
> >  
> > -	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
> > +	intel_encoder->type = encoder_type;
> >  	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
> >  	intel_encoder->cloneable = 0;
> >  
> > -	if (init_dp) {
> > +	if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> >  		if (!intel_ddi_init_dp_connector(intel_dig_port))
> >  			goto err;
> >  
> > @@ -3327,14 +3375,74 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> >  
> >  	/* In theory we don't need the encoder->type check, but leave it just in
> >  	 * case we have some really bad VBTs... */
> > -	if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
> > +	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
> >  		if (!intel_ddi_init_hdmi_connector(intel_dig_port))
> >  			goto err;
> >  	}
> >  
> > -	return;
> > +	return intel_encoder->type;
> >  
> >  err:
> >  	drm_encoder_cleanup(encoder);
> >  	kfree(intel_dig_port);
> > +
> > +	return -ENODEV;
> > +}
> > +
> > +void intel_ddi_init(struct drm_device *dev, enum port port)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(dev);
> > +	uint32_t saved_port_bits;
> > +	bool init_hdmi, init_dp;
> > +	int max_lanes;
> > +
> > +	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> > +		switch (port) {
> > +		case PORT_A:
> > +			max_lanes = 4;
> > +			break;
> > +		case PORT_E:
> > +			max_lanes = 0;
> > +			break;
> > +		default:
> > +			max_lanes = 4;
> > +			break;
> > +		}
> > +	} else {
> > +		switch (port) {
> > +		case PORT_A:
> > +			max_lanes = 2;
> > +			break;
> > +		case PORT_E:
> > +			max_lanes = 2;
> > +			break;
> > +		default:
> > +			max_lanes = 4;
> > +			break;
> > +		}
> > +	}
> > +
> > +	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
> > +		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> > +	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
> > +	if (!init_dp && !init_hdmi) {
> > +		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
> > +			      port_name(port));
> > +		return;
> > +	}
> > +
> > +	saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> > +		(DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES);
> > +
> > +	if (init_dp) {
> > +		int ret = intel_ddi_init_role(dev, port, INTEL_OUTPUT_DISPLAYPORT,
> > +					      saved_port_bits, max_lanes);
> > +		/* Don't register the HDMI connector/encoder when we have eDP */
> > +		if (ret == INTEL_OUTPUT_EDP)
> > +			init_hdmi = false;
> > +	}
> > +
> > +	if (init_hdmi)
> > +		intel_ddi_init_role(dev, port, INTEL_OUTPUT_HDMI,
> > +				    saved_port_bits, max_lanes);
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index bc7aaa3c431e..fc1d7387eb12 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -5252,13 +5252,9 @@ static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
> >  enum intel_display_power_domain
> >  intel_display_port_power_domain(struct intel_encoder *intel_encoder)
> >  {
> > -	struct drm_device *dev = intel_encoder->base.dev;
> >  	struct intel_digital_port *intel_dig_port;
> >  
> >  	switch (intel_encoder->type) {
> > -	case INTEL_OUTPUT_UNKNOWN:
> > -		/* Only DDI platforms should ever use this output type */
> > -		WARN_ON_ONCE(!HAS_DDI(dev));
> >  	case INTEL_OUTPUT_DISPLAYPORT:
> >  	case INTEL_OUTPUT_HDMI:
> >  	case INTEL_OUTPUT_EDP:
> > @@ -5279,20 +5275,9 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
> >  enum intel_display_power_domain
> >  intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
> >  {
> > -	struct drm_device *dev = intel_encoder->base.dev;
> >  	struct intel_digital_port *intel_dig_port;
> >  
> >  	switch (intel_encoder->type) {
> > -	case INTEL_OUTPUT_UNKNOWN:
> > -	case INTEL_OUTPUT_HDMI:
> > -		/*
> > -		 * Only DDI platforms should ever use these output types.
> > -		 * We can get here after the HDMI detect code has already set
> > -		 * the type of the shared encoder. Since we can't be sure
> > -		 * what's the status of the given connectors, play safe and
> > -		 * run the DP detection too.
> > -		 */
> > -		WARN_ON_ONCE(!HAS_DDI(dev));
> >  	case INTEL_OUTPUT_DISPLAYPORT:
> >  	case INTEL_OUTPUT_EDP:
> >  		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
> > @@ -12283,9 +12268,6 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
> >  
> >  		switch (encoder->type) {
> >  			unsigned int port_mask;
> > -		case INTEL_OUTPUT_UNKNOWN:
> > -			if (WARN_ON(!HAS_DDI(dev)))
> > -				break;
> >  		case INTEL_OUTPUT_DISPLAYPORT:
> >  		case INTEL_OUTPUT_HDMI:
> >  		case INTEL_OUTPUT_EDP:
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 7d354b1e5e5f..1d31aa296aaa 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -4601,8 +4601,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> >  
> >  	if (intel_dp->is_mst) {
> >  		/* MST devices are disconnected from a monitor POV */
> > -		if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > -			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> >  		return connector_status_disconnected;
> >  	}
> >  
> > @@ -4632,8 +4630,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> >  	if (ret) {
> >  		/* if we are in MST mode then this connector
> >  		   won't appear connected or have anything with EDID on it */
> > -		if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > -			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> >  		status = connector_status_disconnected;
> >  		goto out;
> >  	}
> > @@ -4648,8 +4644,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> >  
> >  	intel_dp_set_edid(intel_dp);
> >  
> > -	if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > -		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> >  	status = connector_status_connected;
> >  
> >  	/* Try to read the source of the interrupt */
> > @@ -4692,9 +4686,6 @@ intel_dp_force(struct drm_connector *connector)
> >  	intel_dp_set_edid(intel_dp);
> >  
> >  	intel_display_power_put(dev_priv, power_domain);
> > -
> > -	if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > -		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> >  }
> >  
> >  static int intel_dp_get_modes(struct drm_connector *connector)
> > @@ -4969,9 +4960,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
> >  	enum intel_display_power_domain power_domain;
> >  	enum irqreturn ret = IRQ_NONE;
> >  
> > -	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
> > -	    intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
> > -		intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
> > +	if (WARN_ON_ONCE(intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
> > +			 intel_dig_port->base.type != INTEL_OUTPUT_DISPLAYPORT))
> > +		return IRQ_HANDLED;
> >  
> >  	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
> >  		/*
> > @@ -5815,6 +5806,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> >  	enum port port = intel_dig_port->port;
> >  	int type, ret;
> >  
> > +	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT))
> > +		return false;
> > +
> >  	if (WARN(intel_dig_port->max_lanes < 1,
> >  		 "Not enough lanes (%d) for DP on port %c\n",
> >  		 intel_dig_port->max_lanes, port_name(port)))
> > @@ -5851,11 +5845,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> >  	else
> >  		type = DRM_MODE_CONNECTOR_DisplayPort;
> >  
> > -	/*
> > -	 * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
> > -	 * for DP the encoder type can be set by the caller to
> > -	 * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it.
> > -	 */
> >  	if (type == DRM_MODE_CONNECTOR_eDP)
> >  		intel_encoder->type = INTEL_OUTPUT_EDP;
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index a8a84b8c2bac..9e5db3d71e12 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -103,8 +103,7 @@ enum intel_output_type {
> >  	INTEL_OUTPUT_DISPLAYPORT = 7,
> >  	INTEL_OUTPUT_EDP = 8,
> >  	INTEL_OUTPUT_DSI = 9,
> > -	INTEL_OUTPUT_UNKNOWN = 10,
> > -	INTEL_OUTPUT_DP_MST = 11,
> > +	INTEL_OUTPUT_DP_MST = 10,
> >  };
> >  
> >  #define INTEL_DVO_CHIP_NONE 0
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 895189abfd56..75ea9515a9ce 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -2034,6 +2034,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> >  	enum port port = intel_dig_port->port;
> >  	uint8_t alternate_ddc_pin;
> >  
> > +	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_HDMI))
> > +		return;
> > +
> >  	if (WARN(intel_dig_port->max_lanes < 4,
> >  		 "Not enough lanes (%d) for HDMI on port %c\n",
> >  		 intel_dig_port->max_lanes, port_name(port)))
> > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> > index e362a30776fa..a15459a451c2 100644
> > --- a/drivers/gpu/drm/i915/intel_opregion.c
> > +++ b/drivers/gpu/drm/i915/intel_opregion.c
> > @@ -360,7 +360,6 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
> >  	case INTEL_OUTPUT_ANALOG:
> >  		type = DISPLAY_TYPE_CRT;
> >  		break;
> > -	case INTEL_OUTPUT_UNKNOWN:
> >  	case INTEL_OUTPUT_DISPLAYPORT:
> >  	case INTEL_OUTPUT_HDMI:
> >  	case INTEL_OUTPUT_DP_MST:
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart
  2015-12-10 13:52   ` Daniel Vetter
@ 2015-12-10 14:15     ` Ville Syrjälä
  0 siblings, 0 replies; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:15 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:52:29PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:47PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > DDI buffer prorgramming works quite differently depending on
> > the mode of the DDI port (DP/eDP/FDI vs. HDMI/DVI). Let's split
> > the function that does the programming into two matching variants
> > as well.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c    | 94 ++++++++++++++++++++++---------------
> >  drivers/gpu/drm/i915/intel_dp_mst.c |  4 +-
> >  drivers/gpu/drm/i915/intel_drv.h    |  2 +-
> >  3 files changed, 60 insertions(+), 40 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index f812607045d6..c47f45c0f4a2 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -397,37 +397,22 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
> >  
> >  /*
> >   * Starting with Haswell, DDI port buffers must be programmed with correct
> > - * values in advance. The buffer values are different for FDI and DP modes,
> > - * but the HDMI/DVI fields are shared among those. So we program the DDI
> > - * in either FDI or DP modes only, as HDMI connections will work with both
> > - * of those
> > + * values in advance. This function programs the correct values for
> > + * DP/eDP/FDI use cases.
> >   */
> > -void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> > +void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >  	u32 iboost_bit = 0;
> > -	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
> > -	    size;
> > -	int hdmi_level;
> > -	enum port port;
> > +	int i, n_dp_entries, n_edp_entries, size;
> > +	enum port port = intel_ddi_get_encoder_port(encoder);
> >  	const struct ddi_buf_trans *ddi_translations_fdi;
> >  	const struct ddi_buf_trans *ddi_translations_dp;
> >  	const struct ddi_buf_trans *ddi_translations_edp;
> > -	const struct ddi_buf_trans *ddi_translations_hdmi;
> >  	const struct ddi_buf_trans *ddi_translations;
> >  
> > -	port = intel_ddi_get_encoder_port(encoder);
> > -	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> > -
> > -	if (IS_BROXTON(dev_priv)) {
> > -		if (encoder->type != INTEL_OUTPUT_HDMI)
> > -			return;
> > -
> > -		/* Vswing programming for HDMI */
> > -		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> > -					INTEL_OUTPUT_HDMI);
> > +	if (IS_BROXTON(dev_priv))
> >  		return;
> > -	}
> >  
> >  	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> >  		ddi_translations_fdi = NULL;
> > @@ -435,9 +420,6 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> >  				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
> >  		ddi_translations_edp =
> >  				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
> > -		ddi_translations_hdmi =
> > -				skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
> > -		hdmi_default_entry = 8;
> >  		/* If we're boosting the current, set bit 31 of trans1 */
> >  		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> >  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> > @@ -454,11 +436,8 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> >  		ddi_translations_fdi = bdw_ddi_translations_fdi;
> >  		ddi_translations_dp = bdw_ddi_translations_dp;
> >  		ddi_translations_edp = bdw_ddi_translations_edp;
> > -		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> >  		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
> >  		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
> > -		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> > -		hdmi_default_entry = 7;
> >  	} else if (IS_HASWELL(dev_priv)) {
> >  		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_fdi) != 9);
> >  		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_dp) != 9);
> > @@ -466,20 +445,14 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> >  		ddi_translations_fdi = hsw_ddi_translations_fdi;
> >  		ddi_translations_dp = hsw_ddi_translations_dp;
> >  		ddi_translations_edp = hsw_ddi_translations_dp;
> > -		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
> >  		n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
> > -		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
> > -		hdmi_default_entry = 6;
> >  	} else {
> >  		WARN(1, "ddi translation table missing\n");
> >  		ddi_translations_edp = bdw_ddi_translations_dp;
> >  		ddi_translations_fdi = bdw_ddi_translations_fdi;
> >  		ddi_translations_dp = bdw_ddi_translations_dp;
> > -		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> >  		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
> >  		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
> > -		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> > -		hdmi_default_entry = 7;
> >  	}
> >  
> >  	switch (encoder->type) {
> > @@ -488,7 +461,6 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> >  		size = n_edp_entries;
> >  		break;
> >  	case INTEL_OUTPUT_DISPLAYPORT:
> > -	case INTEL_OUTPUT_HDMI:
> >  		ddi_translations = ddi_translations_dp;
> >  		size = n_dp_entries;
> >  		break;
> > @@ -506,10 +478,54 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> >  		I915_WRITE(DDI_BUF_TRANS_HI(port, i),
> >  			   ddi_translations[i].trans2);
> >  	}
> > +}
> > +
> > +/*
> > + * Starting with Haswell, DDI port buffers must be programmed with correct
> > + * values in advance. This function programs the correct values for
> > + * HDMI/DVI use cases.
> > + */
> > +static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +	u32 iboost_bit = 0;
> > +	int n_hdmi_entries, hdmi_default_entry, hdmi_level;
> > +	enum port port = intel_ddi_get_encoder_port(encoder);
> > +	const struct ddi_buf_trans *ddi_translations_hdmi;
> >  
> >  	if (encoder->type != INTEL_OUTPUT_HDMI)
> 
> WARN_ON?

Yeah, or just drop it entirely. Doesn't seem very likely that anyone
would mess this up since it's called from one place only.

> 
> >  		return;
> >  
> > +	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
> > +
> > +	if (IS_BROXTON(dev_priv)) {
> > +		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
> > +					INTEL_OUTPUT_HDMI);
> > +		return;
> > +	}
> > +
> > +	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> > +		ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
> > +		hdmi_default_entry = 8;
> > +		/* If we're boosting the current, set bit 31 of trans1 */
> > +		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> > +		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> > +			iboost_bit = 1<<31;
> > +	} else if (IS_BROADWELL(dev_priv)) {
> > +		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> > +		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> > +		hdmi_default_entry = 7;
> > +	} else if (IS_HASWELL(dev_priv)) {
> > +		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
> > +		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
> > +		hdmi_default_entry = 6;
> > +	} else {
> > +		WARN(1, "ddi translation table missing\n");
> > +		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> > +		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> > +		hdmi_default_entry = 7;
> > +	}
> > +
> >  	/* Choose a good default if VBT is badly populated */
> >  	if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
> >  	    hdmi_level >= n_hdmi_entries)
> > @@ -555,7 +571,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
> >  
> >  	for_each_encoder_on_crtc(dev, crtc, encoder) {
> >  		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
> > -		intel_prepare_ddi_buffers(encoder);
> > +		intel_prepare_dp_ddi_buffers(encoder);
> >  	}
> >  
> >  	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
> > @@ -2376,8 +2392,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
> >  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> >  	int type = intel_encoder->type;
> >  
> > -	intel_prepare_ddi_buffers(intel_encoder);
> > -
> >  	if (type == INTEL_OUTPUT_EDP) {
> >  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> >  		intel_edp_panel_on(intel_dp);
> > @@ -2388,6 +2402,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
> >  	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
> >  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> >  
> > +		intel_prepare_dp_ddi_buffers(intel_encoder);
> > +
> >  		intel_dp_set_link_params(intel_dp, crtc->config);
> >  
> >  		intel_ddi_init_dp_buf_reg(intel_encoder);
> > @@ -2399,9 +2415,13 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
> >  	} else if (type == INTEL_OUTPUT_HDMI) {
> >  		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> >  
> > +		intel_prepare_hdmi_ddi_buffers(intel_encoder);
> > +
> >  		intel_hdmi->set_infoframes(encoder,
> >  					   crtc->config->has_hdmi_sink,
> >  					   &crtc->config->base.adjusted_mode);
> > +	} else if (type == INTEL_OUTPUT_ANALOG) {
> > +		intel_prepare_dp_ddi_buffers(intel_encoder);
> 
> Hm, I was hoping with an encoder split that we could use the vfunc hooks
> instead of these massive if ladders everywhere ... too much trouble still?

I didn't really think about that TBH. But sounds like a decent idea for
a followup patch.

> 
> Anyway, besides the WARN_ON request the patch looks correct, so with that
> addressed Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >  	}
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> > index 73ac68e21b7e..d8e9b28bb2e0 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> > @@ -173,10 +173,10 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
> >  	intel_mst->port = found->port;
> >  
> >  	if (intel_dp->active_mst_links == 0) {
> > -		intel_prepare_ddi_buffers(&intel_dig_port->base);
> > -
> >  		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
> >  
> > +		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
> > +
> >  		intel_dp_set_link_params(intel_dp, intel_crtc->config);
> >  
> >  		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 9e5db3d71e12..f7ee4bc39b33 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -995,7 +995,7 @@ void intel_crt_init(struct drm_device *dev);
> >  /* intel_ddi.c */
> >  void intel_ddi_clk_select(struct intel_encoder *encoder,
> >  			  const struct intel_crtc_state *pipe_config);
> > -void intel_prepare_ddi_buffers(struct intel_encoder *encoder);
> > +void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder);
> >  void hsw_fdi_link_train(struct drm_crtc *crtc);
> >  void intel_ddi_init(struct drm_device *dev, enum port port);
> >  enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/15] drm/i915: Get the iboost setting based on the port type
  2015-12-10 13:55   ` Daniel Vetter
@ 2015-12-10 14:17     ` Ville Syrjälä
  0 siblings, 0 replies; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:17 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:55:41PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:49PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Program the 'iboost_bit' based on what the VBT says it should be for
> > the specific port type, rather than assume it's alwasy the same
> > for DP and HDMI.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> I guess we don't have any indication that vbt would set this differently
> depending upon port?

No idea. I guess it would be a bit weird to have a DP++ port and drive
it differently for DP and HDMI.

> 
> Anyway makes sense, and if it breaks something we'll know.
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 6 ++----
> >  1 file changed, 2 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 8d8f346a9615..f4f5c52a116c 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -421,8 +421,7 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder)
> >  		ddi_translations_edp =
> >  				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
> >  		/* If we're boosting the current, set bit 31 of trans1 */
> > -		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> > -		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> > +		if (dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> >  			iboost_bit = 1<<31;
> >  
> >  		if (WARN_ON(port != PORT_A &&
> > @@ -508,8 +507,7 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder)
> >  		ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
> >  		hdmi_default_entry = 8;
> >  		/* If we're boosting the current, set bit 31 of trans1 */
> > -		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
> > -		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> > +		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level)
> >  			iboost_bit = 1<<31;
> >  	} else if (IS_BROADWELL(dev_priv)) {
> >  		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port()
  2015-12-10 13:57   ` Daniel Vetter
@ 2015-12-10 14:19     ` Ville Syrjälä
  0 siblings, 0 replies; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:19 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:57:09PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:50PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > We no longer have any need to look up the intel_digital_port based
> > on the passed in intel_encoder, but we still want to look up the port.
> > Let's just move that logic into intel_ddi_get_encoder_port() and drop
> > the dig_port stuff.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> I wonder whether we shouldn't just add intel_encoder->port somewhere.

Maybe. We do have a port in sdvo now too, there's one in DSI, and I was
tempted to add it for DVO when doing the encoder->name stuff.

> 
> Anyway Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 34 +++++++---------------------------
> >  1 file changed, 7 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index f4f5c52a116c..b4c3aad2d817 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -304,43 +304,23 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
> >  static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
> >  				    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)
> > +enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder)
> >  {
> > -	struct drm_encoder *encoder = &intel_encoder->base;
> > -
> > -	switch (intel_encoder->type) {
> > +	switch (encoder->type) {
> >  	case INTEL_OUTPUT_DP_MST:
> > -		*dig_port = enc_to_mst(encoder)->primary;
> > -		*port = (*dig_port)->port;
> > -		break;
> > +		return enc_to_mst(&encoder->base)->primary->port;
> >  	case INTEL_OUTPUT_DISPLAYPORT:
> >  	case INTEL_OUTPUT_EDP:
> >  	case INTEL_OUTPUT_HDMI:
> > -		*dig_port = enc_to_dig_port(encoder);
> > -		*port = (*dig_port)->port;
> > -		break;
> > +		return enc_to_dig_port(&encoder->base)->port;
> >  	case INTEL_OUTPUT_ANALOG:
> > -		*dig_port = NULL;
> > -		*port = PORT_E;
> > -		break;
> > +		return PORT_E;
> >  	default:
> > -		WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
> > -		break;
> > +		MISSING_CASE(encoder->type);
> > +		return PORT_A;
> >  	}
> >  }
> >  
> > -enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
> > -{
> > -	struct intel_digital_port *dig_port;
> > -	enum port port;
> > -
> > -	ddi_get_encoder_port(intel_encoder, &dig_port, &port);
> > -
> > -	return port;
> > -}
> > -
> >  static const struct ddi_buf_trans *
> >  skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
> >  {
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders
  2015-12-10 14:10     ` Ville Syrjälä
@ 2015-12-10 14:20       ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-10 14:20 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 04:10:34PM +0200, Ville Syrjälä wrote:
> On Thu, Dec 10, 2015 at 02:47:12PM +0100, Daniel Vetter wrote:
> > On Tue, Dec 08, 2015 at 07:59:45PM +0200, ville.syrjala@linux.intel.com wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Eliminate the troublesome role switching DDI encoder, and just register
> > > a separate encoder for each role (DP and HDMI).
> > > 
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Caveat about max_lanes and pre-DDI platforms still apply.

Caveats been resolved, including my question about port E.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> > 
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c      | 232 +++++++++++++++++++++++++---------
> > >  drivers/gpu/drm/i915/intel_display.c  |  18 ---
> > >  drivers/gpu/drm/i915/intel_dp.c       |  23 +---
> > >  drivers/gpu/drm/i915/intel_drv.h      |   3 +-
> > >  drivers/gpu/drm/i915/intel_hdmi.c     |   3 +
> > >  drivers/gpu/drm/i915/intel_opregion.c |   1 -
> > >  6 files changed, 180 insertions(+), 100 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > > index 074121efb265..5f008f0fdc13 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -318,7 +318,6 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
> > >  	case INTEL_OUTPUT_DISPLAYPORT:
> > >  	case INTEL_OUTPUT_EDP:
> > >  	case INTEL_OUTPUT_HDMI:
> > > -	case INTEL_OUTPUT_UNKNOWN:
> > >  		*dig_port = enc_to_dig_port(encoder);
> > >  		*port = (*dig_port)->port;
> > >  		break;
> > > @@ -1942,19 +1941,19 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
> > >  	switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> > >  	case TRANS_DDI_MODE_SELECT_HDMI:
> > >  	case TRANS_DDI_MODE_SELECT_DVI:
> > > -		return (type == DRM_MODE_CONNECTOR_HDMIA);
> > > +		return type == DRM_MODE_CONNECTOR_HDMIA;
> > >  
> > >  	case TRANS_DDI_MODE_SELECT_DP_SST:
> > > -		if (type == DRM_MODE_CONNECTOR_eDP)
> > > -			return true;
> > > -		return (type == DRM_MODE_CONNECTOR_DisplayPort);
> > > +		return type == DRM_MODE_CONNECTOR_DisplayPort ||
> > > +			type == DRM_MODE_CONNECTOR_eDP;
> > > +
> > >  	case TRANS_DDI_MODE_SELECT_DP_MST:
> > >  		/* if the transcoder is in MST state then
> > >  		 * connector isn't connected */
> > >  		return false;
> > >  
> > >  	case TRANS_DDI_MODE_SELECT_FDI:
> > > -		return (type == DRM_MODE_CONNECTOR_VGA);
> > > +		return type == DRM_MODE_CONNECTOR_VGA;
> > >  
> > >  	default:
> > >  		return false;
> > > @@ -1981,8 +1980,23 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
> > >  		return false;
> > >  
> > >  	if (port == PORT_A) {
> > > +		WARN_ON(encoder->type != INTEL_OUTPUT_EDP);
> > > +
> > >  		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
> > >  
> > > +		if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
> > > +			goto out;
> > > +
> > > +		switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> > > +		case TRANS_DDI_MODE_SELECT_DP_SST:
> > > +			break;
> > > +		default:
> > > +			WARN(1,
> > > +			     "Bad transcoder EDP DDI mode 0x%08x for port %c\n",
> > > +			     tmp, port_name(port));
> > > +			return false;
> > > +		}
> > > +
> > >  		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
> > >  		case TRANS_DDI_EDP_INPUT_A_ON:
> > >  		case TRANS_DDI_EDP_INPUT_A_ONOFF:
> > > @@ -1994,25 +2008,98 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
> > >  		case TRANS_DDI_EDP_INPUT_C_ONOFF:
> > >  			*pipe = PIPE_C;
> > >  			break;
> > > +		default:
> > > +			WARN(1,
> > > +			     "Bad transcoder EDP input select 0x%08x for port %c\n",
> > > +			     tmp, port_name(port));
> > > +			return false;
> > >  		}
> > >  
> > >  		return true;
> > >  	} else {
> > > +		int num_mst_transcoders = 0;
> > > +		int num_sst_transcoders = 0;
> > > +		int num_fdi_transcoders = 0;
> > > +		int num_hdmi_transcoders = 0;
> > > +		int num_transcoders = 0;
> > > +		bool enabled = false;
> > > +
> > >  		for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
> > >  			tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
> > >  
> > > -			if ((tmp & TRANS_DDI_PORT_MASK)
> > > -			    == TRANS_DDI_SELECT_PORT(port)) {
> > > -				if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
> > > -					return false;
> > > +			if ((tmp & TRANS_DDI_FUNC_ENABLE) == 0)
> > > +				continue;
> > > +
> > > +			if ((tmp & TRANS_DDI_PORT_MASK) != TRANS_DDI_SELECT_PORT(port))
> > > +				continue;
> > > +
> > > +			if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST) {
> > > +				num_mst_transcoders++;
> > > +				WARN_ON(port == PORT_E);
> > > +				continue;
> > > +			}
> > > +
> > > +
> > > +			switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> > > +			case TRANS_DDI_MODE_SELECT_DP_SST:
> > > +				WARN_ON(port == PORT_E && INTEL_INFO(dev_priv)->gen < 9);
> > > +
> > > +				num_sst_transcoders++;
> > > +				if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
> > > +				    encoder->type == INTEL_OUTPUT_EDP) {
> > > +					enabled = true;
> > > +					*pipe = i;
> > > +				}
> > > +				break;
> > > +			case TRANS_DDI_MODE_SELECT_HDMI:
> > > +			case TRANS_DDI_MODE_SELECT_DVI:
> > > +				WARN_ON(port == PORT_E);
> > 
> > Hm, previous patches made it look like hdmi on port E is possible - at
> > least you added piles of checks to make sure we have at least 4 lanes
> > everywhere. Am I mistaken?
> 
> DDI E can only have two lanes at most. So it can't do HDMI. Actually
> it's documented that it can only do FDI (or SST on SKL+). Now that I
> think about it, I'm not sure an external DP port with < 4 lanes is
> even legal, so perhaps in practice it can only be eDP or FDI?
> 
> > 
> > > +
> > > +				num_hdmi_transcoders++;
> > > +				if (encoder->type == INTEL_OUTPUT_HDMI) {
> > > +					enabled = true;
> > > +					*pipe = i;
> > > +				}
> > > +				break;
> > > +
> > > +			case TRANS_DDI_MODE_SELECT_FDI:
> > > +				WARN_ON(port != PORT_E || INTEL_INFO(dev_priv)->gen >= 9);
> > > +
> > > +				num_fdi_transcoders++;
> > > +				if (encoder->type == INTEL_OUTPUT_ANALOG) {
> > > +					enabled = true;
> > > +					*pipe = i;
> > > +				}
> > > +				break;
> > >  
> > > -				*pipe = i;
> > > -				return true;
> > > +			default:
> > > +				WARN(1, "Bad transcoder %c DDI mode 0x%08x for port %c\n",
> > > +				     transcoder_name(i), tmp, port_name(port));
> > > +				return false;
> > >  			}
> > >  		}
> > > +
> > > +		num_transcoders = num_sst_transcoders +
> > > +			num_fdi_transcoders + num_hdmi_transcoders;
> > > +
> > > +		if (WARN(num_transcoders && num_mst_transcoders,
> > > +			 "MST and non-MST transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
> > > +			 port_name(port), num_sst_transcoders, num_mst_transcoders,
> > > +			 num_fdi_transcoders, num_hdmi_transcoders))
> > > +			return false;
> > > +
> > > +		if (WARN(num_transcoders > 1,
> > > +			 "Multiple transcoders enabled for port %c (%d sst, %d mst, %d fdi, %d hdmi)\n",
> > > +			 port_name(port), num_sst_transcoders, num_mst_transcoders,
> > > +			 num_fdi_transcoders, num_hdmi_transcoders))
> > > +			return false;
> > > +
> > > +		if (enabled)
> > > +			return true;
> > 
> > This is too big and needs to be extracted into a static function.
> > 
> > Otherwise I didn't spot anything, and getting rid of OUTPUT_UNKNOWN is
> > really nice. I also wonder whether we should long term rework mst to use
> > the fake encoder as the real one. The fake encoder was just done to not
> > confuse the ddi encoder, but now that we have multiples of those we might
> > as well embrace that everywhere.
> 
> Hmm. One idea for MST I've had is that we'd pull out the main link
> management from the mst code, and instead use atomic to set up the main
> link as just another crtc (would need a fake crtc for that), and then
> the streams would just deal with their fake encoders and not mess about
> with the main encoder at all. But sounds like you've had pretty much the
> opposite idea.
> 
> > 
> > Cheers, Daniel
> > 
> > >  	}
> > >  
> > > -	DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
> > > +out:
> > > +	DRM_DEBUG_KMS("No pipe for DDI port %c found\n", port_name(port));
> > >  
> > >  	return false;
> > >  }
> > > @@ -3174,8 +3261,6 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> > >  	int type = encoder->type;
> > >  	int port = intel_ddi_get_encoder_port(encoder);
> > >  
> > > -	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
> > > -
> > >  	if (port == PORT_A)
> > >  		pipe_config->cpu_transcoder = TRANSCODER_EDP;
> > >  
> > > @@ -3224,53 +3309,18 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
> > >  	return connector;
> > >  }
> > >  
> > > -void intel_ddi_init(struct drm_device *dev, enum port port)
> > > +static int intel_ddi_init_role(struct drm_device *dev, enum port port,
> > > +			       int encoder_type, uint32_t saved_port_bits,
> > > +			       int max_lanes)
> > >  {
> > > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > > +	struct drm_i915_private *dev_priv = to_i915(dev);
> > >  	struct intel_digital_port *intel_dig_port;
> > >  	struct intel_encoder *intel_encoder;
> > >  	struct drm_encoder *encoder;
> > > -	bool init_hdmi, init_dp;
> > > -	int max_lanes;
> > > -
> > > -	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> > > -		switch (port) {
> > > -		case PORT_A:
> > > -			max_lanes = 4;
> > > -			break;
> > > -		case PORT_E:
> > > -			max_lanes = 0;
> > > -			break;
> > > -		default:
> > > -			max_lanes = 4;
> > > -			break;
> > > -		}
> > > -	} else {
> > > -		switch (port) {
> > > -		case PORT_A:
> > > -			max_lanes = 2;
> > > -			break;
> > > -		case PORT_E:
> > > -			max_lanes = 2;
> > > -			break;
> > > -		default:
> > > -			max_lanes = 4;
> > > -			break;
> > > -		}
> > > -	}
> > > -
> > > -	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
> > > -		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> > > -	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
> > > -	if (!init_dp && !init_hdmi) {
> > > -		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
> > > -			      port_name(port));
> > > -		return;
> > > -	}
> > >  
> > >  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
> > >  	if (!intel_dig_port)
> > > -		return;
> > > +		return -ENOMEM;
> > >  
> > >  	intel_encoder = &intel_dig_port->base;
> > >  	encoder = &intel_encoder->base;
> > > @@ -3287,9 +3337,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> > >  	intel_encoder->get_config = intel_ddi_get_config;
> > >  
> > >  	intel_dig_port->port = port;
> > > -	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> > > -					  (DDI_BUF_PORT_REVERSAL |
> > > -					   DDI_A_4_LANES);
> > > +	intel_dig_port->saved_port_bits = saved_port_bits;
> > >  	intel_dig_port->max_lanes = max_lanes;
> > >  
> > >  	/*
> > > @@ -3306,11 +3354,11 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> > >  		}
> > >  	}
> > >  
> > > -	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
> > > +	intel_encoder->type = encoder_type;
> > >  	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
> > >  	intel_encoder->cloneable = 0;
> > >  
> > > -	if (init_dp) {
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> > >  		if (!intel_ddi_init_dp_connector(intel_dig_port))
> > >  			goto err;
> > >  
> > > @@ -3327,14 +3375,74 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> > >  
> > >  	/* In theory we don't need the encoder->type check, but leave it just in
> > >  	 * case we have some really bad VBTs... */
> > > -	if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
> > > +	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
> > >  		if (!intel_ddi_init_hdmi_connector(intel_dig_port))
> > >  			goto err;
> > >  	}
> > >  
> > > -	return;
> > > +	return intel_encoder->type;
> > >  
> > >  err:
> > >  	drm_encoder_cleanup(encoder);
> > >  	kfree(intel_dig_port);
> > > +
> > > +	return -ENODEV;
> > > +}
> > > +
> > > +void intel_ddi_init(struct drm_device *dev, enum port port)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(dev);
> > > +	uint32_t saved_port_bits;
> > > +	bool init_hdmi, init_dp;
> > > +	int max_lanes;
> > > +
> > > +	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
> > > +		switch (port) {
> > > +		case PORT_A:
> > > +			max_lanes = 4;
> > > +			break;
> > > +		case PORT_E:
> > > +			max_lanes = 0;
> > > +			break;
> > > +		default:
> > > +			max_lanes = 4;
> > > +			break;
> > > +		}
> > > +	} else {
> > > +		switch (port) {
> > > +		case PORT_A:
> > > +			max_lanes = 2;
> > > +			break;
> > > +		case PORT_E:
> > > +			max_lanes = 2;
> > > +			break;
> > > +		default:
> > > +			max_lanes = 4;
> > > +			break;
> > > +		}
> > > +	}
> > > +
> > > +	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
> > > +		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
> > > +	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
> > > +	if (!init_dp && !init_hdmi) {
> > > +		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
> > > +			      port_name(port));
> > > +		return;
> > > +	}
> > > +
> > > +	saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
> > > +		(DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES);
> > > +
> > > +	if (init_dp) {
> > > +		int ret = intel_ddi_init_role(dev, port, INTEL_OUTPUT_DISPLAYPORT,
> > > +					      saved_port_bits, max_lanes);
> > > +		/* Don't register the HDMI connector/encoder when we have eDP */
> > > +		if (ret == INTEL_OUTPUT_EDP)
> > > +			init_hdmi = false;
> > > +	}
> > > +
> > > +	if (init_hdmi)
> > > +		intel_ddi_init_role(dev, port, INTEL_OUTPUT_HDMI,
> > > +				    saved_port_bits, max_lanes);
> > >  }
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > index bc7aaa3c431e..fc1d7387eb12 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -5252,13 +5252,9 @@ static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
> > >  enum intel_display_power_domain
> > >  intel_display_port_power_domain(struct intel_encoder *intel_encoder)
> > >  {
> > > -	struct drm_device *dev = intel_encoder->base.dev;
> > >  	struct intel_digital_port *intel_dig_port;
> > >  
> > >  	switch (intel_encoder->type) {
> > > -	case INTEL_OUTPUT_UNKNOWN:
> > > -		/* Only DDI platforms should ever use this output type */
> > > -		WARN_ON_ONCE(!HAS_DDI(dev));
> > >  	case INTEL_OUTPUT_DISPLAYPORT:
> > >  	case INTEL_OUTPUT_HDMI:
> > >  	case INTEL_OUTPUT_EDP:
> > > @@ -5279,20 +5275,9 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
> > >  enum intel_display_power_domain
> > >  intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
> > >  {
> > > -	struct drm_device *dev = intel_encoder->base.dev;
> > >  	struct intel_digital_port *intel_dig_port;
> > >  
> > >  	switch (intel_encoder->type) {
> > > -	case INTEL_OUTPUT_UNKNOWN:
> > > -	case INTEL_OUTPUT_HDMI:
> > > -		/*
> > > -		 * Only DDI platforms should ever use these output types.
> > > -		 * We can get here after the HDMI detect code has already set
> > > -		 * the type of the shared encoder. Since we can't be sure
> > > -		 * what's the status of the given connectors, play safe and
> > > -		 * run the DP detection too.
> > > -		 */
> > > -		WARN_ON_ONCE(!HAS_DDI(dev));
> > >  	case INTEL_OUTPUT_DISPLAYPORT:
> > >  	case INTEL_OUTPUT_EDP:
> > >  		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
> > > @@ -12283,9 +12268,6 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
> > >  
> > >  		switch (encoder->type) {
> > >  			unsigned int port_mask;
> > > -		case INTEL_OUTPUT_UNKNOWN:
> > > -			if (WARN_ON(!HAS_DDI(dev)))
> > > -				break;
> > >  		case INTEL_OUTPUT_DISPLAYPORT:
> > >  		case INTEL_OUTPUT_HDMI:
> > >  		case INTEL_OUTPUT_EDP:
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > > index 7d354b1e5e5f..1d31aa296aaa 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -4601,8 +4601,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> > >  
> > >  	if (intel_dp->is_mst) {
> > >  		/* MST devices are disconnected from a monitor POV */
> > > -		if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > > -			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> > >  		return connector_status_disconnected;
> > >  	}
> > >  
> > > @@ -4632,8 +4630,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> > >  	if (ret) {
> > >  		/* if we are in MST mode then this connector
> > >  		   won't appear connected or have anything with EDID on it */
> > > -		if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > > -			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> > >  		status = connector_status_disconnected;
> > >  		goto out;
> > >  	}
> > > @@ -4648,8 +4644,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> > >  
> > >  	intel_dp_set_edid(intel_dp);
> > >  
> > > -	if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > > -		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> > >  	status = connector_status_connected;
> > >  
> > >  	/* Try to read the source of the interrupt */
> > > @@ -4692,9 +4686,6 @@ intel_dp_force(struct drm_connector *connector)
> > >  	intel_dp_set_edid(intel_dp);
> > >  
> > >  	intel_display_power_put(dev_priv, power_domain);
> > > -
> > > -	if (intel_encoder->type != INTEL_OUTPUT_EDP)
> > > -		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> > >  }
> > >  
> > >  static int intel_dp_get_modes(struct drm_connector *connector)
> > > @@ -4969,9 +4960,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
> > >  	enum intel_display_power_domain power_domain;
> > >  	enum irqreturn ret = IRQ_NONE;
> > >  
> > > -	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
> > > -	    intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
> > > -		intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
> > > +	if (WARN_ON_ONCE(intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
> > > +			 intel_dig_port->base.type != INTEL_OUTPUT_DISPLAYPORT))
> > > +		return IRQ_HANDLED;
> > >  
> > >  	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
> > >  		/*
> > > @@ -5815,6 +5806,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> > >  	enum port port = intel_dig_port->port;
> > >  	int type, ret;
> > >  
> > > +	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT))
> > > +		return false;
> > > +
> > >  	if (WARN(intel_dig_port->max_lanes < 1,
> > >  		 "Not enough lanes (%d) for DP on port %c\n",
> > >  		 intel_dig_port->max_lanes, port_name(port)))
> > > @@ -5851,11 +5845,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> > >  	else
> > >  		type = DRM_MODE_CONNECTOR_DisplayPort;
> > >  
> > > -	/*
> > > -	 * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
> > > -	 * for DP the encoder type can be set by the caller to
> > > -	 * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it.
> > > -	 */
> > >  	if (type == DRM_MODE_CONNECTOR_eDP)
> > >  		intel_encoder->type = INTEL_OUTPUT_EDP;
> > >  
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index a8a84b8c2bac..9e5db3d71e12 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -103,8 +103,7 @@ enum intel_output_type {
> > >  	INTEL_OUTPUT_DISPLAYPORT = 7,
> > >  	INTEL_OUTPUT_EDP = 8,
> > >  	INTEL_OUTPUT_DSI = 9,
> > > -	INTEL_OUTPUT_UNKNOWN = 10,
> > > -	INTEL_OUTPUT_DP_MST = 11,
> > > +	INTEL_OUTPUT_DP_MST = 10,
> > >  };
> > >  
> > >  #define INTEL_DVO_CHIP_NONE 0
> > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > > index 895189abfd56..75ea9515a9ce 100644
> > > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > > @@ -2034,6 +2034,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> > >  	enum port port = intel_dig_port->port;
> > >  	uint8_t alternate_ddc_pin;
> > >  
> > > +	if (WARN_ON(intel_encoder->type != INTEL_OUTPUT_HDMI))
> > > +		return;
> > > +
> > >  	if (WARN(intel_dig_port->max_lanes < 4,
> > >  		 "Not enough lanes (%d) for HDMI on port %c\n",
> > >  		 intel_dig_port->max_lanes, port_name(port)))
> > > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> > > index e362a30776fa..a15459a451c2 100644
> > > --- a/drivers/gpu/drm/i915/intel_opregion.c
> > > +++ b/drivers/gpu/drm/i915/intel_opregion.c
> > > @@ -360,7 +360,6 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
> > >  	case INTEL_OUTPUT_ANALOG:
> > >  		type = DISPLAY_TYPE_CRT;
> > >  		break;
> > > -	case INTEL_OUTPUT_UNKNOWN:
> > >  	case INTEL_OUTPUT_DISPLAYPORT:
> > >  	case INTEL_OUTPUT_HDMI:
> > >  	case INTEL_OUTPUT_DP_MST:
> > > -- 
> > > 2.4.10
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi
  2015-12-10 13:48   ` Daniel Vetter
@ 2015-12-10 14:41     ` Ville Syrjälä
  2015-12-11 17:22       ` Daniel Vetter
  0 siblings, 1 reply; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:41 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:48:48PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:46PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > When the DDI port is in HDMI/DVI mode, it automagically uses the buffer
> > translations values from entry 9. Let's make that explicit in the code.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Or WARN_ON(i != 9); Either way don't see that much benefit, but I guess
> won't hurt either. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

I guess I could just squash this with the split DP vs. HDMI buffer
programming patch since the 'i' will be gone there anyway.

> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 5f008f0fdc13..f812607045d6 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -516,9 +516,9 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> >  		hdmi_level = hdmi_default_entry;
> >  
> >  	/* Entry 9 is for HDMI: */
> > -	I915_WRITE(DDI_BUF_TRANS_LO(port, i),
> > +	I915_WRITE(DDI_BUF_TRANS_LO(port, 9),
> >  		   ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
> > -	I915_WRITE(DDI_BUF_TRANS_HI(port, i),
> > +	I915_WRITE(DDI_BUF_TRANS_HI(port, 9),
> >  		   ddi_translations_hdmi[hdmi_level].trans2);
> >  }
> >  
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes
  2015-12-10 13:28   ` Daniel Vetter
@ 2015-12-10 14:43     ` Ville Syrjälä
  0 siblings, 0 replies; 46+ messages in thread
From: Ville Syrjälä @ 2015-12-10 14:43 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 02:28:32PM +0100, Daniel Vetter wrote:
> On Tue, Dec 08, 2015 at 07:59:42PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > The DDI translation tables are supposed to be of certain size,
> > so let's add some compile time asserts to enforce that..
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Not sure this is worth it really. Next patch seems more valuable. Not
> against it, but imo needs someone to really rave about it.

The hardware has a fixed number of registers for this stuff, so these
arrays had better match that 1:1.

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 5d0b03d6d388..838cbbe33517 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -351,6 +351,10 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
> >  static const struct ddi_buf_trans *
> >  skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
> >  {
> > +	BUILD_BUG_ON(ARRAY_SIZE(skl_y_ddi_translations_dp) != 9);
> > +	BUILD_BUG_ON(ARRAY_SIZE(skl_u_ddi_translations_dp) != 9);
> > +	BUILD_BUG_ON(ARRAY_SIZE(skl_ddi_translations_dp) != 9);
> > +
> >  	if (IS_SKL_ULX(dev_priv)) {
> >  		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
> >  		return skl_y_ddi_translations_dp;
> > @@ -366,6 +370,10 @@ skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
> >  static const struct ddi_buf_trans *
> >  skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
> >  {
> > +	BUILD_BUG_ON(ARRAY_SIZE(skl_y_ddi_translations_edp) != 10);
> > +	BUILD_BUG_ON(ARRAY_SIZE(skl_u_ddi_translations_edp) != 10);
> > +	BUILD_BUG_ON(ARRAY_SIZE(skl_ddi_translations_edp) != 10);
> > +
> >  	if (dev_priv->edp_low_vswing) {
> >  		if (IS_SKL_ULX(dev_priv)) {
> >  			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
> > @@ -436,6 +444,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> >  		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
> >  			iboost_bit = 1<<31;
> >  	} else if (IS_BROADWELL(dev_priv)) {
> > +		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_fdi) != 9);
> > +		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_dp) != 9);
> > +		BUILD_BUG_ON(ARRAY_SIZE(bdw_ddi_translations_edp) != 9);
> > +
> >  		ddi_translations_fdi = bdw_ddi_translations_fdi;
> >  		ddi_translations_dp = bdw_ddi_translations_dp;
> >  		ddi_translations_edp = bdw_ddi_translations_edp;
> > @@ -445,6 +457,9 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
> >  		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
> >  		hdmi_default_entry = 7;
> >  	} else if (IS_HASWELL(dev_priv)) {
> > +		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_fdi) != 9);
> > +		BUILD_BUG_ON(ARRAY_SIZE(hsw_ddi_translations_dp) != 9);
> > +
> >  		ddi_translations_fdi = hsw_ddi_translations_fdi;
> >  		ddi_translations_dp = hsw_ddi_translations_dp;
> >  		ddi_translations_edp = hsw_ddi_translations_dp;
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi
  2015-12-10 14:41     ` Ville Syrjälä
@ 2015-12-11 17:22       ` Daniel Vetter
  0 siblings, 0 replies; 46+ messages in thread
From: Daniel Vetter @ 2015-12-11 17:22 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 04:41:54PM +0200, Ville Syrjälä wrote:
> On Thu, Dec 10, 2015 at 02:48:48PM +0100, Daniel Vetter wrote:
> > On Tue, Dec 08, 2015 at 07:59:46PM +0200, ville.syrjala@linux.intel.com wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > When the DDI port is in HDMI/DVI mode, it automagically uses the buffer
> > > translations values from entry 9. Let's make that explicit in the code.
> > > 
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Or WARN_ON(i != 9); Either way don't see that much benefit, but I guess
> > won't hurt either. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> I guess I could just squash this with the split DP vs. HDMI buffer
> programming patch since the 'i' will be gone there anyway.

Ah, that explains things more. Maybe mention this in the commit message.
r-b stands.
-Daniel

> 
> > 
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > > index 5f008f0fdc13..f812607045d6 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -516,9 +516,9 @@ void intel_prepare_ddi_buffers(struct intel_encoder *encoder)
> > >  		hdmi_level = hdmi_default_entry;
> > >  
> > >  	/* Entry 9 is for HDMI: */
> > > -	I915_WRITE(DDI_BUF_TRANS_LO(port, i),
> > > +	I915_WRITE(DDI_BUF_TRANS_LO(port, 9),
> > >  		   ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
> > > -	I915_WRITE(DDI_BUF_TRANS_HI(port, i),
> > > +	I915_WRITE(DDI_BUF_TRANS_HI(port, 9),
> > >  		   ddi_translations_hdmi[hdmi_level].trans2);
> > >  }
> > >  
> > > -- 
> > > 2.4.10
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder
  2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
                   ` (14 preceding siblings ...)
  2015-12-08 17:59 ` [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port() ville.syrjala
@ 2016-01-12 14:52 ` Ville Syrjälä
  15 siblings, 0 replies; 46+ messages in thread
From: Ville Syrjälä @ 2016-01-12 14:52 UTC (permalink / raw)
  To: intel-gfx

On Tue, Dec 08, 2015 at 07:59:35PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> While debugging problems on DDI platforms I got tired of the crap
> caused by the the dual personality DDI encoders, so I went ahead
> and split them into separate HDMI and DP encoders.
> 
> As usual, the hole got a bit deeper after I noticed that I had to
> kill intel_prepare_ddi() as well.
> 
> This also needs the check_digital_port_conflicts() patch [1] because
> otherwise kms_setmode results in a dead machine.
> 
> Series avaialbe there (with [1] included):
> git://github.com/vsyrjala/linux.git ddi_encoder_split_3
> 
> [1] http://lists.freedesktop.org/archives/intel-gfx/2015-December/082284.html
> 
> Ville Syrjälä (15):
>   drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST
>   drm/i915: Check max number of lanes when registering DDI ports
>   drm/i915: Store max lane count in intel_digital_port
>   drm/i915: Remove pointless 'ddi_translations' local variable
>   drm/i915: Eliminate duplicated skl_get_buf_trans_dp()
>   drm/i915: Pass around dev_priv for ddi buffer programming
>   drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes
>   drm/i915: Reject >9 ddi translation entried if port != A/E on SKL
>   drm/i915: Kill intel_prepare_ddi()

Merged up to here. Skipped the BUILD_BUG_ON patch since it didn't get
any r-b love. Thanks for reviews.

>   drm/i915: Split the problematic dual-role DDI encoder into two
>     encoders
>   drm/i915: Explicitly use ddi bug trans entry 9 for hdmi
>   drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart
>   drm/i915: Add a sanity check for 'hdmi_default_entry'
>   drm/i915: Get the iboost setting based on the port type
>   drm/i915: Simplify intel_ddi_get_encoder_port()

I'll repost the rest separately once I find a bit of time to address
the review comments.

> 
>  drivers/gpu/drm/i915/i915_drv.c         |   1 -
>  drivers/gpu/drm/i915/intel_ddi.c        | 542 +++++++++++++++++++-------------
>  drivers/gpu/drm/i915/intel_display.c    |  21 --
>  drivers/gpu/drm/i915/intel_dp.c         |  36 +--
>  drivers/gpu/drm/i915/intel_dp_mst.c     |   4 +-
>  drivers/gpu/drm/i915/intel_drv.h        |   6 +-
>  drivers/gpu/drm/i915/intel_hdmi.c       |   9 +
>  drivers/gpu/drm/i915/intel_opregion.c   |   1 -
>  drivers/gpu/drm/i915/intel_runtime_pm.c |  12 -
>  9 files changed, 344 insertions(+), 288 deletions(-)
> 
> -- 
> 2.4.10

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2016-01-12 14:52 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-08 17:59 [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder ville.syrjala
2015-12-08 17:59 ` [PATCH 01/15] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST ville.syrjala
2015-12-10 13:17   ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 02/15] drm/i915: Check max number of lanes when registering DDI ports ville.syrjala
2015-12-10 13:19   ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 03/15] drm/i915: Store max lane count in intel_digital_port ville.syrjala
2015-12-10 13:22   ` Daniel Vetter
2015-12-10 13:31     ` Ville Syrjälä
2015-12-10 14:08       ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 04/15] drm/i915: Remove pointless 'ddi_translations' local variable ville.syrjala
2015-12-10 13:22   ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 05/15] drm/i915: Eliminate duplicated skl_get_buf_trans_dp() ville.syrjala
2015-12-10 13:24   ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 06/15] drm/i915: Pass around dev_priv for ddi buffer programming ville.syrjala
2015-12-10 13:25   ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 07/15] drm/i915: Add BUILD_BUG_ON()s for DDI translation table sizes ville.syrjala
2015-12-10 13:28   ` Daniel Vetter
2015-12-10 14:43     ` Ville Syrjälä
2015-12-08 17:59 ` [PATCH 08/15] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL ville.syrjala
2015-12-10 13:30   ` Daniel Vetter
2015-12-10 13:42     ` Ville Syrjälä
2015-12-10 14:09       ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 09/15] drm/i915: Kill intel_prepare_ddi() ville.syrjala
2015-12-10 13:37   ` Daniel Vetter
2015-12-10 14:00     ` Ville Syrjälä
2015-12-08 17:59 ` [PATCH 10/15] drm/i915: Split the problematic dual-role DDI encoder into two encoders ville.syrjala
2015-12-08 18:21   ` kbuild test robot
2015-12-10 13:47   ` Daniel Vetter
2015-12-10 14:10     ` Ville Syrjälä
2015-12-10 14:20       ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 11/15] drm/i915: Explicitly use ddi bug trans entry 9 for hdmi ville.syrjala
2015-12-10 13:48   ` Daniel Vetter
2015-12-10 14:41     ` Ville Syrjälä
2015-12-11 17:22       ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 12/15] drm/i915: Split DP/eDP/FDI and HDMI/DVI DDI buffer programming apart ville.syrjala
2015-12-10 13:52   ` Daniel Vetter
2015-12-10 14:15     ` Ville Syrjälä
2015-12-08 17:59 ` [PATCH 13/15] drm/i915: Add a sanity check for 'hdmi_default_entry' ville.syrjala
2015-12-10 13:54   ` Daniel Vetter
2015-12-08 17:59 ` [PATCH 14/15] drm/i915: Get the iboost setting based on the port type ville.syrjala
2015-12-10 13:55   ` Daniel Vetter
2015-12-10 14:17     ` Ville Syrjälä
2015-12-08 17:59 ` [PATCH 15/15] drm/i915: Simplify intel_ddi_get_encoder_port() ville.syrjala
2015-12-10 13:57   ` Daniel Vetter
2015-12-10 14:19     ` Ville Syrjälä
2016-01-12 14:52 ` [PATCH 00/15] drm/i915: Cure DDI from multiple personality disorder Ville Syrjälä

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.