All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-23  0:54 ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx

Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
reverted the order that pipes gets disabled because of TGL
master/slave relationship between transcoders in MST mode.

But as stated in a comment in skl_commit_modeset_enables() the
enabling order is not always crescent, possibly causing previously
selected slave transcoder being enabled before master so another
approach will be needed to select a transcoder to master in MST mode.
It will be similar to the approach taken in port sync.

But instead of implement something like
intel_trans_port_sync_modeset_disables() to MST lets simply it and
iterate over all pipes 2 times, the first one disabling any slave and
then disabling everything else.
The MST bits will be added in another patch.

Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------------
 1 file changed, 22 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 53dc310a5f6d..1b1fbb6d8acc 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14443,53 +14443,16 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 		dev_priv->display.initial_watermarks(state, crtc);
 }
 
-static void intel_trans_port_sync_modeset_disables(struct intel_atomic_state *state,
-						   struct intel_crtc *crtc,
-						   struct intel_crtc_state *old_crtc_state,
-						   struct intel_crtc_state *new_crtc_state)
-{
-	struct intel_crtc *slave_crtc = intel_get_slave_crtc(new_crtc_state);
-	struct intel_crtc_state *new_slave_crtc_state =
-		intel_atomic_get_new_crtc_state(state, slave_crtc);
-	struct intel_crtc_state *old_slave_crtc_state =
-		intel_atomic_get_old_crtc_state(state, slave_crtc);
-
-	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
-		!old_slave_crtc_state);
-
-	/* Disable Slave first */
-	intel_pre_plane_update(old_slave_crtc_state, new_slave_crtc_state);
-	if (old_slave_crtc_state->hw.active)
-		intel_old_crtc_state_disables(state,
-					      old_slave_crtc_state,
-					      new_slave_crtc_state,
-					      slave_crtc);
-
-	/* Disable Master */
-	intel_pre_plane_update(old_crtc_state, new_crtc_state);
-	if (old_crtc_state->hw.active)
-		intel_old_crtc_state_disables(state,
-					      old_crtc_state,
-					      new_crtc_state,
-					      crtc);
-}
-
 static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 {
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
 	struct intel_crtc *crtc;
 	int i;
 
-	/*
-	 * Disable CRTC/pipes in reverse order because some features(MST in
-	 * TGL+) requires master and slave relationship between pipes, so it
-	 * should always pick the lowest pipe as master as it will be enabled
-	 * first and disable in the reverse order so the master will be the
-	 * last one to be disabled.
-	 */
-	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
-						    new_crtc_state, i) {
-		if (!needs_modeset(new_crtc_state))
+	/* Only disable port sync slaves */
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		if (!needs_modeset(new_crtc_state) || !crtc->active)
 			continue;
 
 		/* In case of Transcoder port Sync master slave CRTCs can be
@@ -14497,23 +14460,25 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		 * slave CRTCs are disabled first and then master CRTC since
 		 * Slave vblanks are masked till Master Vblanks.
 		 */
-		if (is_trans_port_sync_mode(new_crtc_state)) {
-			if (is_trans_port_sync_master(new_crtc_state))
-				intel_trans_port_sync_modeset_disables(state,
-								       crtc,
-								       old_crtc_state,
-								       new_crtc_state);
-			else
-				continue;
-		} else {
-			intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		if (!is_trans_port_sync_mode(new_crtc_state))
+			continue;
+		if (is_trans_port_sync_master(new_crtc_state))
+			continue;
 
-			if (old_crtc_state->hw.active)
-				intel_old_crtc_state_disables(state,
-							      old_crtc_state,
-							      new_crtc_state,
-							      crtc);
-		}
+		intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		intel_old_crtc_state_disables(state, old_crtc_state,
+					      new_crtc_state, crtc);
+	}
+
+	/* Disable everything else left on */
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		if (!needs_modeset(new_crtc_state) || !crtc->active)
+			continue;
+
+		intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		intel_old_crtc_state_disables(state, old_crtc_state,
+					      new_crtc_state, crtc);
 	}
 }
 
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-23  0:54 ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx

Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
reverted the order that pipes gets disabled because of TGL
master/slave relationship between transcoders in MST mode.

But as stated in a comment in skl_commit_modeset_enables() the
enabling order is not always crescent, possibly causing previously
selected slave transcoder being enabled before master so another
approach will be needed to select a transcoder to master in MST mode.
It will be similar to the approach taken in port sync.

But instead of implement something like
intel_trans_port_sync_modeset_disables() to MST lets simply it and
iterate over all pipes 2 times, the first one disabling any slave and
then disabling everything else.
The MST bits will be added in another patch.

Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------------
 1 file changed, 22 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 53dc310a5f6d..1b1fbb6d8acc 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14443,53 +14443,16 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 		dev_priv->display.initial_watermarks(state, crtc);
 }
 
-static void intel_trans_port_sync_modeset_disables(struct intel_atomic_state *state,
-						   struct intel_crtc *crtc,
-						   struct intel_crtc_state *old_crtc_state,
-						   struct intel_crtc_state *new_crtc_state)
-{
-	struct intel_crtc *slave_crtc = intel_get_slave_crtc(new_crtc_state);
-	struct intel_crtc_state *new_slave_crtc_state =
-		intel_atomic_get_new_crtc_state(state, slave_crtc);
-	struct intel_crtc_state *old_slave_crtc_state =
-		intel_atomic_get_old_crtc_state(state, slave_crtc);
-
-	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
-		!old_slave_crtc_state);
-
-	/* Disable Slave first */
-	intel_pre_plane_update(old_slave_crtc_state, new_slave_crtc_state);
-	if (old_slave_crtc_state->hw.active)
-		intel_old_crtc_state_disables(state,
-					      old_slave_crtc_state,
-					      new_slave_crtc_state,
-					      slave_crtc);
-
-	/* Disable Master */
-	intel_pre_plane_update(old_crtc_state, new_crtc_state);
-	if (old_crtc_state->hw.active)
-		intel_old_crtc_state_disables(state,
-					      old_crtc_state,
-					      new_crtc_state,
-					      crtc);
-}
-
 static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 {
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
 	struct intel_crtc *crtc;
 	int i;
 
-	/*
-	 * Disable CRTC/pipes in reverse order because some features(MST in
-	 * TGL+) requires master and slave relationship between pipes, so it
-	 * should always pick the lowest pipe as master as it will be enabled
-	 * first and disable in the reverse order so the master will be the
-	 * last one to be disabled.
-	 */
-	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
-						    new_crtc_state, i) {
-		if (!needs_modeset(new_crtc_state))
+	/* Only disable port sync slaves */
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		if (!needs_modeset(new_crtc_state) || !crtc->active)
 			continue;
 
 		/* In case of Transcoder port Sync master slave CRTCs can be
@@ -14497,23 +14460,25 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		 * slave CRTCs are disabled first and then master CRTC since
 		 * Slave vblanks are masked till Master Vblanks.
 		 */
-		if (is_trans_port_sync_mode(new_crtc_state)) {
-			if (is_trans_port_sync_master(new_crtc_state))
-				intel_trans_port_sync_modeset_disables(state,
-								       crtc,
-								       old_crtc_state,
-								       new_crtc_state);
-			else
-				continue;
-		} else {
-			intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		if (!is_trans_port_sync_mode(new_crtc_state))
+			continue;
+		if (is_trans_port_sync_master(new_crtc_state))
+			continue;
 
-			if (old_crtc_state->hw.active)
-				intel_old_crtc_state_disables(state,
-							      old_crtc_state,
-							      new_crtc_state,
-							      crtc);
-		}
+		intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		intel_old_crtc_state_disables(state, old_crtc_state,
+					      new_crtc_state, crtc);
+	}
+
+	/* Disable everything else left on */
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		if (!needs_modeset(new_crtc_state) || !crtc->active)
+			continue;
+
+		intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		intel_old_crtc_state_disables(state, old_crtc_state,
+					      new_crtc_state, crtc);
 	}
 }
 
-- 
2.24.0

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

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

* [PATCH 2/7] drm/i915/display: Check the old state to find port sync slave
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx

If the CRTC is going from enabled to disabled and it is a port sync
slave, it needs to check to the old state to be disabled before the
port sync master.

Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 1b1fbb6d8acc..801b975c7d39 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14460,9 +14460,9 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		 * slave CRTCs are disabled first and then master CRTC since
 		 * Slave vblanks are masked till Master Vblanks.
 		 */
-		if (!is_trans_port_sync_mode(new_crtc_state))
+		if (!is_trans_port_sync_mode(old_crtc_state))
 			continue;
-		if (is_trans_port_sync_master(new_crtc_state))
+		if (is_trans_port_sync_master(old_crtc_state))
 			continue;
 
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 2/7] drm/i915/display: Check the old state to find port sync slave
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx

If the CRTC is going from enabled to disabled and it is a port sync
slave, it needs to check to the old state to be disabled before the
port sync master.

Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 1b1fbb6d8acc..801b975c7d39 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14460,9 +14460,9 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		 * slave CRTCs are disabled first and then master CRTC since
 		 * Slave vblanks are masked till Master Vblanks.
 		 */
-		if (!is_trans_port_sync_mode(new_crtc_state))
+		if (!is_trans_port_sync_mode(old_crtc_state))
 			continue;
-		if (is_trans_port_sync_master(new_crtc_state))
+		if (is_trans_port_sync_master(old_crtc_state))
 			continue;
 
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
-- 
2.24.0

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

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

* [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

On TGL the blending of all the streams have moved from DDI to
transcoder, so now every transcoder working over the same MST port must
send its stream to a master transcoder and master will send to DDI
respecting the time slots.

A previous approach was using the lowest pipe/transcoder as master
transcoder but as the comment in skl_commit_modeset_enables() states,
that is not always true.

So here promoting the first pipe/transcoder of the stream as master.
That caused several other problems as during the commit phase the
state computed should not be changed.

So the master transcoder is store into intel_dp and the modeset in
slave pipes/transcoders is forced using mst_master_trans_pending.

v2:
- added missing config compute to trigger fullmodeset in slave
transcoders

BSpec: 50493
BSpec: 49190
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
 drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149 +++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
 6 files changed, 216 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index a976606d21c7..d2f0d393d3ee 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -35,6 +35,7 @@
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
+#include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
 #include "intel_dsi.h"
 #include "intel_fifo_underrun.h"
@@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
 		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
 		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
 
-		if (INTEL_GEN(dev_priv) >= 12)
-			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
+		if (INTEL_GEN(dev_priv) >= 12) {
+			enum transcoder master;
+
+			master = intel_dp_mst_master_trans_get(encoder);
+			WARN_ON(master == INVALID_TRANSCODER);
+			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
+		}
 	} else {
 		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
 		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 801b975c7d39..35a59108194e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -46,6 +46,7 @@
 #include "display/intel_crt.h"
 #include "display/intel_ddi.h"
 #include "display/intel_dp.h"
+#include "display/intel_dp_mst.h"
 #include "display/intel_dsi.h"
 #include "display/intel_dvo.h"
 #include "display/intel_gmbus.h"
@@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
 	return encoder;
 }
 
+/*
+ * Finds the encoder associated with the given CRTC. This can only be
+ * used when we know that the CRTC isn't feeding multiple encoders!
+ */
+static struct intel_encoder *
+intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
+			   const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_connector_state *connector_state;
+	const struct drm_connector *connector;
+	struct intel_encoder *encoder = NULL;
+	int num_encoders = 0;
+	int i;
+
+	for_each_old_connector_in_state(&state->base, connector,
+					connector_state, i) {
+		if (connector_state->crtc != &crtc->base)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+		num_encoders++;
+	}
+
+	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
+	     num_encoders, pipe_name(crtc->pipe));
+
+	return encoder;
+}
+
 /*
  * Enable PCH resources required for PCH ports:
  *   - PCH PLLs
@@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 #undef PIPE_CONF_CHECK_COLOR_LUT
 #undef PIPE_CONF_QUIRK
 
+	if (fastset && pipe_config->mst_master_trans_pending) {
+		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in mst_master_trans\n",
+			      crtc->base.base.id, crtc->base.name);
+		ret = false;
+	}
+
 	return ret;
 }
 
@@ -14449,22 +14486,35 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	struct intel_crtc *crtc;
 	int i;
 
-	/* Only disable port sync slaves */
+	/* Only disable port sync and MST slaves */
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state) || !crtc->active)
 			continue;
 
+		if (!is_trans_port_sync_mode(new_crtc_state) &&
+		    !intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
+			continue;
+
 		/* In case of Transcoder port Sync master slave CRTCs can be
 		 * assigned in any order and we need to make sure that
 		 * slave CRTCs are disabled first and then master CRTC since
 		 * Slave vblanks are masked till Master Vblanks.
 		 */
-		if (!is_trans_port_sync_mode(old_crtc_state))
-			continue;
-		if (is_trans_port_sync_master(old_crtc_state))
+		if (is_trans_port_sync_mode(new_crtc_state) &&
+		    is_trans_port_sync_master(new_crtc_state))
 			continue;
 
+		if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
+			struct intel_encoder *encoder;
+
+			encoder = intel_get_crtc_old_encoder(state,
+							     old_crtc_state);
+			if (intel_dp_mst_master_trans_get(encoder) ==
+			    old_crtc_state->cpu_transcoder)
+				continue;
+		}
+
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
 		intel_old_crtc_state_disables(state, old_crtc_state,
 					      new_crtc_state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 83ea04149b77..23d747cdca64 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1052,6 +1052,8 @@ struct intel_crtc_state {
 	/* Pointer to master transcoder in case of tiled displays */
 	enum transcoder master_transcoder;
 
+	bool mst_master_trans_pending;
+
 	/* Bitmask to indicate slaves attached */
 	u8 sync_mode_slaves_mask;
 };
@@ -1284,6 +1286,7 @@ struct intel_dp {
 	bool can_mst; /* this port supports mst */
 	bool is_mst;
 	int active_mst_links;
+	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
 
 	/*
 	 * DP_TP_* registers may be either on port or transcoder register space.
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3123958e2081..ceff6901451a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_dp->reset_link_params = true;
 	intel_dp->pps_pipe = INVALID_PIPE;
 	intel_dp->active_pipe = INVALID_PIPE;
+	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
 
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index f8a350359346..9731c3c1d3f2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -87,6 +87,47 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 	return 0;
 }
 
+static int
+intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config,
+				  struct drm_connector_state *conn_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(pipe_config->uapi.state);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_crtc *crtc;
+	enum transcoder master;
+	int i;
+
+	if (INTEL_GEN(dev_priv) < 12)
+		return 0;
+
+	if (!conn_state->crtc)
+		return 0;
+
+	master = intel_dp_mst_master_trans_get(encoder);
+	if (master == INVALID_TRANSCODER)
+		return 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+		/*
+		 * cpu_transcoder is set when computing CRTC state if it will
+		 * be disabled it will not happen, so checking pipe instead
+		 */
+		if (crtc->pipe != (enum pipe)master)
+			continue;
+
+		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
+		    new_crtc_state->uapi.enable)
+			continue;
+
+		pipe_config->mst_master_trans_pending = true;
+		break;
+	}
+
+	return 0;
+}
+
 static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 				       struct intel_crtc_state *pipe_config,
 				       struct drm_connector_state *conn_state)
@@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
 
+	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
+						conn_state);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+intel_dp_mst_atomic_master_trans_check(struct drm_connector *connector,
+				       struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_connector *intel_conn = to_intel_connector(connector);
+	struct drm_connector_state *new_conn_state, *old_conn_state;
+	struct drm_connector_list_iter conn_list_iter;
+	struct intel_crtc_state *intel_crtc_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector *conn_iter;
+
+	if (INTEL_GEN(dev_priv) < 12)
+		return 0;
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+
+	if (!old_conn_state->crtc && !new_conn_state->crtc)
+		return 0;
+
+	/*
+	 * 3 cases that needs be handled here:
+	 * - connector going from disabled to enabled
+	 * - connector going from enabled to disabled:
+	 * if this transcoder was the master, all slaves needs a modeset
+	 * - connector going from enabled to enabled but it needs a modeset:
+	 * if this transcoder was the master, all slaves also needs a modeset
+	 */
+
+	/* disabled -> enabled */
+	if (!old_conn_state->crtc && new_conn_state->crtc)
+		return 0;
+
+	/* enabled -> enabled(modeset)? */
+	if (new_conn_state->crtc) {
+		crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+		if (!drm_atomic_crtc_needs_modeset(crtc_state))
+			return 0;
+	}
+
+	/* handling enabled -> enabled(modeset) and enabled -> disabled */
+	crtc_state = drm_atomic_get_old_crtc_state(state, old_conn_state->crtc);
+	intel_crtc_state = to_intel_crtc_state(crtc_state);
+
+	/* If not master, nothing else needs to be handled */
+	if (intel_conn->mst_port->mst_master_transcoder !=
+	    intel_crtc_state->cpu_transcoder)
+		return 0;
+
+	/* Is master, mark all other CRTCs as needing a modeset */
+	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
+	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
+		struct intel_connector *intel_conn_iter;
+		struct drm_connector_state *conn_iter_state;
+
+		intel_conn_iter = to_intel_connector(conn_iter);
+		if (intel_conn_iter->mst_port != intel_conn->mst_port)
+			continue;
+
+		conn_iter_state = drm_atomic_get_connector_state(state,
+								 conn_iter);
+		if (IS_ERR(conn_iter_state)) {
+			drm_connector_list_iter_end(&conn_list_iter);
+			return PTR_ERR(conn_iter_state);
+		}
+
+		if (!conn_iter_state->crtc)
+			continue;
+
+		crtc_state = drm_atomic_get_crtc_state(state, conn_iter_state->crtc);
+		if (IS_ERR(crtc_state)) {
+			drm_connector_list_iter_end(&conn_list_iter);
+			return PTR_ERR(conn_iter_state);
+		}
+
+		intel_crtc_state = to_intel_crtc_state(crtc_state);
+		crtc_state->mode_changed = true;
+	}
+	drm_connector_list_iter_end(&conn_list_iter);
+
 	return 0;
 }
 
@@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
+	if (ret)
+		return ret;
+
 	if (!old_conn_state->crtc)
 		return 0;
 
@@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
 						  old_crtc_state, NULL);
+		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
 	}
 
 	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
@@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
 
-	if (first_mst_stream)
+	if (first_mst_stream) {
+		WARN_ON(intel_dp->mst_master_transcoder != INVALID_TRANSCODER);
+		intel_dp->mst_master_transcoder = pipe_config->cpu_transcoder;
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	}
 
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
 
@@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
 	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
 	/* encoders will get killed by normal cleanup */
 }
+
+enum transcoder
+intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_dp *intel_dp = &intel_mst->primary->dp;
+
+	return intel_dp->mst_master_transcoder;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
index f660ad80db04..e6f28a517182 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -7,9 +7,11 @@
 #define __INTEL_DP_MST_H__
 
 struct intel_digital_port;
+struct intel_encoder;
 
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
 int intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port);
+enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder *encoder);
 
 #endif /* __INTEL_DP_MST_H__ */
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

On TGL the blending of all the streams have moved from DDI to
transcoder, so now every transcoder working over the same MST port must
send its stream to a master transcoder and master will send to DDI
respecting the time slots.

A previous approach was using the lowest pipe/transcoder as master
transcoder but as the comment in skl_commit_modeset_enables() states,
that is not always true.

So here promoting the first pipe/transcoder of the stream as master.
That caused several other problems as during the commit phase the
state computed should not be changed.

So the master transcoder is store into intel_dp and the modeset in
slave pipes/transcoders is forced using mst_master_trans_pending.

v2:
- added missing config compute to trigger fullmodeset in slave
transcoders

BSpec: 50493
BSpec: 49190
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
 drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149 +++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
 6 files changed, 216 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index a976606d21c7..d2f0d393d3ee 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -35,6 +35,7 @@
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
+#include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
 #include "intel_dsi.h"
 #include "intel_fifo_underrun.h"
@@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
 		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
 		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
 
-		if (INTEL_GEN(dev_priv) >= 12)
-			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
+		if (INTEL_GEN(dev_priv) >= 12) {
+			enum transcoder master;
+
+			master = intel_dp_mst_master_trans_get(encoder);
+			WARN_ON(master == INVALID_TRANSCODER);
+			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
+		}
 	} else {
 		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
 		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 801b975c7d39..35a59108194e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -46,6 +46,7 @@
 #include "display/intel_crt.h"
 #include "display/intel_ddi.h"
 #include "display/intel_dp.h"
+#include "display/intel_dp_mst.h"
 #include "display/intel_dsi.h"
 #include "display/intel_dvo.h"
 #include "display/intel_gmbus.h"
@@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
 	return encoder;
 }
 
+/*
+ * Finds the encoder associated with the given CRTC. This can only be
+ * used when we know that the CRTC isn't feeding multiple encoders!
+ */
+static struct intel_encoder *
+intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
+			   const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_connector_state *connector_state;
+	const struct drm_connector *connector;
+	struct intel_encoder *encoder = NULL;
+	int num_encoders = 0;
+	int i;
+
+	for_each_old_connector_in_state(&state->base, connector,
+					connector_state, i) {
+		if (connector_state->crtc != &crtc->base)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+		num_encoders++;
+	}
+
+	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
+	     num_encoders, pipe_name(crtc->pipe));
+
+	return encoder;
+}
+
 /*
  * Enable PCH resources required for PCH ports:
  *   - PCH PLLs
@@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 #undef PIPE_CONF_CHECK_COLOR_LUT
 #undef PIPE_CONF_QUIRK
 
+	if (fastset && pipe_config->mst_master_trans_pending) {
+		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in mst_master_trans\n",
+			      crtc->base.base.id, crtc->base.name);
+		ret = false;
+	}
+
 	return ret;
 }
 
@@ -14449,22 +14486,35 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	struct intel_crtc *crtc;
 	int i;
 
-	/* Only disable port sync slaves */
+	/* Only disable port sync and MST slaves */
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state) || !crtc->active)
 			continue;
 
+		if (!is_trans_port_sync_mode(new_crtc_state) &&
+		    !intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
+			continue;
+
 		/* In case of Transcoder port Sync master slave CRTCs can be
 		 * assigned in any order and we need to make sure that
 		 * slave CRTCs are disabled first and then master CRTC since
 		 * Slave vblanks are masked till Master Vblanks.
 		 */
-		if (!is_trans_port_sync_mode(old_crtc_state))
-			continue;
-		if (is_trans_port_sync_master(old_crtc_state))
+		if (is_trans_port_sync_mode(new_crtc_state) &&
+		    is_trans_port_sync_master(new_crtc_state))
 			continue;
 
+		if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
+			struct intel_encoder *encoder;
+
+			encoder = intel_get_crtc_old_encoder(state,
+							     old_crtc_state);
+			if (intel_dp_mst_master_trans_get(encoder) ==
+			    old_crtc_state->cpu_transcoder)
+				continue;
+		}
+
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
 		intel_old_crtc_state_disables(state, old_crtc_state,
 					      new_crtc_state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 83ea04149b77..23d747cdca64 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1052,6 +1052,8 @@ struct intel_crtc_state {
 	/* Pointer to master transcoder in case of tiled displays */
 	enum transcoder master_transcoder;
 
+	bool mst_master_trans_pending;
+
 	/* Bitmask to indicate slaves attached */
 	u8 sync_mode_slaves_mask;
 };
@@ -1284,6 +1286,7 @@ struct intel_dp {
 	bool can_mst; /* this port supports mst */
 	bool is_mst;
 	int active_mst_links;
+	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
 
 	/*
 	 * DP_TP_* registers may be either on port or transcoder register space.
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3123958e2081..ceff6901451a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_dp->reset_link_params = true;
 	intel_dp->pps_pipe = INVALID_PIPE;
 	intel_dp->active_pipe = INVALID_PIPE;
+	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
 
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index f8a350359346..9731c3c1d3f2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -87,6 +87,47 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 	return 0;
 }
 
+static int
+intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config,
+				  struct drm_connector_state *conn_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(pipe_config->uapi.state);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_crtc *crtc;
+	enum transcoder master;
+	int i;
+
+	if (INTEL_GEN(dev_priv) < 12)
+		return 0;
+
+	if (!conn_state->crtc)
+		return 0;
+
+	master = intel_dp_mst_master_trans_get(encoder);
+	if (master == INVALID_TRANSCODER)
+		return 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+		/*
+		 * cpu_transcoder is set when computing CRTC state if it will
+		 * be disabled it will not happen, so checking pipe instead
+		 */
+		if (crtc->pipe != (enum pipe)master)
+			continue;
+
+		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
+		    new_crtc_state->uapi.enable)
+			continue;
+
+		pipe_config->mst_master_trans_pending = true;
+		break;
+	}
+
+	return 0;
+}
+
 static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 				       struct intel_crtc_state *pipe_config,
 				       struct drm_connector_state *conn_state)
@@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
 
+	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
+						conn_state);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+intel_dp_mst_atomic_master_trans_check(struct drm_connector *connector,
+				       struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_connector *intel_conn = to_intel_connector(connector);
+	struct drm_connector_state *new_conn_state, *old_conn_state;
+	struct drm_connector_list_iter conn_list_iter;
+	struct intel_crtc_state *intel_crtc_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector *conn_iter;
+
+	if (INTEL_GEN(dev_priv) < 12)
+		return 0;
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+
+	if (!old_conn_state->crtc && !new_conn_state->crtc)
+		return 0;
+
+	/*
+	 * 3 cases that needs be handled here:
+	 * - connector going from disabled to enabled
+	 * - connector going from enabled to disabled:
+	 * if this transcoder was the master, all slaves needs a modeset
+	 * - connector going from enabled to enabled but it needs a modeset:
+	 * if this transcoder was the master, all slaves also needs a modeset
+	 */
+
+	/* disabled -> enabled */
+	if (!old_conn_state->crtc && new_conn_state->crtc)
+		return 0;
+
+	/* enabled -> enabled(modeset)? */
+	if (new_conn_state->crtc) {
+		crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+		if (!drm_atomic_crtc_needs_modeset(crtc_state))
+			return 0;
+	}
+
+	/* handling enabled -> enabled(modeset) and enabled -> disabled */
+	crtc_state = drm_atomic_get_old_crtc_state(state, old_conn_state->crtc);
+	intel_crtc_state = to_intel_crtc_state(crtc_state);
+
+	/* If not master, nothing else needs to be handled */
+	if (intel_conn->mst_port->mst_master_transcoder !=
+	    intel_crtc_state->cpu_transcoder)
+		return 0;
+
+	/* Is master, mark all other CRTCs as needing a modeset */
+	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
+	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
+		struct intel_connector *intel_conn_iter;
+		struct drm_connector_state *conn_iter_state;
+
+		intel_conn_iter = to_intel_connector(conn_iter);
+		if (intel_conn_iter->mst_port != intel_conn->mst_port)
+			continue;
+
+		conn_iter_state = drm_atomic_get_connector_state(state,
+								 conn_iter);
+		if (IS_ERR(conn_iter_state)) {
+			drm_connector_list_iter_end(&conn_list_iter);
+			return PTR_ERR(conn_iter_state);
+		}
+
+		if (!conn_iter_state->crtc)
+			continue;
+
+		crtc_state = drm_atomic_get_crtc_state(state, conn_iter_state->crtc);
+		if (IS_ERR(crtc_state)) {
+			drm_connector_list_iter_end(&conn_list_iter);
+			return PTR_ERR(conn_iter_state);
+		}
+
+		intel_crtc_state = to_intel_crtc_state(crtc_state);
+		crtc_state->mode_changed = true;
+	}
+	drm_connector_list_iter_end(&conn_list_iter);
+
 	return 0;
 }
 
@@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
+	if (ret)
+		return ret;
+
 	if (!old_conn_state->crtc)
 		return 0;
 
@@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
 						  old_crtc_state, NULL);
+		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
 	}
 
 	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
@@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
 
-	if (first_mst_stream)
+	if (first_mst_stream) {
+		WARN_ON(intel_dp->mst_master_transcoder != INVALID_TRANSCODER);
+		intel_dp->mst_master_transcoder = pipe_config->cpu_transcoder;
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	}
 
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
 
@@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
 	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
 	/* encoders will get killed by normal cleanup */
 }
+
+enum transcoder
+intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_dp *intel_dp = &intel_mst->primary->dp;
+
+	return intel_dp->mst_master_transcoder;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
index f660ad80db04..e6f28a517182 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -7,9 +7,11 @@
 #define __INTEL_DP_MST_H__
 
 struct intel_digital_port;
+struct intel_encoder;
 
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
 int intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port);
+enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder *encoder);
 
 #endif /* __INTEL_DP_MST_H__ */
-- 
2.24.0

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

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

* [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

Disabling pipe/transcoder clock before power down sink could cause
sink lost signal, causing it to trigger a hotplug to notify source
that link signal was lost.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index d2f0d393d3ee..7d3a6e3c7f57 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3808,12 +3808,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (!is_mst) {
-		intel_ddi_disable_pipe_clock(old_crtc_state);
 		/*
 		 * Power down sink before disabling the port, otherwise we end
 		 * up getting interrupts from the sink on detecting link loss.
 		 */
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+		intel_ddi_disable_pipe_clock(old_crtc_state);
 	}
 
 	intel_disable_ddi_buf(encoder, old_crtc_state);
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

Disabling pipe/transcoder clock before power down sink could cause
sink lost signal, causing it to trigger a hotplug to notify source
that link signal was lost.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index d2f0d393d3ee..7d3a6e3c7f57 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3808,12 +3808,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (!is_mst) {
-		intel_ddi_disable_pipe_clock(old_crtc_state);
 		/*
 		 * Power down sink before disabling the port, otherwise we end
 		 * up getting interrupts from the sink on detecting link loss.
 		 */
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+		intel_ddi_disable_pipe_clock(old_crtc_state);
 	}
 
 	intel_disable_ddi_buf(encoder, old_crtc_state);
-- 
2.24.0

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

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

* [PATCH 5/7] drm/i915/display/mst: Move DPMS_OFF call to post_disable
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

Moving just to simplify handling as there is no change in behavior.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 14 +++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 -
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 7d3a6e3c7f57..cfcaa7c81575 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3807,14 +3807,14 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 					  INTEL_OUTPUT_DP_MST);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
-	if (!is_mst) {
-		/*
-		 * Power down sink before disabling the port, otherwise we end
-		 * up getting interrupts from the sink on detecting link loss.
-		 */
-		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+	/*
+	 * Power down sink before disabling the port, otherwise we end
+	 * up getting interrupts from the sink on detecting link loss.
+	 */
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+
+	if (!is_mst)
 		intel_ddi_disable_pipe_clock(old_crtc_state);
-	}
 
 	intel_disable_ddi_buf(encoder, old_crtc_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 9731c3c1d3f2..94549848653a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -390,7 +390,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 
 	intel_mst->connector = NULL;
 	if (intel_dp->active_mst_links == 0) {
-		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
 						  old_crtc_state, NULL);
 		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 5/7] drm/i915/display/mst: Move DPMS_OFF call to post_disable
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

Moving just to simplify handling as there is no change in behavior.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 14 +++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 -
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 7d3a6e3c7f57..cfcaa7c81575 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3807,14 +3807,14 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 					  INTEL_OUTPUT_DP_MST);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
-	if (!is_mst) {
-		/*
-		 * Power down sink before disabling the port, otherwise we end
-		 * up getting interrupts from the sink on detecting link loss.
-		 */
-		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+	/*
+	 * Power down sink before disabling the port, otherwise we end
+	 * up getting interrupts from the sink on detecting link loss.
+	 */
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+
+	if (!is_mst)
 		intel_ddi_disable_pipe_clock(old_crtc_state);
-	}
 
 	intel_disable_ddi_buf(encoder, old_crtc_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 9731c3c1d3f2..94549848653a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -390,7 +390,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 
 	intel_mst->connector = NULL;
 	if (intel_dp->active_mst_links == 0) {
-		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
 						  old_crtc_state, NULL);
 		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
-- 
2.24.0

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

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

* [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx

For TGL the step to turn off the transcoder clock was moved to after
the complete shutdown of DDI. Only the MST slave transcoders should
disable the clock before that.

BSpec: 49190
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c    |  9 ++++++++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index cfcaa7c81575..aa0249333175 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3813,7 +3813,7 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 	 */
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 
-	if (!is_mst)
+	if (INTEL_GEN(dev_priv) < 12 && !is_mst)
 		intel_ddi_disable_pipe_clock(old_crtc_state);
 
 	intel_disable_ddi_buf(encoder, old_crtc_state);
@@ -3826,6 +3826,13 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 		intel_display_power_put_unchecked(dev_priv,
 						  dig_port->ddi_io_power_domain);
 
+	/*
+	 * From TGL BSpec "If single stream or multi-stream master transcoder:
+	 * Configure Transcoder Clock select to direct no clock to the
+	 * transcoder"
+	 */
+	if (INTEL_GEN(dev_priv) >= 12)
+		intel_ddi_disable_pipe_clock(old_crtc_state);
 	intel_ddi_clk_disable(encoder);
 	tgl_clear_psr2_transcoder_exitline(old_crtc_state);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 94549848653a..53afe3e179f7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -369,8 +369,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 
-	intel_ddi_disable_pipe_clock(old_crtc_state);
+	intel_dp->active_mst_links--;
+
+	/*
+	 * From TGL BSpec "If multi-stream slave transcoder: Configure
+	 * Transcoder Clock Select to direct no clock to the transcoder"
+	 *
+	 * From older GENs BSpec "Configure Transcoder Clock Select to direct
+	 * no clock to the transcoder"
+	 */
+	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)
+		intel_ddi_disable_pipe_clock(old_crtc_state);
 
 	/* this can fail */
 	drm_dp_check_act_status(&intel_dp->mst_mgr);
@@ -386,8 +397,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
 				     false);
 
-	intel_dp->active_mst_links--;
-
 	intel_mst->connector = NULL;
 	if (intel_dp->active_mst_links == 0) {
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx

For TGL the step to turn off the transcoder clock was moved to after
the complete shutdown of DDI. Only the MST slave transcoders should
disable the clock before that.

BSpec: 49190
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c    |  9 ++++++++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index cfcaa7c81575..aa0249333175 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3813,7 +3813,7 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 	 */
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 
-	if (!is_mst)
+	if (INTEL_GEN(dev_priv) < 12 && !is_mst)
 		intel_ddi_disable_pipe_clock(old_crtc_state);
 
 	intel_disable_ddi_buf(encoder, old_crtc_state);
@@ -3826,6 +3826,13 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 		intel_display_power_put_unchecked(dev_priv,
 						  dig_port->ddi_io_power_domain);
 
+	/*
+	 * From TGL BSpec "If single stream or multi-stream master transcoder:
+	 * Configure Transcoder Clock select to direct no clock to the
+	 * transcoder"
+	 */
+	if (INTEL_GEN(dev_priv) >= 12)
+		intel_ddi_disable_pipe_clock(old_crtc_state);
 	intel_ddi_clk_disable(encoder);
 	tgl_clear_psr2_transcoder_exitline(old_crtc_state);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 94549848653a..53afe3e179f7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -369,8 +369,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 
-	intel_ddi_disable_pipe_clock(old_crtc_state);
+	intel_dp->active_mst_links--;
+
+	/*
+	 * From TGL BSpec "If multi-stream slave transcoder: Configure
+	 * Transcoder Clock Select to direct no clock to the transcoder"
+	 *
+	 * From older GENs BSpec "Configure Transcoder Clock Select to direct
+	 * no clock to the transcoder"
+	 */
+	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)
+		intel_ddi_disable_pipe_clock(old_crtc_state);
 
 	/* this can fail */
 	drm_dp_check_act_status(&intel_dp->mst_mgr);
@@ -386,8 +397,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
 				     false);
 
-	intel_dp->active_mst_links--;
-
 	intel_mst->connector = NULL;
 	if (intel_dp->active_mst_links == 0) {
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
-- 
2.24.0

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

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

* [PATCH 7/7] drm/display/dp: Fix MST disable sequences
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

The disable sequence after wait for transcoder off was not correctly
implemented.
The MST disable sequence is basically the same for HSW, SKL, ICL and
TGL, with just minor changes on TGL.

So here calling a new MST function to do the MST sequences, most of
the steps just moved from the post disable hook.

This plus the previous changes, fixed the hotplugs triggered by MST
sink during the disable/enable sequence, those were causing source to
try to do a link training while it was not ready causing CPU pipe
FIFO underrrus on TGL.

BSpec: 4231
BSpec: 4163
BSpec: 22243
BSpec: 49190
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     | 25 +++++--
 drivers/gpu/drm/i915/display/intel_display.c |  2 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 78 ++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp_mst.h  |  2 +
 4 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index aa0249333175..5950bc1ccc88 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -34,6 +34,7 @@
 #include "intel_ddi.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
+#include "intel_dp_mst.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
@@ -1954,17 +1955,27 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
-	u32 val = I915_READ(reg);
+	u32 val;
+
+	val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	val &= ~TRANS_DDI_FUNC_ENABLE;
 
 	if (INTEL_GEN(dev_priv) >= 12) {
-		val &= ~(TRANS_DDI_FUNC_ENABLE | TGL_TRANS_DDI_PORT_MASK |
-			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
+		if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
+			val &= ~TGL_TRANS_DDI_PORT_MASK;
+		} else {
+			struct intel_encoder *encoder;
+			enum transcoder master;
+
+			encoder = intel_ddi_get_crtc_encoder(crtc);
+			master = intel_dp_mst_master_trans_get(encoder);
+			if (crtc_state->cpu_transcoder != master)
+				val &= ~TGL_TRANS_DDI_PORT_MASK;
+		}
 	} else {
-		val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK |
-			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
+		val &= ~TRANS_DDI_PORT_MASK;
 	}
-	I915_WRITE(reg, val);
+	I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
 
 	if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME &&
 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 35a59108194e..e81b3d731c16 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6843,6 +6843,8 @@ static void haswell_crtc_disable(struct intel_atomic_state *state,
 	if (!transcoder_is_dsi(cpu_transcoder))
 		intel_disable_pipe(old_crtc_state);
 
+	intel_dp_mst_post_trans_disabled(old_crtc_state);
+
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_disable_transcoder_port_sync(old_crtc_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 53afe3e179f7..dc5e372bc32b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -360,6 +360,57 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
 					  old_crtc_state, old_conn_state);
 }
 
+static void
+dp_mst_post_trans_disabled(struct intel_encoder *encoder,
+			   const struct intel_crtc_state *old_crtc_state,
+			   const struct drm_connector_state *old_conn_state)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct intel_connector *connector =
+		to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 val;
+
+	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+
+	val = I915_READ(TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder));
+	val &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+	I915_WRITE(TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder), val);
+
+	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+				  DP_TP_STATUS_ACT_SENT, 1))
+		DRM_ERROR("Timed out waiting for ACT sent when disabling\n");
+
+	drm_dp_check_act_status(&intel_dp->mst_mgr);
+
+	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
+}
+
+void
+intel_dp_mst_post_trans_disabled(const struct intel_crtc_state *old_crtc_state)
+{
+	struct drm_atomic_state *state = old_crtc_state->uapi.state;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
+		return;
+
+	for_each_old_connector_in_state(state, conn, old_conn_state, i) {
+		struct intel_encoder *encoder;
+
+		if (old_conn_state->crtc != old_crtc_state->uapi.crtc)
+			continue;
+
+		encoder = to_intel_encoder(old_conn_state->best_encoder);
+		dp_mst_post_trans_disabled(encoder, old_crtc_state,
+					   old_conn_state);
+	}
+}
+
 static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 				      const struct intel_crtc_state *old_crtc_state,
 				      const struct drm_connector_state *old_conn_state)
@@ -373,6 +424,12 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 
 	intel_dp->active_mst_links--;
 
+	/*
+	 * Power down mst path before disabling the port, otherwise we end
+	 * up getting interrupts from the sink upon detecting link loss.
+	 */
+	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
+				     false);
 	/*
 	 * From TGL BSpec "If multi-stream slave transcoder: Configure
 	 * Transcoder Clock Select to direct no clock to the transcoder"
@@ -383,22 +440,17 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)
 		intel_ddi_disable_pipe_clock(old_crtc_state);
 
-	/* this can fail */
-	drm_dp_check_act_status(&intel_dp->mst_mgr);
-	/* and this can also fail */
-	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
-
-	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
-
-	/*
-	 * Power down mst path before disabling the port, otherwise we end
-	 * up getting interrupts from the sink upon detecting link loss.
-	 */
-	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
-				     false);
 
 	intel_mst->connector = NULL;
 	if (intel_dp->active_mst_links == 0) {
+		enum transcoder cpu_transcoder;
+		u32 val;
+
+		cpu_transcoder = old_crtc_state->cpu_transcoder;
+		val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+		val &= ~TGL_TRANS_DDI_PORT_MASK;
+		I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
+
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
 						  old_crtc_state, NULL);
 		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
index e6f28a517182..567873c0ac91 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -7,11 +7,13 @@
 #define __INTEL_DP_MST_H__
 
 struct intel_digital_port;
+struct intel_crtc_state;
 struct intel_encoder;
 
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
 int intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port);
+void intel_dp_mst_post_trans_disabled(const struct intel_crtc_state *old_crtc_state);
 enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder *encoder);
 
 #endif /* __INTEL_DP_MST_H__ */
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 7/7] drm/display/dp: Fix MST disable sequences
@ 2019-11-23  0:54   ` José Roberto de Souza
  0 siblings, 0 replies; 65+ messages in thread
From: José Roberto de Souza @ 2019-11-23  0:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Lucas De Marchi

The disable sequence after wait for transcoder off was not correctly
implemented.
The MST disable sequence is basically the same for HSW, SKL, ICL and
TGL, with just minor changes on TGL.

So here calling a new MST function to do the MST sequences, most of
the steps just moved from the post disable hook.

This plus the previous changes, fixed the hotplugs triggered by MST
sink during the disable/enable sequence, those were causing source to
try to do a link training while it was not ready causing CPU pipe
FIFO underrrus on TGL.

BSpec: 4231
BSpec: 4163
BSpec: 22243
BSpec: 49190
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     | 25 +++++--
 drivers/gpu/drm/i915/display/intel_display.c |  2 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 78 ++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp_mst.h  |  2 +
 4 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index aa0249333175..5950bc1ccc88 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -34,6 +34,7 @@
 #include "intel_ddi.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
+#include "intel_dp_mst.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
@@ -1954,17 +1955,27 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
-	u32 val = I915_READ(reg);
+	u32 val;
+
+	val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	val &= ~TRANS_DDI_FUNC_ENABLE;
 
 	if (INTEL_GEN(dev_priv) >= 12) {
-		val &= ~(TRANS_DDI_FUNC_ENABLE | TGL_TRANS_DDI_PORT_MASK |
-			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
+		if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
+			val &= ~TGL_TRANS_DDI_PORT_MASK;
+		} else {
+			struct intel_encoder *encoder;
+			enum transcoder master;
+
+			encoder = intel_ddi_get_crtc_encoder(crtc);
+			master = intel_dp_mst_master_trans_get(encoder);
+			if (crtc_state->cpu_transcoder != master)
+				val &= ~TGL_TRANS_DDI_PORT_MASK;
+		}
 	} else {
-		val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK |
-			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
+		val &= ~TRANS_DDI_PORT_MASK;
 	}
-	I915_WRITE(reg, val);
+	I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
 
 	if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME &&
 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 35a59108194e..e81b3d731c16 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6843,6 +6843,8 @@ static void haswell_crtc_disable(struct intel_atomic_state *state,
 	if (!transcoder_is_dsi(cpu_transcoder))
 		intel_disable_pipe(old_crtc_state);
 
+	intel_dp_mst_post_trans_disabled(old_crtc_state);
+
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_disable_transcoder_port_sync(old_crtc_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 53afe3e179f7..dc5e372bc32b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -360,6 +360,57 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
 					  old_crtc_state, old_conn_state);
 }
 
+static void
+dp_mst_post_trans_disabled(struct intel_encoder *encoder,
+			   const struct intel_crtc_state *old_crtc_state,
+			   const struct drm_connector_state *old_conn_state)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct intel_connector *connector =
+		to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 val;
+
+	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+
+	val = I915_READ(TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder));
+	val &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+	I915_WRITE(TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder), val);
+
+	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+				  DP_TP_STATUS_ACT_SENT, 1))
+		DRM_ERROR("Timed out waiting for ACT sent when disabling\n");
+
+	drm_dp_check_act_status(&intel_dp->mst_mgr);
+
+	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
+}
+
+void
+intel_dp_mst_post_trans_disabled(const struct intel_crtc_state *old_crtc_state)
+{
+	struct drm_atomic_state *state = old_crtc_state->uapi.state;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
+		return;
+
+	for_each_old_connector_in_state(state, conn, old_conn_state, i) {
+		struct intel_encoder *encoder;
+
+		if (old_conn_state->crtc != old_crtc_state->uapi.crtc)
+			continue;
+
+		encoder = to_intel_encoder(old_conn_state->best_encoder);
+		dp_mst_post_trans_disabled(encoder, old_crtc_state,
+					   old_conn_state);
+	}
+}
+
 static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 				      const struct intel_crtc_state *old_crtc_state,
 				      const struct drm_connector_state *old_conn_state)
@@ -373,6 +424,12 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 
 	intel_dp->active_mst_links--;
 
+	/*
+	 * Power down mst path before disabling the port, otherwise we end
+	 * up getting interrupts from the sink upon detecting link loss.
+	 */
+	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
+				     false);
 	/*
 	 * From TGL BSpec "If multi-stream slave transcoder: Configure
 	 * Transcoder Clock Select to direct no clock to the transcoder"
@@ -383,22 +440,17 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)
 		intel_ddi_disable_pipe_clock(old_crtc_state);
 
-	/* this can fail */
-	drm_dp_check_act_status(&intel_dp->mst_mgr);
-	/* and this can also fail */
-	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
-
-	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
-
-	/*
-	 * Power down mst path before disabling the port, otherwise we end
-	 * up getting interrupts from the sink upon detecting link loss.
-	 */
-	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
-				     false);
 
 	intel_mst->connector = NULL;
 	if (intel_dp->active_mst_links == 0) {
+		enum transcoder cpu_transcoder;
+		u32 val;
+
+		cpu_transcoder = old_crtc_state->cpu_transcoder;
+		val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+		val &= ~TGL_TRANS_DDI_PORT_MASK;
+		I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
+
 		intel_dig_port->base.post_disable(&intel_dig_port->base,
 						  old_crtc_state, NULL);
 		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
index e6f28a517182..567873c0ac91 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -7,11 +7,13 @@
 #define __INTEL_DP_MST_H__
 
 struct intel_digital_port;
+struct intel_crtc_state;
 struct intel_encoder;
 
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
 int intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port);
+void intel_dp_mst_post_trans_disabled(const struct intel_crtc_state *old_crtc_state);
 enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder *encoder);
 
 #endif /* __INTEL_DP_MST_H__ */
-- 
2.24.0

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

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

* ✓ Fi.CI.BAT: success for series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-23  1:28   ` Patchwork
  0 siblings, 0 replies; 65+ messages in thread
From: Patchwork @ 2019-11-23  1:28 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
URL   : https://patchwork.freedesktop.org/series/69921/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7409 -> Patchwork_15404
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/index.html

Known issues
------------

  Here are the changes found in Patchwork_15404 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-bxt-dsi:         [PASS][1] -> [INCOMPLETE][2] ([fdo#103927])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-bxt-dsi/igt@kms_flip@basic-flip-vs-dpms.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-bxt-dsi/igt@kms_flip@basic-flip-vs-dpms.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-hsw-peppy:       [PASS][3] -> [DMESG-WARN][4] ([fdo#102614])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html

  
#### Possible fixes ####

  * igt@i915_module_load@reload-no-display:
    - fi-skl-lmem:        [DMESG-WARN][5] ([fdo#112261]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-skl-lmem/igt@i915_module_load@reload-no-display.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-skl-lmem/igt@i915_module_load@reload-no-display.html

  * igt@kms_addfb_basic@addfb25-y-tiled:
    - fi-icl-dsi:         [DMESG-WARN][7] ([fdo#106107]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-icl-dsi/igt@kms_addfb_basic@addfb25-y-tiled.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-icl-dsi/igt@kms_addfb_basic@addfb25-y-tiled.html

  
#### Warnings ####

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-kbl-x1275:       [DMESG-WARN][9] ([fdo#103558] / [fdo#105602] / [fdo#105763]) -> [DMESG-WARN][10] ([fdo#103558] / [fdo#105602]) +4 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-kbl-x1275/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-kbl-x1275/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_flip@basic-flip-vs-modeset:
    - fi-kbl-x1275:       [DMESG-WARN][11] ([fdo#103558] / [fdo#105602]) -> [DMESG-WARN][12] ([fdo#103558] / [fdo#105602] / [fdo#105763]) +6 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html

  
  [fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
  [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#112261]: https://bugs.freedesktop.org/show_bug.cgi?id=112261


Participating hosts (50 -> 43)
------------------------------

  Missing    (7): fi-ilk-m540 fi-cml-s fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7409 -> Patchwork_15404

  CI-20190529: 20190529
  CI_DRM_7409: a00b5b72443d01a635ab02f55c589aa42ca04bcc @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5301: 3fa72891269b16943e6511166aeebee094206791 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_15404: d43a3946f9f86b90f7e61f03b3e0b3eb7c954457 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

d43a3946f9f8 drm/display/dp: Fix MST disable sequences
2663150050e2 drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
dbe1ba29775e drm/i915/display/mst: Move DPMS_OFF call to post_disable
e065899bd06b drm/i915/dp: Power down sink before disable pipe/transcoder clock
e3e3a41e875f drm/i915/tgl: Select master trasconder for MST stream
3fbb1cbbbf0c drm/i915/display: Check the old state to find port sync slave
9a3531db8d01 drm/i915/display: Refactor intel_commit_modeset_disables()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-23  1:28   ` Patchwork
  0 siblings, 0 replies; 65+ messages in thread
From: Patchwork @ 2019-11-23  1:28 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
URL   : https://patchwork.freedesktop.org/series/69921/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7409 -> Patchwork_15404
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/index.html

Known issues
------------

  Here are the changes found in Patchwork_15404 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-bxt-dsi:         [PASS][1] -> [INCOMPLETE][2] ([fdo#103927])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-bxt-dsi/igt@kms_flip@basic-flip-vs-dpms.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-bxt-dsi/igt@kms_flip@basic-flip-vs-dpms.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-hsw-peppy:       [PASS][3] -> [DMESG-WARN][4] ([fdo#102614])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html

  
#### Possible fixes ####

  * igt@i915_module_load@reload-no-display:
    - fi-skl-lmem:        [DMESG-WARN][5] ([fdo#112261]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-skl-lmem/igt@i915_module_load@reload-no-display.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-skl-lmem/igt@i915_module_load@reload-no-display.html

  * igt@kms_addfb_basic@addfb25-y-tiled:
    - fi-icl-dsi:         [DMESG-WARN][7] ([fdo#106107]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-icl-dsi/igt@kms_addfb_basic@addfb25-y-tiled.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-icl-dsi/igt@kms_addfb_basic@addfb25-y-tiled.html

  
#### Warnings ####

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-kbl-x1275:       [DMESG-WARN][9] ([fdo#103558] / [fdo#105602] / [fdo#105763]) -> [DMESG-WARN][10] ([fdo#103558] / [fdo#105602]) +4 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-kbl-x1275/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-kbl-x1275/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_flip@basic-flip-vs-modeset:
    - fi-kbl-x1275:       [DMESG-WARN][11] ([fdo#103558] / [fdo#105602]) -> [DMESG-WARN][12] ([fdo#103558] / [fdo#105602] / [fdo#105763]) +6 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html

  
  [fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
  [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#112261]: https://bugs.freedesktop.org/show_bug.cgi?id=112261


Participating hosts (50 -> 43)
------------------------------

  Missing    (7): fi-ilk-m540 fi-cml-s fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7409 -> Patchwork_15404

  CI-20190529: 20190529
  CI_DRM_7409: a00b5b72443d01a635ab02f55c589aa42ca04bcc @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5301: 3fa72891269b16943e6511166aeebee094206791 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_15404: d43a3946f9f86b90f7e61f03b3e0b3eb7c954457 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

d43a3946f9f8 drm/display/dp: Fix MST disable sequences
2663150050e2 drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
dbe1ba29775e drm/i915/display/mst: Move DPMS_OFF call to post_disable
e065899bd06b drm/i915/dp: Power down sink before disable pipe/transcoder clock
e3e3a41e875f drm/i915/tgl: Select master trasconder for MST stream
3fbb1cbbbf0c drm/i915/display: Check the old state to find port sync slave
9a3531db8d01 drm/i915/display: Refactor intel_commit_modeset_disables()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.IGT: success for series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-24  7:11   ` Patchwork
  0 siblings, 0 replies; 65+ messages in thread
From: Patchwork @ 2019-11-24  7:11 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
URL   : https://patchwork.freedesktop.org/series/69921/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7409_full -> Patchwork_15404_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Known issues
------------

  Here are the changes found in Patchwork_15404_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_persistence@vcs1-hostile:
    - shard-iclb:         [PASS][1] -> [SKIP][2] ([fdo#109276] / [fdo#112080])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@gem_ctx_persistence@vcs1-hostile.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@gem_ctx_persistence@vcs1-hostile.html

  * igt@gem_eio@in-flight-suspend:
    - shard-tglb:         [PASS][3] -> [INCOMPLETE][4] ([fdo#111832] / [fdo#111850] / [fdo#112081])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb7/igt@gem_eio@in-flight-suspend.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb1/igt@gem_eio@in-flight-suspend.html

  * igt@gem_eio@suspend:
    - shard-tglb:         [PASS][5] -> [INCOMPLETE][6] ([fdo#111850])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb6/igt@gem_eio@suspend.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb7/igt@gem_eio@suspend.html

  * igt@gem_exec_schedule@preempt-queue-chain-bsd1:
    - shard-tglb:         [PASS][7] -> [INCOMPLETE][8] ([fdo#111606] / [fdo#111677])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb1/igt@gem_exec_schedule@preempt-queue-chain-bsd1.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@gem_exec_schedule@preempt-queue-chain-bsd1.html

  * igt@gem_exec_schedule@preemptive-hang-bsd:
    - shard-iclb:         [PASS][9] -> [SKIP][10] ([fdo#112146]) +5 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb3/igt@gem_exec_schedule@preemptive-hang-bsd.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html

  * igt@gem_persistent_relocs@forked-interruptible-thrash-inactive:
    - shard-apl:          [PASS][11] -> [FAIL][12] ([fdo#112037])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-apl1/igt@gem_persistent_relocs@forked-interruptible-thrash-inactive.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-apl4/igt@gem_persistent_relocs@forked-interruptible-thrash-inactive.html

  * igt@gem_persistent_relocs@forked-interruptible-thrashing:
    - shard-tglb:         [PASS][13] -> [FAIL][14] ([fdo#112037])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb4/igt@gem_persistent_relocs@forked-interruptible-thrashing.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb1/igt@gem_persistent_relocs@forked-interruptible-thrashing.html

  * igt@gem_persistent_relocs@forked-thrashing:
    - shard-snb:          [PASS][15] -> [FAIL][16] ([fdo#112037])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-snb4/igt@gem_persistent_relocs@forked-thrashing.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-snb1/igt@gem_persistent_relocs@forked-thrashing.html

  * igt@gem_softpin@noreloc-s3:
    - shard-skl:          [PASS][17] -> [INCOMPLETE][18] ([fdo#104108])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl2/igt@gem_softpin@noreloc-s3.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl9/igt@gem_softpin@noreloc-s3.html

  * igt@gem_sync@basic-all:
    - shard-tglb:         [PASS][19] -> [INCOMPLETE][20] ([fdo#111880])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb4/igt@gem_sync@basic-all.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@gem_sync@basic-all.html

  * igt@gem_userptr_blits@map-fixed-invalidate-busy:
    - shard-snb:          [PASS][21] -> [DMESG-WARN][22] ([fdo#111870])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-snb4/igt@gem_userptr_blits@map-fixed-invalidate-busy.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-snb7/igt@gem_userptr_blits@map-fixed-invalidate-busy.html

  * igt@gem_userptr_blits@sync-unmap-after-close:
    - shard-hsw:          [PASS][23] -> [DMESG-WARN][24] ([fdo#111870])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-hsw7/igt@gem_userptr_blits@sync-unmap-after-close.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-hsw7/igt@gem_userptr_blits@sync-unmap-after-close.html

  * igt@gem_workarounds@suspend-resume:
    - shard-tglb:         [PASS][25] -> [INCOMPLETE][26] ([fdo#111832] / [fdo#111850]) +2 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb3/igt@gem_workarounds@suspend-resume.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb5/igt@gem_workarounds@suspend-resume.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          [PASS][27] -> [DMESG-WARN][28] ([fdo#108566]) +1 similar issue
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-apl7/igt@i915_suspend@fence-restore-tiled2untiled.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-apl1/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_atomic_transition@plane-toggle-modeset-transition:
    - shard-tglb:         [PASS][29] -> [DMESG-WARN][30] ([fdo#111600])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb9/igt@kms_atomic_transition@plane-toggle-modeset-transition.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb8/igt@kms_atomic_transition@plane-toggle-modeset-transition.html

  * igt@kms_color@pipe-a-ctm-negative:
    - shard-skl:          [PASS][31] -> [DMESG-WARN][32] ([fdo#106107]) +1 similar issue
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl2/igt@kms_color@pipe-a-ctm-negative.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl7/igt@kms_color@pipe-a-ctm-negative.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite:
    - shard-iclb:         [PASS][33] -> [FAIL][34] ([fdo#103167]) +7 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite.html

  * igt@kms_psr@psr2_primary_page_flip:
    - shard-iclb:         [PASS][35] -> [SKIP][36] ([fdo#109441])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@kms_psr@psr2_primary_page_flip.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb6/igt@kms_psr@psr2_primary_page_flip.html

  * igt@kms_setmode@basic:
    - shard-skl:          [PASS][37] -> [FAIL][38] ([fdo#99912])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl9/igt@kms_setmode@basic.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl3/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-kbl:          [PASS][39] -> [DMESG-WARN][40] ([fdo#108566]) +8 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-kbl7/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-kbl1/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  * igt@perf_pmu@busy-no-semaphores-vcs1:
    - shard-iclb:         [PASS][41] -> [SKIP][42] ([fdo#112080]) +6 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@perf_pmu@busy-no-semaphores-vcs1.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@perf_pmu@busy-no-semaphores-vcs1.html

  * igt@prime_busy@after-bsd2:
    - shard-iclb:         [PASS][43] -> [SKIP][44] ([fdo#109276]) +17 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@prime_busy@after-bsd2.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb3/igt@prime_busy@after-bsd2.html

  
#### Possible fixes ####

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-kbl:          [DMESG-WARN][45] ([fdo#108566]) -> [PASS][46] +9 similar issues
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-kbl7/igt@gem_ctx_isolation@rcs0-s3.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-kbl7/igt@gem_ctx_isolation@rcs0-s3.html
    - shard-apl:          [DMESG-WARN][47] ([fdo#108566]) -> [PASS][48] +1 similar issue
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-apl4/igt@gem_ctx_isolation@rcs0-s3.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-apl6/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@gem_ctx_persistence@vcs1-queued:
    - shard-iclb:         [SKIP][49] ([fdo#109276] / [fdo#112080]) -> [PASS][50] +6 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb3/igt@gem_ctx_persistence@vcs1-queued.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@gem_ctx_persistence@vcs1-queued.html

  * igt@gem_ctx_shared@exec-single-timeline-bsd:
    - shard-iclb:         [SKIP][51] ([fdo#110841]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@gem_ctx_shared@exec-single-timeline-bsd.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb6/igt@gem_ctx_shared@exec-single-timeline-bsd.html

  * igt@gem_ctx_switch@all-heavy:
    - shard-tglb:         [INCOMPLETE][53] ([fdo#111998]) -> [PASS][54]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb6/igt@gem_ctx_switch@all-heavy.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb7/igt@gem_ctx_switch@all-heavy.html

  * igt@gem_exec_parallel@vcs1-fds:
    - shard-iclb:         [SKIP][55] ([fdo#112080]) -> [PASS][56] +18 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb5/igt@gem_exec_parallel@vcs1-fds.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb4/igt@gem_exec_parallel@vcs1-fds.html

  * igt@gem_exec_schedule@reorder-wide-bsd:
    - shard-iclb:         [SKIP][57] ([fdo#112146]) -> [PASS][58] +7 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@gem_exec_schedule@reorder-wide-bsd.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb3/igt@gem_exec_schedule@reorder-wide-bsd.html

  * igt@gem_userptr_blits@map-fixed-invalidate-overlap-busy:
    - shard-snb:          [DMESG-WARN][59] ([fdo#111870]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-snb7/igt@gem_userptr_blits@map-fixed-invalidate-overlap-busy.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-snb1/igt@gem_userptr_blits@map-fixed-invalidate-overlap-busy.html

  * igt@i915_pm_dc@dc5-dpms:
    - shard-iclb:         [FAIL][61] ([fdo#111795 ]) -> [PASS][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb3/igt@i915_pm_dc@dc5-dpms.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@i915_pm_dc@dc5-dpms.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-90:
    - shard-skl:          [INCOMPLETE][63] ([fdo#112347]) -> [PASS][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl9/igt@kms_big_fb@yf-tiled-32bpp-rotate-90.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl10/igt@kms_big_fb@yf-tiled-32bpp-rotate-90.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
    - shard-hsw:          [FAIL][65] ([fdo#105767]) -> [PASS][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html

  * igt@kms_flip@flip-vs-expired-vblank:
    - shard-glk:          [FAIL][67] ([fdo#105363]) -> [PASS][68]
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-glk5/igt@kms_flip@flip-vs-expired-vblank.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-glk4/igt@kms_flip@flip-vs-expired-vblank.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-tglb:         [INCOMPLETE][69] ([fdo#111832] / [fdo#111850] / [fdo#112031]) -> [PASS][70]
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb7/igt@kms_flip@flip-vs-suspend-interruptible.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_flip@plain-flip-fb-recreate:
    - shard-glk:          [FAIL][71] ([fdo#100368]) -> [PASS][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-glk4/igt@kms_flip@plain-flip-fb-recreate.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-glk5/igt@kms_flip@plain-flip-fb-recreate.html

  * igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw:
    - shard-iclb:         [FAIL][73] ([fdo#103167]) -> [PASS][74] +2 similar issues
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt:
    - shard-tglb:         [FAIL][75] ([fdo#103167]) -> [PASS][76]
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb7/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][77] ([fdo#108145] / [fdo#110403]) -> [PASS][78] +1 similar issue
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl5/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_plane_lowres@pipe-a-tiling-y:
    - shard-iclb:         [FAIL][79] ([fdo#103166]) -> [PASS][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb6/igt@kms_plane_lowres@pipe-a-tiling-y.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb2/igt@kms_plane_lowres@pipe-a-tiling-y.html

  * igt@kms_psr@no_drrs:
    - shard-iclb:         [FAIL][81] ([fdo#108341]) -> [PASS][82]
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@kms_psr@no_drrs.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@kms_psr@no_drrs.html

  * igt@kms_psr@psr2_no_drrs:
    - shard-iclb:         [SKIP][83] ([fdo#109441]) -> [PASS][84] +2 similar issues
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb4/igt@kms_psr@psr2_no_drrs.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb2/igt@kms_psr@psr2_no_drrs.html

  * igt@kms_vblank@pipe-c-ts-continuation-suspend:
    - shard-tglb:         [INCOMPLETE][85] ([fdo#111832] / [fdo#111850]) -> [PASS][86] +2 similar issues
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb4/igt@kms_vblank@pipe-c-ts-continuation-suspend.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb9/igt@kms_vblank@pipe-c-ts-continuation-suspend.html

  * igt@kms_vblank@pipe-d-ts-continuation-suspend:
    - shard-tglb:         [INCOMPLETE][87] ([fdo#111850]) -> [PASS][88]
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb2/igt@kms_vblank@pipe-d-ts-continuation-suspend.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@kms_vblank@pipe-d-ts-continuation-suspend.html

  * igt@prime_vgem@fence-wait-bsd2:
    - shard-iclb:         [SKIP][89] ([fdo#109276]) -> [PASS][90] +27 similar issues
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb8/igt@prime_vgem@fence-wait-bsd2.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@prime_vgem@fence-wait-bsd2.html

  
#### Warnings ####

  * igt@gem_ctx_isolation@vcs1-nonpriv:
    - shard-iclb:         [SKIP][91] ([fdo#109276] / [fdo#112080]) -> [FAIL][92] ([fdo#111329])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@gem_ctx_isolation@vcs1-nonpriv.html

  * igt@gem_ctx_isolation@vcs1-nonpriv-switch:
    - shard-iclb:         [FAIL][93] ([fdo#111329]) -> [SKIP][94] ([fdo#109276] / [fdo#112080])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@gem_ctx_isolation@vcs1-nonpriv-switch.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv-switch.html

  * igt@gem_exec_schedule@deep-bsd2:
    - shard-tglb:         [INCOMPLETE][95] ([fdo#111671]) -> [FAIL][96] ([fdo#111646]) +1 similar issue
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb8/igt@gem_exec_schedule@deep-bsd2.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb9/igt@gem_exec_schedule@deep-bsd2.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [SKIP][97] ([fdo#109441]) -> [DMESG-WARN][98] ([fdo#107724])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb4/igt@kms_psr@psr2_suspend.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb2/igt@kms_psr@psr2_suspend.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#100368]: https://bugs.freedesktop.org/show_bug.cgi?id=100368
  [fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
  [fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
  [fdo#105767]: https://bugs.freedesktop.org/show_bug.cgi?id=105767
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108341]: https://bugs.freedesktop.org/show_bug.cgi?id=108341
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#110403]: https://bugs.freedesktop.org/show_bug.cgi?id=110403
  [fdo#110841]: https://bugs.freedesktop.org/show_bug.cgi?id=110841
  [fdo#111329]: https://bugs.freedesktop.org/show_bug.cgi?id=111329
  [fdo#111600]: https://bugs.freedesktop.org/show_bug.cgi?id=111600
  [fdo#111606]: https://bugs.freedesktop.org/show_bug.cgi?id=111606
  [fdo#111646]: https://bugs.freedesktop.org/show_bug.cgi?id=111646
  [fdo#111671]: https://bugs.freedesktop.org/show_bug.cgi?id=111671
  [fdo#111677]: https://bugs.freedesktop.org/show_bug.cgi?id=111677
  [fdo#111795 ]: https://bugs.freedesktop.org/show_bug.cgi?id=111795 
  [fdo#111832]: https://bugs.freedesktop.org/show_bug.cgi?id=111832
  [fdo#111850]: https://bugs.f

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✓ Fi.CI.IGT: success for series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-24  7:11   ` Patchwork
  0 siblings, 0 replies; 65+ messages in thread
From: Patchwork @ 2019-11-24  7:11 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
URL   : https://patchwork.freedesktop.org/series/69921/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7409_full -> Patchwork_15404_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Known issues
------------

  Here are the changes found in Patchwork_15404_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_persistence@vcs1-hostile:
    - shard-iclb:         [PASS][1] -> [SKIP][2] ([fdo#109276] / [fdo#112080])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@gem_ctx_persistence@vcs1-hostile.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@gem_ctx_persistence@vcs1-hostile.html

  * igt@gem_eio@in-flight-suspend:
    - shard-tglb:         [PASS][3] -> [INCOMPLETE][4] ([fdo#111832] / [fdo#111850] / [fdo#112081])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb7/igt@gem_eio@in-flight-suspend.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb1/igt@gem_eio@in-flight-suspend.html

  * igt@gem_eio@suspend:
    - shard-tglb:         [PASS][5] -> [INCOMPLETE][6] ([fdo#111850])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb6/igt@gem_eio@suspend.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb7/igt@gem_eio@suspend.html

  * igt@gem_exec_schedule@preempt-queue-chain-bsd1:
    - shard-tglb:         [PASS][7] -> [INCOMPLETE][8] ([fdo#111606] / [fdo#111677])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb1/igt@gem_exec_schedule@preempt-queue-chain-bsd1.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@gem_exec_schedule@preempt-queue-chain-bsd1.html

  * igt@gem_exec_schedule@preemptive-hang-bsd:
    - shard-iclb:         [PASS][9] -> [SKIP][10] ([fdo#112146]) +5 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb3/igt@gem_exec_schedule@preemptive-hang-bsd.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html

  * igt@gem_persistent_relocs@forked-interruptible-thrash-inactive:
    - shard-apl:          [PASS][11] -> [FAIL][12] ([fdo#112037])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-apl1/igt@gem_persistent_relocs@forked-interruptible-thrash-inactive.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-apl4/igt@gem_persistent_relocs@forked-interruptible-thrash-inactive.html

  * igt@gem_persistent_relocs@forked-interruptible-thrashing:
    - shard-tglb:         [PASS][13] -> [FAIL][14] ([fdo#112037])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb4/igt@gem_persistent_relocs@forked-interruptible-thrashing.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb1/igt@gem_persistent_relocs@forked-interruptible-thrashing.html

  * igt@gem_persistent_relocs@forked-thrashing:
    - shard-snb:          [PASS][15] -> [FAIL][16] ([fdo#112037])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-snb4/igt@gem_persistent_relocs@forked-thrashing.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-snb1/igt@gem_persistent_relocs@forked-thrashing.html

  * igt@gem_softpin@noreloc-s3:
    - shard-skl:          [PASS][17] -> [INCOMPLETE][18] ([fdo#104108])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl2/igt@gem_softpin@noreloc-s3.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl9/igt@gem_softpin@noreloc-s3.html

  * igt@gem_sync@basic-all:
    - shard-tglb:         [PASS][19] -> [INCOMPLETE][20] ([fdo#111880])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb4/igt@gem_sync@basic-all.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@gem_sync@basic-all.html

  * igt@gem_userptr_blits@map-fixed-invalidate-busy:
    - shard-snb:          [PASS][21] -> [DMESG-WARN][22] ([fdo#111870])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-snb4/igt@gem_userptr_blits@map-fixed-invalidate-busy.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-snb7/igt@gem_userptr_blits@map-fixed-invalidate-busy.html

  * igt@gem_userptr_blits@sync-unmap-after-close:
    - shard-hsw:          [PASS][23] -> [DMESG-WARN][24] ([fdo#111870])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-hsw7/igt@gem_userptr_blits@sync-unmap-after-close.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-hsw7/igt@gem_userptr_blits@sync-unmap-after-close.html

  * igt@gem_workarounds@suspend-resume:
    - shard-tglb:         [PASS][25] -> [INCOMPLETE][26] ([fdo#111832] / [fdo#111850]) +2 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb3/igt@gem_workarounds@suspend-resume.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb5/igt@gem_workarounds@suspend-resume.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          [PASS][27] -> [DMESG-WARN][28] ([fdo#108566]) +1 similar issue
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-apl7/igt@i915_suspend@fence-restore-tiled2untiled.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-apl1/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_atomic_transition@plane-toggle-modeset-transition:
    - shard-tglb:         [PASS][29] -> [DMESG-WARN][30] ([fdo#111600])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb9/igt@kms_atomic_transition@plane-toggle-modeset-transition.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb8/igt@kms_atomic_transition@plane-toggle-modeset-transition.html

  * igt@kms_color@pipe-a-ctm-negative:
    - shard-skl:          [PASS][31] -> [DMESG-WARN][32] ([fdo#106107]) +1 similar issue
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl2/igt@kms_color@pipe-a-ctm-negative.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl7/igt@kms_color@pipe-a-ctm-negative.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite:
    - shard-iclb:         [PASS][33] -> [FAIL][34] ([fdo#103167]) +7 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite.html

  * igt@kms_psr@psr2_primary_page_flip:
    - shard-iclb:         [PASS][35] -> [SKIP][36] ([fdo#109441])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@kms_psr@psr2_primary_page_flip.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb6/igt@kms_psr@psr2_primary_page_flip.html

  * igt@kms_setmode@basic:
    - shard-skl:          [PASS][37] -> [FAIL][38] ([fdo#99912])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl9/igt@kms_setmode@basic.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl3/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-kbl:          [PASS][39] -> [DMESG-WARN][40] ([fdo#108566]) +8 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-kbl7/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-kbl1/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  * igt@perf_pmu@busy-no-semaphores-vcs1:
    - shard-iclb:         [PASS][41] -> [SKIP][42] ([fdo#112080]) +6 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@perf_pmu@busy-no-semaphores-vcs1.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@perf_pmu@busy-no-semaphores-vcs1.html

  * igt@prime_busy@after-bsd2:
    - shard-iclb:         [PASS][43] -> [SKIP][44] ([fdo#109276]) +17 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@prime_busy@after-bsd2.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb3/igt@prime_busy@after-bsd2.html

  
#### Possible fixes ####

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-kbl:          [DMESG-WARN][45] ([fdo#108566]) -> [PASS][46] +9 similar issues
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-kbl7/igt@gem_ctx_isolation@rcs0-s3.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-kbl7/igt@gem_ctx_isolation@rcs0-s3.html
    - shard-apl:          [DMESG-WARN][47] ([fdo#108566]) -> [PASS][48] +1 similar issue
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-apl4/igt@gem_ctx_isolation@rcs0-s3.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-apl6/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@gem_ctx_persistence@vcs1-queued:
    - shard-iclb:         [SKIP][49] ([fdo#109276] / [fdo#112080]) -> [PASS][50] +6 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb3/igt@gem_ctx_persistence@vcs1-queued.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@gem_ctx_persistence@vcs1-queued.html

  * igt@gem_ctx_shared@exec-single-timeline-bsd:
    - shard-iclb:         [SKIP][51] ([fdo#110841]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@gem_ctx_shared@exec-single-timeline-bsd.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb6/igt@gem_ctx_shared@exec-single-timeline-bsd.html

  * igt@gem_ctx_switch@all-heavy:
    - shard-tglb:         [INCOMPLETE][53] ([fdo#111998]) -> [PASS][54]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb6/igt@gem_ctx_switch@all-heavy.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb7/igt@gem_ctx_switch@all-heavy.html

  * igt@gem_exec_parallel@vcs1-fds:
    - shard-iclb:         [SKIP][55] ([fdo#112080]) -> [PASS][56] +18 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb5/igt@gem_exec_parallel@vcs1-fds.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb4/igt@gem_exec_parallel@vcs1-fds.html

  * igt@gem_exec_schedule@reorder-wide-bsd:
    - shard-iclb:         [SKIP][57] ([fdo#112146]) -> [PASS][58] +7 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb2/igt@gem_exec_schedule@reorder-wide-bsd.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb3/igt@gem_exec_schedule@reorder-wide-bsd.html

  * igt@gem_userptr_blits@map-fixed-invalidate-overlap-busy:
    - shard-snb:          [DMESG-WARN][59] ([fdo#111870]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-snb7/igt@gem_userptr_blits@map-fixed-invalidate-overlap-busy.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-snb1/igt@gem_userptr_blits@map-fixed-invalidate-overlap-busy.html

  * igt@i915_pm_dc@dc5-dpms:
    - shard-iclb:         [FAIL][61] ([fdo#111795 ]) -> [PASS][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb3/igt@i915_pm_dc@dc5-dpms.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@i915_pm_dc@dc5-dpms.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-90:
    - shard-skl:          [INCOMPLETE][63] ([fdo#112347]) -> [PASS][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl9/igt@kms_big_fb@yf-tiled-32bpp-rotate-90.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl10/igt@kms_big_fb@yf-tiled-32bpp-rotate-90.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
    - shard-hsw:          [FAIL][65] ([fdo#105767]) -> [PASS][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html

  * igt@kms_flip@flip-vs-expired-vblank:
    - shard-glk:          [FAIL][67] ([fdo#105363]) -> [PASS][68]
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-glk5/igt@kms_flip@flip-vs-expired-vblank.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-glk4/igt@kms_flip@flip-vs-expired-vblank.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-tglb:         [INCOMPLETE][69] ([fdo#111832] / [fdo#111850] / [fdo#112031]) -> [PASS][70]
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb7/igt@kms_flip@flip-vs-suspend-interruptible.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_flip@plain-flip-fb-recreate:
    - shard-glk:          [FAIL][71] ([fdo#100368]) -> [PASS][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-glk4/igt@kms_flip@plain-flip-fb-recreate.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-glk5/igt@kms_flip@plain-flip-fb-recreate.html

  * igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw:
    - shard-iclb:         [FAIL][73] ([fdo#103167]) -> [PASS][74] +2 similar issues
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt:
    - shard-tglb:         [FAIL][75] ([fdo#103167]) -> [PASS][76]
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb7/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][77] ([fdo#108145] / [fdo#110403]) -> [PASS][78] +1 similar issue
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-skl5/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_plane_lowres@pipe-a-tiling-y:
    - shard-iclb:         [FAIL][79] ([fdo#103166]) -> [PASS][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb6/igt@kms_plane_lowres@pipe-a-tiling-y.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb2/igt@kms_plane_lowres@pipe-a-tiling-y.html

  * igt@kms_psr@no_drrs:
    - shard-iclb:         [FAIL][81] ([fdo#108341]) -> [PASS][82]
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@kms_psr@no_drrs.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@kms_psr@no_drrs.html

  * igt@kms_psr@psr2_no_drrs:
    - shard-iclb:         [SKIP][83] ([fdo#109441]) -> [PASS][84] +2 similar issues
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb4/igt@kms_psr@psr2_no_drrs.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb2/igt@kms_psr@psr2_no_drrs.html

  * igt@kms_vblank@pipe-c-ts-continuation-suspend:
    - shard-tglb:         [INCOMPLETE][85] ([fdo#111832] / [fdo#111850]) -> [PASS][86] +2 similar issues
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb4/igt@kms_vblank@pipe-c-ts-continuation-suspend.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb9/igt@kms_vblank@pipe-c-ts-continuation-suspend.html

  * igt@kms_vblank@pipe-d-ts-continuation-suspend:
    - shard-tglb:         [INCOMPLETE][87] ([fdo#111850]) -> [PASS][88]
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb2/igt@kms_vblank@pipe-d-ts-continuation-suspend.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb6/igt@kms_vblank@pipe-d-ts-continuation-suspend.html

  * igt@prime_vgem@fence-wait-bsd2:
    - shard-iclb:         [SKIP][89] ([fdo#109276]) -> [PASS][90] +27 similar issues
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb8/igt@prime_vgem@fence-wait-bsd2.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@prime_vgem@fence-wait-bsd2.html

  
#### Warnings ####

  * igt@gem_ctx_isolation@vcs1-nonpriv:
    - shard-iclb:         [SKIP][91] ([fdo#109276] / [fdo#112080]) -> [FAIL][92] ([fdo#111329])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb1/igt@gem_ctx_isolation@vcs1-nonpriv.html

  * igt@gem_ctx_isolation@vcs1-nonpriv-switch:
    - shard-iclb:         [FAIL][93] ([fdo#111329]) -> [SKIP][94] ([fdo#109276] / [fdo#112080])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb1/igt@gem_ctx_isolation@vcs1-nonpriv-switch.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv-switch.html

  * igt@gem_exec_schedule@deep-bsd2:
    - shard-tglb:         [INCOMPLETE][95] ([fdo#111671]) -> [FAIL][96] ([fdo#111646]) +1 similar issue
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-tglb8/igt@gem_exec_schedule@deep-bsd2.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-tglb9/igt@gem_exec_schedule@deep-bsd2.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [SKIP][97] ([fdo#109441]) -> [DMESG-WARN][98] ([fdo#107724])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7409/shard-iclb4/igt@kms_psr@psr2_suspend.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/shard-iclb2/igt@kms_psr@psr2_suspend.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#100368]: https://bugs.freedesktop.org/show_bug.cgi?id=100368
  [fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
  [fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
  [fdo#105767]: https://bugs.freedesktop.org/show_bug.cgi?id=105767
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108341]: https://bugs.freedesktop.org/show_bug.cgi?id=108341
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#110403]: https://bugs.freedesktop.org/show_bug.cgi?id=110403
  [fdo#110841]: https://bugs.freedesktop.org/show_bug.cgi?id=110841
  [fdo#111329]: https://bugs.freedesktop.org/show_bug.cgi?id=111329
  [fdo#111600]: https://bugs.freedesktop.org/show_bug.cgi?id=111600
  [fdo#111606]: https://bugs.freedesktop.org/show_bug.cgi?id=111606
  [fdo#111646]: https://bugs.freedesktop.org/show_bug.cgi?id=111646
  [fdo#111671]: https://bugs.freedesktop.org/show_bug.cgi?id=111671
  [fdo#111677]: https://bugs.freedesktop.org/show_bug.cgi?id=111677
  [fdo#111795 ]: https://bugs.freedesktop.org/show_bug.cgi?id=111795 
  [fdo#111832]: https://bugs.freedesktop.org/show_bug.cgi?id=111832
  [fdo#111850]: https://bugs.f

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15404/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 19:40   ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 19:40 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza wrote:
> Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> reverted the order that pipes gets disabled because of TGL
> master/slave relationship between transcoders in MST mode.
> 
> But as stated in a comment in skl_commit_modeset_enables() the
> enabling order is not always crescent, possibly causing previously
> selected slave transcoder being enabled before master so another
> approach will be needed to select a transcoder to master in MST mode.
> It will be similar to the approach taken in port sync.
> 
> But instead of implement something like
> intel_trans_port_sync_modeset_disables() to MST lets simply it and
> iterate over all pipes 2 times, the first one disabling any slave and
> then disabling everything else.
> The MST bits will be added in another patch.
> 
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------------
>  1 file changed, 22 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 53dc310a5f6d..1b1fbb6d8acc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14443,53 +14443,16 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>  		dev_priv->display.initial_watermarks(state, crtc);
>  }
>  
> -static void intel_trans_port_sync_modeset_disables(struct intel_atomic_state *state,
> -						   struct intel_crtc *crtc,
> -						   struct intel_crtc_state *old_crtc_state,
> -						   struct intel_crtc_state *new_crtc_state)
> -{
> -	struct intel_crtc *slave_crtc = intel_get_slave_crtc(new_crtc_state);
> -	struct intel_crtc_state *new_slave_crtc_state =
> -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> -	struct intel_crtc_state *old_slave_crtc_state =
> -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> -
> -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> -		!old_slave_crtc_state);
> -
> -	/* Disable Slave first */
> -	intel_pre_plane_update(old_slave_crtc_state, new_slave_crtc_state);
> -	if (old_slave_crtc_state->hw.active)
> -		intel_old_crtc_state_disables(state,
> -					      old_slave_crtc_state,
> -					      new_slave_crtc_state,
> -					      slave_crtc);
> -
> -	/* Disable Master */
> -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> -	if (old_crtc_state->hw.active)
> -		intel_old_crtc_state_disables(state,
> -					      old_crtc_state,
> -					      new_crtc_state,
> -					      crtc);
> -}
> -
>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  {
>  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>  	struct intel_crtc *crtc;
>  	int i;
>  
> -	/*
> -	 * Disable CRTC/pipes in reverse order because some features(MST in
> -	 * TGL+) requires master and slave relationship between pipes, so it
> -	 * should always pick the lowest pipe as master as it will be enabled
> -	 * first and disable in the reverse order so the master will be the
> -	 * last one to be disabled.
> -	 */
> -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
> -						    new_crtc_state, i) {
> -		if (!needs_modeset(new_crtc_state))
> +	/* Only disable port sync slaves */
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		if (!needs_modeset(new_crtc_state) || !crtc->active)

What's the deal with these crtc->active checks?

>  			continue;
>  
>  		/* In case of Transcoder port Sync master slave CRTCs can be
> @@ -14497,23 +14460,25 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  		 * slave CRTCs are disabled first and then master CRTC since
>  		 * Slave vblanks are masked till Master Vblanks.
>  		 */
> -		if (is_trans_port_sync_mode(new_crtc_state)) {
> -			if (is_trans_port_sync_master(new_crtc_state))
> -				intel_trans_port_sync_modeset_disables(state,
> -								       crtc,
> -								       old_crtc_state,
> -								       new_crtc_state);
> -			else
> -				continue;
> -		} else {
> -			intel_pre_plane_update(old_crtc_state, new_crtc_state);
> +		if (!is_trans_port_sync_mode(new_crtc_state))
> +			continue;
> +		if (is_trans_port_sync_master(new_crtc_state))
> +			continue;

We don't have is_trans_sync_slave()?

>  
> -			if (old_crtc_state->hw.active)
> -				intel_old_crtc_state_disables(state,
> -							      old_crtc_state,
> -							      new_crtc_state,
> -							      crtc);
> -		}
> +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> +		intel_old_crtc_state_disables(state, old_crtc_state,
> +					      new_crtc_state, crtc);
> +	}
> +
> +	/* Disable everything else left on */
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> +			continue;
> +
> +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> +		intel_old_crtc_state_disables(state, old_crtc_state,
> +					      new_crtc_state, crtc);

Pondering if there's any chance of some odd fail if we have two ports
running in port sync mode. That will now lead to
disable_slave(0)->disable_slave(1)->disable_master(0)->disable_master(1)...

>  	}
>  }
>  
> -- 
> 2.24.0

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

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 19:40   ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 19:40 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza wrote:
> Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> reverted the order that pipes gets disabled because of TGL
> master/slave relationship between transcoders in MST mode.
> 
> But as stated in a comment in skl_commit_modeset_enables() the
> enabling order is not always crescent, possibly causing previously
> selected slave transcoder being enabled before master so another
> approach will be needed to select a transcoder to master in MST mode.
> It will be similar to the approach taken in port sync.
> 
> But instead of implement something like
> intel_trans_port_sync_modeset_disables() to MST lets simply it and
> iterate over all pipes 2 times, the first one disabling any slave and
> then disabling everything else.
> The MST bits will be added in another patch.
> 
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------------
>  1 file changed, 22 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 53dc310a5f6d..1b1fbb6d8acc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14443,53 +14443,16 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>  		dev_priv->display.initial_watermarks(state, crtc);
>  }
>  
> -static void intel_trans_port_sync_modeset_disables(struct intel_atomic_state *state,
> -						   struct intel_crtc *crtc,
> -						   struct intel_crtc_state *old_crtc_state,
> -						   struct intel_crtc_state *new_crtc_state)
> -{
> -	struct intel_crtc *slave_crtc = intel_get_slave_crtc(new_crtc_state);
> -	struct intel_crtc_state *new_slave_crtc_state =
> -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> -	struct intel_crtc_state *old_slave_crtc_state =
> -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> -
> -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> -		!old_slave_crtc_state);
> -
> -	/* Disable Slave first */
> -	intel_pre_plane_update(old_slave_crtc_state, new_slave_crtc_state);
> -	if (old_slave_crtc_state->hw.active)
> -		intel_old_crtc_state_disables(state,
> -					      old_slave_crtc_state,
> -					      new_slave_crtc_state,
> -					      slave_crtc);
> -
> -	/* Disable Master */
> -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> -	if (old_crtc_state->hw.active)
> -		intel_old_crtc_state_disables(state,
> -					      old_crtc_state,
> -					      new_crtc_state,
> -					      crtc);
> -}
> -
>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  {
>  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>  	struct intel_crtc *crtc;
>  	int i;
>  
> -	/*
> -	 * Disable CRTC/pipes in reverse order because some features(MST in
> -	 * TGL+) requires master and slave relationship between pipes, so it
> -	 * should always pick the lowest pipe as master as it will be enabled
> -	 * first and disable in the reverse order so the master will be the
> -	 * last one to be disabled.
> -	 */
> -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
> -						    new_crtc_state, i) {
> -		if (!needs_modeset(new_crtc_state))
> +	/* Only disable port sync slaves */
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		if (!needs_modeset(new_crtc_state) || !crtc->active)

What's the deal with these crtc->active checks?

>  			continue;
>  
>  		/* In case of Transcoder port Sync master slave CRTCs can be
> @@ -14497,23 +14460,25 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  		 * slave CRTCs are disabled first and then master CRTC since
>  		 * Slave vblanks are masked till Master Vblanks.
>  		 */
> -		if (is_trans_port_sync_mode(new_crtc_state)) {
> -			if (is_trans_port_sync_master(new_crtc_state))
> -				intel_trans_port_sync_modeset_disables(state,
> -								       crtc,
> -								       old_crtc_state,
> -								       new_crtc_state);
> -			else
> -				continue;
> -		} else {
> -			intel_pre_plane_update(old_crtc_state, new_crtc_state);
> +		if (!is_trans_port_sync_mode(new_crtc_state))
> +			continue;
> +		if (is_trans_port_sync_master(new_crtc_state))
> +			continue;

We don't have is_trans_sync_slave()?

>  
> -			if (old_crtc_state->hw.active)
> -				intel_old_crtc_state_disables(state,
> -							      old_crtc_state,
> -							      new_crtc_state,
> -							      crtc);
> -		}
> +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> +		intel_old_crtc_state_disables(state, old_crtc_state,
> +					      new_crtc_state, crtc);
> +	}
> +
> +	/* Disable everything else left on */
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> +			continue;
> +
> +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> +		intel_old_crtc_state_disables(state, old_crtc_state,
> +					      new_crtc_state, crtc);

Pondering if there's any chance of some odd fail if we have two ports
running in port sync mode. That will now lead to
disable_slave(0)->disable_slave(1)->disable_master(0)->disable_master(1)...

>  	}
>  }
>  
> -- 
> 2.24.0

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

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

* Re: [PATCH 2/7] drm/i915/display: Check the old state to find port sync slave
@ 2019-11-26 19:41     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 19:41 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Fri, Nov 22, 2019 at 04:54:54PM -0800, José Roberto de Souza wrote:
> If the CRTC is going from enabled to disabled and it is a port sync
> slave, it needs to check to the old state to be disabled before the
> port sync master.
> 
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 1b1fbb6d8acc..801b975c7d39 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14460,9 +14460,9 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  		 * slave CRTCs are disabled first and then master CRTC since
>  		 * Slave vblanks are masked till Master Vblanks.
>  		 */
> -		if (!is_trans_port_sync_mode(new_crtc_state))
> +		if (!is_trans_port_sync_mode(old_crtc_state))
>  			continue;
> -		if (is_trans_port_sync_master(new_crtc_state))
> +		if (is_trans_port_sync_master(old_crtc_state))
>  			continue;

Maybe this should be patch 1?

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  
>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> -- 
> 2.24.0

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

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

* Re: [Intel-gfx] [PATCH 2/7] drm/i915/display: Check the old state to find port sync slave
@ 2019-11-26 19:41     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 19:41 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Fri, Nov 22, 2019 at 04:54:54PM -0800, José Roberto de Souza wrote:
> If the CRTC is going from enabled to disabled and it is a port sync
> slave, it needs to check to the old state to be disabled before the
> port sync master.
> 
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 1b1fbb6d8acc..801b975c7d39 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14460,9 +14460,9 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  		 * slave CRTCs are disabled first and then master CRTC since
>  		 * Slave vblanks are masked till Master Vblanks.
>  		 */
> -		if (!is_trans_port_sync_mode(new_crtc_state))
> +		if (!is_trans_port_sync_mode(old_crtc_state))
>  			continue;
> -		if (is_trans_port_sync_master(new_crtc_state))
> +		if (is_trans_port_sync_master(old_crtc_state))
>  			continue;

Maybe this should be patch 1?

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  
>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> -- 
> 2.24.0

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

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

* Re: [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-26 20:05     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 20:05 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Lucas De Marchi

On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza wrote:
> On TGL the blending of all the streams have moved from DDI to
> transcoder, so now every transcoder working over the same MST port must
> send its stream to a master transcoder and master will send to DDI
> respecting the time slots.
> 
> A previous approach was using the lowest pipe/transcoder as master
> transcoder but as the comment in skl_commit_modeset_enables() states,
> that is not always true.
> 
> So here promoting the first pipe/transcoder of the stream as master.
> That caused several other problems as during the commit phase the
> state computed should not be changed.
> 
> So the master transcoder is store into intel_dp and the modeset in
> slave pipes/transcoders is forced using mst_master_trans_pending.
> 
> v2:
> - added missing config compute to trigger fullmodeset in slave
> transcoders
> 
> BSpec: 50493
> BSpec: 49190
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
>  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
>  .../drm/i915/display/intel_display_types.h    |   3 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149 +++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
>  6 files changed, 216 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index a976606d21c7..d2f0d393d3ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -35,6 +35,7 @@
>  #include "intel_display_types.h"
>  #include "intel_dp.h"
>  #include "intel_dp_link_training.h"
> +#include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
>  #include "intel_dsi.h"
>  #include "intel_fifo_underrun.h"
> @@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
>  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
>  
> -		if (INTEL_GEN(dev_priv) >= 12)
> -			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> +		if (INTEL_GEN(dev_priv) >= 12) {
> +			enum transcoder master;
> +
> +			master = intel_dp_mst_master_trans_get(encoder);

Why isn't that just stored in the crtc state like everything else?

I'm thinking we should maybe do it just like port sync and have both
master + slave_mask. That way it should be pretty trivial to add all
the relevant crtcs to the state when needed.

> +			WARN_ON(master == INVALID_TRANSCODER);
> +			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
> +		}
>  	} else {
>  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
>  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 801b975c7d39..35a59108194e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -46,6 +46,7 @@
>  #include "display/intel_crt.h"
>  #include "display/intel_ddi.h"
>  #include "display/intel_dp.h"
> +#include "display/intel_dp_mst.h"
>  #include "display/intel_dsi.h"
>  #include "display/intel_dvo.h"
>  #include "display/intel_gmbus.h"
> @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>  	return encoder;
>  }
>  
> +/*
> + * Finds the encoder associated with the given CRTC. This can only be
> + * used when we know that the CRTC isn't feeding multiple encoders!
> + */
> +static struct intel_encoder *
> +intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
> +			   const struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_connector_state *connector_state;
> +	const struct drm_connector *connector;
> +	struct intel_encoder *encoder = NULL;
> +	int num_encoders = 0;
> +	int i;
> +
> +	for_each_old_connector_in_state(&state->base, connector,
> +					connector_state, i) {
> +		if (connector_state->crtc != &crtc->base)
> +			continue;
> +
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +		num_encoders++;
> +	}
> +
> +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> +	     num_encoders, pipe_name(crtc->pipe));
> +
> +	return encoder;
> +}

Argh. I was hoping to kill the other one of these. Got it down to 1
remaining user now I think.

> +
>  /*
>   * Enable PCH resources required for PCH ports:
>   *   - PCH PLLs
> @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  #undef PIPE_CONF_CHECK_COLOR_LUT
>  #undef PIPE_CONF_QUIRK
>  
> +	if (fastset && pipe_config->mst_master_trans_pending) {
> +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in mst_master_trans\n",
> +			      crtc->base.base.id, crtc->base.name);
> +		ret = false;
> +	}
> +
>  	return ret;
>  }
>  
> @@ -14449,22 +14486,35 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	struct intel_crtc *crtc;
>  	int i;
>  
> -	/* Only disable port sync slaves */
> +	/* Only disable port sync and MST slaves */
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
>  		if (!needs_modeset(new_crtc_state) || !crtc->active)
>  			continue;
>  
> +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> +		    !intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
> +			continue;
> +
>  		/* In case of Transcoder port Sync master slave CRTCs can be
>  		 * assigned in any order and we need to make sure that
>  		 * slave CRTCs are disabled first and then master CRTC since
>  		 * Slave vblanks are masked till Master Vblanks.
>  		 */
> -		if (!is_trans_port_sync_mode(old_crtc_state))
> -			continue;
> -		if (is_trans_port_sync_master(old_crtc_state))
> +		if (is_trans_port_sync_mode(new_crtc_state) &&
> +		    is_trans_port_sync_master(new_crtc_state))
>  			continue;
>  
> +		if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
> +			struct intel_encoder *encoder;
> +
> +			encoder = intel_get_crtc_old_encoder(state,
> +							     old_crtc_state);
> +			if (intel_dp_mst_master_trans_get(encoder) ==
> +			    old_crtc_state->cpu_transcoder)
> +				continue;
> +		}
> +
>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>  		intel_old_crtc_state_disables(state, old_crtc_state,
>  					      new_crtc_state, crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..23d747cdca64 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
>  	/* Pointer to master transcoder in case of tiled displays */
>  	enum transcoder master_transcoder;
>  
> +	bool mst_master_trans_pending;
> +
>  	/* Bitmask to indicate slaves attached */
>  	u8 sync_mode_slaves_mask;
>  };
> @@ -1284,6 +1286,7 @@ struct intel_dp {
>  	bool can_mst; /* this port supports mst */
>  	bool is_mst;
>  	int active_mst_links;
> +	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
>  
>  	/*
>  	 * DP_TP_* registers may be either on port or transcoder register space.
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 3123958e2081..ceff6901451a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_dp->reset_link_params = true;
>  	intel_dp->pps_pipe = INVALID_PIPE;
>  	intel_dp->active_pipe = INVALID_PIPE;
> +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
>  
>  	/* Preserve the current hw state. */
>  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index f8a350359346..9731c3c1d3f2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -87,6 +87,47 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  	return 0;
>  }
>  
> +static int
> +intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
> +				  struct intel_crtc_state *pipe_config,
> +				  struct drm_connector_state *conn_state)
> +{
> +	struct intel_atomic_state *state = to_intel_atomic_state(pipe_config->uapi.state);
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	struct intel_crtc_state *new_crtc_state;
> +	struct intel_crtc *crtc;
> +	enum transcoder master;
> +	int i;
> +
> +	if (INTEL_GEN(dev_priv) < 12)
> +		return 0;
> +
> +	if (!conn_state->crtc)
> +		return 0;
> +
> +	master = intel_dp_mst_master_trans_get(encoder);
> +	if (master == INVALID_TRANSCODER)
> +		return 0;
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> +		/*
> +		 * cpu_transcoder is set when computing CRTC state if it will
> +		 * be disabled it will not happen, so checking pipe instead
> +		 */
> +		if (crtc->pipe != (enum pipe)master)
> +			continue;
> +
> +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
> +		    new_crtc_state->uapi.enable)
> +			continue;
> +
> +		pipe_config->mst_master_trans_pending = true;
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>  static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  				       struct intel_crtc_state *pipe_config,
>  				       struct drm_connector_state *conn_state)
> @@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  
>  	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
>  
> +	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
> +						conn_state);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +intel_dp_mst_atomic_master_trans_check(struct drm_connector *connector,
> +				       struct drm_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_connector *intel_conn = to_intel_connector(connector);
> +	struct drm_connector_state *new_conn_state, *old_conn_state;
> +	struct drm_connector_list_iter conn_list_iter;
> +	struct intel_crtc_state *intel_crtc_state;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_connector *conn_iter;
> +
> +	if (INTEL_GEN(dev_priv) < 12)
> +		return 0;
> +
> +	new_conn_state = drm_atomic_get_new_connector_state(state, connector);
> +	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
> +
> +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> +		return 0;
> +
> +	/*
> +	 * 3 cases that needs be handled here:
> +	 * - connector going from disabled to enabled
> +	 * - connector going from enabled to disabled:
> +	 * if this transcoder was the master, all slaves needs a modeset
> +	 * - connector going from enabled to enabled but it needs a modeset:
> +	 * if this transcoder was the master, all slaves also needs a modeset
> +	 */
> +
> +	/* disabled -> enabled */
> +	if (!old_conn_state->crtc && new_conn_state->crtc)
> +		return 0;
> +
> +	/* enabled -> enabled(modeset)? */
> +	if (new_conn_state->crtc) {
> +		crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
> +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> +			return 0;
> +	}
> +
> +	/* handling enabled -> enabled(modeset) and enabled -> disabled */
> +	crtc_state = drm_atomic_get_old_crtc_state(state, old_conn_state->crtc);
> +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> +
> +	/* If not master, nothing else needs to be handled */
> +	if (intel_conn->mst_port->mst_master_transcoder !=
> +	    intel_crtc_state->cpu_transcoder)
> +		return 0;
> +
> +	/* Is master, mark all other CRTCs as needing a modeset */
> +	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
> +	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
> +		struct intel_connector *intel_conn_iter;
> +		struct drm_connector_state *conn_iter_state;
> +
> +		intel_conn_iter = to_intel_connector(conn_iter);
> +		if (intel_conn_iter->mst_port != intel_conn->mst_port)
> +			continue;
> +
> +		conn_iter_state = drm_atomic_get_connector_state(state,
> +								 conn_iter);
> +		if (IS_ERR(conn_iter_state)) {
> +			drm_connector_list_iter_end(&conn_list_iter);
> +			return PTR_ERR(conn_iter_state);
> +		}
> +
> +		if (!conn_iter_state->crtc)
> +			continue;
> +
> +		crtc_state = drm_atomic_get_crtc_state(state, conn_iter_state->crtc);
> +		if (IS_ERR(crtc_state)) {
> +			drm_connector_list_iter_end(&conn_list_iter);
> +			return PTR_ERR(conn_iter_state);
> +		}
> +
> +		intel_crtc_state = to_intel_crtc_state(crtc_state);
> +		crtc_state->mode_changed = true;
> +	}
> +	drm_connector_list_iter_end(&conn_list_iter);
> +
>  	return 0;
>  }
>  
> @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
>  	if (ret)
>  		return ret;
>  
> +	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
> +	if (ret)
> +		return ret;
> +
>  	if (!old_conn_state->crtc)
>  		return 0;
>  
> @@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  		intel_dig_port->base.post_disable(&intel_dig_port->base,
>  						  old_crtc_state, NULL);
> +		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
>  	}
>  
>  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
>  
> -	if (first_mst_stream)
> +	if (first_mst_stream) {
> +		WARN_ON(intel_dp->mst_master_transcoder != INVALID_TRANSCODER);
> +		intel_dp->mst_master_transcoder = pipe_config->cpu_transcoder;
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> +	}
>  
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
>  
> @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
>  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
>  	/* encoders will get killed by normal cleanup */
>  }
> +
> +enum transcoder
> +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> +{
> +	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
> +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> +
> +	return intel_dp->mst_master_transcoder;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> index f660ad80db04..e6f28a517182 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> @@ -7,9 +7,11 @@
>  #define __INTEL_DP_MST_H__
>  
>  struct intel_digital_port;
> +struct intel_encoder;
>  
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
>  void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
>  int intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port);
> +enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder *encoder);
>  
>  #endif /* __INTEL_DP_MST_H__ */
> -- 
> 2.24.0

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

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-26 20:05     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 20:05 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Lucas De Marchi

On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza wrote:
> On TGL the blending of all the streams have moved from DDI to
> transcoder, so now every transcoder working over the same MST port must
> send its stream to a master transcoder and master will send to DDI
> respecting the time slots.
> 
> A previous approach was using the lowest pipe/transcoder as master
> transcoder but as the comment in skl_commit_modeset_enables() states,
> that is not always true.
> 
> So here promoting the first pipe/transcoder of the stream as master.
> That caused several other problems as during the commit phase the
> state computed should not be changed.
> 
> So the master transcoder is store into intel_dp and the modeset in
> slave pipes/transcoders is forced using mst_master_trans_pending.
> 
> v2:
> - added missing config compute to trigger fullmodeset in slave
> transcoders
> 
> BSpec: 50493
> BSpec: 49190
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
>  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
>  .../drm/i915/display/intel_display_types.h    |   3 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149 +++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
>  6 files changed, 216 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index a976606d21c7..d2f0d393d3ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -35,6 +35,7 @@
>  #include "intel_display_types.h"
>  #include "intel_dp.h"
>  #include "intel_dp_link_training.h"
> +#include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
>  #include "intel_dsi.h"
>  #include "intel_fifo_underrun.h"
> @@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
>  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
>  
> -		if (INTEL_GEN(dev_priv) >= 12)
> -			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> +		if (INTEL_GEN(dev_priv) >= 12) {
> +			enum transcoder master;
> +
> +			master = intel_dp_mst_master_trans_get(encoder);

Why isn't that just stored in the crtc state like everything else?

I'm thinking we should maybe do it just like port sync and have both
master + slave_mask. That way it should be pretty trivial to add all
the relevant crtcs to the state when needed.

> +			WARN_ON(master == INVALID_TRANSCODER);
> +			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
> +		}
>  	} else {
>  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
>  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 801b975c7d39..35a59108194e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -46,6 +46,7 @@
>  #include "display/intel_crt.h"
>  #include "display/intel_ddi.h"
>  #include "display/intel_dp.h"
> +#include "display/intel_dp_mst.h"
>  #include "display/intel_dsi.h"
>  #include "display/intel_dvo.h"
>  #include "display/intel_gmbus.h"
> @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>  	return encoder;
>  }
>  
> +/*
> + * Finds the encoder associated with the given CRTC. This can only be
> + * used when we know that the CRTC isn't feeding multiple encoders!
> + */
> +static struct intel_encoder *
> +intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
> +			   const struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_connector_state *connector_state;
> +	const struct drm_connector *connector;
> +	struct intel_encoder *encoder = NULL;
> +	int num_encoders = 0;
> +	int i;
> +
> +	for_each_old_connector_in_state(&state->base, connector,
> +					connector_state, i) {
> +		if (connector_state->crtc != &crtc->base)
> +			continue;
> +
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +		num_encoders++;
> +	}
> +
> +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> +	     num_encoders, pipe_name(crtc->pipe));
> +
> +	return encoder;
> +}

Argh. I was hoping to kill the other one of these. Got it down to 1
remaining user now I think.

> +
>  /*
>   * Enable PCH resources required for PCH ports:
>   *   - PCH PLLs
> @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  #undef PIPE_CONF_CHECK_COLOR_LUT
>  #undef PIPE_CONF_QUIRK
>  
> +	if (fastset && pipe_config->mst_master_trans_pending) {
> +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in mst_master_trans\n",
> +			      crtc->base.base.id, crtc->base.name);
> +		ret = false;
> +	}
> +
>  	return ret;
>  }
>  
> @@ -14449,22 +14486,35 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	struct intel_crtc *crtc;
>  	int i;
>  
> -	/* Only disable port sync slaves */
> +	/* Only disable port sync and MST slaves */
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
>  		if (!needs_modeset(new_crtc_state) || !crtc->active)
>  			continue;
>  
> +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> +		    !intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
> +			continue;
> +
>  		/* In case of Transcoder port Sync master slave CRTCs can be
>  		 * assigned in any order and we need to make sure that
>  		 * slave CRTCs are disabled first and then master CRTC since
>  		 * Slave vblanks are masked till Master Vblanks.
>  		 */
> -		if (!is_trans_port_sync_mode(old_crtc_state))
> -			continue;
> -		if (is_trans_port_sync_master(old_crtc_state))
> +		if (is_trans_port_sync_mode(new_crtc_state) &&
> +		    is_trans_port_sync_master(new_crtc_state))
>  			continue;
>  
> +		if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
> +			struct intel_encoder *encoder;
> +
> +			encoder = intel_get_crtc_old_encoder(state,
> +							     old_crtc_state);
> +			if (intel_dp_mst_master_trans_get(encoder) ==
> +			    old_crtc_state->cpu_transcoder)
> +				continue;
> +		}
> +
>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>  		intel_old_crtc_state_disables(state, old_crtc_state,
>  					      new_crtc_state, crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..23d747cdca64 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
>  	/* Pointer to master transcoder in case of tiled displays */
>  	enum transcoder master_transcoder;
>  
> +	bool mst_master_trans_pending;
> +
>  	/* Bitmask to indicate slaves attached */
>  	u8 sync_mode_slaves_mask;
>  };
> @@ -1284,6 +1286,7 @@ struct intel_dp {
>  	bool can_mst; /* this port supports mst */
>  	bool is_mst;
>  	int active_mst_links;
> +	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
>  
>  	/*
>  	 * DP_TP_* registers may be either on port or transcoder register space.
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 3123958e2081..ceff6901451a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_dp->reset_link_params = true;
>  	intel_dp->pps_pipe = INVALID_PIPE;
>  	intel_dp->active_pipe = INVALID_PIPE;
> +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
>  
>  	/* Preserve the current hw state. */
>  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index f8a350359346..9731c3c1d3f2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -87,6 +87,47 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  	return 0;
>  }
>  
> +static int
> +intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
> +				  struct intel_crtc_state *pipe_config,
> +				  struct drm_connector_state *conn_state)
> +{
> +	struct intel_atomic_state *state = to_intel_atomic_state(pipe_config->uapi.state);
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	struct intel_crtc_state *new_crtc_state;
> +	struct intel_crtc *crtc;
> +	enum transcoder master;
> +	int i;
> +
> +	if (INTEL_GEN(dev_priv) < 12)
> +		return 0;
> +
> +	if (!conn_state->crtc)
> +		return 0;
> +
> +	master = intel_dp_mst_master_trans_get(encoder);
> +	if (master == INVALID_TRANSCODER)
> +		return 0;
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> +		/*
> +		 * cpu_transcoder is set when computing CRTC state if it will
> +		 * be disabled it will not happen, so checking pipe instead
> +		 */
> +		if (crtc->pipe != (enum pipe)master)
> +			continue;
> +
> +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
> +		    new_crtc_state->uapi.enable)
> +			continue;
> +
> +		pipe_config->mst_master_trans_pending = true;
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>  static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  				       struct intel_crtc_state *pipe_config,
>  				       struct drm_connector_state *conn_state)
> @@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  
>  	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
>  
> +	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
> +						conn_state);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +intel_dp_mst_atomic_master_trans_check(struct drm_connector *connector,
> +				       struct drm_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_connector *intel_conn = to_intel_connector(connector);
> +	struct drm_connector_state *new_conn_state, *old_conn_state;
> +	struct drm_connector_list_iter conn_list_iter;
> +	struct intel_crtc_state *intel_crtc_state;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_connector *conn_iter;
> +
> +	if (INTEL_GEN(dev_priv) < 12)
> +		return 0;
> +
> +	new_conn_state = drm_atomic_get_new_connector_state(state, connector);
> +	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
> +
> +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> +		return 0;
> +
> +	/*
> +	 * 3 cases that needs be handled here:
> +	 * - connector going from disabled to enabled
> +	 * - connector going from enabled to disabled:
> +	 * if this transcoder was the master, all slaves needs a modeset
> +	 * - connector going from enabled to enabled but it needs a modeset:
> +	 * if this transcoder was the master, all slaves also needs a modeset
> +	 */
> +
> +	/* disabled -> enabled */
> +	if (!old_conn_state->crtc && new_conn_state->crtc)
> +		return 0;
> +
> +	/* enabled -> enabled(modeset)? */
> +	if (new_conn_state->crtc) {
> +		crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
> +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> +			return 0;
> +	}
> +
> +	/* handling enabled -> enabled(modeset) and enabled -> disabled */
> +	crtc_state = drm_atomic_get_old_crtc_state(state, old_conn_state->crtc);
> +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> +
> +	/* If not master, nothing else needs to be handled */
> +	if (intel_conn->mst_port->mst_master_transcoder !=
> +	    intel_crtc_state->cpu_transcoder)
> +		return 0;
> +
> +	/* Is master, mark all other CRTCs as needing a modeset */
> +	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
> +	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
> +		struct intel_connector *intel_conn_iter;
> +		struct drm_connector_state *conn_iter_state;
> +
> +		intel_conn_iter = to_intel_connector(conn_iter);
> +		if (intel_conn_iter->mst_port != intel_conn->mst_port)
> +			continue;
> +
> +		conn_iter_state = drm_atomic_get_connector_state(state,
> +								 conn_iter);
> +		if (IS_ERR(conn_iter_state)) {
> +			drm_connector_list_iter_end(&conn_list_iter);
> +			return PTR_ERR(conn_iter_state);
> +		}
> +
> +		if (!conn_iter_state->crtc)
> +			continue;
> +
> +		crtc_state = drm_atomic_get_crtc_state(state, conn_iter_state->crtc);
> +		if (IS_ERR(crtc_state)) {
> +			drm_connector_list_iter_end(&conn_list_iter);
> +			return PTR_ERR(conn_iter_state);
> +		}
> +
> +		intel_crtc_state = to_intel_crtc_state(crtc_state);
> +		crtc_state->mode_changed = true;
> +	}
> +	drm_connector_list_iter_end(&conn_list_iter);
> +
>  	return 0;
>  }
>  
> @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
>  	if (ret)
>  		return ret;
>  
> +	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
> +	if (ret)
> +		return ret;
> +
>  	if (!old_conn_state->crtc)
>  		return 0;
>  
> @@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  		intel_dig_port->base.post_disable(&intel_dig_port->base,
>  						  old_crtc_state, NULL);
> +		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
>  	}
>  
>  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
>  
> -	if (first_mst_stream)
> +	if (first_mst_stream) {
> +		WARN_ON(intel_dp->mst_master_transcoder != INVALID_TRANSCODER);
> +		intel_dp->mst_master_transcoder = pipe_config->cpu_transcoder;
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> +	}
>  
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
>  
> @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
>  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
>  	/* encoders will get killed by normal cleanup */
>  }
> +
> +enum transcoder
> +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> +{
> +	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
> +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> +
> +	return intel_dp->mst_master_transcoder;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> index f660ad80db04..e6f28a517182 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> @@ -7,9 +7,11 @@
>  #define __INTEL_DP_MST_H__
>  
>  struct intel_digital_port;
> +struct intel_encoder;
>  
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
>  void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
>  int intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port);
> +enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder *encoder);
>  
>  #endif /* __INTEL_DP_MST_H__ */
> -- 
> 2.24.0

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

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

* Re: [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-26 20:15     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 20:15 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Lucas De Marchi

On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza wrote:
> Disabling pipe/transcoder clock before power down sink could cause
> sink lost signal, causing it to trigger a hotplug to notify source
> that link signal was lost.
> 
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index d2f0d393d3ee..7d3a6e3c7f57 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3808,12 +3808,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
>  
>  	if (!is_mst) {
> -		intel_ddi_disable_pipe_clock(old_crtc_state);
>  		/*
>  		 * Power down sink before disabling the port, otherwise we end
>  		 * up getting interrupts from the sink on detecting link loss.
>  		 */
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +		intel_ddi_disable_pipe_clock(old_crtc_state);
>  	}

The spec seems to say that we should do this after turning off
DDI_BUF_CTL on tgl+.

>  
>  	intel_disable_ddi_buf(encoder, old_crtc_state);
> -- 
> 2.24.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-26 20:15     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-26 20:15 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Lucas De Marchi

On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza wrote:
> Disabling pipe/transcoder clock before power down sink could cause
> sink lost signal, causing it to trigger a hotplug to notify source
> that link signal was lost.
> 
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index d2f0d393d3ee..7d3a6e3c7f57 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3808,12 +3808,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
>  
>  	if (!is_mst) {
> -		intel_ddi_disable_pipe_clock(old_crtc_state);
>  		/*
>  		 * Power down sink before disabling the port, otherwise we end
>  		 * up getting interrupts from the sink on detecting link loss.
>  		 */
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +		intel_ddi_disable_pipe_clock(old_crtc_state);
>  	}

The spec seems to say that we should do this after turning off
DDI_BUF_CTL on tgl+.

>  
>  	intel_disable_ddi_buf(encoder, old_crtc_state);
> -- 
> 2.24.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-26 20:30       ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 20:30 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> wrote:
> > On TGL the blending of all the streams have moved from DDI to
> > transcoder, so now every transcoder working over the same MST port
> > must
> > send its stream to a master transcoder and master will send to DDI
> > respecting the time slots.
> > 
> > A previous approach was using the lowest pipe/transcoder as master
> > transcoder but as the comment in skl_commit_modeset_enables()
> > states,
> > that is not always true.
> > 
> > So here promoting the first pipe/transcoder of the stream as
> > master.
> > That caused several other problems as during the commit phase the
> > state computed should not be changed.
> > 
> > So the master transcoder is store into intel_dp and the modeset in
> > slave pipes/transcoders is forced using mst_master_trans_pending.
> > 
> > v2:
> > - added missing config compute to trigger fullmodeset in slave
> > transcoders
> > 
> > BSpec: 50493
> > BSpec: 49190
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> >  .../drm/i915/display/intel_display_types.h    |   3 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > +++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> >  6 files changed, 216 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index a976606d21c7..d2f0d393d3ee 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -35,6 +35,7 @@
> >  #include "intel_display_types.h"
> >  #include "intel_dp.h"
> >  #include "intel_dp_link_training.h"
> > +#include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> >  #include "intel_dsi.h"
> >  #include "intel_fifo_underrun.h"
> > @@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const
> > struct intel_crtc_state *crtc_state)
> >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> >  
> > -		if (INTEL_GEN(dev_priv) >= 12)
> > -			temp |=
> > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > +		if (INTEL_GEN(dev_priv) >= 12) {
> > +			enum transcoder master;
> > +
> > +			master =
> > intel_dp_mst_master_trans_get(encoder);
> 
> Why isn't that just stored in the crtc state like everything else?
> 
> I'm thinking we should maybe do it just like port sync and have both
> master + slave_mask. That way it should be pretty trivial to add all
> the relevant crtcs to the state when needed.

I guess port sync is not doing the right thing and it could cause
underruns.
When it is going to enable the master CRTC of the port sync it forcibly
enables the slave first, what could cause underruns because of overlap
in ddb allocations(that is what I understood from the comment in
skl_commit_modeset_enables()).

So for MST we only know who is the master in the commit phase and at
this point we should not modify the computed state.

> 
> > +			WARN_ON(master == INVALID_TRANSCODER);
> > +			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > +		}
> >  	} else {
> >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 801b975c7d39..35a59108194e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -46,6 +46,7 @@
> >  #include "display/intel_crt.h"
> >  #include "display/intel_ddi.h"
> >  #include "display/intel_dp.h"
> > +#include "display/intel_dp_mst.h"
> >  #include "display/intel_dsi.h"
> >  #include "display/intel_dvo.h"
> >  #include "display/intel_gmbus.h"
> > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > intel_atomic_state *state,
> >  	return encoder;
> >  }
> >  
> > +/*
> > + * Finds the encoder associated with the given CRTC. This can only
> > be
> > + * used when we know that the CRTC isn't feeding multiple
> > encoders!
> > + */
> > +static struct intel_encoder *
> > +intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
> > +			   const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > +	const struct drm_connector_state *connector_state;
> > +	const struct drm_connector *connector;
> > +	struct intel_encoder *encoder = NULL;
> > +	int num_encoders = 0;
> > +	int i;
> > +
> > +	for_each_old_connector_in_state(&state->base, connector,
> > +					connector_state, i) {
> > +		if (connector_state->crtc != &crtc->base)
> > +			continue;
> > +
> > +		encoder = to_intel_encoder(connector_state-
> > >best_encoder);
> > +		num_encoders++;
> > +	}
> > +
> > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > +	     num_encoders, pipe_name(crtc->pipe));
> > +
> > +	return encoder;
> > +}
> 
> Argh. I was hoping to kill the other one of these. Got it down to 1
> remaining user now I think.
> 
> > +
> >  /*
> >   * Enable PCH resources required for PCH ports:
> >   *   - PCH PLLs
> > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > intel_crtc_state *current_config,
> >  #undef PIPE_CONF_CHECK_COLOR_LUT
> >  #undef PIPE_CONF_QUIRK
> >  
> > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > mst_master_trans\n",
> > +			      crtc->base.base.id, crtc->base.name);
> > +		ret = false;
> > +	}
> > +
> >  	return ret;
> >  }
> >  
> > @@ -14449,22 +14486,35 @@ static void
> > intel_commit_modeset_disables(struct intel_atomic_state *state)
> >  	struct intel_crtc *crtc;
> >  	int i;
> >  
> > -	/* Only disable port sync slaves */
> > +	/* Only disable port sync and MST slaves */
> >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > old_crtc_state,
> >  					    new_crtc_state, i) {
> >  		if (!needs_modeset(new_crtc_state) || !crtc->active)
> >  			continue;
> >  
> > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > +		    !intel_crtc_has_type(old_crtc_state,
> > INTEL_OUTPUT_DP_MST))
> > +			continue;
> > +
> >  		/* In case of Transcoder port Sync master slave CRTCs
> > can be
> >  		 * assigned in any order and we need to make sure that
> >  		 * slave CRTCs are disabled first and then master CRTC
> > since
> >  		 * Slave vblanks are masked till Master Vblanks.
> >  		 */
> > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > -			continue;
> > -		if (is_trans_port_sync_master(old_crtc_state))
> > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > +		    is_trans_port_sync_master(new_crtc_state))
> >  			continue;
> >  
> > +		if (intel_crtc_has_type(old_crtc_state,
> > INTEL_OUTPUT_DP_MST)) {
> > +			struct intel_encoder *encoder;
> > +
> > +			encoder = intel_get_crtc_old_encoder(state,
> > +							     old_crtc_s
> > tate);
> > +			if (intel_dp_mst_master_trans_get(encoder) ==
> > +			    old_crtc_state->cpu_transcoder)
> > +				continue;
> > +		}
> > +
> >  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> >  		intel_old_crtc_state_disables(state, old_crtc_state,
> >  					      new_crtc_state, crtc);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 83ea04149b77..23d747cdca64 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> >  	/* Pointer to master transcoder in case of tiled displays */
> >  	enum transcoder master_transcoder;
> >  
> > +	bool mst_master_trans_pending;
> > +
> >  	/* Bitmask to indicate slaves attached */
> >  	u8 sync_mode_slaves_mask;
> >  };
> > @@ -1284,6 +1286,7 @@ struct intel_dp {
> >  	bool can_mst; /* this port supports mst */
> >  	bool is_mst;
> >  	int active_mst_links;
> > +	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
> >  
> >  	/*
> >  	 * DP_TP_* registers may be either on port or transcoder
> > register space.
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 3123958e2081..ceff6901451a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > intel_digital_port *intel_dig_port,
> >  	intel_dp->reset_link_params = true;
> >  	intel_dp->pps_pipe = INVALID_PIPE;
> >  	intel_dp->active_pipe = INVALID_PIPE;
> > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> >  
> >  	/* Preserve the current hw state. */
> >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index f8a350359346..9731c3c1d3f2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -87,6 +87,47 @@ static int
> > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  	return 0;
> >  }
> >  
> > +static int
> > +intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
> > +				  struct intel_crtc_state *pipe_config,
> > +				  struct drm_connector_state
> > *conn_state)
> > +{
> > +	struct intel_atomic_state *state =
> > to_intel_atomic_state(pipe_config->uapi.state);
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +	struct intel_crtc_state *new_crtc_state;
> > +	struct intel_crtc *crtc;
> > +	enum transcoder master;
> > +	int i;
> > +
> > +	if (INTEL_GEN(dev_priv) < 12)
> > +		return 0;
> > +
> > +	if (!conn_state->crtc)
> > +		return 0;
> > +
> > +	master = intel_dp_mst_master_trans_get(encoder);
> > +	if (master == INVALID_TRANSCODER)
> > +		return 0;
> > +
> > +	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state,
> > i) {
> > +		/*
> > +		 * cpu_transcoder is set when computing CRTC state if
> > it will
> > +		 * be disabled it will not happen, so checking pipe
> > instead
> > +		 */
> > +		if (crtc->pipe != (enum pipe)master)
> > +			continue;
> > +
> > +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > >uapi) &&
> > +		    new_crtc_state->uapi.enable)
> > +			continue;
> > +
> > +		pipe_config->mst_master_trans_pending = true;
> > +		break;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int intel_dp_mst_compute_config(struct intel_encoder
> > *encoder,
> >  				       struct intel_crtc_state
> > *pipe_config,
> >  				       struct drm_connector_state
> > *conn_state)
> > @@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct
> > intel_encoder *encoder,
> >  
> >  	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
> >  
> > +	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
> > +						conn_state);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > *connector,
> > +				       struct drm_atomic_state *state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > +	struct intel_connector *intel_conn =
> > to_intel_connector(connector);
> > +	struct drm_connector_state *new_conn_state, *old_conn_state;
> > +	struct drm_connector_list_iter conn_list_iter;
> > +	struct intel_crtc_state *intel_crtc_state;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_connector *conn_iter;
> > +
> > +	if (INTEL_GEN(dev_priv) < 12)
> > +		return 0;
> > +
> > +	new_conn_state = drm_atomic_get_new_connector_state(state,
> > connector);
> > +	old_conn_state = drm_atomic_get_old_connector_state(state,
> > connector);
> > +
> > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > +		return 0;
> > +
> > +	/*
> > +	 * 3 cases that needs be handled here:
> > +	 * - connector going from disabled to enabled
> > +	 * - connector going from enabled to disabled:
> > +	 * if this transcoder was the master, all slaves needs a
> > modeset
> > +	 * - connector going from enabled to enabled but it needs a
> > modeset:
> > +	 * if this transcoder was the master, all slaves also needs a
> > modeset
> > +	 */
> > +
> > +	/* disabled -> enabled */
> > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > +		return 0;
> > +
> > +	/* enabled -> enabled(modeset)? */
> > +	if (new_conn_state->crtc) {
> > +		crtc_state = drm_atomic_get_new_crtc_state(state,
> > new_conn_state->crtc);
> > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > +			return 0;
> > +	}
> > +
> > +	/* handling enabled -> enabled(modeset) and enabled -> disabled
> > */
> > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > old_conn_state->crtc);
> > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > +
> > +	/* If not master, nothing else needs to be handled */
> > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > +	    intel_crtc_state->cpu_transcoder)
> > +		return 0;
> > +
> > +	/* Is master, mark all other CRTCs as needing a modeset */
> > +	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
> > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
> > +		struct intel_connector *intel_conn_iter;
> > +		struct drm_connector_state *conn_iter_state;
> > +
> > +		intel_conn_iter = to_intel_connector(conn_iter);
> > +		if (intel_conn_iter->mst_port != intel_conn->mst_port)
> > +			continue;
> > +
> > +		conn_iter_state = drm_atomic_get_connector_state(state,
> > +								 conn_i
> > ter);
> > +		if (IS_ERR(conn_iter_state)) {
> > +			drm_connector_list_iter_end(&conn_list_iter);
> > +			return PTR_ERR(conn_iter_state);
> > +		}
> > +
> > +		if (!conn_iter_state->crtc)
> > +			continue;
> > +
> > +		crtc_state = drm_atomic_get_crtc_state(state,
> > conn_iter_state->crtc);
> > +		if (IS_ERR(crtc_state)) {
> > +			drm_connector_list_iter_end(&conn_list_iter);
> > +			return PTR_ERR(conn_iter_state);
> > +		}
> > +
> > +		intel_crtc_state = to_intel_crtc_state(crtc_state);
> > +		crtc_state->mode_changed = true;
> > +	}
> > +	drm_connector_list_iter_end(&conn_list_iter);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector
> > *connector,
> >  	if (ret)
> >  		return ret;
> >  
> > +	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
> > +	if (ret)
> > +		return ret;
> > +
> >  	if (!old_conn_state->crtc)
> >  		return 0;
> >  
> > @@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct
> > intel_encoder *encoder,
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> >  		intel_dig_port->base.post_disable(&intel_dig_port-
> > >base,
> >  						  old_crtc_state,
> > NULL);
> > +		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> >  	}
> >  
> >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > intel_encoder *encoder,
> >  
> >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> >  
> > -	if (first_mst_stream)
> > +	if (first_mst_stream) {
> > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > INVALID_TRANSCODER);
> > +		intel_dp->mst_master_transcoder = pipe_config-
> > >cpu_transcoder;
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > +	}
> >  
> >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector-
> > >port, true);
> >  
> > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > intel_digital_port *intel_dig_port)
> >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> >  	/* encoders will get killed by normal cleanup */
> >  }
> > +
> > +enum transcoder
> > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > +{
> > +	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder-
> > >base);
> > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > +
> > +	return intel_dp->mst_master_transcoder;
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > index f660ad80db04..e6f28a517182 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > @@ -7,9 +7,11 @@
> >  #define __INTEL_DP_MST_H__
> >  
> >  struct intel_digital_port;
> > +struct intel_encoder;
> >  
> >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > *intel_dig_port, int conn_id);
> >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > *intel_dig_port);
> >  int intel_dp_mst_encoder_active_links(struct intel_digital_port
> > *intel_dig_port);
> > +enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder
> > *encoder);
> >  
> >  #endif /* __INTEL_DP_MST_H__ */
> > -- 
> > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-26 20:30       ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 20:30 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> wrote:
> > On TGL the blending of all the streams have moved from DDI to
> > transcoder, so now every transcoder working over the same MST port
> > must
> > send its stream to a master transcoder and master will send to DDI
> > respecting the time slots.
> > 
> > A previous approach was using the lowest pipe/transcoder as master
> > transcoder but as the comment in skl_commit_modeset_enables()
> > states,
> > that is not always true.
> > 
> > So here promoting the first pipe/transcoder of the stream as
> > master.
> > That caused several other problems as during the commit phase the
> > state computed should not be changed.
> > 
> > So the master transcoder is store into intel_dp and the modeset in
> > slave pipes/transcoders is forced using mst_master_trans_pending.
> > 
> > v2:
> > - added missing config compute to trigger fullmodeset in slave
> > transcoders
> > 
> > BSpec: 50493
> > BSpec: 49190
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> >  .../drm/i915/display/intel_display_types.h    |   3 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > +++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> >  6 files changed, 216 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index a976606d21c7..d2f0d393d3ee 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -35,6 +35,7 @@
> >  #include "intel_display_types.h"
> >  #include "intel_dp.h"
> >  #include "intel_dp_link_training.h"
> > +#include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> >  #include "intel_dsi.h"
> >  #include "intel_fifo_underrun.h"
> > @@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const
> > struct intel_crtc_state *crtc_state)
> >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> >  
> > -		if (INTEL_GEN(dev_priv) >= 12)
> > -			temp |=
> > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > +		if (INTEL_GEN(dev_priv) >= 12) {
> > +			enum transcoder master;
> > +
> > +			master =
> > intel_dp_mst_master_trans_get(encoder);
> 
> Why isn't that just stored in the crtc state like everything else?
> 
> I'm thinking we should maybe do it just like port sync and have both
> master + slave_mask. That way it should be pretty trivial to add all
> the relevant crtcs to the state when needed.

I guess port sync is not doing the right thing and it could cause
underruns.
When it is going to enable the master CRTC of the port sync it forcibly
enables the slave first, what could cause underruns because of overlap
in ddb allocations(that is what I understood from the comment in
skl_commit_modeset_enables()).

So for MST we only know who is the master in the commit phase and at
this point we should not modify the computed state.

> 
> > +			WARN_ON(master == INVALID_TRANSCODER);
> > +			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > +		}
> >  	} else {
> >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 801b975c7d39..35a59108194e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -46,6 +46,7 @@
> >  #include "display/intel_crt.h"
> >  #include "display/intel_ddi.h"
> >  #include "display/intel_dp.h"
> > +#include "display/intel_dp_mst.h"
> >  #include "display/intel_dsi.h"
> >  #include "display/intel_dvo.h"
> >  #include "display/intel_gmbus.h"
> > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > intel_atomic_state *state,
> >  	return encoder;
> >  }
> >  
> > +/*
> > + * Finds the encoder associated with the given CRTC. This can only
> > be
> > + * used when we know that the CRTC isn't feeding multiple
> > encoders!
> > + */
> > +static struct intel_encoder *
> > +intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
> > +			   const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > +	const struct drm_connector_state *connector_state;
> > +	const struct drm_connector *connector;
> > +	struct intel_encoder *encoder = NULL;
> > +	int num_encoders = 0;
> > +	int i;
> > +
> > +	for_each_old_connector_in_state(&state->base, connector,
> > +					connector_state, i) {
> > +		if (connector_state->crtc != &crtc->base)
> > +			continue;
> > +
> > +		encoder = to_intel_encoder(connector_state-
> > >best_encoder);
> > +		num_encoders++;
> > +	}
> > +
> > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > +	     num_encoders, pipe_name(crtc->pipe));
> > +
> > +	return encoder;
> > +}
> 
> Argh. I was hoping to kill the other one of these. Got it down to 1
> remaining user now I think.
> 
> > +
> >  /*
> >   * Enable PCH resources required for PCH ports:
> >   *   - PCH PLLs
> > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > intel_crtc_state *current_config,
> >  #undef PIPE_CONF_CHECK_COLOR_LUT
> >  #undef PIPE_CONF_QUIRK
> >  
> > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > mst_master_trans\n",
> > +			      crtc->base.base.id, crtc->base.name);
> > +		ret = false;
> > +	}
> > +
> >  	return ret;
> >  }
> >  
> > @@ -14449,22 +14486,35 @@ static void
> > intel_commit_modeset_disables(struct intel_atomic_state *state)
> >  	struct intel_crtc *crtc;
> >  	int i;
> >  
> > -	/* Only disable port sync slaves */
> > +	/* Only disable port sync and MST slaves */
> >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > old_crtc_state,
> >  					    new_crtc_state, i) {
> >  		if (!needs_modeset(new_crtc_state) || !crtc->active)
> >  			continue;
> >  
> > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > +		    !intel_crtc_has_type(old_crtc_state,
> > INTEL_OUTPUT_DP_MST))
> > +			continue;
> > +
> >  		/* In case of Transcoder port Sync master slave CRTCs
> > can be
> >  		 * assigned in any order and we need to make sure that
> >  		 * slave CRTCs are disabled first and then master CRTC
> > since
> >  		 * Slave vblanks are masked till Master Vblanks.
> >  		 */
> > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > -			continue;
> > -		if (is_trans_port_sync_master(old_crtc_state))
> > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > +		    is_trans_port_sync_master(new_crtc_state))
> >  			continue;
> >  
> > +		if (intel_crtc_has_type(old_crtc_state,
> > INTEL_OUTPUT_DP_MST)) {
> > +			struct intel_encoder *encoder;
> > +
> > +			encoder = intel_get_crtc_old_encoder(state,
> > +							     old_crtc_s
> > tate);
> > +			if (intel_dp_mst_master_trans_get(encoder) ==
> > +			    old_crtc_state->cpu_transcoder)
> > +				continue;
> > +		}
> > +
> >  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> >  		intel_old_crtc_state_disables(state, old_crtc_state,
> >  					      new_crtc_state, crtc);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 83ea04149b77..23d747cdca64 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> >  	/* Pointer to master transcoder in case of tiled displays */
> >  	enum transcoder master_transcoder;
> >  
> > +	bool mst_master_trans_pending;
> > +
> >  	/* Bitmask to indicate slaves attached */
> >  	u8 sync_mode_slaves_mask;
> >  };
> > @@ -1284,6 +1286,7 @@ struct intel_dp {
> >  	bool can_mst; /* this port supports mst */
> >  	bool is_mst;
> >  	int active_mst_links;
> > +	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
> >  
> >  	/*
> >  	 * DP_TP_* registers may be either on port or transcoder
> > register space.
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 3123958e2081..ceff6901451a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > intel_digital_port *intel_dig_port,
> >  	intel_dp->reset_link_params = true;
> >  	intel_dp->pps_pipe = INVALID_PIPE;
> >  	intel_dp->active_pipe = INVALID_PIPE;
> > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> >  
> >  	/* Preserve the current hw state. */
> >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index f8a350359346..9731c3c1d3f2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -87,6 +87,47 @@ static int
> > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  	return 0;
> >  }
> >  
> > +static int
> > +intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
> > +				  struct intel_crtc_state *pipe_config,
> > +				  struct drm_connector_state
> > *conn_state)
> > +{
> > +	struct intel_atomic_state *state =
> > to_intel_atomic_state(pipe_config->uapi.state);
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +	struct intel_crtc_state *new_crtc_state;
> > +	struct intel_crtc *crtc;
> > +	enum transcoder master;
> > +	int i;
> > +
> > +	if (INTEL_GEN(dev_priv) < 12)
> > +		return 0;
> > +
> > +	if (!conn_state->crtc)
> > +		return 0;
> > +
> > +	master = intel_dp_mst_master_trans_get(encoder);
> > +	if (master == INVALID_TRANSCODER)
> > +		return 0;
> > +
> > +	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state,
> > i) {
> > +		/*
> > +		 * cpu_transcoder is set when computing CRTC state if
> > it will
> > +		 * be disabled it will not happen, so checking pipe
> > instead
> > +		 */
> > +		if (crtc->pipe != (enum pipe)master)
> > +			continue;
> > +
> > +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > >uapi) &&
> > +		    new_crtc_state->uapi.enable)
> > +			continue;
> > +
> > +		pipe_config->mst_master_trans_pending = true;
> > +		break;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int intel_dp_mst_compute_config(struct intel_encoder
> > *encoder,
> >  				       struct intel_crtc_state
> > *pipe_config,
> >  				       struct drm_connector_state
> > *conn_state)
> > @@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct
> > intel_encoder *encoder,
> >  
> >  	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
> >  
> > +	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
> > +						conn_state);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > *connector,
> > +				       struct drm_atomic_state *state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > +	struct intel_connector *intel_conn =
> > to_intel_connector(connector);
> > +	struct drm_connector_state *new_conn_state, *old_conn_state;
> > +	struct drm_connector_list_iter conn_list_iter;
> > +	struct intel_crtc_state *intel_crtc_state;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_connector *conn_iter;
> > +
> > +	if (INTEL_GEN(dev_priv) < 12)
> > +		return 0;
> > +
> > +	new_conn_state = drm_atomic_get_new_connector_state(state,
> > connector);
> > +	old_conn_state = drm_atomic_get_old_connector_state(state,
> > connector);
> > +
> > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > +		return 0;
> > +
> > +	/*
> > +	 * 3 cases that needs be handled here:
> > +	 * - connector going from disabled to enabled
> > +	 * - connector going from enabled to disabled:
> > +	 * if this transcoder was the master, all slaves needs a
> > modeset
> > +	 * - connector going from enabled to enabled but it needs a
> > modeset:
> > +	 * if this transcoder was the master, all slaves also needs a
> > modeset
> > +	 */
> > +
> > +	/* disabled -> enabled */
> > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > +		return 0;
> > +
> > +	/* enabled -> enabled(modeset)? */
> > +	if (new_conn_state->crtc) {
> > +		crtc_state = drm_atomic_get_new_crtc_state(state,
> > new_conn_state->crtc);
> > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > +			return 0;
> > +	}
> > +
> > +	/* handling enabled -> enabled(modeset) and enabled -> disabled
> > */
> > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > old_conn_state->crtc);
> > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > +
> > +	/* If not master, nothing else needs to be handled */
> > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > +	    intel_crtc_state->cpu_transcoder)
> > +		return 0;
> > +
> > +	/* Is master, mark all other CRTCs as needing a modeset */
> > +	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
> > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
> > +		struct intel_connector *intel_conn_iter;
> > +		struct drm_connector_state *conn_iter_state;
> > +
> > +		intel_conn_iter = to_intel_connector(conn_iter);
> > +		if (intel_conn_iter->mst_port != intel_conn->mst_port)
> > +			continue;
> > +
> > +		conn_iter_state = drm_atomic_get_connector_state(state,
> > +								 conn_i
> > ter);
> > +		if (IS_ERR(conn_iter_state)) {
> > +			drm_connector_list_iter_end(&conn_list_iter);
> > +			return PTR_ERR(conn_iter_state);
> > +		}
> > +
> > +		if (!conn_iter_state->crtc)
> > +			continue;
> > +
> > +		crtc_state = drm_atomic_get_crtc_state(state,
> > conn_iter_state->crtc);
> > +		if (IS_ERR(crtc_state)) {
> > +			drm_connector_list_iter_end(&conn_list_iter);
> > +			return PTR_ERR(conn_iter_state);
> > +		}
> > +
> > +		intel_crtc_state = to_intel_crtc_state(crtc_state);
> > +		crtc_state->mode_changed = true;
> > +	}
> > +	drm_connector_list_iter_end(&conn_list_iter);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector
> > *connector,
> >  	if (ret)
> >  		return ret;
> >  
> > +	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
> > +	if (ret)
> > +		return ret;
> > +
> >  	if (!old_conn_state->crtc)
> >  		return 0;
> >  
> > @@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct
> > intel_encoder *encoder,
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> >  		intel_dig_port->base.post_disable(&intel_dig_port-
> > >base,
> >  						  old_crtc_state,
> > NULL);
> > +		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> >  	}
> >  
> >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > intel_encoder *encoder,
> >  
> >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> >  
> > -	if (first_mst_stream)
> > +	if (first_mst_stream) {
> > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > INVALID_TRANSCODER);
> > +		intel_dp->mst_master_transcoder = pipe_config-
> > >cpu_transcoder;
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > +	}
> >  
> >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector-
> > >port, true);
> >  
> > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > intel_digital_port *intel_dig_port)
> >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> >  	/* encoders will get killed by normal cleanup */
> >  }
> > +
> > +enum transcoder
> > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > +{
> > +	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder-
> > >base);
> > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > +
> > +	return intel_dp->mst_master_transcoder;
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > index f660ad80db04..e6f28a517182 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > @@ -7,9 +7,11 @@
> >  #define __INTEL_DP_MST_H__
> >  
> >  struct intel_digital_port;
> > +struct intel_encoder;
> >  
> >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > *intel_dig_port, int conn_id);
> >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > *intel_dig_port);
> >  int intel_dp_mst_encoder_active_links(struct intel_digital_port
> > *intel_dig_port);
> > +enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder
> > *encoder);
> >  
> >  #endif /* __INTEL_DP_MST_H__ */
> > -- 
> > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 22:03     ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 22:03 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> wrote:
> > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> > reverted the order that pipes gets disabled because of TGL
> > master/slave relationship between transcoders in MST mode.
> > 
> > But as stated in a comment in skl_commit_modeset_enables() the
> > enabling order is not always crescent, possibly causing previously
> > selected slave transcoder being enabled before master so another
> > approach will be needed to select a transcoder to master in MST
> > mode.
> > It will be similar to the approach taken in port sync.
> > 
> > But instead of implement something like
> > intel_trans_port_sync_modeset_disables() to MST lets simply it and
> > iterate over all pipes 2 times, the first one disabling any slave
> > and
> > then disabling everything else.
> > The MST bits will be added in another patch.
> > 
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Matt Roper <matthew.d.roper@intel.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
> > ------
> >  1 file changed, 22 insertions(+), 57 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -14443,53 +14443,16 @@ static void
> > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> >  		dev_priv->display.initial_watermarks(state, crtc);
> >  }
> >  
> > -static void intel_trans_port_sync_modeset_disables(struct
> > intel_atomic_state *state,
> > -						   struct intel_crtc
> > *crtc,
> > -						   struct
> > intel_crtc_state *old_crtc_state,
> > -						   struct
> > intel_crtc_state *new_crtc_state)
> > -{
> > -	struct intel_crtc *slave_crtc =
> > intel_get_slave_crtc(new_crtc_state);
> > -	struct intel_crtc_state *new_slave_crtc_state =
> > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> > -	struct intel_crtc_state *old_slave_crtc_state =
> > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> > -
> > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > -		!old_slave_crtc_state);
> > -
> > -	/* Disable Slave first */
> > -	intel_pre_plane_update(old_slave_crtc_state,
> > new_slave_crtc_state);
> > -	if (old_slave_crtc_state->hw.active)
> > -		intel_old_crtc_state_disables(state,
> > -					      old_slave_crtc_state,
> > -					      new_slave_crtc_state,
> > -					      slave_crtc);
> > -
> > -	/* Disable Master */
> > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > -	if (old_crtc_state->hw.active)
> > -		intel_old_crtc_state_disables(state,
> > -					      old_crtc_state,
> > -					      new_crtc_state,
> > -					      crtc);
> > -}
> > -
> >  static void intel_commit_modeset_disables(struct
> > intel_atomic_state *state)
> >  {
> >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> >  	struct intel_crtc *crtc;
> >  	int i;
> >  
> > -	/*
> > -	 * Disable CRTC/pipes in reverse order because some
> > features(MST in
> > -	 * TGL+) requires master and slave relationship between pipes,
> > so it
> > -	 * should always pick the lowest pipe as master as it will be
> > enabled
> > -	 * first and disable in the reverse order so the master will be
> > the
> > -	 * last one to be disabled.
> > -	 */
> > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
> > old_crtc_state,
> > -						    new_crtc_state, i)
> > {
> > -		if (!needs_modeset(new_crtc_state))
> > +	/* Only disable port sync slaves */
> > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > old_crtc_state,
> > +					    new_crtc_state, i) {
> > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> 
> What's the deal with these crtc->active checks?

With just one loop we were using "old_crtc_state->hw.active" but as we
should not modify the computed state in this phase and
intel_old_crtc_state_disables() sets crtc->active = false, using it
instead.

> 
> >  			continue;
> >  
> >  		/* In case of Transcoder port Sync master slave CRTCs
> > can be
> > @@ -14497,23 +14460,25 @@ static void
> > intel_commit_modeset_disables(struct intel_atomic_state *state)
> >  		 * slave CRTCs are disabled first and then master CRTC
> > since
> >  		 * Slave vblanks are masked till Master Vblanks.
> >  		 */
> > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > -			if (is_trans_port_sync_master(new_crtc_state))
> > -				intel_trans_port_sync_modeset_disables(
> > state,
> > -								       
> > crtc,
> > -								       
> > old_crtc_state,
> > -								       
> > new_crtc_state);
> > -			else
> > -				continue;
> > -		} else {
> > -			intel_pre_plane_update(old_crtc_state,
> > new_crtc_state);
> > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > +			continue;
> > +		if (is_trans_port_sync_master(new_crtc_state))
> > +			continue;
> 
> We don't have is_trans_sync_slave()?

We don't.

> 
> >  
> > -			if (old_crtc_state->hw.active)
> > -				intel_old_crtc_state_disables(state,
> > -							      old_crtc_
> > state,
> > -							      new_crtc_
> > state,
> > -							      crtc);
> > -		}
> > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > +					      new_crtc_state, crtc);
> > +	}
> > +
> > +	/* Disable everything else left on */
> > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > old_crtc_state,
> > +					    new_crtc_state, i) {
> > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > +			continue;
> > +
> > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > +					      new_crtc_state, crtc);
> 
> Pondering if there's any chance of some odd fail if we have two ports
> running in port sync mode. That will now lead to
> disable_slave(0)->disable_slave(1)->disable_master(0)-
> >disable_master(1)...

Thoughts Manasi?

> 
> >  	}
> >  }
> >  
> > -- 
> > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 22:03     ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 22:03 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> wrote:
> > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> > reverted the order that pipes gets disabled because of TGL
> > master/slave relationship between transcoders in MST mode.
> > 
> > But as stated in a comment in skl_commit_modeset_enables() the
> > enabling order is not always crescent, possibly causing previously
> > selected slave transcoder being enabled before master so another
> > approach will be needed to select a transcoder to master in MST
> > mode.
> > It will be similar to the approach taken in port sync.
> > 
> > But instead of implement something like
> > intel_trans_port_sync_modeset_disables() to MST lets simply it and
> > iterate over all pipes 2 times, the first one disabling any slave
> > and
> > then disabling everything else.
> > The MST bits will be added in another patch.
> > 
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > Cc: Matt Roper <matthew.d.roper@intel.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
> > ------
> >  1 file changed, 22 insertions(+), 57 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -14443,53 +14443,16 @@ static void
> > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> >  		dev_priv->display.initial_watermarks(state, crtc);
> >  }
> >  
> > -static void intel_trans_port_sync_modeset_disables(struct
> > intel_atomic_state *state,
> > -						   struct intel_crtc
> > *crtc,
> > -						   struct
> > intel_crtc_state *old_crtc_state,
> > -						   struct
> > intel_crtc_state *new_crtc_state)
> > -{
> > -	struct intel_crtc *slave_crtc =
> > intel_get_slave_crtc(new_crtc_state);
> > -	struct intel_crtc_state *new_slave_crtc_state =
> > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> > -	struct intel_crtc_state *old_slave_crtc_state =
> > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> > -
> > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > -		!old_slave_crtc_state);
> > -
> > -	/* Disable Slave first */
> > -	intel_pre_plane_update(old_slave_crtc_state,
> > new_slave_crtc_state);
> > -	if (old_slave_crtc_state->hw.active)
> > -		intel_old_crtc_state_disables(state,
> > -					      old_slave_crtc_state,
> > -					      new_slave_crtc_state,
> > -					      slave_crtc);
> > -
> > -	/* Disable Master */
> > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > -	if (old_crtc_state->hw.active)
> > -		intel_old_crtc_state_disables(state,
> > -					      old_crtc_state,
> > -					      new_crtc_state,
> > -					      crtc);
> > -}
> > -
> >  static void intel_commit_modeset_disables(struct
> > intel_atomic_state *state)
> >  {
> >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> >  	struct intel_crtc *crtc;
> >  	int i;
> >  
> > -	/*
> > -	 * Disable CRTC/pipes in reverse order because some
> > features(MST in
> > -	 * TGL+) requires master and slave relationship between pipes,
> > so it
> > -	 * should always pick the lowest pipe as master as it will be
> > enabled
> > -	 * first and disable in the reverse order so the master will be
> > the
> > -	 * last one to be disabled.
> > -	 */
> > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
> > old_crtc_state,
> > -						    new_crtc_state, i)
> > {
> > -		if (!needs_modeset(new_crtc_state))
> > +	/* Only disable port sync slaves */
> > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > old_crtc_state,
> > +					    new_crtc_state, i) {
> > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> 
> What's the deal with these crtc->active checks?

With just one loop we were using "old_crtc_state->hw.active" but as we
should not modify the computed state in this phase and
intel_old_crtc_state_disables() sets crtc->active = false, using it
instead.

> 
> >  			continue;
> >  
> >  		/* In case of Transcoder port Sync master slave CRTCs
> > can be
> > @@ -14497,23 +14460,25 @@ static void
> > intel_commit_modeset_disables(struct intel_atomic_state *state)
> >  		 * slave CRTCs are disabled first and then master CRTC
> > since
> >  		 * Slave vblanks are masked till Master Vblanks.
> >  		 */
> > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > -			if (is_trans_port_sync_master(new_crtc_state))
> > -				intel_trans_port_sync_modeset_disables(
> > state,
> > -								       
> > crtc,
> > -								       
> > old_crtc_state,
> > -								       
> > new_crtc_state);
> > -			else
> > -				continue;
> > -		} else {
> > -			intel_pre_plane_update(old_crtc_state,
> > new_crtc_state);
> > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > +			continue;
> > +		if (is_trans_port_sync_master(new_crtc_state))
> > +			continue;
> 
> We don't have is_trans_sync_slave()?

We don't.

> 
> >  
> > -			if (old_crtc_state->hw.active)
> > -				intel_old_crtc_state_disables(state,
> > -							      old_crtc_
> > state,
> > -							      new_crtc_
> > state,
> > -							      crtc);
> > -		}
> > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > +					      new_crtc_state, crtc);
> > +	}
> > +
> > +	/* Disable everything else left on */
> > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > old_crtc_state,
> > +					    new_crtc_state, i) {
> > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > +			continue;
> > +
> > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > +					      new_crtc_state, crtc);
> 
> Pondering if there's any chance of some odd fail if we have two ports
> running in port sync mode. That will now lead to
> disable_slave(0)->disable_slave(1)->disable_master(0)-
> >disable_master(1)...

Thoughts Manasi?

> 
> >  	}
> >  }
> >  
> > -- 
> > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-26 22:12       ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 22:12 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> wrote:
> > Disabling pipe/transcoder clock before power down sink could cause
> > sink lost signal, causing it to trigger a hotplug to notify source
> > that link signal was lost.
> > 
> > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3808,12 +3808,12 @@ static void
> > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> >  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
> >  
> >  	if (!is_mst) {
> > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> >  		/*
> >  		 * Power down sink before disabling the port, otherwise
> > we end
> >  		 * up getting interrupts from the sink on detecting
> > link loss.
> >  		 */
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> >  	}
> 
> The spec seems to say that we should do this after turning off
> DDI_BUF_CTL on tgl+.

What step? I can't find any step talking about AUX DP_SET_POWER.

My understating is that we should power off sink before interfering in
the mainlink signal otherwise sink could trigger hotplugs to notify
source about link loss.

> 
> >  
> >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > -- 
> > 2.24.0
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-26 22:12       ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 22:12 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> wrote:
> > Disabling pipe/transcoder clock before power down sink could cause
> > sink lost signal, causing it to trigger a hotplug to notify source
> > that link signal was lost.
> > 
> > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3808,12 +3808,12 @@ static void
> > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> >  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
> >  
> >  	if (!is_mst) {
> > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> >  		/*
> >  		 * Power down sink before disabling the port, otherwise
> > we end
> >  		 * up getting interrupts from the sink on detecting
> > link loss.
> >  		 */
> >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> >  	}
> 
> The spec seems to say that we should do this after turning off
> DDI_BUF_CTL on tgl+.

What step? I can't find any step talking about AUX DP_SET_POWER.

My understating is that we should power off sink before interfering in
the mainlink signal otherwise sink could trigger hotplugs to notify
source about link loss.

> 
> >  
> >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > -- 
> > 2.24.0
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 22:49       ` Matt Roper
  0 siblings, 0 replies; 65+ messages in thread
From: Matt Roper @ 2019-11-26 22:49 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx

On Tue, Nov 26, 2019 at 02:03:08PM -0800, Souza, Jose wrote:
> On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> > wrote:
> > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> > > reverted the order that pipes gets disabled because of TGL
> > > master/slave relationship between transcoders in MST mode.
> > > 
> > > But as stated in a comment in skl_commit_modeset_enables() the
> > > enabling order is not always crescent, possibly causing previously
> > > selected slave transcoder being enabled before master so another
> > > approach will be needed to select a transcoder to master in MST
> > > mode.
> > > It will be similar to the approach taken in port sync.
> > > 
> > > But instead of implement something like
> > > intel_trans_port_sync_modeset_disables() to MST lets simply it and
> > > iterate over all pipes 2 times, the first one disabling any slave
> > > and
> > > then disabling everything else.
> > > The MST bits will be added in another patch.
> > > 
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Matt Roper <matthew.d.roper@intel.com>
> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
> > > ------
> > >  1 file changed, 22 insertions(+), 57 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -14443,53 +14443,16 @@ static void
> > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > >  		dev_priv->display.initial_watermarks(state, crtc);
> > >  }
> > >  
> > > -static void intel_trans_port_sync_modeset_disables(struct
> > > intel_atomic_state *state,
> > > -						   struct intel_crtc
> > > *crtc,
> > > -						   struct
> > > intel_crtc_state *old_crtc_state,
> > > -						   struct
> > > intel_crtc_state *new_crtc_state)
> > > -{
> > > -	struct intel_crtc *slave_crtc =
> > > intel_get_slave_crtc(new_crtc_state);
> > > -	struct intel_crtc_state *new_slave_crtc_state =
> > > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> > > -	struct intel_crtc_state *old_slave_crtc_state =
> > > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> > > -
> > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > > -		!old_slave_crtc_state);
> > > -
> > > -	/* Disable Slave first */
> > > -	intel_pre_plane_update(old_slave_crtc_state,
> > > new_slave_crtc_state);
> > > -	if (old_slave_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_slave_crtc_state,
> > > -					      new_slave_crtc_state,
> > > -					      slave_crtc);
> > > -
> > > -	/* Disable Master */
> > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > -	if (old_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_crtc_state,
> > > -					      new_crtc_state,
> > > -					      crtc);
> > > -}
> > > -
> > >  static void intel_commit_modeset_disables(struct
> > > intel_atomic_state *state)
> > >  {
> > >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> > >  	struct intel_crtc *crtc;
> > >  	int i;
> > >  
> > > -	/*
> > > -	 * Disable CRTC/pipes in reverse order because some
> > > features(MST in
> > > -	 * TGL+) requires master and slave relationship between pipes,
> > > so it
> > > -	 * should always pick the lowest pipe as master as it will be
> > > enabled
> > > -	 * first and disable in the reverse order so the master will be
> > > the
> > > -	 * last one to be disabled.
> > > -	 */
> > > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
> > > old_crtc_state,
> > > -						    new_crtc_state, i)
> > > {
> > > -		if (!needs_modeset(new_crtc_state))
> > > +	/* Only disable port sync slaves */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > 
> > What's the deal with these crtc->active checks?
> 
> With just one loop we were using "old_crtc_state->hw.active" but as we
> should not modify the computed state in this phase and
> intel_old_crtc_state_disables() sets crtc->active = false, using it
> instead.

I don't think we want to be using intel_crtc->active for anything new if
we can help it.  We have to keep that field around right now to support
some of our ancient platforms that still don't have atomic support yet,
but we don't want to be using it anywhere new we don't already have to
for legacy reasons.

You're only looking at the active flag here, not modifying it, so it
should be fine to use old_crtc_state->active for the pre-modeset status
of the CRTC (and new_crtc_state->active anywhere you need the
post-modeset status).

If you're just trying to keep track of which ones you've already
disabled in this function when you come back around for your second
loop, it would be better to just maintain a bitmask of CRTCs you turned
off in the first pass as a local variable in this function so you know
what to skip on the second pass.


Matt

> 
> > 
> > >  			continue;
> > >  
> > >  		/* In case of Transcoder port Sync master slave CRTCs
> > > can be
> > > @@ -14497,23 +14460,25 @@ static void
> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > >  		 * slave CRTCs are disabled first and then master CRTC
> > > since
> > >  		 * Slave vblanks are masked till Master Vblanks.
> > >  		 */
> > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > > -			if (is_trans_port_sync_master(new_crtc_state))
> > > -				intel_trans_port_sync_modeset_disables(
> > > state,
> > > -								       
> > > crtc,
> > > -								       
> > > old_crtc_state,
> > > -								       
> > > new_crtc_state);
> > > -			else
> > > -				continue;
> > > -		} else {
> > > -			intel_pre_plane_update(old_crtc_state,
> > > new_crtc_state);
> > > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > > +			continue;
> > > +		if (is_trans_port_sync_master(new_crtc_state))
> > > +			continue;
> > 
> > We don't have is_trans_sync_slave()?
> 
> We don't.
> 
> > 
> > >  
> > > -			if (old_crtc_state->hw.active)
> > > -				intel_old_crtc_state_disables(state,
> > > -							      old_crtc_
> > > state,
> > > -							      new_crtc_
> > > state,
> > > -							      crtc);
> > > -		}
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > > +	}
> > > +
> > > +	/* Disable everything else left on */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > > +			continue;
> > > +
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > 
> > Pondering if there's any chance of some odd fail if we have two ports
> > running in port sync mode. That will now lead to
> > disable_slave(0)->disable_slave(1)->disable_master(0)-
> > >disable_master(1)...
> 
> Thoughts Manasi?
> 
> > 
> > >  	}
> > >  }
> > >  
> > > -- 
> > > 2.24.0

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 22:49       ` Matt Roper
  0 siblings, 0 replies; 65+ messages in thread
From: Matt Roper @ 2019-11-26 22:49 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx

On Tue, Nov 26, 2019 at 02:03:08PM -0800, Souza, Jose wrote:
> On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> > wrote:
> > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> > > reverted the order that pipes gets disabled because of TGL
> > > master/slave relationship between transcoders in MST mode.
> > > 
> > > But as stated in a comment in skl_commit_modeset_enables() the
> > > enabling order is not always crescent, possibly causing previously
> > > selected slave transcoder being enabled before master so another
> > > approach will be needed to select a transcoder to master in MST
> > > mode.
> > > It will be similar to the approach taken in port sync.
> > > 
> > > But instead of implement something like
> > > intel_trans_port_sync_modeset_disables() to MST lets simply it and
> > > iterate over all pipes 2 times, the first one disabling any slave
> > > and
> > > then disabling everything else.
> > > The MST bits will be added in another patch.
> > > 
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Matt Roper <matthew.d.roper@intel.com>
> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
> > > ------
> > >  1 file changed, 22 insertions(+), 57 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -14443,53 +14443,16 @@ static void
> > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > >  		dev_priv->display.initial_watermarks(state, crtc);
> > >  }
> > >  
> > > -static void intel_trans_port_sync_modeset_disables(struct
> > > intel_atomic_state *state,
> > > -						   struct intel_crtc
> > > *crtc,
> > > -						   struct
> > > intel_crtc_state *old_crtc_state,
> > > -						   struct
> > > intel_crtc_state *new_crtc_state)
> > > -{
> > > -	struct intel_crtc *slave_crtc =
> > > intel_get_slave_crtc(new_crtc_state);
> > > -	struct intel_crtc_state *new_slave_crtc_state =
> > > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> > > -	struct intel_crtc_state *old_slave_crtc_state =
> > > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> > > -
> > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > > -		!old_slave_crtc_state);
> > > -
> > > -	/* Disable Slave first */
> > > -	intel_pre_plane_update(old_slave_crtc_state,
> > > new_slave_crtc_state);
> > > -	if (old_slave_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_slave_crtc_state,
> > > -					      new_slave_crtc_state,
> > > -					      slave_crtc);
> > > -
> > > -	/* Disable Master */
> > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > -	if (old_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_crtc_state,
> > > -					      new_crtc_state,
> > > -					      crtc);
> > > -}
> > > -
> > >  static void intel_commit_modeset_disables(struct
> > > intel_atomic_state *state)
> > >  {
> > >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> > >  	struct intel_crtc *crtc;
> > >  	int i;
> > >  
> > > -	/*
> > > -	 * Disable CRTC/pipes in reverse order because some
> > > features(MST in
> > > -	 * TGL+) requires master and slave relationship between pipes,
> > > so it
> > > -	 * should always pick the lowest pipe as master as it will be
> > > enabled
> > > -	 * first and disable in the reverse order so the master will be
> > > the
> > > -	 * last one to be disabled.
> > > -	 */
> > > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
> > > old_crtc_state,
> > > -						    new_crtc_state, i)
> > > {
> > > -		if (!needs_modeset(new_crtc_state))
> > > +	/* Only disable port sync slaves */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > 
> > What's the deal with these crtc->active checks?
> 
> With just one loop we were using "old_crtc_state->hw.active" but as we
> should not modify the computed state in this phase and
> intel_old_crtc_state_disables() sets crtc->active = false, using it
> instead.

I don't think we want to be using intel_crtc->active for anything new if
we can help it.  We have to keep that field around right now to support
some of our ancient platforms that still don't have atomic support yet,
but we don't want to be using it anywhere new we don't already have to
for legacy reasons.

You're only looking at the active flag here, not modifying it, so it
should be fine to use old_crtc_state->active for the pre-modeset status
of the CRTC (and new_crtc_state->active anywhere you need the
post-modeset status).

If you're just trying to keep track of which ones you've already
disabled in this function when you come back around for your second
loop, it would be better to just maintain a bitmask of CRTCs you turned
off in the first pass as a local variable in this function so you know
what to skip on the second pass.


Matt

> 
> > 
> > >  			continue;
> > >  
> > >  		/* In case of Transcoder port Sync master slave CRTCs
> > > can be
> > > @@ -14497,23 +14460,25 @@ static void
> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > >  		 * slave CRTCs are disabled first and then master CRTC
> > > since
> > >  		 * Slave vblanks are masked till Master Vblanks.
> > >  		 */
> > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > > -			if (is_trans_port_sync_master(new_crtc_state))
> > > -				intel_trans_port_sync_modeset_disables(
> > > state,
> > > -								       
> > > crtc,
> > > -								       
> > > old_crtc_state,
> > > -								       
> > > new_crtc_state);
> > > -			else
> > > -				continue;
> > > -		} else {
> > > -			intel_pre_plane_update(old_crtc_state,
> > > new_crtc_state);
> > > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > > +			continue;
> > > +		if (is_trans_port_sync_master(new_crtc_state))
> > > +			continue;
> > 
> > We don't have is_trans_sync_slave()?
> 
> We don't.
> 
> > 
> > >  
> > > -			if (old_crtc_state->hw.active)
> > > -				intel_old_crtc_state_disables(state,
> > > -							      old_crtc_
> > > state,
> > > -							      new_crtc_
> > > state,
> > > -							      crtc);
> > > -		}
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > > +	}
> > > +
> > > +	/* Disable everything else left on */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > > +			continue;
> > > +
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > 
> > Pondering if there's any chance of some odd fail if we have two ports
> > running in port sync mode. That will now lead to
> > disable_slave(0)->disable_slave(1)->disable_master(0)-
> > >disable_master(1)...
> 
> Thoughts Manasi?
> 
> > 
> > >  	}
> > >  }
> > >  
> > > -- 
> > > 2.24.0

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 23:03         ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 23:03 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: intel-gfx

On Tue, 2019-11-26 at 14:49 -0800, Matt Roper wrote:
> On Tue, Nov 26, 2019 at 02:03:08PM -0800, Souza, Jose wrote:
> > On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> > > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> > > wrote:
> > > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse
> > > > order")
> > > > reverted the order that pipes gets disabled because of TGL
> > > > master/slave relationship between transcoders in MST mode.
> > > > 
> > > > But as stated in a comment in skl_commit_modeset_enables() the
> > > > enabling order is not always crescent, possibly causing
> > > > previously
> > > > selected slave transcoder being enabled before master so
> > > > another
> > > > approach will be needed to select a transcoder to master in MST
> > > > mode.
> > > > It will be similar to the approach taken in port sync.
> > > > 
> > > > But instead of implement something like
> > > > intel_trans_port_sync_modeset_disables() to MST lets simply it
> > > > and
> > > > iterate over all pipes 2 times, the first one disabling any
> > > > slave
> > > > and
> > > > then disabling everything else.
> > > > The MST bits will be added in another patch.
> > > > 
> > > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > > Cc: Matt Roper <matthew.d.roper@intel.com>
> > > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++----
> > > > ----
> > > > ------
> > > >  1 file changed, 22 insertions(+), 57 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -14443,53 +14443,16 @@ static void
> > > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > > >  		dev_priv->display.initial_watermarks(state,
> > > > crtc);
> > > >  }
> > > >  
> > > > -static void intel_trans_port_sync_modeset_disables(struct
> > > > intel_atomic_state *state,
> > > > -						   struct
> > > > intel_crtc
> > > > *crtc,
> > > > -						   struct
> > > > intel_crtc_state *old_crtc_state,
> > > > -						   struct
> > > > intel_crtc_state *new_crtc_state)
> > > > -{
> > > > -	struct intel_crtc *slave_crtc =
> > > > intel_get_slave_crtc(new_crtc_state);
> > > > -	struct intel_crtc_state *new_slave_crtc_state =
> > > > -		intel_atomic_get_new_crtc_state(state,
> > > > slave_crtc);
> > > > -	struct intel_crtc_state *old_slave_crtc_state =
> > > > -		intel_atomic_get_old_crtc_state(state,
> > > > slave_crtc);
> > > > -
> > > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > > > -		!old_slave_crtc_state);
> > > > -
> > > > -	/* Disable Slave first */
> > > > -	intel_pre_plane_update(old_slave_crtc_state,
> > > > new_slave_crtc_state);
> > > > -	if (old_slave_crtc_state->hw.active)
> > > > -		intel_old_crtc_state_disables(state,
> > > > -					      old_slave_crtc_st
> > > > ate,
> > > > -					      new_slave_crtc_st
> > > > ate,
> > > > -					      slave_crtc);
> > > > -
> > > > -	/* Disable Master */
> > > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > > -	if (old_crtc_state->hw.active)
> > > > -		intel_old_crtc_state_disables(state,
> > > > -					      old_crtc_state,
> > > > -					      new_crtc_state,
> > > > -					      crtc);
> > > > -}
> > > > -
> > > >  static void intel_commit_modeset_disables(struct
> > > > intel_atomic_state *state)
> > > >  {
> > > >  	struct intel_crtc_state *new_crtc_state,
> > > > *old_crtc_state;
> > > >  	struct intel_crtc *crtc;
> > > >  	int i;
> > > >  
> > > > -	/*
> > > > -	 * Disable CRTC/pipes in reverse order because some
> > > > features(MST in
> > > > -	 * TGL+) requires master and slave relationship between
> > > > pipes,
> > > > so it
> > > > -	 * should always pick the lowest pipe as master as it
> > > > will be
> > > > enabled
> > > > -	 * first and disable in the reverse order so the master
> > > > will be
> > > > the
> > > > -	 * last one to be disabled.
> > > > -	 */
> > > > -	for_each_oldnew_intel_crtc_in_state_reverse(state,
> > > > crtc,
> > > > old_crtc_state,
> > > > -						    new_crtc_st
> > > > ate, i)
> > > > {
> > > > -		if (!needs_modeset(new_crtc_state))
> > > > +	/* Only disable port sync slaves */
> > > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > old_crtc_state,
> > > > +					    new_crtc_state, i)
> > > > {
> > > > +		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > >active)
> > > 
> > > What's the deal with these crtc->active checks?
> > 
> > With just one loop we were using "old_crtc_state->hw.active" but as
> > we
> > should not modify the computed state in this phase and
> > intel_old_crtc_state_disables() sets crtc->active = false, using it
> > instead.
> 
> I don't think we want to be using intel_crtc->active for anything new
> if
> we can help it.  We have to keep that field around right now to
> support
> some of our ancient platforms that still don't have atomic support
> yet,
> but we don't want to be using it anywhere new we don't already have
> to
> for legacy reasons.
> 
> You're only looking at the active flag here, not modifying it, so it
> should be fine to use old_crtc_state->active for the pre-modeset
> status
> of the CRTC (and new_crtc_state->active anywhere you need the
> post-modeset status).
> 
> If you're just trying to keep track of which ones you've already
> disabled in this function when you come back around for your second
> loop, it would be better to just maintain a bitmask of CRTCs you
> turned
> off in the first pass as a local variable in this function so you
> know
> what to skip on the second pass.
> 

Thanks for the headsup, just used it because was easiest option.
Will fix it after get more comments in the other patches.

> 
> Matt
> 
> > > >  			continue;
> > > >  
> > > >  		/* In case of Transcoder port Sync master slave
> > > > CRTCs
> > > > can be
> > > > @@ -14497,23 +14460,25 @@ static void
> > > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > > >  		 * slave CRTCs are disabled first and then
> > > > master CRTC
> > > > since
> > > >  		 * Slave vblanks are masked till Master
> > > > Vblanks.
> > > >  		 */
> > > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > > > -			if
> > > > (is_trans_port_sync_master(new_crtc_state))
> > > > -				intel_trans_port_sync_modeset_d
> > > > isables(
> > > > state,
> > > > -								
> > > >        
> > > > crtc,
> > > > -								
> > > >        
> > > > old_crtc_state,
> > > > -								
> > > >        
> > > > new_crtc_state);
> > > > -			else
> > > > -				continue;
> > > > -		} else {
> > > > -			intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > > > +			continue;
> > > > +		if (is_trans_port_sync_master(new_crtc_state))
> > > > +			continue;
> > > 
> > > We don't have is_trans_sync_slave()?
> > 
> > We don't.
> > 
> > > >  
> > > > -			if (old_crtc_state->hw.active)
> > > > -				intel_old_crtc_state_disables(s
> > > > tate,
> > > > -							      o
> > > > ld_crtc_
> > > > state,
> > > > -							      n
> > > > ew_crtc_
> > > > state,
> > > > -							      c
> > > > rtc);
> > > > -		}
> > > > +		intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > > +		intel_old_crtc_state_disables(state,
> > > > old_crtc_state,
> > > > +					      new_crtc_state,
> > > > crtc);
> > > > +	}
> > > > +
> > > > +	/* Disable everything else left on */
> > > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > old_crtc_state,
> > > > +					    new_crtc_state, i)
> > > > {
> > > > +		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > >active)
> > > > +			continue;
> > > > +
> > > > +		intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > > +		intel_old_crtc_state_disables(state,
> > > > old_crtc_state,
> > > > +					      new_crtc_state,
> > > > crtc);
> > > 
> > > Pondering if there's any chance of some odd fail if we have two
> > > ports
> > > running in port sync mode. That will now lead to
> > > disable_slave(0)->disable_slave(1)->disable_master(0)-
> > > > disable_master(1)...
> > 
> > Thoughts Manasi?
> > 
> > > >  	}
> > > >  }
> > > >  
> > > > -- 
> > > > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-26 23:03         ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-26 23:03 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: intel-gfx

On Tue, 2019-11-26 at 14:49 -0800, Matt Roper wrote:
> On Tue, Nov 26, 2019 at 02:03:08PM -0800, Souza, Jose wrote:
> > On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> > > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> > > wrote:
> > > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse
> > > > order")
> > > > reverted the order that pipes gets disabled because of TGL
> > > > master/slave relationship between transcoders in MST mode.
> > > > 
> > > > But as stated in a comment in skl_commit_modeset_enables() the
> > > > enabling order is not always crescent, possibly causing
> > > > previously
> > > > selected slave transcoder being enabled before master so
> > > > another
> > > > approach will be needed to select a transcoder to master in MST
> > > > mode.
> > > > It will be similar to the approach taken in port sync.
> > > > 
> > > > But instead of implement something like
> > > > intel_trans_port_sync_modeset_disables() to MST lets simply it
> > > > and
> > > > iterate over all pipes 2 times, the first one disabling any
> > > > slave
> > > > and
> > > > then disabling everything else.
> > > > The MST bits will be added in another patch.
> > > > 
> > > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > > Cc: Matt Roper <matthew.d.roper@intel.com>
> > > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++----
> > > > ----
> > > > ------
> > > >  1 file changed, 22 insertions(+), 57 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -14443,53 +14443,16 @@ static void
> > > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > > >  		dev_priv->display.initial_watermarks(state,
> > > > crtc);
> > > >  }
> > > >  
> > > > -static void intel_trans_port_sync_modeset_disables(struct
> > > > intel_atomic_state *state,
> > > > -						   struct
> > > > intel_crtc
> > > > *crtc,
> > > > -						   struct
> > > > intel_crtc_state *old_crtc_state,
> > > > -						   struct
> > > > intel_crtc_state *new_crtc_state)
> > > > -{
> > > > -	struct intel_crtc *slave_crtc =
> > > > intel_get_slave_crtc(new_crtc_state);
> > > > -	struct intel_crtc_state *new_slave_crtc_state =
> > > > -		intel_atomic_get_new_crtc_state(state,
> > > > slave_crtc);
> > > > -	struct intel_crtc_state *old_slave_crtc_state =
> > > > -		intel_atomic_get_old_crtc_state(state,
> > > > slave_crtc);
> > > > -
> > > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > > > -		!old_slave_crtc_state);
> > > > -
> > > > -	/* Disable Slave first */
> > > > -	intel_pre_plane_update(old_slave_crtc_state,
> > > > new_slave_crtc_state);
> > > > -	if (old_slave_crtc_state->hw.active)
> > > > -		intel_old_crtc_state_disables(state,
> > > > -					      old_slave_crtc_st
> > > > ate,
> > > > -					      new_slave_crtc_st
> > > > ate,
> > > > -					      slave_crtc);
> > > > -
> > > > -	/* Disable Master */
> > > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > > -	if (old_crtc_state->hw.active)
> > > > -		intel_old_crtc_state_disables(state,
> > > > -					      old_crtc_state,
> > > > -					      new_crtc_state,
> > > > -					      crtc);
> > > > -}
> > > > -
> > > >  static void intel_commit_modeset_disables(struct
> > > > intel_atomic_state *state)
> > > >  {
> > > >  	struct intel_crtc_state *new_crtc_state,
> > > > *old_crtc_state;
> > > >  	struct intel_crtc *crtc;
> > > >  	int i;
> > > >  
> > > > -	/*
> > > > -	 * Disable CRTC/pipes in reverse order because some
> > > > features(MST in
> > > > -	 * TGL+) requires master and slave relationship between
> > > > pipes,
> > > > so it
> > > > -	 * should always pick the lowest pipe as master as it
> > > > will be
> > > > enabled
> > > > -	 * first and disable in the reverse order so the master
> > > > will be
> > > > the
> > > > -	 * last one to be disabled.
> > > > -	 */
> > > > -	for_each_oldnew_intel_crtc_in_state_reverse(state,
> > > > crtc,
> > > > old_crtc_state,
> > > > -						    new_crtc_st
> > > > ate, i)
> > > > {
> > > > -		if (!needs_modeset(new_crtc_state))
> > > > +	/* Only disable port sync slaves */
> > > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > old_crtc_state,
> > > > +					    new_crtc_state, i)
> > > > {
> > > > +		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > >active)
> > > 
> > > What's the deal with these crtc->active checks?
> > 
> > With just one loop we were using "old_crtc_state->hw.active" but as
> > we
> > should not modify the computed state in this phase and
> > intel_old_crtc_state_disables() sets crtc->active = false, using it
> > instead.
> 
> I don't think we want to be using intel_crtc->active for anything new
> if
> we can help it.  We have to keep that field around right now to
> support
> some of our ancient platforms that still don't have atomic support
> yet,
> but we don't want to be using it anywhere new we don't already have
> to
> for legacy reasons.
> 
> You're only looking at the active flag here, not modifying it, so it
> should be fine to use old_crtc_state->active for the pre-modeset
> status
> of the CRTC (and new_crtc_state->active anywhere you need the
> post-modeset status).
> 
> If you're just trying to keep track of which ones you've already
> disabled in this function when you come back around for your second
> loop, it would be better to just maintain a bitmask of CRTCs you
> turned
> off in the first pass as a local variable in this function so you
> know
> what to skip on the second pass.
> 

Thanks for the headsup, just used it because was easiest option.
Will fix it after get more comments in the other patches.

> 
> Matt
> 
> > > >  			continue;
> > > >  
> > > >  		/* In case of Transcoder port Sync master slave
> > > > CRTCs
> > > > can be
> > > > @@ -14497,23 +14460,25 @@ static void
> > > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > > >  		 * slave CRTCs are disabled first and then
> > > > master CRTC
> > > > since
> > > >  		 * Slave vblanks are masked till Master
> > > > Vblanks.
> > > >  		 */
> > > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > > > -			if
> > > > (is_trans_port_sync_master(new_crtc_state))
> > > > -				intel_trans_port_sync_modeset_d
> > > > isables(
> > > > state,
> > > > -								
> > > >        
> > > > crtc,
> > > > -								
> > > >        
> > > > old_crtc_state,
> > > > -								
> > > >        
> > > > new_crtc_state);
> > > > -			else
> > > > -				continue;
> > > > -		} else {
> > > > -			intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > > > +			continue;
> > > > +		if (is_trans_port_sync_master(new_crtc_state))
> > > > +			continue;
> > > 
> > > We don't have is_trans_sync_slave()?
> > 
> > We don't.
> > 
> > > >  
> > > > -			if (old_crtc_state->hw.active)
> > > > -				intel_old_crtc_state_disables(s
> > > > tate,
> > > > -							      o
> > > > ld_crtc_
> > > > state,
> > > > -							      n
> > > > ew_crtc_
> > > > state,
> > > > -							      c
> > > > rtc);
> > > > -		}
> > > > +		intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > > +		intel_old_crtc_state_disables(state,
> > > > old_crtc_state,
> > > > +					      new_crtc_state,
> > > > crtc);
> > > > +	}
> > > > +
> > > > +	/* Disable everything else left on */
> > > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > old_crtc_state,
> > > > +					    new_crtc_state, i)
> > > > {
> > > > +		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > >active)
> > > > +			continue;
> > > > +
> > > > +		intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > > +		intel_old_crtc_state_disables(state,
> > > > old_crtc_state,
> > > > +					      new_crtc_state,
> > > > crtc);
> > > 
> > > Pondering if there's any chance of some odd fail if we have two
> > > ports
> > > running in port sync mode. That will now lead to
> > > disable_slave(0)->disable_slave(1)->disable_master(0)-
> > > > disable_master(1)...
> > 
> > Thoughts Manasi?
> > 
> > > >  	}
> > > >  }
> > > >  
> > > > -- 
> > > > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-27 18:49         ` Lucas De Marchi
  0 siblings, 0 replies; 65+ messages in thread
From: Lucas De Marchi @ 2019-11-27 18:49 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Tue, Nov 26, 2019 at 02:49:47PM -0800, Matt Roper wrote:
>On Tue, Nov 26, 2019 at 02:03:08PM -0800, Souza, Jose wrote:
>> On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
>> > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
>> > wrote:
>> > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
>> > > reverted the order that pipes gets disabled because of TGL
>> > > master/slave relationship between transcoders in MST mode.
>> > >
>> > > But as stated in a comment in skl_commit_modeset_enables() the
>> > > enabling order is not always crescent, possibly causing previously
>> > > selected slave transcoder being enabled before master so another
>> > > approach will be needed to select a transcoder to master in MST
>> > > mode.
>> > > It will be similar to the approach taken in port sync.
>> > >
>> > > But instead of implement something like
>> > > intel_trans_port_sync_modeset_disables() to MST lets simply it and
>> > > iterate over all pipes 2 times, the first one disabling any slave
>> > > and
>> > > then disabling everything else.
>> > > The MST bits will be added in another patch.
>> > >
>> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
>> > > Cc: Matt Roper <matthew.d.roper@intel.com>
>> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
>> > > ---
>> > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
>> > > ------
>> > >  1 file changed, 22 insertions(+), 57 deletions(-)
>> > >
>> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
>> > > b/drivers/gpu/drm/i915/display/intel_display.c
>> > > index 53dc310a5f6d..1b1fbb6d8acc 100644
>> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
>> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> > > @@ -14443,53 +14443,16 @@ static void
>> > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
>> > >  		dev_priv->display.initial_watermarks(state, crtc);
>> > >  }
>> > >
>> > > -static void intel_trans_port_sync_modeset_disables(struct
>> > > intel_atomic_state *state,
>> > > -						   struct intel_crtc
>> > > *crtc,
>> > > -						   struct
>> > > intel_crtc_state *old_crtc_state,
>> > > -						   struct
>> > > intel_crtc_state *new_crtc_state)
>> > > -{
>> > > -	struct intel_crtc *slave_crtc =
>> > > intel_get_slave_crtc(new_crtc_state);
>> > > -	struct intel_crtc_state *new_slave_crtc_state =
>> > > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
>> > > -	struct intel_crtc_state *old_slave_crtc_state =
>> > > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
>> > > -
>> > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
>> > > -		!old_slave_crtc_state);
>> > > -
>> > > -	/* Disable Slave first */
>> > > -	intel_pre_plane_update(old_slave_crtc_state,
>> > > new_slave_crtc_state);
>> > > -	if (old_slave_crtc_state->hw.active)
>> > > -		intel_old_crtc_state_disables(state,
>> > > -					      old_slave_crtc_state,
>> > > -					      new_slave_crtc_state,
>> > > -					      slave_crtc);
>> > > -
>> > > -	/* Disable Master */
>> > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
>> > > -	if (old_crtc_state->hw.active)
>> > > -		intel_old_crtc_state_disables(state,
>> > > -					      old_crtc_state,
>> > > -					      new_crtc_state,
>> > > -					      crtc);
>> > > -}
>> > > -
>> > >  static void intel_commit_modeset_disables(struct
>> > > intel_atomic_state *state)
>> > >  {
>> > >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>> > >  	struct intel_crtc *crtc;
>> > >  	int i;
>> > >
>> > > -	/*
>> > > -	 * Disable CRTC/pipes in reverse order because some
>> > > features(MST in
>> > > -	 * TGL+) requires master and slave relationship between pipes,
>> > > so it
>> > > -	 * should always pick the lowest pipe as master as it will be
>> > > enabled
>> > > -	 * first and disable in the reverse order so the master will be
>> > > the
>> > > -	 * last one to be disabled.
>> > > -	 */
>> > > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
>> > > old_crtc_state,
>> > > -						    new_crtc_state, i)
>> > > {
>> > > -		if (!needs_modeset(new_crtc_state))
>> > > +	/* Only disable port sync slaves */
>> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
>> > > old_crtc_state,
>> > > +					    new_crtc_state, i) {
>> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
>> >
>> > What's the deal with these crtc->active checks?
>>
>> With just one loop we were using "old_crtc_state->hw.active" but as we
>> should not modify the computed state in this phase and
>> intel_old_crtc_state_disables() sets crtc->active = false, using it
>> instead.
>
>I don't think we want to be using intel_crtc->active for anything new if
>we can help it.  We have to keep that field around right now to support
>some of our ancient platforms that still don't have atomic support yet,
>but we don't want to be using it anywhere new we don't already have to
>for legacy reasons.

humm, good to know. Maybe this deserves a comment like this in
struct intel_crtc.active?

>
>You're only looking at the active flag here, not modifying it, so it
>should be fine to use old_crtc_state->active for the pre-modeset status
>of the CRTC (and new_crtc_state->active anywhere you need the
>post-modeset status).
>
>If you're just trying to keep track of which ones you've already
>disabled in this function when you come back around for your second
>loop, it would be better to just maintain a bitmask of CRTCs you turned
>off in the first pass as a local variable in this function so you know
>what to skip on the second pass.

yep, that's a great suggestion.

Lucas De Marchi

>
>
>Matt
>
>>
>> >
>> > >  			continue;
>> > >
>> > >  		/* In case of Transcoder port Sync master slave CRTCs
>> > > can be
>> > > @@ -14497,23 +14460,25 @@ static void
>> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
>> > >  		 * slave CRTCs are disabled first and then master CRTC
>> > > since
>> > >  		 * Slave vblanks are masked till Master Vblanks.
>> > >  		 */
>> > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
>> > > -			if (is_trans_port_sync_master(new_crtc_state))
>> > > -				intel_trans_port_sync_modeset_disables(
>> > > state,
>> > > -								
>> > > crtc,
>> > > -								
>> > > old_crtc_state,
>> > > -								
>> > > new_crtc_state);
>> > > -			else
>> > > -				continue;
>> > > -		} else {
>> > > -			intel_pre_plane_update(old_crtc_state,
>> > > new_crtc_state);
>> > > +		if (!is_trans_port_sync_mode(new_crtc_state))
>> > > +			continue;
>> > > +		if (is_trans_port_sync_master(new_crtc_state))
>> > > +			continue;
>> >
>> > We don't have is_trans_sync_slave()?
>>
>> We don't.
>>
>> >
>> > >
>> > > -			if (old_crtc_state->hw.active)
>> > > -				intel_old_crtc_state_disables(state,
>> > > -							      old_crtc_
>> > > state,
>> > > -							      new_crtc_
>> > > state,
>> > > -							      crtc);
>> > > -		}
>> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
>> > > +					      new_crtc_state, crtc);
>> > > +	}
>> > > +
>> > > +	/* Disable everything else left on */
>> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
>> > > old_crtc_state,
>> > > +					    new_crtc_state, i) {
>> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
>> > > +			continue;
>> > > +
>> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
>> > > +					      new_crtc_state, crtc);
>> >
>> > Pondering if there's any chance of some odd fail if we have two ports
>> > running in port sync mode. That will now lead to
>> > disable_slave(0)->disable_slave(1)->disable_master(0)-
>> > >disable_master(1)...
>>
>> Thoughts Manasi?
>>
>> >
>> > >  	}
>> > >  }
>> > >
>> > > --
>> > > 2.24.0
>
>-- 
>Matt Roper
>Graphics Software Engineer
>VTT-OSGC Platform Enablement
>Intel Corporation
>(916) 356-2795
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-27 18:49         ` Lucas De Marchi
  0 siblings, 0 replies; 65+ messages in thread
From: Lucas De Marchi @ 2019-11-27 18:49 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Tue, Nov 26, 2019 at 02:49:47PM -0800, Matt Roper wrote:
>On Tue, Nov 26, 2019 at 02:03:08PM -0800, Souza, Jose wrote:
>> On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
>> > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
>> > wrote:
>> > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
>> > > reverted the order that pipes gets disabled because of TGL
>> > > master/slave relationship between transcoders in MST mode.
>> > >
>> > > But as stated in a comment in skl_commit_modeset_enables() the
>> > > enabling order is not always crescent, possibly causing previously
>> > > selected slave transcoder being enabled before master so another
>> > > approach will be needed to select a transcoder to master in MST
>> > > mode.
>> > > It will be similar to the approach taken in port sync.
>> > >
>> > > But instead of implement something like
>> > > intel_trans_port_sync_modeset_disables() to MST lets simply it and
>> > > iterate over all pipes 2 times, the first one disabling any slave
>> > > and
>> > > then disabling everything else.
>> > > The MST bits will be added in another patch.
>> > >
>> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
>> > > Cc: Matt Roper <matthew.d.roper@intel.com>
>> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
>> > > ---
>> > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
>> > > ------
>> > >  1 file changed, 22 insertions(+), 57 deletions(-)
>> > >
>> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
>> > > b/drivers/gpu/drm/i915/display/intel_display.c
>> > > index 53dc310a5f6d..1b1fbb6d8acc 100644
>> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
>> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> > > @@ -14443,53 +14443,16 @@ static void
>> > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
>> > >  		dev_priv->display.initial_watermarks(state, crtc);
>> > >  }
>> > >
>> > > -static void intel_trans_port_sync_modeset_disables(struct
>> > > intel_atomic_state *state,
>> > > -						   struct intel_crtc
>> > > *crtc,
>> > > -						   struct
>> > > intel_crtc_state *old_crtc_state,
>> > > -						   struct
>> > > intel_crtc_state *new_crtc_state)
>> > > -{
>> > > -	struct intel_crtc *slave_crtc =
>> > > intel_get_slave_crtc(new_crtc_state);
>> > > -	struct intel_crtc_state *new_slave_crtc_state =
>> > > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
>> > > -	struct intel_crtc_state *old_slave_crtc_state =
>> > > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
>> > > -
>> > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
>> > > -		!old_slave_crtc_state);
>> > > -
>> > > -	/* Disable Slave first */
>> > > -	intel_pre_plane_update(old_slave_crtc_state,
>> > > new_slave_crtc_state);
>> > > -	if (old_slave_crtc_state->hw.active)
>> > > -		intel_old_crtc_state_disables(state,
>> > > -					      old_slave_crtc_state,
>> > > -					      new_slave_crtc_state,
>> > > -					      slave_crtc);
>> > > -
>> > > -	/* Disable Master */
>> > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
>> > > -	if (old_crtc_state->hw.active)
>> > > -		intel_old_crtc_state_disables(state,
>> > > -					      old_crtc_state,
>> > > -					      new_crtc_state,
>> > > -					      crtc);
>> > > -}
>> > > -
>> > >  static void intel_commit_modeset_disables(struct
>> > > intel_atomic_state *state)
>> > >  {
>> > >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>> > >  	struct intel_crtc *crtc;
>> > >  	int i;
>> > >
>> > > -	/*
>> > > -	 * Disable CRTC/pipes in reverse order because some
>> > > features(MST in
>> > > -	 * TGL+) requires master and slave relationship between pipes,
>> > > so it
>> > > -	 * should always pick the lowest pipe as master as it will be
>> > > enabled
>> > > -	 * first and disable in the reverse order so the master will be
>> > > the
>> > > -	 * last one to be disabled.
>> > > -	 */
>> > > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
>> > > old_crtc_state,
>> > > -						    new_crtc_state, i)
>> > > {
>> > > -		if (!needs_modeset(new_crtc_state))
>> > > +	/* Only disable port sync slaves */
>> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
>> > > old_crtc_state,
>> > > +					    new_crtc_state, i) {
>> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
>> >
>> > What's the deal with these crtc->active checks?
>>
>> With just one loop we were using "old_crtc_state->hw.active" but as we
>> should not modify the computed state in this phase and
>> intel_old_crtc_state_disables() sets crtc->active = false, using it
>> instead.
>
>I don't think we want to be using intel_crtc->active for anything new if
>we can help it.  We have to keep that field around right now to support
>some of our ancient platforms that still don't have atomic support yet,
>but we don't want to be using it anywhere new we don't already have to
>for legacy reasons.

humm, good to know. Maybe this deserves a comment like this in
struct intel_crtc.active?

>
>You're only looking at the active flag here, not modifying it, so it
>should be fine to use old_crtc_state->active for the pre-modeset status
>of the CRTC (and new_crtc_state->active anywhere you need the
>post-modeset status).
>
>If you're just trying to keep track of which ones you've already
>disabled in this function when you come back around for your second
>loop, it would be better to just maintain a bitmask of CRTCs you turned
>off in the first pass as a local variable in this function so you know
>what to skip on the second pass.

yep, that's a great suggestion.

Lucas De Marchi

>
>
>Matt
>
>>
>> >
>> > >  			continue;
>> > >
>> > >  		/* In case of Transcoder port Sync master slave CRTCs
>> > > can be
>> > > @@ -14497,23 +14460,25 @@ static void
>> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
>> > >  		 * slave CRTCs are disabled first and then master CRTC
>> > > since
>> > >  		 * Slave vblanks are masked till Master Vblanks.
>> > >  		 */
>> > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
>> > > -			if (is_trans_port_sync_master(new_crtc_state))
>> > > -				intel_trans_port_sync_modeset_disables(
>> > > state,
>> > > -								
>> > > crtc,
>> > > -								
>> > > old_crtc_state,
>> > > -								
>> > > new_crtc_state);
>> > > -			else
>> > > -				continue;
>> > > -		} else {
>> > > -			intel_pre_plane_update(old_crtc_state,
>> > > new_crtc_state);
>> > > +		if (!is_trans_port_sync_mode(new_crtc_state))
>> > > +			continue;
>> > > +		if (is_trans_port_sync_master(new_crtc_state))
>> > > +			continue;
>> >
>> > We don't have is_trans_sync_slave()?
>>
>> We don't.
>>
>> >
>> > >
>> > > -			if (old_crtc_state->hw.active)
>> > > -				intel_old_crtc_state_disables(state,
>> > > -							      old_crtc_
>> > > state,
>> > > -							      new_crtc_
>> > > state,
>> > > -							      crtc);
>> > > -		}
>> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
>> > > +					      new_crtc_state, crtc);
>> > > +	}
>> > > +
>> > > +	/* Disable everything else left on */
>> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
>> > > old_crtc_state,
>> > > +					    new_crtc_state, i) {
>> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
>> > > +			continue;
>> > > +
>> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
>> > > +					      new_crtc_state, crtc);
>> >
>> > Pondering if there's any chance of some odd fail if we have two ports
>> > running in port sync mode. That will now lead to
>> > disable_slave(0)->disable_slave(1)->disable_master(0)-
>> > >disable_master(1)...
>>
>> Thoughts Manasi?
>>
>> >
>> > >  	}
>> > >  }
>> > >
>> > > --
>> > > 2.24.0
>
>-- 
>Matt Roper
>Graphics Software Engineer
>VTT-OSGC Platform Enablement
>Intel Corporation
>(916) 356-2795
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-27 19:11       ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-27 19:11 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx

On Tue, Nov 26, 2019 at 10:03:08PM +0000, Souza, Jose wrote:
> On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> > wrote:
> > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> > > reverted the order that pipes gets disabled because of TGL
> > > master/slave relationship between transcoders in MST mode.
> > > 
> > > But as stated in a comment in skl_commit_modeset_enables() the
> > > enabling order is not always crescent, possibly causing previously
> > > selected slave transcoder being enabled before master so another
> > > approach will be needed to select a transcoder to master in MST
> > > mode.
> > > It will be similar to the approach taken in port sync.
> > > 
> > > But instead of implement something like
> > > intel_trans_port_sync_modeset_disables() to MST lets simply it and
> > > iterate over all pipes 2 times, the first one disabling any slave
> > > and
> > > then disabling everything else.
> > > The MST bits will be added in another patch.
> > > 
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Matt Roper <matthew.d.roper@intel.com>
> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
> > > ------
> > >  1 file changed, 22 insertions(+), 57 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -14443,53 +14443,16 @@ static void
> > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > >  		dev_priv->display.initial_watermarks(state, crtc);
> > >  }
> > >  
> > > -static void intel_trans_port_sync_modeset_disables(struct
> > > intel_atomic_state *state,
> > > -						   struct intel_crtc
> > > *crtc,
> > > -						   struct
> > > intel_crtc_state *old_crtc_state,
> > > -						   struct
> > > intel_crtc_state *new_crtc_state)
> > > -{
> > > -	struct intel_crtc *slave_crtc =
> > > intel_get_slave_crtc(new_crtc_state);
> > > -	struct intel_crtc_state *new_slave_crtc_state =
> > > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> > > -	struct intel_crtc_state *old_slave_crtc_state =
> > > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> > > -
> > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > > -		!old_slave_crtc_state);
> > > -
> > > -	/* Disable Slave first */
> > > -	intel_pre_plane_update(old_slave_crtc_state,
> > > new_slave_crtc_state);
> > > -	if (old_slave_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_slave_crtc_state,
> > > -					      new_slave_crtc_state,
> > > -					      slave_crtc);
> > > -
> > > -	/* Disable Master */
> > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > -	if (old_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_crtc_state,
> > > -					      new_crtc_state,
> > > -					      crtc);
> > > -}
> > > -
> > >  static void intel_commit_modeset_disables(struct
> > > intel_atomic_state *state)
> > >  {
> > >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> > >  	struct intel_crtc *crtc;
> > >  	int i;
> > >  
> > > -	/*
> > > -	 * Disable CRTC/pipes in reverse order because some
> > > features(MST in
> > > -	 * TGL+) requires master and slave relationship between pipes,
> > > so it
> > > -	 * should always pick the lowest pipe as master as it will be
> > > enabled
> > > -	 * first and disable in the reverse order so the master will be
> > > the
> > > -	 * last one to be disabled.
> > > -	 */
> > > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
> > > old_crtc_state,
> > > -						    new_crtc_state, i)
> > > {
> > > -		if (!needs_modeset(new_crtc_state))
> > > +	/* Only disable port sync slaves */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > 
> > What's the deal with these crtc->active checks?
> 
> With just one loop we were using "old_crtc_state->hw.active" but as we
> should not modify the computed state in this phase and
> intel_old_crtc_state_disables() sets crtc->active = false, using it
> instead.

You should never use it. We should aim towards eliminating it. I don't
think we're far off now.

> 
> > 
> > >  			continue;
> > >  
> > >  		/* In case of Transcoder port Sync master slave CRTCs
> > > can be
> > > @@ -14497,23 +14460,25 @@ static void
> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > >  		 * slave CRTCs are disabled first and then master CRTC
> > > since
> > >  		 * Slave vblanks are masked till Master Vblanks.
> > >  		 */
> > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > > -			if (is_trans_port_sync_master(new_crtc_state))
> > > -				intel_trans_port_sync_modeset_disables(
> > > state,
> > > -								       
> > > crtc,
> > > -								       
> > > old_crtc_state,
> > > -								       
> > > new_crtc_state);
> > > -			else
> > > -				continue;
> > > -		} else {
> > > -			intel_pre_plane_update(old_crtc_state,
> > > new_crtc_state);
> > > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > > +			continue;
> > > +		if (is_trans_port_sync_master(new_crtc_state))
> > > +			continue;
> > 
> > We don't have is_trans_sync_slave()?
> 
> We don't.

Maybe add it?

> 
> > 
> > >  
> > > -			if (old_crtc_state->hw.active)
> > > -				intel_old_crtc_state_disables(state,
> > > -							      old_crtc_
> > > state,
> > > -							      new_crtc_
> > > state,
> > > -							      crtc);
> > > -		}
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > > +	}
> > > +
> > > +	/* Disable everything else left on */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > > +			continue;
> > > +
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > 
> > Pondering if there's any chance of some odd fail if we have two ports
> > running in port sync mode. That will now lead to
> > disable_slave(0)->disable_slave(1)->disable_master(0)-
> > >disable_master(1)...
> 
> Thoughts Manasi?
> 
> > 
> > >  	}
> > >  }
> > >  
> > > -- 
> > > 2.24.0

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

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

* Re: [Intel-gfx] [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables()
@ 2019-11-27 19:11       ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-27 19:11 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx

On Tue, Nov 26, 2019 at 10:03:08PM +0000, Souza, Jose wrote:
> On Tue, 2019-11-26 at 21:40 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:53PM -0800, José Roberto de Souza
> > wrote:
> > > Commit 9c722e17c1b9 ("drm/i915: Disable pipes in reverse order")
> > > reverted the order that pipes gets disabled because of TGL
> > > master/slave relationship between transcoders in MST mode.
> > > 
> > > But as stated in a comment in skl_commit_modeset_enables() the
> > > enabling order is not always crescent, possibly causing previously
> > > selected slave transcoder being enabled before master so another
> > > approach will be needed to select a transcoder to master in MST
> > > mode.
> > > It will be similar to the approach taken in port sync.
> > > 
> > > But instead of implement something like
> > > intel_trans_port_sync_modeset_disables() to MST lets simply it and
> > > iterate over all pipes 2 times, the first one disabling any slave
> > > and
> > > then disabling everything else.
> > > The MST bits will be added in another patch.
> > > 
> > > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > > Cc: Matt Roper <matthew.d.roper@intel.com>
> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 79 ++++++--------
> > > ------
> > >  1 file changed, 22 insertions(+), 57 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 53dc310a5f6d..1b1fbb6d8acc 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -14443,53 +14443,16 @@ static void
> > > intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > >  		dev_priv->display.initial_watermarks(state, crtc);
> > >  }
> > >  
> > > -static void intel_trans_port_sync_modeset_disables(struct
> > > intel_atomic_state *state,
> > > -						   struct intel_crtc
> > > *crtc,
> > > -						   struct
> > > intel_crtc_state *old_crtc_state,
> > > -						   struct
> > > intel_crtc_state *new_crtc_state)
> > > -{
> > > -	struct intel_crtc *slave_crtc =
> > > intel_get_slave_crtc(new_crtc_state);
> > > -	struct intel_crtc_state *new_slave_crtc_state =
> > > -		intel_atomic_get_new_crtc_state(state, slave_crtc);
> > > -	struct intel_crtc_state *old_slave_crtc_state =
> > > -		intel_atomic_get_old_crtc_state(state, slave_crtc);
> > > -
> > > -	WARN_ON(!slave_crtc || !new_slave_crtc_state ||
> > > -		!old_slave_crtc_state);
> > > -
> > > -	/* Disable Slave first */
> > > -	intel_pre_plane_update(old_slave_crtc_state,
> > > new_slave_crtc_state);
> > > -	if (old_slave_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_slave_crtc_state,
> > > -					      new_slave_crtc_state,
> > > -					      slave_crtc);
> > > -
> > > -	/* Disable Master */
> > > -	intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > -	if (old_crtc_state->hw.active)
> > > -		intel_old_crtc_state_disables(state,
> > > -					      old_crtc_state,
> > > -					      new_crtc_state,
> > > -					      crtc);
> > > -}
> > > -
> > >  static void intel_commit_modeset_disables(struct
> > > intel_atomic_state *state)
> > >  {
> > >  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> > >  	struct intel_crtc *crtc;
> > >  	int i;
> > >  
> > > -	/*
> > > -	 * Disable CRTC/pipes in reverse order because some
> > > features(MST in
> > > -	 * TGL+) requires master and slave relationship between pipes,
> > > so it
> > > -	 * should always pick the lowest pipe as master as it will be
> > > enabled
> > > -	 * first and disable in the reverse order so the master will be
> > > the
> > > -	 * last one to be disabled.
> > > -	 */
> > > -	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc,
> > > old_crtc_state,
> > > -						    new_crtc_state, i)
> > > {
> > > -		if (!needs_modeset(new_crtc_state))
> > > +	/* Only disable port sync slaves */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > 
> > What's the deal with these crtc->active checks?
> 
> With just one loop we were using "old_crtc_state->hw.active" but as we
> should not modify the computed state in this phase and
> intel_old_crtc_state_disables() sets crtc->active = false, using it
> instead.

You should never use it. We should aim towards eliminating it. I don't
think we're far off now.

> 
> > 
> > >  			continue;
> > >  
> > >  		/* In case of Transcoder port Sync master slave CRTCs
> > > can be
> > > @@ -14497,23 +14460,25 @@ static void
> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > >  		 * slave CRTCs are disabled first and then master CRTC
> > > since
> > >  		 * Slave vblanks are masked till Master Vblanks.
> > >  		 */
> > > -		if (is_trans_port_sync_mode(new_crtc_state)) {
> > > -			if (is_trans_port_sync_master(new_crtc_state))
> > > -				intel_trans_port_sync_modeset_disables(
> > > state,
> > > -								       
> > > crtc,
> > > -								       
> > > old_crtc_state,
> > > -								       
> > > new_crtc_state);
> > > -			else
> > > -				continue;
> > > -		} else {
> > > -			intel_pre_plane_update(old_crtc_state,
> > > new_crtc_state);
> > > +		if (!is_trans_port_sync_mode(new_crtc_state))
> > > +			continue;
> > > +		if (is_trans_port_sync_master(new_crtc_state))
> > > +			continue;
> > 
> > We don't have is_trans_sync_slave()?
> 
> We don't.

Maybe add it?

> 
> > 
> > >  
> > > -			if (old_crtc_state->hw.active)
> > > -				intel_old_crtc_state_disables(state,
> > > -							      old_crtc_
> > > state,
> > > -							      new_crtc_
> > > state,
> > > -							      crtc);
> > > -		}
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > > +	}
> > > +
> > > +	/* Disable everything else left on */
> > > +	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > > +					    new_crtc_state, i) {
> > > +		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > > +			continue;
> > > +
> > > +		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > > +		intel_old_crtc_state_disables(state, old_crtc_state,
> > > +					      new_crtc_state, crtc);
> > 
> > Pondering if there's any chance of some odd fail if we have two ports
> > running in port sync mode. That will now lead to
> > disable_slave(0)->disable_slave(1)->disable_master(0)-
> > >disable_master(1)...
> 
> Thoughts Manasi?
> 
> > 
> > >  	}
> > >  }
> > >  
> > > -- 
> > > 2.24.0

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

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

* Re: [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-27 19:24         ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-27 19:24 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Tue, Nov 26, 2019 at 10:12:52PM +0000, Souza, Jose wrote:
> On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> > wrote:
> > > Disabling pipe/transcoder clock before power down sink could cause
> > > sink lost signal, causing it to trigger a hotplug to notify source
> > > that link signal was lost.
> > > 
> > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -3808,12 +3808,12 @@ static void
> > > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> > >  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
> > >  
> > >  	if (!is_mst) {
> > > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> > >  		/*
> > >  		 * Power down sink before disabling the port, otherwise
> > > we end
> > >  		 * up getting interrupts from the sink on detecting
> > > link loss.
> > >  		 */
> > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > >  	}
> > 
> > The spec seems to say that we should do this after turning off
> > DDI_BUF_CTL on tgl+.
> 
> What step? I can't find any step talking about AUX DP_SET_POWER.

I was talking about DDI_BUF disable vs. transcoder clock disable.

> 
> My understating is that we should power off sink before interfering in
> the mainlink signal otherwise sink could trigger hotplugs to notify
> source about link loss.

Pretty much. Nothing wrong with your patch for pre-tgl I think, but for
tgl+ you didn't move the clock disable quite far enough to match the
bspec sequence.

> 
> > 
> > >  
> > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > -- 
> > > 2.24.0
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-27 19:24         ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-27 19:24 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Tue, Nov 26, 2019 at 10:12:52PM +0000, Souza, Jose wrote:
> On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> > wrote:
> > > Disabling pipe/transcoder clock before power down sink could cause
> > > sink lost signal, causing it to trigger a hotplug to notify source
> > > that link signal was lost.
> > > 
> > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -3808,12 +3808,12 @@ static void
> > > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> > >  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
> > >  
> > >  	if (!is_mst) {
> > > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> > >  		/*
> > >  		 * Power down sink before disabling the port, otherwise
> > > we end
> > >  		 * up getting interrupts from the sink on detecting
> > > link loss.
> > >  		 */
> > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > >  	}
> > 
> > The spec seems to say that we should do this after turning off
> > DDI_BUF_CTL on tgl+.
> 
> What step? I can't find any step talking about AUX DP_SET_POWER.

I was talking about DDI_BUF disable vs. transcoder clock disable.

> 
> My understating is that we should power off sink before interfering in
> the mainlink signal otherwise sink could trigger hotplugs to notify
> source about link loss.

Pretty much. Nothing wrong with your patch for pre-tgl I think, but for
tgl+ you didn't move the clock disable quite far enough to match the
bspec sequence.

> 
> > 
> > >  
> > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > -- 
> > > 2.24.0
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-27 19:59         ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-27 19:59 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> > wrote:
> > > On TGL the blending of all the streams have moved from DDI to
> > > transcoder, so now every transcoder working over the same MST port
> > > must
> > > send its stream to a master transcoder and master will send to DDI
> > > respecting the time slots.
> > > 
> > > A previous approach was using the lowest pipe/transcoder as master
> > > transcoder but as the comment in skl_commit_modeset_enables()
> > > states,
> > > that is not always true.
> > > 
> > > So here promoting the first pipe/transcoder of the stream as
> > > master.
> > > That caused several other problems as during the commit phase the
> > > state computed should not be changed.
> > > 
> > > So the master transcoder is store into intel_dp and the modeset in
> > > slave pipes/transcoders is forced using mst_master_trans_pending.
> > > 
> > > v2:
> > > - added missing config compute to trigger fullmodeset in slave
> > > transcoders
> > > 
> > > BSpec: 50493
> > > BSpec: 49190
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > +++++++++++++++++-
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index a976606d21c7..d2f0d393d3ee 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -35,6 +35,7 @@
> > >  #include "intel_display_types.h"
> > >  #include "intel_dp.h"
> > >  #include "intel_dp_link_training.h"
> > > +#include "intel_dp_mst.h"
> > >  #include "intel_dpio_phy.h"
> > >  #include "intel_dsi.h"
> > >  #include "intel_fifo_underrun.h"
> > > @@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const
> > > struct intel_crtc_state *crtc_state)
> > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > >  
> > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > -			temp |=
> > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > +			enum transcoder master;
> > > +
> > > +			master =
> > > intel_dp_mst_master_trans_get(encoder);
> > 
> > Why isn't that just stored in the crtc state like everything else?
> > 
> > I'm thinking we should maybe do it just like port sync and have both
> > master + slave_mask. That way it should be pretty trivial to add all
> > the relevant crtcs to the state when needed.
> 
> I guess port sync is not doing the right thing and it could cause
> underruns.
> When it is going to enable the master CRTC of the port sync it forcibly
> enables the slave first, what could cause underruns because of overlap
> in ddb allocations(that is what I understood from the comment in
> skl_commit_modeset_enables()).

Not necessarily just underruns but even a system hang. The fix should be
a trivial "check the slave for ddb overlap as well", but apparently I
failed at convicing people to do that.

I've actually been pondering about decoupling the plane updates from
the crtc enable stuff entirely. At least theoretically crtc enable
should be able to excute in any order as long we don't enable any
new planes.

But none of that really matters for the discussion at hand. Though
there are other problems with the port sync stuff that would need
to be handled better. Eg. I think it now adds both crtcs to the state
always which is going to cut the fps in half. Also the place where
it does that stuff is rather suspicious. All that stuff should be
somewhere a bit higher up IMO.

> 
> So for MST we only know who is the master in the commit phase and at
> this point we should not modify the computed state.

I'm not suggesting modifying anything during commit phase. I think
you are effectiely doing that right now by stuffing that mst master
transcoder into intel_dp.

> 
> > 
> > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > +			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > +		}
> > >  	} else {
> > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 801b975c7d39..35a59108194e 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -46,6 +46,7 @@
> > >  #include "display/intel_crt.h"
> > >  #include "display/intel_ddi.h"
> > >  #include "display/intel_dp.h"
> > > +#include "display/intel_dp_mst.h"
> > >  #include "display/intel_dsi.h"
> > >  #include "display/intel_dvo.h"
> > >  #include "display/intel_gmbus.h"
> > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > > intel_atomic_state *state,
> > >  	return encoder;
> > >  }
> > >  
> > > +/*
> > > + * Finds the encoder associated with the given CRTC. This can only
> > > be
> > > + * used when we know that the CRTC isn't feeding multiple
> > > encoders!
> > > + */
> > > +static struct intel_encoder *
> > > +intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
> > > +			   const struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > +	const struct drm_connector_state *connector_state;
> > > +	const struct drm_connector *connector;
> > > +	struct intel_encoder *encoder = NULL;
> > > +	int num_encoders = 0;
> > > +	int i;
> > > +
> > > +	for_each_old_connector_in_state(&state->base, connector,
> > > +					connector_state, i) {
> > > +		if (connector_state->crtc != &crtc->base)
> > > +			continue;
> > > +
> > > +		encoder = to_intel_encoder(connector_state-
> > > >best_encoder);
> > > +		num_encoders++;
> > > +	}
> > > +
> > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > +	     num_encoders, pipe_name(crtc->pipe));
> > > +
> > > +	return encoder;
> > > +}
> > 
> > Argh. I was hoping to kill the other one of these. Got it down to 1
> > remaining user now I think.
> > 
> > > +
> > >  /*
> > >   * Enable PCH resources required for PCH ports:
> > >   *   - PCH PLLs
> > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > > intel_crtc_state *current_config,
> > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > >  #undef PIPE_CONF_QUIRK
> > >  
> > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > mst_master_trans\n",
> > > +			      crtc->base.base.id, crtc->base.name);
> > > +		ret = false;
> > > +	}
> > > +
> > >  	return ret;
> > >  }
> > >  
> > > @@ -14449,22 +14486,35 @@ static void
> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > >  	struct intel_crtc *crtc;
> > >  	int i;
> > >  
> > > -	/* Only disable port sync slaves */
> > > +	/* Only disable port sync and MST slaves */
> > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > >  					    new_crtc_state, i) {
> > >  		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > >  			continue;
> > >  
> > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > +		    !intel_crtc_has_type(old_crtc_state,
> > > INTEL_OUTPUT_DP_MST))
> > > +			continue;
> > > +
> > >  		/* In case of Transcoder port Sync master slave CRTCs
> > > can be
> > >  		 * assigned in any order and we need to make sure that
> > >  		 * slave CRTCs are disabled first and then master CRTC
> > > since
> > >  		 * Slave vblanks are masked till Master Vblanks.
> > >  		 */
> > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > -			continue;
> > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > +		    is_trans_port_sync_master(new_crtc_state))
> > >  			continue;
> > >  
> > > +		if (intel_crtc_has_type(old_crtc_state,
> > > INTEL_OUTPUT_DP_MST)) {
> > > +			struct intel_encoder *encoder;
> > > +
> > > +			encoder = intel_get_crtc_old_encoder(state,
> > > +							     old_crtc_s
> > > tate);
> > > +			if (intel_dp_mst_master_trans_get(encoder) ==
> > > +			    old_crtc_state->cpu_transcoder)
> > > +				continue;
> > > +		}
> > > +
> > >  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > >  		intel_old_crtc_state_disables(state, old_crtc_state,
> > >  					      new_crtc_state, crtc);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 83ea04149b77..23d747cdca64 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > >  	/* Pointer to master transcoder in case of tiled displays */
> > >  	enum transcoder master_transcoder;
> > >  
> > > +	bool mst_master_trans_pending;
> > > +
> > >  	/* Bitmask to indicate slaves attached */
> > >  	u8 sync_mode_slaves_mask;
> > >  };
> > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > >  	bool can_mst; /* this port supports mst */
> > >  	bool is_mst;
> > >  	int active_mst_links;
> > > +	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
> > >  
> > >  	/*
> > >  	 * DP_TP_* registers may be either on port or transcoder
> > > register space.
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index 3123958e2081..ceff6901451a 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > intel_digital_port *intel_dig_port,
> > >  	intel_dp->reset_link_params = true;
> > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > >  
> > >  	/* Preserve the current hw state. */
> > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > index f8a350359346..9731c3c1d3f2 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > @@ -87,6 +87,47 @@ static int
> > > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > >  	return 0;
> > >  }
> > >  
> > > +static int
> > > +intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
> > > +				  struct intel_crtc_state *pipe_config,
> > > +				  struct drm_connector_state
> > > *conn_state)
> > > +{
> > > +	struct intel_atomic_state *state =
> > > to_intel_atomic_state(pipe_config->uapi.state);
> > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > +	struct intel_crtc_state *new_crtc_state;
> > > +	struct intel_crtc *crtc;
> > > +	enum transcoder master;
> > > +	int i;
> > > +
> > > +	if (INTEL_GEN(dev_priv) < 12)
> > > +		return 0;
> > > +
> > > +	if (!conn_state->crtc)
> > > +		return 0;
> > > +
> > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > +	if (master == INVALID_TRANSCODER)
> > > +		return 0;
> > > +
> > > +	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state,
> > > i) {
> > > +		/*
> > > +		 * cpu_transcoder is set when computing CRTC state if
> > > it will
> > > +		 * be disabled it will not happen, so checking pipe
> > > instead
> > > +		 */
> > > +		if (crtc->pipe != (enum pipe)master)
> > > +			continue;
> > > +
> > > +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > >uapi) &&
> > > +		    new_crtc_state->uapi.enable)
> > > +			continue;
> > > +
> > > +		pipe_config->mst_master_trans_pending = true;
> > > +		break;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static int intel_dp_mst_compute_config(struct intel_encoder
> > > *encoder,
> > >  				       struct intel_crtc_state
> > > *pipe_config,
> > >  				       struct drm_connector_state
> > > *conn_state)
> > > @@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct
> > > intel_encoder *encoder,
> > >  
> > >  	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
> > >  
> > > +	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
> > > +						conn_state);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int
> > > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > > *connector,
> > > +				       struct drm_atomic_state *state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > > +	struct intel_connector *intel_conn =
> > > to_intel_connector(connector);
> > > +	struct drm_connector_state *new_conn_state, *old_conn_state;
> > > +	struct drm_connector_list_iter conn_list_iter;
> > > +	struct intel_crtc_state *intel_crtc_state;
> > > +	struct drm_crtc_state *crtc_state;
> > > +	struct drm_connector *conn_iter;
> > > +
> > > +	if (INTEL_GEN(dev_priv) < 12)
> > > +		return 0;
> > > +
> > > +	new_conn_state = drm_atomic_get_new_connector_state(state,
> > > connector);
> > > +	old_conn_state = drm_atomic_get_old_connector_state(state,
> > > connector);
> > > +
> > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > +		return 0;
> > > +
> > > +	/*
> > > +	 * 3 cases that needs be handled here:
> > > +	 * - connector going from disabled to enabled
> > > +	 * - connector going from enabled to disabled:
> > > +	 * if this transcoder was the master, all slaves needs a
> > > modeset
> > > +	 * - connector going from enabled to enabled but it needs a
> > > modeset:
> > > +	 * if this transcoder was the master, all slaves also needs a
> > > modeset
> > > +	 */
> > > +
> > > +	/* disabled -> enabled */
> > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > +		return 0;
> > > +
> > > +	/* enabled -> enabled(modeset)? */
> > > +	if (new_conn_state->crtc) {
> > > +		crtc_state = drm_atomic_get_new_crtc_state(state,
> > > new_conn_state->crtc);
> > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > +			return 0;
> > > +	}
> > > +
> > > +	/* handling enabled -> enabled(modeset) and enabled -> disabled
> > > */
> > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > old_conn_state->crtc);
> > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > +
> > > +	/* If not master, nothing else needs to be handled */
> > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > +	    intel_crtc_state->cpu_transcoder)
> > > +		return 0;
> > > +
> > > +	/* Is master, mark all other CRTCs as needing a modeset */
> > > +	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
> > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
> > > +		struct intel_connector *intel_conn_iter;
> > > +		struct drm_connector_state *conn_iter_state;
> > > +
> > > +		intel_conn_iter = to_intel_connector(conn_iter);
> > > +		if (intel_conn_iter->mst_port != intel_conn->mst_port)
> > > +			continue;
> > > +
> > > +		conn_iter_state = drm_atomic_get_connector_state(state,
> > > +								 conn_i
> > > ter);
> > > +		if (IS_ERR(conn_iter_state)) {
> > > +			drm_connector_list_iter_end(&conn_list_iter);
> > > +			return PTR_ERR(conn_iter_state);
> > > +		}
> > > +
> > > +		if (!conn_iter_state->crtc)
> > > +			continue;
> > > +
> > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > conn_iter_state->crtc);
> > > +		if (IS_ERR(crtc_state)) {
> > > +			drm_connector_list_iter_end(&conn_list_iter);
> > > +			return PTR_ERR(conn_iter_state);
> > > +		}
> > > +
> > > +		intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > +		crtc_state->mode_changed = true;
> > > +	}
> > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > +
> > >  	return 0;
> > >  }
> > >  
> > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector
> > > *connector,
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > +	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > >  	if (!old_conn_state->crtc)
> > >  		return 0;
> > >  
> > > @@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct
> > > intel_encoder *encoder,
> > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > >  		intel_dig_port->base.post_disable(&intel_dig_port-
> > > >base,
> > >  						  old_crtc_state,
> > > NULL);
> > > +		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > >  	}
> > >  
> > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> > > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > > intel_encoder *encoder,
> > >  
> > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> > >  
> > > -	if (first_mst_stream)
> > > +	if (first_mst_stream) {
> > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > INVALID_TRANSCODER);
> > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > >cpu_transcoder;
> > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > +	}
> > >  
> > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector-
> > > >port, true);
> > >  
> > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > intel_digital_port *intel_dig_port)
> > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > >  	/* encoders will get killed by normal cleanup */
> > >  }
> > > +
> > > +enum transcoder
> > > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > > +{
> > > +	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder-
> > > >base);
> > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > +
> > > +	return intel_dp->mst_master_transcoder;
> > > +}
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > index f660ad80db04..e6f28a517182 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > @@ -7,9 +7,11 @@
> > >  #define __INTEL_DP_MST_H__
> > >  
> > >  struct intel_digital_port;
> > > +struct intel_encoder;
> > >  
> > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > *intel_dig_port, int conn_id);
> > >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > > *intel_dig_port);
> > >  int intel_dp_mst_encoder_active_links(struct intel_digital_port
> > > *intel_dig_port);
> > > +enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder
> > > *encoder);
> > >  
> > >  #endif /* __INTEL_DP_MST_H__ */
> > > -- 
> > > 2.24.0

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

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-27 19:59         ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-27 19:59 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> > wrote:
> > > On TGL the blending of all the streams have moved from DDI to
> > > transcoder, so now every transcoder working over the same MST port
> > > must
> > > send its stream to a master transcoder and master will send to DDI
> > > respecting the time slots.
> > > 
> > > A previous approach was using the lowest pipe/transcoder as master
> > > transcoder but as the comment in skl_commit_modeset_enables()
> > > states,
> > > that is not always true.
> > > 
> > > So here promoting the first pipe/transcoder of the stream as
> > > master.
> > > That caused several other problems as during the commit phase the
> > > state computed should not be changed.
> > > 
> > > So the master transcoder is store into intel_dp and the modeset in
> > > slave pipes/transcoders is forced using mst_master_trans_pending.
> > > 
> > > v2:
> > > - added missing config compute to trigger fullmodeset in slave
> > > transcoders
> > > 
> > > BSpec: 50493
> > > BSpec: 49190
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > +++++++++++++++++-
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index a976606d21c7..d2f0d393d3ee 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -35,6 +35,7 @@
> > >  #include "intel_display_types.h"
> > >  #include "intel_dp.h"
> > >  #include "intel_dp_link_training.h"
> > > +#include "intel_dp_mst.h"
> > >  #include "intel_dpio_phy.h"
> > >  #include "intel_dsi.h"
> > >  #include "intel_fifo_underrun.h"
> > > @@ -1903,8 +1904,13 @@ intel_ddi_transcoder_func_reg_val_get(const
> > > struct intel_crtc_state *crtc_state)
> > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > >  
> > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > -			temp |=
> > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > +			enum transcoder master;
> > > +
> > > +			master =
> > > intel_dp_mst_master_trans_get(encoder);
> > 
> > Why isn't that just stored in the crtc state like everything else?
> > 
> > I'm thinking we should maybe do it just like port sync and have both
> > master + slave_mask. That way it should be pretty trivial to add all
> > the relevant crtcs to the state when needed.
> 
> I guess port sync is not doing the right thing and it could cause
> underruns.
> When it is going to enable the master CRTC of the port sync it forcibly
> enables the slave first, what could cause underruns because of overlap
> in ddb allocations(that is what I understood from the comment in
> skl_commit_modeset_enables()).

Not necessarily just underruns but even a system hang. The fix should be
a trivial "check the slave for ddb overlap as well", but apparently I
failed at convicing people to do that.

I've actually been pondering about decoupling the plane updates from
the crtc enable stuff entirely. At least theoretically crtc enable
should be able to excute in any order as long we don't enable any
new planes.

But none of that really matters for the discussion at hand. Though
there are other problems with the port sync stuff that would need
to be handled better. Eg. I think it now adds both crtcs to the state
always which is going to cut the fps in half. Also the place where
it does that stuff is rather suspicious. All that stuff should be
somewhere a bit higher up IMO.

> 
> So for MST we only know who is the master in the commit phase and at
> this point we should not modify the computed state.

I'm not suggesting modifying anything during commit phase. I think
you are effectiely doing that right now by stuffing that mst master
transcoder into intel_dp.

> 
> > 
> > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > +			temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > +		}
> > >  	} else {
> > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 801b975c7d39..35a59108194e 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -46,6 +46,7 @@
> > >  #include "display/intel_crt.h"
> > >  #include "display/intel_ddi.h"
> > >  #include "display/intel_dp.h"
> > > +#include "display/intel_dp_mst.h"
> > >  #include "display/intel_dsi.h"
> > >  #include "display/intel_dvo.h"
> > >  #include "display/intel_gmbus.h"
> > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > > intel_atomic_state *state,
> > >  	return encoder;
> > >  }
> > >  
> > > +/*
> > > + * Finds the encoder associated with the given CRTC. This can only
> > > be
> > > + * used when we know that the CRTC isn't feeding multiple
> > > encoders!
> > > + */
> > > +static struct intel_encoder *
> > > +intel_get_crtc_old_encoder(const struct intel_atomic_state *state,
> > > +			   const struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > +	const struct drm_connector_state *connector_state;
> > > +	const struct drm_connector *connector;
> > > +	struct intel_encoder *encoder = NULL;
> > > +	int num_encoders = 0;
> > > +	int i;
> > > +
> > > +	for_each_old_connector_in_state(&state->base, connector,
> > > +					connector_state, i) {
> > > +		if (connector_state->crtc != &crtc->base)
> > > +			continue;
> > > +
> > > +		encoder = to_intel_encoder(connector_state-
> > > >best_encoder);
> > > +		num_encoders++;
> > > +	}
> > > +
> > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > +	     num_encoders, pipe_name(crtc->pipe));
> > > +
> > > +	return encoder;
> > > +}
> > 
> > Argh. I was hoping to kill the other one of these. Got it down to 1
> > remaining user now I think.
> > 
> > > +
> > >  /*
> > >   * Enable PCH resources required for PCH ports:
> > >   *   - PCH PLLs
> > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > > intel_crtc_state *current_config,
> > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > >  #undef PIPE_CONF_QUIRK
> > >  
> > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > mst_master_trans\n",
> > > +			      crtc->base.base.id, crtc->base.name);
> > > +		ret = false;
> > > +	}
> > > +
> > >  	return ret;
> > >  }
> > >  
> > > @@ -14449,22 +14486,35 @@ static void
> > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > >  	struct intel_crtc *crtc;
> > >  	int i;
> > >  
> > > -	/* Only disable port sync slaves */
> > > +	/* Only disable port sync and MST slaves */
> > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > old_crtc_state,
> > >  					    new_crtc_state, i) {
> > >  		if (!needs_modeset(new_crtc_state) || !crtc->active)
> > >  			continue;
> > >  
> > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > +		    !intel_crtc_has_type(old_crtc_state,
> > > INTEL_OUTPUT_DP_MST))
> > > +			continue;
> > > +
> > >  		/* In case of Transcoder port Sync master slave CRTCs
> > > can be
> > >  		 * assigned in any order and we need to make sure that
> > >  		 * slave CRTCs are disabled first and then master CRTC
> > > since
> > >  		 * Slave vblanks are masked till Master Vblanks.
> > >  		 */
> > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > -			continue;
> > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > +		    is_trans_port_sync_master(new_crtc_state))
> > >  			continue;
> > >  
> > > +		if (intel_crtc_has_type(old_crtc_state,
> > > INTEL_OUTPUT_DP_MST)) {
> > > +			struct intel_encoder *encoder;
> > > +
> > > +			encoder = intel_get_crtc_old_encoder(state,
> > > +							     old_crtc_s
> > > tate);
> > > +			if (intel_dp_mst_master_trans_get(encoder) ==
> > > +			    old_crtc_state->cpu_transcoder)
> > > +				continue;
> > > +		}
> > > +
> > >  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > >  		intel_old_crtc_state_disables(state, old_crtc_state,
> > >  					      new_crtc_state, crtc);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 83ea04149b77..23d747cdca64 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > >  	/* Pointer to master transcoder in case of tiled displays */
> > >  	enum transcoder master_transcoder;
> > >  
> > > +	bool mst_master_trans_pending;
> > > +
> > >  	/* Bitmask to indicate slaves attached */
> > >  	u8 sync_mode_slaves_mask;
> > >  };
> > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > >  	bool can_mst; /* this port supports mst */
> > >  	bool is_mst;
> > >  	int active_mst_links;
> > > +	enum transcoder mst_master_transcoder; /* Only used in TGL+ */
> > >  
> > >  	/*
> > >  	 * DP_TP_* registers may be either on port or transcoder
> > > register space.
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index 3123958e2081..ceff6901451a 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > intel_digital_port *intel_dig_port,
> > >  	intel_dp->reset_link_params = true;
> > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > >  
> > >  	/* Preserve the current hw state. */
> > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > index f8a350359346..9731c3c1d3f2 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > @@ -87,6 +87,47 @@ static int
> > > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > >  	return 0;
> > >  }
> > >  
> > > +static int
> > > +intel_dp_mst_master_trans_compute(struct intel_encoder *encoder,
> > > +				  struct intel_crtc_state *pipe_config,
> > > +				  struct drm_connector_state
> > > *conn_state)
> > > +{
> > > +	struct intel_atomic_state *state =
> > > to_intel_atomic_state(pipe_config->uapi.state);
> > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > +	struct intel_crtc_state *new_crtc_state;
> > > +	struct intel_crtc *crtc;
> > > +	enum transcoder master;
> > > +	int i;
> > > +
> > > +	if (INTEL_GEN(dev_priv) < 12)
> > > +		return 0;
> > > +
> > > +	if (!conn_state->crtc)
> > > +		return 0;
> > > +
> > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > +	if (master == INVALID_TRANSCODER)
> > > +		return 0;
> > > +
> > > +	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state,
> > > i) {
> > > +		/*
> > > +		 * cpu_transcoder is set when computing CRTC state if
> > > it will
> > > +		 * be disabled it will not happen, so checking pipe
> > > instead
> > > +		 */
> > > +		if (crtc->pipe != (enum pipe)master)
> > > +			continue;
> > > +
> > > +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > >uapi) &&
> > > +		    new_crtc_state->uapi.enable)
> > > +			continue;
> > > +
> > > +		pipe_config->mst_master_trans_pending = true;
> > > +		break;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static int intel_dp_mst_compute_config(struct intel_encoder
> > > *encoder,
> > >  				       struct intel_crtc_state
> > > *pipe_config,
> > >  				       struct drm_connector_state
> > > *conn_state)
> > > @@ -154,6 +195,95 @@ static int intel_dp_mst_compute_config(struct
> > > intel_encoder *encoder,
> > >  
> > >  	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
> > >  
> > > +	ret = intel_dp_mst_master_trans_compute(encoder, pipe_config,
> > > +						conn_state);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int
> > > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > > *connector,
> > > +				       struct drm_atomic_state *state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > > +	struct intel_connector *intel_conn =
> > > to_intel_connector(connector);
> > > +	struct drm_connector_state *new_conn_state, *old_conn_state;
> > > +	struct drm_connector_list_iter conn_list_iter;
> > > +	struct intel_crtc_state *intel_crtc_state;
> > > +	struct drm_crtc_state *crtc_state;
> > > +	struct drm_connector *conn_iter;
> > > +
> > > +	if (INTEL_GEN(dev_priv) < 12)
> > > +		return 0;
> > > +
> > > +	new_conn_state = drm_atomic_get_new_connector_state(state,
> > > connector);
> > > +	old_conn_state = drm_atomic_get_old_connector_state(state,
> > > connector);
> > > +
> > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > +		return 0;
> > > +
> > > +	/*
> > > +	 * 3 cases that needs be handled here:
> > > +	 * - connector going from disabled to enabled
> > > +	 * - connector going from enabled to disabled:
> > > +	 * if this transcoder was the master, all slaves needs a
> > > modeset
> > > +	 * - connector going from enabled to enabled but it needs a
> > > modeset:
> > > +	 * if this transcoder was the master, all slaves also needs a
> > > modeset
> > > +	 */
> > > +
> > > +	/* disabled -> enabled */
> > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > +		return 0;
> > > +
> > > +	/* enabled -> enabled(modeset)? */
> > > +	if (new_conn_state->crtc) {
> > > +		crtc_state = drm_atomic_get_new_crtc_state(state,
> > > new_conn_state->crtc);
> > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > +			return 0;
> > > +	}
> > > +
> > > +	/* handling enabled -> enabled(modeset) and enabled -> disabled
> > > */
> > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > old_conn_state->crtc);
> > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > +
> > > +	/* If not master, nothing else needs to be handled */
> > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > +	    intel_crtc_state->cpu_transcoder)
> > > +		return 0;
> > > +
> > > +	/* Is master, mark all other CRTCs as needing a modeset */
> > > +	drm_connector_list_iter_begin(state->dev, &conn_list_iter);
> > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter) {
> > > +		struct intel_connector *intel_conn_iter;
> > > +		struct drm_connector_state *conn_iter_state;
> > > +
> > > +		intel_conn_iter = to_intel_connector(conn_iter);
> > > +		if (intel_conn_iter->mst_port != intel_conn->mst_port)
> > > +			continue;
> > > +
> > > +		conn_iter_state = drm_atomic_get_connector_state(state,
> > > +								 conn_i
> > > ter);
> > > +		if (IS_ERR(conn_iter_state)) {
> > > +			drm_connector_list_iter_end(&conn_list_iter);
> > > +			return PTR_ERR(conn_iter_state);
> > > +		}
> > > +
> > > +		if (!conn_iter_state->crtc)
> > > +			continue;
> > > +
> > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > conn_iter_state->crtc);
> > > +		if (IS_ERR(crtc_state)) {
> > > +			drm_connector_list_iter_end(&conn_list_iter);
> > > +			return PTR_ERR(conn_iter_state);
> > > +		}
> > > +
> > > +		intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > +		crtc_state->mode_changed = true;
> > > +	}
> > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > +
> > >  	return 0;
> > >  }
> > >  
> > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct drm_connector
> > > *connector,
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > +	ret = intel_dp_mst_atomic_master_trans_check(connector, state);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > >  	if (!old_conn_state->crtc)
> > >  		return 0;
> > >  
> > > @@ -259,6 +393,7 @@ static void intel_mst_post_disable_dp(struct
> > > intel_encoder *encoder,
> > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > >  		intel_dig_port->base.post_disable(&intel_dig_port-
> > > >base,
> > >  						  old_crtc_state,
> > > NULL);
> > > +		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > >  	}
> > >  
> > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> > > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > > intel_encoder *encoder,
> > >  
> > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> > >  
> > > -	if (first_mst_stream)
> > > +	if (first_mst_stream) {
> > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > INVALID_TRANSCODER);
> > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > >cpu_transcoder;
> > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > +	}
> > >  
> > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector-
> > > >port, true);
> > >  
> > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > intel_digital_port *intel_dig_port)
> > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > >  	/* encoders will get killed by normal cleanup */
> > >  }
> > > +
> > > +enum transcoder
> > > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > > +{
> > > +	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder-
> > > >base);
> > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > +
> > > +	return intel_dp->mst_master_transcoder;
> > > +}
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > index f660ad80db04..e6f28a517182 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > @@ -7,9 +7,11 @@
> > >  #define __INTEL_DP_MST_H__
> > >  
> > >  struct intel_digital_port;
> > > +struct intel_encoder;
> > >  
> > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > *intel_dig_port, int conn_id);
> > >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > > *intel_dig_port);
> > >  int intel_dp_mst_encoder_active_links(struct intel_digital_port
> > > *intel_dig_port);
> > > +enum transcoder intel_dp_mst_master_trans_get(struct intel_encoder
> > > *encoder);
> > >  
> > >  #endif /* __INTEL_DP_MST_H__ */
> > > -- 
> > > 2.24.0

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

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

* Re: [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-28  1:08           ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-28  1:08 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Wed, 2019-11-27 at 21:24 +0200, Ville Syrjälä wrote:
> On Tue, Nov 26, 2019 at 10:12:52PM +0000, Souza, Jose wrote:
> > On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> > > On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> > > wrote:
> > > > Disabling pipe/transcoder clock before power down sink could
> > > > cause
> > > > sink lost signal, causing it to trigger a hotplug to notify
> > > > source
> > > > that link signal was lost.
> > > > 
> > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -3808,12 +3808,12 @@ static void
> > > > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> > > >  	enum phy phy = intel_port_to_phy(dev_priv, encoder-
> > > > >port);
> > > >  
> > > >  	if (!is_mst) {
> > > > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > >  		/*
> > > >  		 * Power down sink before disabling the port,
> > > > otherwise
> > > > we end
> > > >  		 * up getting interrupts from the sink on
> > > > detecting
> > > > link loss.
> > > >  		 */
> > > >  		intel_dp_sink_dpms(intel_dp,
> > > > DRM_MODE_DPMS_OFF);
> > > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > >  	}
> > > 
> > > The spec seems to say that we should do this after turning off
> > > DDI_BUF_CTL on tgl+.
> > 
> > What step? I can't find any step talking about AUX DP_SET_POWER.
> 
> I was talking about DDI_BUF disable vs. transcoder clock disable.
> 
> > My understating is that we should power off sink before interfering
> > in
> > the mainlink signal otherwise sink could trigger hotplugs to notify
> > source about link loss.
> 
> Pretty much. Nothing wrong with your patch for pre-tgl I think, but
> for
> tgl+ you didn't move the clock disable quite far enough to match the
> bspec sequence.

Aaahh
That is fixed patch 6 "drm/i915/display/tgl: Fix the order of the step
to turn transcoder clock off" :D

> 
> > > >  
> > > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > > -- 
> > > > 2.24.0
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-28  1:08           ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-28  1:08 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Wed, 2019-11-27 at 21:24 +0200, Ville Syrjälä wrote:
> On Tue, Nov 26, 2019 at 10:12:52PM +0000, Souza, Jose wrote:
> > On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> > > On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> > > wrote:
> > > > Disabling pipe/transcoder clock before power down sink could
> > > > cause
> > > > sink lost signal, causing it to trigger a hotplug to notify
> > > > source
> > > > that link signal was lost.
> > > > 
> > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -3808,12 +3808,12 @@ static void
> > > > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> > > >  	enum phy phy = intel_port_to_phy(dev_priv, encoder-
> > > > >port);
> > > >  
> > > >  	if (!is_mst) {
> > > > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > >  		/*
> > > >  		 * Power down sink before disabling the port,
> > > > otherwise
> > > > we end
> > > >  		 * up getting interrupts from the sink on
> > > > detecting
> > > > link loss.
> > > >  		 */
> > > >  		intel_dp_sink_dpms(intel_dp,
> > > > DRM_MODE_DPMS_OFF);
> > > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > >  	}
> > > 
> > > The spec seems to say that we should do this after turning off
> > > DDI_BUF_CTL on tgl+.
> > 
> > What step? I can't find any step talking about AUX DP_SET_POWER.
> 
> I was talking about DDI_BUF disable vs. transcoder clock disable.
> 
> > My understating is that we should power off sink before interfering
> > in
> > the mainlink signal otherwise sink could trigger hotplugs to notify
> > source about link loss.
> 
> Pretty much. Nothing wrong with your patch for pre-tgl I think, but
> for
> tgl+ you didn't move the clock disable quite far enough to match the
> bspec sequence.

Aaahh
That is fixed patch 6 "drm/i915/display/tgl: Fix the order of the step
to turn transcoder clock off" :D

> 
> > > >  
> > > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > > -- 
> > > > 2.24.0
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-28  1:14           ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-28  1:14 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> > > wrote:
> > > > On TGL the blending of all the streams have moved from DDI to
> > > > transcoder, so now every transcoder working over the same MST
> > > > port
> > > > must
> > > > send its stream to a master transcoder and master will send to
> > > > DDI
> > > > respecting the time slots.
> > > > 
> > > > A previous approach was using the lowest pipe/transcoder as
> > > > master
> > > > transcoder but as the comment in skl_commit_modeset_enables()
> > > > states,
> > > > that is not always true.
> > > > 
> > > > So here promoting the first pipe/transcoder of the stream as
> > > > master.
> > > > That caused several other problems as during the commit phase
> > > > the
> > > > state computed should not be changed.
> > > > 
> > > > So the master transcoder is store into intel_dp and the modeset
> > > > in
> > > > slave pipes/transcoders is forced using
> > > > mst_master_trans_pending.
> > > > 
> > > > v2:
> > > > - added missing config compute to trigger fullmodeset in slave
> > > > transcoders
> > > > 
> > > > BSpec: 50493
> > > > BSpec: 49190
> > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > +++++++++++++++++-
> > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -35,6 +35,7 @@
> > > >  #include "intel_display_types.h"
> > > >  #include "intel_dp.h"
> > > >  #include "intel_dp_link_training.h"
> > > > +#include "intel_dp_mst.h"
> > > >  #include "intel_dpio_phy.h"
> > > >  #include "intel_dsi.h"
> > > >  #include "intel_fifo_underrun.h"
> > > > @@ -1903,8 +1904,13 @@
> > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > struct intel_crtc_state *crtc_state)
> > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > >  
> > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > -			temp |=
> > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > +			enum transcoder master;
> > > > +
> > > > +			master =
> > > > intel_dp_mst_master_trans_get(encoder);
> > > 
> > > Why isn't that just stored in the crtc state like everything
> > > else?
> > > 
> > > I'm thinking we should maybe do it just like port sync and have
> > > both
> > > master + slave_mask. That way it should be pretty trivial to add
> > > all
> > > the relevant crtcs to the state when needed.
> > 
> > I guess port sync is not doing the right thing and it could cause
> > underruns.
> > When it is going to enable the master CRTC of the port sync it
> > forcibly
> > enables the slave first, what could cause underruns because of
> > overlap
> > in ddb allocations(that is what I understood from the comment in
> > skl_commit_modeset_enables()).
> 
> Not necessarily just underruns but even a system hang. The fix should
> be
> a trivial "check the slave for ddb overlap as well", but apparently I
> failed at convicing people to do that.
> 
> I've actually been pondering about decoupling the plane updates from
> the crtc enable stuff entirely. At least theoretically crtc enable
> should be able to excute in any order as long we don't enable any
> new planes.
> 
> But none of that really matters for the discussion at hand. Though
> there are other problems with the port sync stuff that would need
> to be handled better. Eg. I think it now adds both crtcs to the state
> always which is going to cut the fps in half. Also the place where
> it does that stuff is rather suspicious. All that stuff should be
> somewhere a bit higher up IMO.
> 
> > So for MST we only know who is the master in the commit phase and
> > at
> > this point we should not modify the computed state.
> 
> I'm not suggesting modifying anything during commit phase. I think
> you are effectiely doing that right now by stuffing that mst master
> transcoder into intel_dp.

Sorry, I still don't get what approach are you suggesting here.

If we can't modify the state in the commit phase, adding
mst_master_transcoder in the CRTC state will not be possible while
respecting the order imposed by ddb allocations.

> 
> > > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > > +			temp |=
> > > > TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > > +		}
> > > >  	} else {
> > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 801b975c7d39..35a59108194e 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -46,6 +46,7 @@
> > > >  #include "display/intel_crt.h"
> > > >  #include "display/intel_ddi.h"
> > > >  #include "display/intel_dp.h"
> > > > +#include "display/intel_dp_mst.h"
> > > >  #include "display/intel_dsi.h"
> > > >  #include "display/intel_dvo.h"
> > > >  #include "display/intel_gmbus.h"
> > > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > > > intel_atomic_state *state,
> > > >  	return encoder;
> > > >  }
> > > >  
> > > > +/*
> > > > + * Finds the encoder associated with the given CRTC. This can
> > > > only
> > > > be
> > > > + * used when we know that the CRTC isn't feeding multiple
> > > > encoders!
> > > > + */
> > > > +static struct intel_encoder *
> > > > +intel_get_crtc_old_encoder(const struct intel_atomic_state
> > > > *state,
> > > > +			   const struct intel_crtc_state
> > > > *crtc_state)
> > > > +{
> > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > >uapi.crtc);
> > > > +	const struct drm_connector_state *connector_state;
> > > > +	const struct drm_connector *connector;
> > > > +	struct intel_encoder *encoder = NULL;
> > > > +	int num_encoders = 0;
> > > > +	int i;
> > > > +
> > > > +	for_each_old_connector_in_state(&state->base,
> > > > connector,
> > > > +					connector_state, i) {
> > > > +		if (connector_state->crtc != &crtc->base)
> > > > +			continue;
> > > > +
> > > > +		encoder = to_intel_encoder(connector_state-
> > > > > best_encoder);
> > > > +		num_encoders++;
> > > > +	}
> > > > +
> > > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > > +	     num_encoders, pipe_name(crtc->pipe));
> > > > +
> > > > +	return encoder;
> > > > +}
> > > 
> > > Argh. I was hoping to kill the other one of these. Got it down to
> > > 1
> > > remaining user now I think.
> > > 
> > > > +
> > > >  /*
> > > >   * Enable PCH resources required for PCH ports:
> > > >   *   - PCH PLLs
> > > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > > > intel_crtc_state *current_config,
> > > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > > >  #undef PIPE_CONF_QUIRK
> > > >  
> > > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > > mst_master_trans\n",
> > > > +			      crtc->base.base.id, crtc-
> > > > >base.name);
> > > > +		ret = false;
> > > > +	}
> > > > +
> > > >  	return ret;
> > > >  }
> > > >  
> > > > @@ -14449,22 +14486,35 @@ static void
> > > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > > >  	struct intel_crtc *crtc;
> > > >  	int i;
> > > >  
> > > > -	/* Only disable port sync slaves */
> > > > +	/* Only disable port sync and MST slaves */
> > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > old_crtc_state,
> > > >  					    new_crtc_state, i)
> > > > {
> > > >  		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > >active)
> > > >  			continue;
> > > >  
> > > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > > +		    !intel_crtc_has_type(old_crtc_state,
> > > > INTEL_OUTPUT_DP_MST))
> > > > +			continue;
> > > > +
> > > >  		/* In case of Transcoder port Sync master slave
> > > > CRTCs
> > > > can be
> > > >  		 * assigned in any order and we need to make
> > > > sure that
> > > >  		 * slave CRTCs are disabled first and then
> > > > master CRTC
> > > > since
> > > >  		 * Slave vblanks are masked till Master
> > > > Vblanks.
> > > >  		 */
> > > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > > -			continue;
> > > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > > +		    is_trans_port_sync_master(new_crtc_state))
> > > >  			continue;
> > > >  
> > > > +		if (intel_crtc_has_type(old_crtc_state,
> > > > INTEL_OUTPUT_DP_MST)) {
> > > > +			struct intel_encoder *encoder;
> > > > +
> > > > +			encoder =
> > > > intel_get_crtc_old_encoder(state,
> > > > +							     ol
> > > > d_crtc_s
> > > > tate);
> > > > +			if
> > > > (intel_dp_mst_master_trans_get(encoder) ==
> > > > +			    old_crtc_state->cpu_transcoder)
> > > > +				continue;
> > > > +		}
> > > > +
> > > >  		intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > >  		intel_old_crtc_state_disables(state,
> > > > old_crtc_state,
> > > >  					      new_crtc_state,
> > > > crtc);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > index 83ea04149b77..23d747cdca64 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > > >  	/* Pointer to master transcoder in case of tiled
> > > > displays */
> > > >  	enum transcoder master_transcoder;
> > > >  
> > > > +	bool mst_master_trans_pending;
> > > > +
> > > >  	/* Bitmask to indicate slaves attached */
> > > >  	u8 sync_mode_slaves_mask;
> > > >  };
> > > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > > >  	bool can_mst; /* this port supports mst */
> > > >  	bool is_mst;
> > > >  	int active_mst_links;
> > > > +	enum transcoder mst_master_transcoder; /* Only used in
> > > > TGL+ */
> > > >  
> > > >  	/*
> > > >  	 * DP_TP_* registers may be either on port or
> > > > transcoder
> > > > register space.
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > index 3123958e2081..ceff6901451a 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > > intel_digital_port *intel_dig_port,
> > > >  	intel_dp->reset_link_params = true;
> > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > > >  
> > > >  	/* Preserve the current hw state. */
> > > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > index f8a350359346..9731c3c1d3f2 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > @@ -87,6 +87,47 @@ static int
> > > > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > >  	return 0;
> > > >  }
> > > >  
> > > > +static int
> > > > +intel_dp_mst_master_trans_compute(struct intel_encoder
> > > > *encoder,
> > > > +				  struct intel_crtc_state
> > > > *pipe_config,
> > > > +				  struct drm_connector_state
> > > > *conn_state)
> > > > +{
> > > > +	struct intel_atomic_state *state =
> > > > to_intel_atomic_state(pipe_config->uapi.state);
> > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > >base.dev);
> > > > +	struct intel_crtc_state *new_crtc_state;
> > > > +	struct intel_crtc *crtc;
> > > > +	enum transcoder master;
> > > > +	int i;
> > > > +
> > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > +		return 0;
> > > > +
> > > > +	if (!conn_state->crtc)
> > > > +		return 0;
> > > > +
> > > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > > +	if (master == INVALID_TRANSCODER)
> > > > +		return 0;
> > > > +
> > > > +	for_each_new_intel_crtc_in_state(state, crtc,
> > > > new_crtc_state,
> > > > i) {
> > > > +		/*
> > > > +		 * cpu_transcoder is set when computing CRTC
> > > > state if
> > > > it will
> > > > +		 * be disabled it will not happen, so checking
> > > > pipe
> > > > instead
> > > > +		 */
> > > > +		if (crtc->pipe != (enum pipe)master)
> > > > +			continue;
> > > > +
> > > > +		if
> > > > (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > > > uapi) &&
> > > > +		    new_crtc_state->uapi.enable)
> > > > +			continue;
> > > > +
> > > > +		pipe_config->mst_master_trans_pending = true;
> > > > +		break;
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >  static int intel_dp_mst_compute_config(struct intel_encoder
> > > > *encoder,
> > > >  				       struct intel_crtc_state
> > > > *pipe_config,
> > > >  				       struct
> > > > drm_connector_state
> > > > *conn_state)
> > > > @@ -154,6 +195,95 @@ static int
> > > > intel_dp_mst_compute_config(struct
> > > > intel_encoder *encoder,
> > > >  
> > > >  	intel_ddi_compute_min_voltage_level(dev_priv,
> > > > pipe_config);
> > > >  
> > > > +	ret = intel_dp_mst_master_trans_compute(encoder,
> > > > pipe_config,
> > > > +						conn_state);
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +static int
> > > > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > > > *connector,
> > > > +				       struct drm_atomic_state
> > > > *state)
> > > > +{
> > > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > > >dev);
> > > > +	struct intel_connector *intel_conn =
> > > > to_intel_connector(connector);
> > > > +	struct drm_connector_state *new_conn_state,
> > > > *old_conn_state;
> > > > +	struct drm_connector_list_iter conn_list_iter;
> > > > +	struct intel_crtc_state *intel_crtc_state;
> > > > +	struct drm_crtc_state *crtc_state;
> > > > +	struct drm_connector *conn_iter;
> > > > +
> > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > +		return 0;
> > > > +
> > > > +	new_conn_state =
> > > > drm_atomic_get_new_connector_state(state,
> > > > connector);
> > > > +	old_conn_state =
> > > > drm_atomic_get_old_connector_state(state,
> > > > connector);
> > > > +
> > > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > > +		return 0;
> > > > +
> > > > +	/*
> > > > +	 * 3 cases that needs be handled here:
> > > > +	 * - connector going from disabled to enabled
> > > > +	 * - connector going from enabled to disabled:
> > > > +	 * if this transcoder was the master, all slaves needs
> > > > a
> > > > modeset
> > > > +	 * - connector going from enabled to enabled but it
> > > > needs a
> > > > modeset:
> > > > +	 * if this transcoder was the master, all slaves also
> > > > needs a
> > > > modeset
> > > > +	 */
> > > > +
> > > > +	/* disabled -> enabled */
> > > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > > +		return 0;
> > > > +
> > > > +	/* enabled -> enabled(modeset)? */
> > > > +	if (new_conn_state->crtc) {
> > > > +		crtc_state =
> > > > drm_atomic_get_new_crtc_state(state,
> > > > new_conn_state->crtc);
> > > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > > +			return 0;
> > > > +	}
> > > > +
> > > > +	/* handling enabled -> enabled(modeset) and enabled ->
> > > > disabled
> > > > */
> > > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > > old_conn_state->crtc);
> > > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > > +
> > > > +	/* If not master, nothing else needs to be handled */
> > > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > > +	    intel_crtc_state->cpu_transcoder)
> > > > +		return 0;
> > > > +
> > > > +	/* Is master, mark all other CRTCs as needing a modeset
> > > > */
> > > > +	drm_connector_list_iter_begin(state->dev,
> > > > &conn_list_iter);
> > > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter)
> > > > {
> > > > +		struct intel_connector *intel_conn_iter;
> > > > +		struct drm_connector_state *conn_iter_state;
> > > > +
> > > > +		intel_conn_iter =
> > > > to_intel_connector(conn_iter);
> > > > +		if (intel_conn_iter->mst_port != intel_conn-
> > > > >mst_port)
> > > > +			continue;
> > > > +
> > > > +		conn_iter_state =
> > > > drm_atomic_get_connector_state(state,
> > > > +								
> > > >  conn_i
> > > > ter);
> > > > +		if (IS_ERR(conn_iter_state)) {
> > > > +			drm_connector_list_iter_end(&conn_list_
> > > > iter);
> > > > +			return PTR_ERR(conn_iter_state);
> > > > +		}
> > > > +
> > > > +		if (!conn_iter_state->crtc)
> > > > +			continue;
> > > > +
> > > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > > conn_iter_state->crtc);
> > > > +		if (IS_ERR(crtc_state)) {
> > > > +			drm_connector_list_iter_end(&conn_list_
> > > > iter);
> > > > +			return PTR_ERR(conn_iter_state);
> > > > +		}
> > > > +
> > > > +		intel_crtc_state =
> > > > to_intel_crtc_state(crtc_state);
> > > > +		crtc_state->mode_changed = true;
> > > > +	}
> > > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > > +
> > > >  	return 0;
> > > >  }
> > > >  
> > > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct
> > > > drm_connector
> > > > *connector,
> > > >  	if (ret)
> > > >  		return ret;
> > > >  
> > > > +	ret = intel_dp_mst_atomic_master_trans_check(connector,
> > > > state);
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > >  	if (!old_conn_state->crtc)
> > > >  		return 0;
> > > >  
> > > > @@ -259,6 +393,7 @@ static void
> > > > intel_mst_post_disable_dp(struct
> > > > intel_encoder *encoder,
> > > >  		intel_dp_sink_dpms(intel_dp,
> > > > DRM_MODE_DPMS_OFF);
> > > >  		intel_dig_port-
> > > > >base.post_disable(&intel_dig_port-
> > > > > base,
> > > >  						  old_crtc_stat
> > > > e,
> > > > NULL);
> > > > +		intel_dp->mst_master_transcoder =
> > > > INVALID_TRANSCODER;
> > > >  	}
> > > >  
> > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > >active_mst_links);
> > > > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > > > intel_encoder *encoder,
> > > >  
> > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > >active_mst_links);
> > > >  
> > > > -	if (first_mst_stream)
> > > > +	if (first_mst_stream) {
> > > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > > INVALID_TRANSCODER);
> > > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > > > cpu_transcoder;
> > > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > > +	}
> > > >  
> > > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr,
> > > > connector-
> > > > > port, true);
> > > >  
> > > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > > intel_digital_port *intel_dig_port)
> > > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > > >  	/* encoders will get killed by normal cleanup */
> > > >  }
> > > > +
> > > > +enum transcoder
> > > > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > > > +{
> > > > +	struct intel_dp_mst_encoder *intel_mst =
> > > > enc_to_mst(&encoder-
> > > > > base);
> > > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > > +
> > > > +	return intel_dp->mst_master_transcoder;
> > > > +}
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > index f660ad80db04..e6f28a517182 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > @@ -7,9 +7,11 @@
> > > >  #define __INTEL_DP_MST_H__
> > > >  
> > > >  struct intel_digital_port;
> > > > +struct intel_encoder;
> > > >  
> > > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > > *intel_dig_port, int conn_id);
> > > >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > > > *intel_dig_port);
> > > >  int intel_dp_mst_encoder_active_links(struct
> > > > intel_digital_port
> > > > *intel_dig_port);
> > > > +enum transcoder intel_dp_mst_master_trans_get(struct
> > > > intel_encoder
> > > > *encoder);
> > > >  
> > > >  #endif /* __INTEL_DP_MST_H__ */
> > > > -- 
> > > > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-28  1:14           ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-11-28  1:14 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> > > wrote:
> > > > On TGL the blending of all the streams have moved from DDI to
> > > > transcoder, so now every transcoder working over the same MST
> > > > port
> > > > must
> > > > send its stream to a master transcoder and master will send to
> > > > DDI
> > > > respecting the time slots.
> > > > 
> > > > A previous approach was using the lowest pipe/transcoder as
> > > > master
> > > > transcoder but as the comment in skl_commit_modeset_enables()
> > > > states,
> > > > that is not always true.
> > > > 
> > > > So here promoting the first pipe/transcoder of the stream as
> > > > master.
> > > > That caused several other problems as during the commit phase
> > > > the
> > > > state computed should not be changed.
> > > > 
> > > > So the master transcoder is store into intel_dp and the modeset
> > > > in
> > > > slave pipes/transcoders is forced using
> > > > mst_master_trans_pending.
> > > > 
> > > > v2:
> > > > - added missing config compute to trigger fullmodeset in slave
> > > > transcoders
> > > > 
> > > > BSpec: 50493
> > > > BSpec: 49190
> > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > +++++++++++++++++-
> > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -35,6 +35,7 @@
> > > >  #include "intel_display_types.h"
> > > >  #include "intel_dp.h"
> > > >  #include "intel_dp_link_training.h"
> > > > +#include "intel_dp_mst.h"
> > > >  #include "intel_dpio_phy.h"
> > > >  #include "intel_dsi.h"
> > > >  #include "intel_fifo_underrun.h"
> > > > @@ -1903,8 +1904,13 @@
> > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > struct intel_crtc_state *crtc_state)
> > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > >  
> > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > -			temp |=
> > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > +			enum transcoder master;
> > > > +
> > > > +			master =
> > > > intel_dp_mst_master_trans_get(encoder);
> > > 
> > > Why isn't that just stored in the crtc state like everything
> > > else?
> > > 
> > > I'm thinking we should maybe do it just like port sync and have
> > > both
> > > master + slave_mask. That way it should be pretty trivial to add
> > > all
> > > the relevant crtcs to the state when needed.
> > 
> > I guess port sync is not doing the right thing and it could cause
> > underruns.
> > When it is going to enable the master CRTC of the port sync it
> > forcibly
> > enables the slave first, what could cause underruns because of
> > overlap
> > in ddb allocations(that is what I understood from the comment in
> > skl_commit_modeset_enables()).
> 
> Not necessarily just underruns but even a system hang. The fix should
> be
> a trivial "check the slave for ddb overlap as well", but apparently I
> failed at convicing people to do that.
> 
> I've actually been pondering about decoupling the plane updates from
> the crtc enable stuff entirely. At least theoretically crtc enable
> should be able to excute in any order as long we don't enable any
> new planes.
> 
> But none of that really matters for the discussion at hand. Though
> there are other problems with the port sync stuff that would need
> to be handled better. Eg. I think it now adds both crtcs to the state
> always which is going to cut the fps in half. Also the place where
> it does that stuff is rather suspicious. All that stuff should be
> somewhere a bit higher up IMO.
> 
> > So for MST we only know who is the master in the commit phase and
> > at
> > this point we should not modify the computed state.
> 
> I'm not suggesting modifying anything during commit phase. I think
> you are effectiely doing that right now by stuffing that mst master
> transcoder into intel_dp.

Sorry, I still don't get what approach are you suggesting here.

If we can't modify the state in the commit phase, adding
mst_master_transcoder in the CRTC state will not be possible while
respecting the order imposed by ddb allocations.

> 
> > > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > > +			temp |=
> > > > TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > > +		}
> > > >  	} else {
> > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 801b975c7d39..35a59108194e 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -46,6 +46,7 @@
> > > >  #include "display/intel_crt.h"
> > > >  #include "display/intel_ddi.h"
> > > >  #include "display/intel_dp.h"
> > > > +#include "display/intel_dp_mst.h"
> > > >  #include "display/intel_dsi.h"
> > > >  #include "display/intel_dvo.h"
> > > >  #include "display/intel_gmbus.h"
> > > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > > > intel_atomic_state *state,
> > > >  	return encoder;
> > > >  }
> > > >  
> > > > +/*
> > > > + * Finds the encoder associated with the given CRTC. This can
> > > > only
> > > > be
> > > > + * used when we know that the CRTC isn't feeding multiple
> > > > encoders!
> > > > + */
> > > > +static struct intel_encoder *
> > > > +intel_get_crtc_old_encoder(const struct intel_atomic_state
> > > > *state,
> > > > +			   const struct intel_crtc_state
> > > > *crtc_state)
> > > > +{
> > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > >uapi.crtc);
> > > > +	const struct drm_connector_state *connector_state;
> > > > +	const struct drm_connector *connector;
> > > > +	struct intel_encoder *encoder = NULL;
> > > > +	int num_encoders = 0;
> > > > +	int i;
> > > > +
> > > > +	for_each_old_connector_in_state(&state->base,
> > > > connector,
> > > > +					connector_state, i) {
> > > > +		if (connector_state->crtc != &crtc->base)
> > > > +			continue;
> > > > +
> > > > +		encoder = to_intel_encoder(connector_state-
> > > > > best_encoder);
> > > > +		num_encoders++;
> > > > +	}
> > > > +
> > > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > > +	     num_encoders, pipe_name(crtc->pipe));
> > > > +
> > > > +	return encoder;
> > > > +}
> > > 
> > > Argh. I was hoping to kill the other one of these. Got it down to
> > > 1
> > > remaining user now I think.
> > > 
> > > > +
> > > >  /*
> > > >   * Enable PCH resources required for PCH ports:
> > > >   *   - PCH PLLs
> > > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > > > intel_crtc_state *current_config,
> > > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > > >  #undef PIPE_CONF_QUIRK
> > > >  
> > > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > > mst_master_trans\n",
> > > > +			      crtc->base.base.id, crtc-
> > > > >base.name);
> > > > +		ret = false;
> > > > +	}
> > > > +
> > > >  	return ret;
> > > >  }
> > > >  
> > > > @@ -14449,22 +14486,35 @@ static void
> > > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > > >  	struct intel_crtc *crtc;
> > > >  	int i;
> > > >  
> > > > -	/* Only disable port sync slaves */
> > > > +	/* Only disable port sync and MST slaves */
> > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > old_crtc_state,
> > > >  					    new_crtc_state, i)
> > > > {
> > > >  		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > >active)
> > > >  			continue;
> > > >  
> > > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > > +		    !intel_crtc_has_type(old_crtc_state,
> > > > INTEL_OUTPUT_DP_MST))
> > > > +			continue;
> > > > +
> > > >  		/* In case of Transcoder port Sync master slave
> > > > CRTCs
> > > > can be
> > > >  		 * assigned in any order and we need to make
> > > > sure that
> > > >  		 * slave CRTCs are disabled first and then
> > > > master CRTC
> > > > since
> > > >  		 * Slave vblanks are masked till Master
> > > > Vblanks.
> > > >  		 */
> > > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > > -			continue;
> > > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > > +		    is_trans_port_sync_master(new_crtc_state))
> > > >  			continue;
> > > >  
> > > > +		if (intel_crtc_has_type(old_crtc_state,
> > > > INTEL_OUTPUT_DP_MST)) {
> > > > +			struct intel_encoder *encoder;
> > > > +
> > > > +			encoder =
> > > > intel_get_crtc_old_encoder(state,
> > > > +							     ol
> > > > d_crtc_s
> > > > tate);
> > > > +			if
> > > > (intel_dp_mst_master_trans_get(encoder) ==
> > > > +			    old_crtc_state->cpu_transcoder)
> > > > +				continue;
> > > > +		}
> > > > +
> > > >  		intel_pre_plane_update(old_crtc_state,
> > > > new_crtc_state);
> > > >  		intel_old_crtc_state_disables(state,
> > > > old_crtc_state,
> > > >  					      new_crtc_state,
> > > > crtc);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > index 83ea04149b77..23d747cdca64 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > > >  	/* Pointer to master transcoder in case of tiled
> > > > displays */
> > > >  	enum transcoder master_transcoder;
> > > >  
> > > > +	bool mst_master_trans_pending;
> > > > +
> > > >  	/* Bitmask to indicate slaves attached */
> > > >  	u8 sync_mode_slaves_mask;
> > > >  };
> > > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > > >  	bool can_mst; /* this port supports mst */
> > > >  	bool is_mst;
> > > >  	int active_mst_links;
> > > > +	enum transcoder mst_master_transcoder; /* Only used in
> > > > TGL+ */
> > > >  
> > > >  	/*
> > > >  	 * DP_TP_* registers may be either on port or
> > > > transcoder
> > > > register space.
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > index 3123958e2081..ceff6901451a 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > > intel_digital_port *intel_dig_port,
> > > >  	intel_dp->reset_link_params = true;
> > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > > >  
> > > >  	/* Preserve the current hw state. */
> > > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > index f8a350359346..9731c3c1d3f2 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > @@ -87,6 +87,47 @@ static int
> > > > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > >  	return 0;
> > > >  }
> > > >  
> > > > +static int
> > > > +intel_dp_mst_master_trans_compute(struct intel_encoder
> > > > *encoder,
> > > > +				  struct intel_crtc_state
> > > > *pipe_config,
> > > > +				  struct drm_connector_state
> > > > *conn_state)
> > > > +{
> > > > +	struct intel_atomic_state *state =
> > > > to_intel_atomic_state(pipe_config->uapi.state);
> > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > >base.dev);
> > > > +	struct intel_crtc_state *new_crtc_state;
> > > > +	struct intel_crtc *crtc;
> > > > +	enum transcoder master;
> > > > +	int i;
> > > > +
> > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > +		return 0;
> > > > +
> > > > +	if (!conn_state->crtc)
> > > > +		return 0;
> > > > +
> > > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > > +	if (master == INVALID_TRANSCODER)
> > > > +		return 0;
> > > > +
> > > > +	for_each_new_intel_crtc_in_state(state, crtc,
> > > > new_crtc_state,
> > > > i) {
> > > > +		/*
> > > > +		 * cpu_transcoder is set when computing CRTC
> > > > state if
> > > > it will
> > > > +		 * be disabled it will not happen, so checking
> > > > pipe
> > > > instead
> > > > +		 */
> > > > +		if (crtc->pipe != (enum pipe)master)
> > > > +			continue;
> > > > +
> > > > +		if
> > > > (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > > > uapi) &&
> > > > +		    new_crtc_state->uapi.enable)
> > > > +			continue;
> > > > +
> > > > +		pipe_config->mst_master_trans_pending = true;
> > > > +		break;
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >  static int intel_dp_mst_compute_config(struct intel_encoder
> > > > *encoder,
> > > >  				       struct intel_crtc_state
> > > > *pipe_config,
> > > >  				       struct
> > > > drm_connector_state
> > > > *conn_state)
> > > > @@ -154,6 +195,95 @@ static int
> > > > intel_dp_mst_compute_config(struct
> > > > intel_encoder *encoder,
> > > >  
> > > >  	intel_ddi_compute_min_voltage_level(dev_priv,
> > > > pipe_config);
> > > >  
> > > > +	ret = intel_dp_mst_master_trans_compute(encoder,
> > > > pipe_config,
> > > > +						conn_state);
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +static int
> > > > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > > > *connector,
> > > > +				       struct drm_atomic_state
> > > > *state)
> > > > +{
> > > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > > >dev);
> > > > +	struct intel_connector *intel_conn =
> > > > to_intel_connector(connector);
> > > > +	struct drm_connector_state *new_conn_state,
> > > > *old_conn_state;
> > > > +	struct drm_connector_list_iter conn_list_iter;
> > > > +	struct intel_crtc_state *intel_crtc_state;
> > > > +	struct drm_crtc_state *crtc_state;
> > > > +	struct drm_connector *conn_iter;
> > > > +
> > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > +		return 0;
> > > > +
> > > > +	new_conn_state =
> > > > drm_atomic_get_new_connector_state(state,
> > > > connector);
> > > > +	old_conn_state =
> > > > drm_atomic_get_old_connector_state(state,
> > > > connector);
> > > > +
> > > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > > +		return 0;
> > > > +
> > > > +	/*
> > > > +	 * 3 cases that needs be handled here:
> > > > +	 * - connector going from disabled to enabled
> > > > +	 * - connector going from enabled to disabled:
> > > > +	 * if this transcoder was the master, all slaves needs
> > > > a
> > > > modeset
> > > > +	 * - connector going from enabled to enabled but it
> > > > needs a
> > > > modeset:
> > > > +	 * if this transcoder was the master, all slaves also
> > > > needs a
> > > > modeset
> > > > +	 */
> > > > +
> > > > +	/* disabled -> enabled */
> > > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > > +		return 0;
> > > > +
> > > > +	/* enabled -> enabled(modeset)? */
> > > > +	if (new_conn_state->crtc) {
> > > > +		crtc_state =
> > > > drm_atomic_get_new_crtc_state(state,
> > > > new_conn_state->crtc);
> > > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > > +			return 0;
> > > > +	}
> > > > +
> > > > +	/* handling enabled -> enabled(modeset) and enabled ->
> > > > disabled
> > > > */
> > > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > > old_conn_state->crtc);
> > > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > > +
> > > > +	/* If not master, nothing else needs to be handled */
> > > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > > +	    intel_crtc_state->cpu_transcoder)
> > > > +		return 0;
> > > > +
> > > > +	/* Is master, mark all other CRTCs as needing a modeset
> > > > */
> > > > +	drm_connector_list_iter_begin(state->dev,
> > > > &conn_list_iter);
> > > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter)
> > > > {
> > > > +		struct intel_connector *intel_conn_iter;
> > > > +		struct drm_connector_state *conn_iter_state;
> > > > +
> > > > +		intel_conn_iter =
> > > > to_intel_connector(conn_iter);
> > > > +		if (intel_conn_iter->mst_port != intel_conn-
> > > > >mst_port)
> > > > +			continue;
> > > > +
> > > > +		conn_iter_state =
> > > > drm_atomic_get_connector_state(state,
> > > > +								
> > > >  conn_i
> > > > ter);
> > > > +		if (IS_ERR(conn_iter_state)) {
> > > > +			drm_connector_list_iter_end(&conn_list_
> > > > iter);
> > > > +			return PTR_ERR(conn_iter_state);
> > > > +		}
> > > > +
> > > > +		if (!conn_iter_state->crtc)
> > > > +			continue;
> > > > +
> > > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > > conn_iter_state->crtc);
> > > > +		if (IS_ERR(crtc_state)) {
> > > > +			drm_connector_list_iter_end(&conn_list_
> > > > iter);
> > > > +			return PTR_ERR(conn_iter_state);
> > > > +		}
> > > > +
> > > > +		intel_crtc_state =
> > > > to_intel_crtc_state(crtc_state);
> > > > +		crtc_state->mode_changed = true;
> > > > +	}
> > > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > > +
> > > >  	return 0;
> > > >  }
> > > >  
> > > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct
> > > > drm_connector
> > > > *connector,
> > > >  	if (ret)
> > > >  		return ret;
> > > >  
> > > > +	ret = intel_dp_mst_atomic_master_trans_check(connector,
> > > > state);
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > >  	if (!old_conn_state->crtc)
> > > >  		return 0;
> > > >  
> > > > @@ -259,6 +393,7 @@ static void
> > > > intel_mst_post_disable_dp(struct
> > > > intel_encoder *encoder,
> > > >  		intel_dp_sink_dpms(intel_dp,
> > > > DRM_MODE_DPMS_OFF);
> > > >  		intel_dig_port-
> > > > >base.post_disable(&intel_dig_port-
> > > > > base,
> > > >  						  old_crtc_stat
> > > > e,
> > > > NULL);
> > > > +		intel_dp->mst_master_transcoder =
> > > > INVALID_TRANSCODER;
> > > >  	}
> > > >  
> > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > >active_mst_links);
> > > > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > > > intel_encoder *encoder,
> > > >  
> > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > >active_mst_links);
> > > >  
> > > > -	if (first_mst_stream)
> > > > +	if (first_mst_stream) {
> > > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > > INVALID_TRANSCODER);
> > > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > > > cpu_transcoder;
> > > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > > +	}
> > > >  
> > > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr,
> > > > connector-
> > > > > port, true);
> > > >  
> > > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > > intel_digital_port *intel_dig_port)
> > > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > > >  	/* encoders will get killed by normal cleanup */
> > > >  }
> > > > +
> > > > +enum transcoder
> > > > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > > > +{
> > > > +	struct intel_dp_mst_encoder *intel_mst =
> > > > enc_to_mst(&encoder-
> > > > > base);
> > > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > > +
> > > > +	return intel_dp->mst_master_transcoder;
> > > > +}
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > index f660ad80db04..e6f28a517182 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > @@ -7,9 +7,11 @@
> > > >  #define __INTEL_DP_MST_H__
> > > >  
> > > >  struct intel_digital_port;
> > > > +struct intel_encoder;
> > > >  
> > > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > > *intel_dig_port, int conn_id);
> > > >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > > > *intel_dig_port);
> > > >  int intel_dp_mst_encoder_active_links(struct
> > > > intel_digital_port
> > > > *intel_dig_port);
> > > > +enum transcoder intel_dp_mst_master_trans_get(struct
> > > > intel_encoder
> > > > *encoder);
> > > >  
> > > >  #endif /* __INTEL_DP_MST_H__ */
> > > > -- 
> > > > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-28 12:06             ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 12:06 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> > > > wrote:
> > > > > On TGL the blending of all the streams have moved from DDI to
> > > > > transcoder, so now every transcoder working over the same MST
> > > > > port
> > > > > must
> > > > > send its stream to a master transcoder and master will send to
> > > > > DDI
> > > > > respecting the time slots.
> > > > > 
> > > > > A previous approach was using the lowest pipe/transcoder as
> > > > > master
> > > > > transcoder but as the comment in skl_commit_modeset_enables()
> > > > > states,
> > > > > that is not always true.
> > > > > 
> > > > > So here promoting the first pipe/transcoder of the stream as
> > > > > master.
> > > > > That caused several other problems as during the commit phase
> > > > > the
> > > > > state computed should not be changed.
> > > > > 
> > > > > So the master transcoder is store into intel_dp and the modeset
> > > > > in
> > > > > slave pipes/transcoders is forced using
> > > > > mst_master_trans_pending.
> > > > > 
> > > > > v2:
> > > > > - added missing config compute to trigger fullmodeset in slave
> > > > > transcoders
> > > > > 
> > > > > BSpec: 50493
> > > > > BSpec: 49190
> > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > +++++++++++++++++-
> > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > @@ -35,6 +35,7 @@
> > > > >  #include "intel_display_types.h"
> > > > >  #include "intel_dp.h"
> > > > >  #include "intel_dp_link_training.h"
> > > > > +#include "intel_dp_mst.h"
> > > > >  #include "intel_dpio_phy.h"
> > > > >  #include "intel_dsi.h"
> > > > >  #include "intel_fifo_underrun.h"
> > > > > @@ -1903,8 +1904,13 @@
> > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > struct intel_crtc_state *crtc_state)
> > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > >  
> > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > -			temp |=
> > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > +			enum transcoder master;
> > > > > +
> > > > > +			master =
> > > > > intel_dp_mst_master_trans_get(encoder);
> > > > 
> > > > Why isn't that just stored in the crtc state like everything
> > > > else?
> > > > 
> > > > I'm thinking we should maybe do it just like port sync and have
> > > > both
> > > > master + slave_mask. That way it should be pretty trivial to add
> > > > all
> > > > the relevant crtcs to the state when needed.
> > > 
> > > I guess port sync is not doing the right thing and it could cause
> > > underruns.
> > > When it is going to enable the master CRTC of the port sync it
> > > forcibly
> > > enables the slave first, what could cause underruns because of
> > > overlap
> > > in ddb allocations(that is what I understood from the comment in
> > > skl_commit_modeset_enables()).
> > 
> > Not necessarily just underruns but even a system hang. The fix should
> > be
> > a trivial "check the slave for ddb overlap as well", but apparently I
> > failed at convicing people to do that.
> > 
> > I've actually been pondering about decoupling the plane updates from
> > the crtc enable stuff entirely. At least theoretically crtc enable
> > should be able to excute in any order as long we don't enable any
> > new planes.
> > 
> > But none of that really matters for the discussion at hand. Though
> > there are other problems with the port sync stuff that would need
> > to be handled better. Eg. I think it now adds both crtcs to the state
> > always which is going to cut the fps in half. Also the place where
> > it does that stuff is rather suspicious. All that stuff should be
> > somewhere a bit higher up IMO.
> > 
> > > So for MST we only know who is the master in the commit phase and
> > > at
> > > this point we should not modify the computed state.
> > 
> > I'm not suggesting modifying anything during commit phase. I think
> > you are effectiely doing that right now by stuffing that mst master
> > transcoder into intel_dp.
> 
> Sorry, I still don't get what approach are you suggesting here.
> 
> If we can't modify the state in the commit phase, adding
> mst_master_transcoder in the CRTC state will not be possible while
> respecting the order imposed by ddb allocations.

The ddb allocation ordering only comes into play when there are
already active pipes. It should always be possible to not enable
the slaves until the master has been shuffled into place in the 
ddb and enabled.

> 
> > 
> > > > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > > > +			temp |=
> > > > > TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > > > +		}
> > > > >  	} else {
> > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index 801b975c7d39..35a59108194e 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -46,6 +46,7 @@
> > > > >  #include "display/intel_crt.h"
> > > > >  #include "display/intel_ddi.h"
> > > > >  #include "display/intel_dp.h"
> > > > > +#include "display/intel_dp_mst.h"
> > > > >  #include "display/intel_dsi.h"
> > > > >  #include "display/intel_dvo.h"
> > > > >  #include "display/intel_gmbus.h"
> > > > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > > > > intel_atomic_state *state,
> > > > >  	return encoder;
> > > > >  }
> > > > >  
> > > > > +/*
> > > > > + * Finds the encoder associated with the given CRTC. This can
> > > > > only
> > > > > be
> > > > > + * used when we know that the CRTC isn't feeding multiple
> > > > > encoders!
> > > > > + */
> > > > > +static struct intel_encoder *
> > > > > +intel_get_crtc_old_encoder(const struct intel_atomic_state
> > > > > *state,
> > > > > +			   const struct intel_crtc_state
> > > > > *crtc_state)
> > > > > +{
> > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > >uapi.crtc);
> > > > > +	const struct drm_connector_state *connector_state;
> > > > > +	const struct drm_connector *connector;
> > > > > +	struct intel_encoder *encoder = NULL;
> > > > > +	int num_encoders = 0;
> > > > > +	int i;
> > > > > +
> > > > > +	for_each_old_connector_in_state(&state->base,
> > > > > connector,
> > > > > +					connector_state, i) {
> > > > > +		if (connector_state->crtc != &crtc->base)
> > > > > +			continue;
> > > > > +
> > > > > +		encoder = to_intel_encoder(connector_state-
> > > > > > best_encoder);
> > > > > +		num_encoders++;
> > > > > +	}
> > > > > +
> > > > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > > > +	     num_encoders, pipe_name(crtc->pipe));
> > > > > +
> > > > > +	return encoder;
> > > > > +}
> > > > 
> > > > Argh. I was hoping to kill the other one of these. Got it down to
> > > > 1
> > > > remaining user now I think.
> > > > 
> > > > > +
> > > > >  /*
> > > > >   * Enable PCH resources required for PCH ports:
> > > > >   *   - PCH PLLs
> > > > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > > > > intel_crtc_state *current_config,
> > > > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > > > >  #undef PIPE_CONF_QUIRK
> > > > >  
> > > > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > > > mst_master_trans\n",
> > > > > +			      crtc->base.base.id, crtc-
> > > > > >base.name);
> > > > > +		ret = false;
> > > > > +	}
> > > > > +
> > > > >  	return ret;
> > > > >  }
> > > > >  
> > > > > @@ -14449,22 +14486,35 @@ static void
> > > > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > > > >  	struct intel_crtc *crtc;
> > > > >  	int i;
> > > > >  
> > > > > -	/* Only disable port sync slaves */
> > > > > +	/* Only disable port sync and MST slaves */
> > > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > > old_crtc_state,
> > > > >  					    new_crtc_state, i)
> > > > > {
> > > > >  		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > > >active)
> > > > >  			continue;
> > > > >  
> > > > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > > > +		    !intel_crtc_has_type(old_crtc_state,
> > > > > INTEL_OUTPUT_DP_MST))
> > > > > +			continue;
> > > > > +
> > > > >  		/* In case of Transcoder port Sync master slave
> > > > > CRTCs
> > > > > can be
> > > > >  		 * assigned in any order and we need to make
> > > > > sure that
> > > > >  		 * slave CRTCs are disabled first and then
> > > > > master CRTC
> > > > > since
> > > > >  		 * Slave vblanks are masked till Master
> > > > > Vblanks.
> > > > >  		 */
> > > > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > > > -			continue;
> > > > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > > > +		    is_trans_port_sync_master(new_crtc_state))
> > > > >  			continue;
> > > > >  
> > > > > +		if (intel_crtc_has_type(old_crtc_state,
> > > > > INTEL_OUTPUT_DP_MST)) {
> > > > > +			struct intel_encoder *encoder;
> > > > > +
> > > > > +			encoder =
> > > > > intel_get_crtc_old_encoder(state,
> > > > > +							     ol
> > > > > d_crtc_s
> > > > > tate);
> > > > > +			if
> > > > > (intel_dp_mst_master_trans_get(encoder) ==
> > > > > +			    old_crtc_state->cpu_transcoder)
> > > > > +				continue;
> > > > > +		}
> > > > > +
> > > > >  		intel_pre_plane_update(old_crtc_state,
> > > > > new_crtc_state);
> > > > >  		intel_old_crtc_state_disables(state,
> > > > > old_crtc_state,
> > > > >  					      new_crtc_state,
> > > > > crtc);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > index 83ea04149b77..23d747cdca64 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > > > >  	/* Pointer to master transcoder in case of tiled
> > > > > displays */
> > > > >  	enum transcoder master_transcoder;
> > > > >  
> > > > > +	bool mst_master_trans_pending;
> > > > > +
> > > > >  	/* Bitmask to indicate slaves attached */
> > > > >  	u8 sync_mode_slaves_mask;
> > > > >  };
> > > > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > > > >  	bool can_mst; /* this port supports mst */
> > > > >  	bool is_mst;
> > > > >  	int active_mst_links;
> > > > > +	enum transcoder mst_master_transcoder; /* Only used in
> > > > > TGL+ */
> > > > >  
> > > > >  	/*
> > > > >  	 * DP_TP_* registers may be either on port or
> > > > > transcoder
> > > > > register space.
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > index 3123958e2081..ceff6901451a 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > > > intel_digital_port *intel_dig_port,
> > > > >  	intel_dp->reset_link_params = true;
> > > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > > > >  
> > > > >  	/* Preserve the current hw state. */
> > > > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > index f8a350359346..9731c3c1d3f2 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > @@ -87,6 +87,47 @@ static int
> > > > > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > > >  	return 0;
> > > > >  }
> > > > >  
> > > > > +static int
> > > > > +intel_dp_mst_master_trans_compute(struct intel_encoder
> > > > > *encoder,
> > > > > +				  struct intel_crtc_state
> > > > > *pipe_config,
> > > > > +				  struct drm_connector_state
> > > > > *conn_state)
> > > > > +{
> > > > > +	struct intel_atomic_state *state =
> > > > > to_intel_atomic_state(pipe_config->uapi.state);
> > > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > > >base.dev);
> > > > > +	struct intel_crtc_state *new_crtc_state;
> > > > > +	struct intel_crtc *crtc;
> > > > > +	enum transcoder master;
> > > > > +	int i;
> > > > > +
> > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > +		return 0;
> > > > > +
> > > > > +	if (!conn_state->crtc)
> > > > > +		return 0;
> > > > > +
> > > > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > > > +	if (master == INVALID_TRANSCODER)
> > > > > +		return 0;
> > > > > +
> > > > > +	for_each_new_intel_crtc_in_state(state, crtc,
> > > > > new_crtc_state,
> > > > > i) {
> > > > > +		/*
> > > > > +		 * cpu_transcoder is set when computing CRTC
> > > > > state if
> > > > > it will
> > > > > +		 * be disabled it will not happen, so checking
> > > > > pipe
> > > > > instead
> > > > > +		 */
> > > > > +		if (crtc->pipe != (enum pipe)master)
> > > > > +			continue;
> > > > > +
> > > > > +		if
> > > > > (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > > > > uapi) &&
> > > > > +		    new_crtc_state->uapi.enable)
> > > > > +			continue;
> > > > > +
> > > > > +		pipe_config->mst_master_trans_pending = true;
> > > > > +		break;
> > > > > +	}
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >  static int intel_dp_mst_compute_config(struct intel_encoder
> > > > > *encoder,
> > > > >  				       struct intel_crtc_state
> > > > > *pipe_config,
> > > > >  				       struct
> > > > > drm_connector_state
> > > > > *conn_state)
> > > > > @@ -154,6 +195,95 @@ static int
> > > > > intel_dp_mst_compute_config(struct
> > > > > intel_encoder *encoder,
> > > > >  
> > > > >  	intel_ddi_compute_min_voltage_level(dev_priv,
> > > > > pipe_config);
> > > > >  
> > > > > +	ret = intel_dp_mst_master_trans_compute(encoder,
> > > > > pipe_config,
> > > > > +						conn_state);
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +static int
> > > > > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > > > > *connector,
> > > > > +				       struct drm_atomic_state
> > > > > *state)
> > > > > +{
> > > > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > > > >dev);
> > > > > +	struct intel_connector *intel_conn =
> > > > > to_intel_connector(connector);
> > > > > +	struct drm_connector_state *new_conn_state,
> > > > > *old_conn_state;
> > > > > +	struct drm_connector_list_iter conn_list_iter;
> > > > > +	struct intel_crtc_state *intel_crtc_state;
> > > > > +	struct drm_crtc_state *crtc_state;
> > > > > +	struct drm_connector *conn_iter;
> > > > > +
> > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > +		return 0;
> > > > > +
> > > > > +	new_conn_state =
> > > > > drm_atomic_get_new_connector_state(state,
> > > > > connector);
> > > > > +	old_conn_state =
> > > > > drm_atomic_get_old_connector_state(state,
> > > > > connector);
> > > > > +
> > > > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > > > +		return 0;
> > > > > +
> > > > > +	/*
> > > > > +	 * 3 cases that needs be handled here:
> > > > > +	 * - connector going from disabled to enabled
> > > > > +	 * - connector going from enabled to disabled:
> > > > > +	 * if this transcoder was the master, all slaves needs
> > > > > a
> > > > > modeset
> > > > > +	 * - connector going from enabled to enabled but it
> > > > > needs a
> > > > > modeset:
> > > > > +	 * if this transcoder was the master, all slaves also
> > > > > needs a
> > > > > modeset
> > > > > +	 */
> > > > > +
> > > > > +	/* disabled -> enabled */
> > > > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > > > +		return 0;
> > > > > +
> > > > > +	/* enabled -> enabled(modeset)? */
> > > > > +	if (new_conn_state->crtc) {
> > > > > +		crtc_state =
> > > > > drm_atomic_get_new_crtc_state(state,
> > > > > new_conn_state->crtc);
> > > > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > > > +			return 0;
> > > > > +	}
> > > > > +
> > > > > +	/* handling enabled -> enabled(modeset) and enabled ->
> > > > > disabled
> > > > > */
> > > > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > > > old_conn_state->crtc);
> > > > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > > > +
> > > > > +	/* If not master, nothing else needs to be handled */
> > > > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > > > +	    intel_crtc_state->cpu_transcoder)
> > > > > +		return 0;
> > > > > +
> > > > > +	/* Is master, mark all other CRTCs as needing a modeset
> > > > > */
> > > > > +	drm_connector_list_iter_begin(state->dev,
> > > > > &conn_list_iter);
> > > > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter)
> > > > > {
> > > > > +		struct intel_connector *intel_conn_iter;
> > > > > +		struct drm_connector_state *conn_iter_state;
> > > > > +
> > > > > +		intel_conn_iter =
> > > > > to_intel_connector(conn_iter);
> > > > > +		if (intel_conn_iter->mst_port != intel_conn-
> > > > > >mst_port)
> > > > > +			continue;
> > > > > +
> > > > > +		conn_iter_state =
> > > > > drm_atomic_get_connector_state(state,
> > > > > +								
> > > > >  conn_i
> > > > > ter);
> > > > > +		if (IS_ERR(conn_iter_state)) {
> > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > iter);
> > > > > +			return PTR_ERR(conn_iter_state);
> > > > > +		}
> > > > > +
> > > > > +		if (!conn_iter_state->crtc)
> > > > > +			continue;
> > > > > +
> > > > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > > > conn_iter_state->crtc);
> > > > > +		if (IS_ERR(crtc_state)) {
> > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > iter);
> > > > > +			return PTR_ERR(conn_iter_state);
> > > > > +		}
> > > > > +
> > > > > +		intel_crtc_state =
> > > > > to_intel_crtc_state(crtc_state);
> > > > > +		crtc_state->mode_changed = true;
> > > > > +	}
> > > > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > > > +
> > > > >  	return 0;
> > > > >  }
> > > > >  
> > > > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct
> > > > > drm_connector
> > > > > *connector,
> > > > >  	if (ret)
> > > > >  		return ret;
> > > > >  
> > > > > +	ret = intel_dp_mst_atomic_master_trans_check(connector,
> > > > > state);
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > > +
> > > > >  	if (!old_conn_state->crtc)
> > > > >  		return 0;
> > > > >  
> > > > > @@ -259,6 +393,7 @@ static void
> > > > > intel_mst_post_disable_dp(struct
> > > > > intel_encoder *encoder,
> > > > >  		intel_dp_sink_dpms(intel_dp,
> > > > > DRM_MODE_DPMS_OFF);
> > > > >  		intel_dig_port-
> > > > > >base.post_disable(&intel_dig_port-
> > > > > > base,
> > > > >  						  old_crtc_stat
> > > > > e,
> > > > > NULL);
> > > > > +		intel_dp->mst_master_transcoder =
> > > > > INVALID_TRANSCODER;
> > > > >  	}
> > > > >  
> > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > >active_mst_links);
> > > > > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > > > > intel_encoder *encoder,
> > > > >  
> > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > >active_mst_links);
> > > > >  
> > > > > -	if (first_mst_stream)
> > > > > +	if (first_mst_stream) {
> > > > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > > > INVALID_TRANSCODER);
> > > > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > > > > cpu_transcoder;
> > > > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > > > +	}
> > > > >  
> > > > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr,
> > > > > connector-
> > > > > > port, true);
> > > > >  
> > > > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > > > intel_digital_port *intel_dig_port)
> > > > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > > > >  	/* encoders will get killed by normal cleanup */
> > > > >  }
> > > > > +
> > > > > +enum transcoder
> > > > > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > > > > +{
> > > > > +	struct intel_dp_mst_encoder *intel_mst =
> > > > > enc_to_mst(&encoder-
> > > > > > base);
> > > > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > > > +
> > > > > +	return intel_dp->mst_master_transcoder;
> > > > > +}
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > index f660ad80db04..e6f28a517182 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > @@ -7,9 +7,11 @@
> > > > >  #define __INTEL_DP_MST_H__
> > > > >  
> > > > >  struct intel_digital_port;
> > > > > +struct intel_encoder;
> > > > >  
> > > > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > > > *intel_dig_port, int conn_id);
> > > > >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > > > > *intel_dig_port);
> > > > >  int intel_dp_mst_encoder_active_links(struct
> > > > > intel_digital_port
> > > > > *intel_dig_port);
> > > > > +enum transcoder intel_dp_mst_master_trans_get(struct
> > > > > intel_encoder
> > > > > *encoder);
> > > > >  
> > > > >  #endif /* __INTEL_DP_MST_H__ */
> > > > > -- 
> > > > > 2.24.0

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

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-11-28 12:06             ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 12:06 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de Souza
> > > > wrote:
> > > > > On TGL the blending of all the streams have moved from DDI to
> > > > > transcoder, so now every transcoder working over the same MST
> > > > > port
> > > > > must
> > > > > send its stream to a master transcoder and master will send to
> > > > > DDI
> > > > > respecting the time slots.
> > > > > 
> > > > > A previous approach was using the lowest pipe/transcoder as
> > > > > master
> > > > > transcoder but as the comment in skl_commit_modeset_enables()
> > > > > states,
> > > > > that is not always true.
> > > > > 
> > > > > So here promoting the first pipe/transcoder of the stream as
> > > > > master.
> > > > > That caused several other problems as during the commit phase
> > > > > the
> > > > > state computed should not be changed.
> > > > > 
> > > > > So the master transcoder is store into intel_dp and the modeset
> > > > > in
> > > > > slave pipes/transcoders is forced using
> > > > > mst_master_trans_pending.
> > > > > 
> > > > > v2:
> > > > > - added missing config compute to trigger fullmodeset in slave
> > > > > transcoders
> > > > > 
> > > > > BSpec: 50493
> > > > > BSpec: 49190
> > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58 ++++++-
> > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > +++++++++++++++++-
> > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > @@ -35,6 +35,7 @@
> > > > >  #include "intel_display_types.h"
> > > > >  #include "intel_dp.h"
> > > > >  #include "intel_dp_link_training.h"
> > > > > +#include "intel_dp_mst.h"
> > > > >  #include "intel_dpio_phy.h"
> > > > >  #include "intel_dsi.h"
> > > > >  #include "intel_fifo_underrun.h"
> > > > > @@ -1903,8 +1904,13 @@
> > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > struct intel_crtc_state *crtc_state)
> > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > >  
> > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > -			temp |=
> > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > +			enum transcoder master;
> > > > > +
> > > > > +			master =
> > > > > intel_dp_mst_master_trans_get(encoder);
> > > > 
> > > > Why isn't that just stored in the crtc state like everything
> > > > else?
> > > > 
> > > > I'm thinking we should maybe do it just like port sync and have
> > > > both
> > > > master + slave_mask. That way it should be pretty trivial to add
> > > > all
> > > > the relevant crtcs to the state when needed.
> > > 
> > > I guess port sync is not doing the right thing and it could cause
> > > underruns.
> > > When it is going to enable the master CRTC of the port sync it
> > > forcibly
> > > enables the slave first, what could cause underruns because of
> > > overlap
> > > in ddb allocations(that is what I understood from the comment in
> > > skl_commit_modeset_enables()).
> > 
> > Not necessarily just underruns but even a system hang. The fix should
> > be
> > a trivial "check the slave for ddb overlap as well", but apparently I
> > failed at convicing people to do that.
> > 
> > I've actually been pondering about decoupling the plane updates from
> > the crtc enable stuff entirely. At least theoretically crtc enable
> > should be able to excute in any order as long we don't enable any
> > new planes.
> > 
> > But none of that really matters for the discussion at hand. Though
> > there are other problems with the port sync stuff that would need
> > to be handled better. Eg. I think it now adds both crtcs to the state
> > always which is going to cut the fps in half. Also the place where
> > it does that stuff is rather suspicious. All that stuff should be
> > somewhere a bit higher up IMO.
> > 
> > > So for MST we only know who is the master in the commit phase and
> > > at
> > > this point we should not modify the computed state.
> > 
> > I'm not suggesting modifying anything during commit phase. I think
> > you are effectiely doing that right now by stuffing that mst master
> > transcoder into intel_dp.
> 
> Sorry, I still don't get what approach are you suggesting here.
> 
> If we can't modify the state in the commit phase, adding
> mst_master_transcoder in the CRTC state will not be possible while
> respecting the order imposed by ddb allocations.

The ddb allocation ordering only comes into play when there are
already active pipes. It should always be possible to not enable
the slaves until the master has been shuffled into place in the 
ddb and enabled.

> 
> > 
> > > > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > > > +			temp |=
> > > > > TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > > > +		}
> > > > >  	} else {
> > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index 801b975c7d39..35a59108194e 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -46,6 +46,7 @@
> > > > >  #include "display/intel_crt.h"
> > > > >  #include "display/intel_ddi.h"
> > > > >  #include "display/intel_dp.h"
> > > > > +#include "display/intel_dp_mst.h"
> > > > >  #include "display/intel_dsi.h"
> > > > >  #include "display/intel_dvo.h"
> > > > >  #include "display/intel_gmbus.h"
> > > > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const struct
> > > > > intel_atomic_state *state,
> > > > >  	return encoder;
> > > > >  }
> > > > >  
> > > > > +/*
> > > > > + * Finds the encoder associated with the given CRTC. This can
> > > > > only
> > > > > be
> > > > > + * used when we know that the CRTC isn't feeding multiple
> > > > > encoders!
> > > > > + */
> > > > > +static struct intel_encoder *
> > > > > +intel_get_crtc_old_encoder(const struct intel_atomic_state
> > > > > *state,
> > > > > +			   const struct intel_crtc_state
> > > > > *crtc_state)
> > > > > +{
> > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > >uapi.crtc);
> > > > > +	const struct drm_connector_state *connector_state;
> > > > > +	const struct drm_connector *connector;
> > > > > +	struct intel_encoder *encoder = NULL;
> > > > > +	int num_encoders = 0;
> > > > > +	int i;
> > > > > +
> > > > > +	for_each_old_connector_in_state(&state->base,
> > > > > connector,
> > > > > +					connector_state, i) {
> > > > > +		if (connector_state->crtc != &crtc->base)
> > > > > +			continue;
> > > > > +
> > > > > +		encoder = to_intel_encoder(connector_state-
> > > > > > best_encoder);
> > > > > +		num_encoders++;
> > > > > +	}
> > > > > +
> > > > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > > > +	     num_encoders, pipe_name(crtc->pipe));
> > > > > +
> > > > > +	return encoder;
> > > > > +}
> > > > 
> > > > Argh. I was hoping to kill the other one of these. Got it down to
> > > > 1
> > > > remaining user now I think.
> > > > 
> > > > > +
> > > > >  /*
> > > > >   * Enable PCH resources required for PCH ports:
> > > > >   *   - PCH PLLs
> > > > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const struct
> > > > > intel_crtc_state *current_config,
> > > > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > > > >  #undef PIPE_CONF_QUIRK
> > > > >  
> > > > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > > > mst_master_trans\n",
> > > > > +			      crtc->base.base.id, crtc-
> > > > > >base.name);
> > > > > +		ret = false;
> > > > > +	}
> > > > > +
> > > > >  	return ret;
> > > > >  }
> > > > >  
> > > > > @@ -14449,22 +14486,35 @@ static void
> > > > > intel_commit_modeset_disables(struct intel_atomic_state *state)
> > > > >  	struct intel_crtc *crtc;
> > > > >  	int i;
> > > > >  
> > > > > -	/* Only disable port sync slaves */
> > > > > +	/* Only disable port sync and MST slaves */
> > > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > > old_crtc_state,
> > > > >  					    new_crtc_state, i)
> > > > > {
> > > > >  		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > > >active)
> > > > >  			continue;
> > > > >  
> > > > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > > > +		    !intel_crtc_has_type(old_crtc_state,
> > > > > INTEL_OUTPUT_DP_MST))
> > > > > +			continue;
> > > > > +
> > > > >  		/* In case of Transcoder port Sync master slave
> > > > > CRTCs
> > > > > can be
> > > > >  		 * assigned in any order and we need to make
> > > > > sure that
> > > > >  		 * slave CRTCs are disabled first and then
> > > > > master CRTC
> > > > > since
> > > > >  		 * Slave vblanks are masked till Master
> > > > > Vblanks.
> > > > >  		 */
> > > > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > > > -			continue;
> > > > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > > > +		    is_trans_port_sync_master(new_crtc_state))
> > > > >  			continue;
> > > > >  
> > > > > +		if (intel_crtc_has_type(old_crtc_state,
> > > > > INTEL_OUTPUT_DP_MST)) {
> > > > > +			struct intel_encoder *encoder;
> > > > > +
> > > > > +			encoder =
> > > > > intel_get_crtc_old_encoder(state,
> > > > > +							     ol
> > > > > d_crtc_s
> > > > > tate);
> > > > > +			if
> > > > > (intel_dp_mst_master_trans_get(encoder) ==
> > > > > +			    old_crtc_state->cpu_transcoder)
> > > > > +				continue;
> > > > > +		}
> > > > > +
> > > > >  		intel_pre_plane_update(old_crtc_state,
> > > > > new_crtc_state);
> > > > >  		intel_old_crtc_state_disables(state,
> > > > > old_crtc_state,
> > > > >  					      new_crtc_state,
> > > > > crtc);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > index 83ea04149b77..23d747cdca64 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > > > >  	/* Pointer to master transcoder in case of tiled
> > > > > displays */
> > > > >  	enum transcoder master_transcoder;
> > > > >  
> > > > > +	bool mst_master_trans_pending;
> > > > > +
> > > > >  	/* Bitmask to indicate slaves attached */
> > > > >  	u8 sync_mode_slaves_mask;
> > > > >  };
> > > > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > > > >  	bool can_mst; /* this port supports mst */
> > > > >  	bool is_mst;
> > > > >  	int active_mst_links;
> > > > > +	enum transcoder mst_master_transcoder; /* Only used in
> > > > > TGL+ */
> > > > >  
> > > > >  	/*
> > > > >  	 * DP_TP_* registers may be either on port or
> > > > > transcoder
> > > > > register space.
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > index 3123958e2081..ceff6901451a 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > > > intel_digital_port *intel_dig_port,
> > > > >  	intel_dp->reset_link_params = true;
> > > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > > > >  
> > > > >  	/* Preserve the current hw state. */
> > > > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > index f8a350359346..9731c3c1d3f2 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > @@ -87,6 +87,47 @@ static int
> > > > > intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > > >  	return 0;
> > > > >  }
> > > > >  
> > > > > +static int
> > > > > +intel_dp_mst_master_trans_compute(struct intel_encoder
> > > > > *encoder,
> > > > > +				  struct intel_crtc_state
> > > > > *pipe_config,
> > > > > +				  struct drm_connector_state
> > > > > *conn_state)
> > > > > +{
> > > > > +	struct intel_atomic_state *state =
> > > > > to_intel_atomic_state(pipe_config->uapi.state);
> > > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > > >base.dev);
> > > > > +	struct intel_crtc_state *new_crtc_state;
> > > > > +	struct intel_crtc *crtc;
> > > > > +	enum transcoder master;
> > > > > +	int i;
> > > > > +
> > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > +		return 0;
> > > > > +
> > > > > +	if (!conn_state->crtc)
> > > > > +		return 0;
> > > > > +
> > > > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > > > +	if (master == INVALID_TRANSCODER)
> > > > > +		return 0;
> > > > > +
> > > > > +	for_each_new_intel_crtc_in_state(state, crtc,
> > > > > new_crtc_state,
> > > > > i) {
> > > > > +		/*
> > > > > +		 * cpu_transcoder is set when computing CRTC
> > > > > state if
> > > > > it will
> > > > > +		 * be disabled it will not happen, so checking
> > > > > pipe
> > > > > instead
> > > > > +		 */
> > > > > +		if (crtc->pipe != (enum pipe)master)
> > > > > +			continue;
> > > > > +
> > > > > +		if
> > > > > (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > > > > uapi) &&
> > > > > +		    new_crtc_state->uapi.enable)
> > > > > +			continue;
> > > > > +
> > > > > +		pipe_config->mst_master_trans_pending = true;
> > > > > +		break;
> > > > > +	}
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >  static int intel_dp_mst_compute_config(struct intel_encoder
> > > > > *encoder,
> > > > >  				       struct intel_crtc_state
> > > > > *pipe_config,
> > > > >  				       struct
> > > > > drm_connector_state
> > > > > *conn_state)
> > > > > @@ -154,6 +195,95 @@ static int
> > > > > intel_dp_mst_compute_config(struct
> > > > > intel_encoder *encoder,
> > > > >  
> > > > >  	intel_ddi_compute_min_voltage_level(dev_priv,
> > > > > pipe_config);
> > > > >  
> > > > > +	ret = intel_dp_mst_master_trans_compute(encoder,
> > > > > pipe_config,
> > > > > +						conn_state);
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +static int
> > > > > +intel_dp_mst_atomic_master_trans_check(struct drm_connector
> > > > > *connector,
> > > > > +				       struct drm_atomic_state
> > > > > *state)
> > > > > +{
> > > > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > > > >dev);
> > > > > +	struct intel_connector *intel_conn =
> > > > > to_intel_connector(connector);
> > > > > +	struct drm_connector_state *new_conn_state,
> > > > > *old_conn_state;
> > > > > +	struct drm_connector_list_iter conn_list_iter;
> > > > > +	struct intel_crtc_state *intel_crtc_state;
> > > > > +	struct drm_crtc_state *crtc_state;
> > > > > +	struct drm_connector *conn_iter;
> > > > > +
> > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > +		return 0;
> > > > > +
> > > > > +	new_conn_state =
> > > > > drm_atomic_get_new_connector_state(state,
> > > > > connector);
> > > > > +	old_conn_state =
> > > > > drm_atomic_get_old_connector_state(state,
> > > > > connector);
> > > > > +
> > > > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > > > +		return 0;
> > > > > +
> > > > > +	/*
> > > > > +	 * 3 cases that needs be handled here:
> > > > > +	 * - connector going from disabled to enabled
> > > > > +	 * - connector going from enabled to disabled:
> > > > > +	 * if this transcoder was the master, all slaves needs
> > > > > a
> > > > > modeset
> > > > > +	 * - connector going from enabled to enabled but it
> > > > > needs a
> > > > > modeset:
> > > > > +	 * if this transcoder was the master, all slaves also
> > > > > needs a
> > > > > modeset
> > > > > +	 */
> > > > > +
> > > > > +	/* disabled -> enabled */
> > > > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > > > +		return 0;
> > > > > +
> > > > > +	/* enabled -> enabled(modeset)? */
> > > > > +	if (new_conn_state->crtc) {
> > > > > +		crtc_state =
> > > > > drm_atomic_get_new_crtc_state(state,
> > > > > new_conn_state->crtc);
> > > > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > > > +			return 0;
> > > > > +	}
> > > > > +
> > > > > +	/* handling enabled -> enabled(modeset) and enabled ->
> > > > > disabled
> > > > > */
> > > > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > > > old_conn_state->crtc);
> > > > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > > > +
> > > > > +	/* If not master, nothing else needs to be handled */
> > > > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > > > +	    intel_crtc_state->cpu_transcoder)
> > > > > +		return 0;
> > > > > +
> > > > > +	/* Is master, mark all other CRTCs as needing a modeset
> > > > > */
> > > > > +	drm_connector_list_iter_begin(state->dev,
> > > > > &conn_list_iter);
> > > > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter)
> > > > > {
> > > > > +		struct intel_connector *intel_conn_iter;
> > > > > +		struct drm_connector_state *conn_iter_state;
> > > > > +
> > > > > +		intel_conn_iter =
> > > > > to_intel_connector(conn_iter);
> > > > > +		if (intel_conn_iter->mst_port != intel_conn-
> > > > > >mst_port)
> > > > > +			continue;
> > > > > +
> > > > > +		conn_iter_state =
> > > > > drm_atomic_get_connector_state(state,
> > > > > +								
> > > > >  conn_i
> > > > > ter);
> > > > > +		if (IS_ERR(conn_iter_state)) {
> > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > iter);
> > > > > +			return PTR_ERR(conn_iter_state);
> > > > > +		}
> > > > > +
> > > > > +		if (!conn_iter_state->crtc)
> > > > > +			continue;
> > > > > +
> > > > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > > > conn_iter_state->crtc);
> > > > > +		if (IS_ERR(crtc_state)) {
> > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > iter);
> > > > > +			return PTR_ERR(conn_iter_state);
> > > > > +		}
> > > > > +
> > > > > +		intel_crtc_state =
> > > > > to_intel_crtc_state(crtc_state);
> > > > > +		crtc_state->mode_changed = true;
> > > > > +	}
> > > > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > > > +
> > > > >  	return 0;
> > > > >  }
> > > > >  
> > > > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct
> > > > > drm_connector
> > > > > *connector,
> > > > >  	if (ret)
> > > > >  		return ret;
> > > > >  
> > > > > +	ret = intel_dp_mst_atomic_master_trans_check(connector,
> > > > > state);
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > > +
> > > > >  	if (!old_conn_state->crtc)
> > > > >  		return 0;
> > > > >  
> > > > > @@ -259,6 +393,7 @@ static void
> > > > > intel_mst_post_disable_dp(struct
> > > > > intel_encoder *encoder,
> > > > >  		intel_dp_sink_dpms(intel_dp,
> > > > > DRM_MODE_DPMS_OFF);
> > > > >  		intel_dig_port-
> > > > > >base.post_disable(&intel_dig_port-
> > > > > > base,
> > > > >  						  old_crtc_stat
> > > > > e,
> > > > > NULL);
> > > > > +		intel_dp->mst_master_transcoder =
> > > > > INVALID_TRANSCODER;
> > > > >  	}
> > > > >  
> > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > >active_mst_links);
> > > > > @@ -314,8 +449,11 @@ static void intel_mst_pre_enable_dp(struct
> > > > > intel_encoder *encoder,
> > > > >  
> > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > >active_mst_links);
> > > > >  
> > > > > -	if (first_mst_stream)
> > > > > +	if (first_mst_stream) {
> > > > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > > > INVALID_TRANSCODER);
> > > > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > > > > cpu_transcoder;
> > > > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > > > +	}
> > > > >  
> > > > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr,
> > > > > connector-
> > > > > > port, true);
> > > > >  
> > > > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > > > intel_digital_port *intel_dig_port)
> > > > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > > > >  	/* encoders will get killed by normal cleanup */
> > > > >  }
> > > > > +
> > > > > +enum transcoder
> > > > > +intel_dp_mst_master_trans_get(struct intel_encoder *encoder)
> > > > > +{
> > > > > +	struct intel_dp_mst_encoder *intel_mst =
> > > > > enc_to_mst(&encoder-
> > > > > > base);
> > > > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > > > +
> > > > > +	return intel_dp->mst_master_transcoder;
> > > > > +}
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > index f660ad80db04..e6f28a517182 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > @@ -7,9 +7,11 @@
> > > > >  #define __INTEL_DP_MST_H__
> > > > >  
> > > > >  struct intel_digital_port;
> > > > > +struct intel_encoder;
> > > > >  
> > > > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > > > *intel_dig_port, int conn_id);
> > > > >  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > > > > *intel_dig_port);
> > > > >  int intel_dp_mst_encoder_active_links(struct
> > > > > intel_digital_port
> > > > > *intel_dig_port);
> > > > > +enum transcoder intel_dp_mst_master_trans_get(struct
> > > > > intel_encoder
> > > > > *encoder);
> > > > >  
> > > > >  #endif /* __INTEL_DP_MST_H__ */
> > > > > -- 
> > > > > 2.24.0

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

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

* Re: [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-28 18:30             ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 18:30 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Thu, Nov 28, 2019 at 01:08:36AM +0000, Souza, Jose wrote:
> On Wed, 2019-11-27 at 21:24 +0200, Ville Syrjälä wrote:
> > On Tue, Nov 26, 2019 at 10:12:52PM +0000, Souza, Jose wrote:
> > > On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> > > > On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> > > > wrote:
> > > > > Disabling pipe/transcoder clock before power down sink could
> > > > > cause
> > > > > sink lost signal, causing it to trigger a hotplug to notify
> > > > > source
> > > > > that link signal was lost.
> > > > > 
> > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > @@ -3808,12 +3808,12 @@ static void
> > > > > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> > > > >  	enum phy phy = intel_port_to_phy(dev_priv, encoder-
> > > > > >port);
> > > > >  
> > > > >  	if (!is_mst) {
> > > > > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > > >  		/*
> > > > >  		 * Power down sink before disabling the port,
> > > > > otherwise
> > > > > we end
> > > > >  		 * up getting interrupts from the sink on
> > > > > detecting
> > > > > link loss.
> > > > >  		 */
> > > > >  		intel_dp_sink_dpms(intel_dp,
> > > > > DRM_MODE_DPMS_OFF);
> > > > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > > >  	}
> > > > 
> > > > The spec seems to say that we should do this after turning off
> > > > DDI_BUF_CTL on tgl+.
> > > 
> > > What step? I can't find any step talking about AUX DP_SET_POWER.
> > 
> > I was talking about DDI_BUF disable vs. transcoder clock disable.
> > 
> > > My understating is that we should power off sink before interfering
> > > in
> > > the mainlink signal otherwise sink could trigger hotplugs to notify
> > > source about link loss.
> > 
> > Pretty much. Nothing wrong with your patch for pre-tgl I think, but
> > for
> > tgl+ you didn't move the clock disable quite far enough to match the
> > bspec sequence.
> 
> Aaahh
> That is fixed patch 6 "drm/i915/display/tgl: Fix the order of the step
> to turn transcoder clock off" :D

Ah, should have kept on reading.

In that case this one is 
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
> > 
> > > > >  
> > > > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > > > -- 
> > > > > 2.24.0
> > > > > 
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock
@ 2019-11-28 18:30             ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 18:30 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Thu, Nov 28, 2019 at 01:08:36AM +0000, Souza, Jose wrote:
> On Wed, 2019-11-27 at 21:24 +0200, Ville Syrjälä wrote:
> > On Tue, Nov 26, 2019 at 10:12:52PM +0000, Souza, Jose wrote:
> > > On Tue, 2019-11-26 at 22:15 +0200, Ville Syrjälä wrote:
> > > > On Fri, Nov 22, 2019 at 04:54:56PM -0800, José Roberto de Souza
> > > > wrote:
> > > > > Disabling pipe/transcoder clock before power down sink could
> > > > > cause
> > > > > sink lost signal, causing it to trigger a hotplug to notify
> > > > > source
> > > > > that link signal was lost.
> > > > > 
> > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > index d2f0d393d3ee..7d3a6e3c7f57 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > @@ -3808,12 +3808,12 @@ static void
> > > > > intel_ddi_post_disable_dp(struct intel_encoder *encoder,
> > > > >  	enum phy phy = intel_port_to_phy(dev_priv, encoder-
> > > > > >port);
> > > > >  
> > > > >  	if (!is_mst) {
> > > > > -		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > > >  		/*
> > > > >  		 * Power down sink before disabling the port,
> > > > > otherwise
> > > > > we end
> > > > >  		 * up getting interrupts from the sink on
> > > > > detecting
> > > > > link loss.
> > > > >  		 */
> > > > >  		intel_dp_sink_dpms(intel_dp,
> > > > > DRM_MODE_DPMS_OFF);
> > > > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > > > >  	}
> > > > 
> > > > The spec seems to say that we should do this after turning off
> > > > DDI_BUF_CTL on tgl+.
> > > 
> > > What step? I can't find any step talking about AUX DP_SET_POWER.
> > 
> > I was talking about DDI_BUF disable vs. transcoder clock disable.
> > 
> > > My understating is that we should power off sink before interfering
> > > in
> > > the mainlink signal otherwise sink could trigger hotplugs to notify
> > > source about link loss.
> > 
> > Pretty much. Nothing wrong with your patch for pre-tgl I think, but
> > for
> > tgl+ you didn't move the clock disable quite far enough to match the
> > bspec sequence.
> 
> Aaahh
> That is fixed patch 6 "drm/i915/display/tgl: Fix the order of the step
> to turn transcoder clock off" :D

Ah, should have kept on reading.

In that case this one is 
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
> > 
> > > > >  
> > > > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > > > -- 
> > > > > 2.24.0
> > > > > 
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 5/7] drm/i915/display/mst: Move DPMS_OFF call to post_disable
@ 2019-11-28 18:31     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 18:31 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Lucas De Marchi

On Fri, Nov 22, 2019 at 04:54:57PM -0800, José Roberto de Souza wrote:
> Moving just to simplify handling as there is no change in behavior.

lgtm
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c    | 14 +++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 -
>  2 files changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 7d3a6e3c7f57..cfcaa7c81575 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3807,14 +3807,14 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  					  INTEL_OUTPUT_DP_MST);
>  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
>  
> -	if (!is_mst) {
> -		/*
> -		 * Power down sink before disabling the port, otherwise we end
> -		 * up getting interrupts from the sink on detecting link loss.
> -		 */
> -		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +	/*
> +	 * Power down sink before disabling the port, otherwise we end
> +	 * up getting interrupts from the sink on detecting link loss.
> +	 */
> +	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +
> +	if (!is_mst)
>  		intel_ddi_disable_pipe_clock(old_crtc_state);
> -	}
>  
>  	intel_disable_ddi_buf(encoder, old_crtc_state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 9731c3c1d3f2..94549848653a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -390,7 +390,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  
>  	intel_mst->connector = NULL;
>  	if (intel_dp->active_mst_links == 0) {
> -		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  		intel_dig_port->base.post_disable(&intel_dig_port->base,
>  						  old_crtc_state, NULL);
>  		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> -- 
> 2.24.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH 5/7] drm/i915/display/mst: Move DPMS_OFF call to post_disable
@ 2019-11-28 18:31     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 18:31 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Lucas De Marchi

On Fri, Nov 22, 2019 at 04:54:57PM -0800, José Roberto de Souza wrote:
> Moving just to simplify handling as there is no change in behavior.

lgtm
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c    | 14 +++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 -
>  2 files changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 7d3a6e3c7f57..cfcaa7c81575 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3807,14 +3807,14 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  					  INTEL_OUTPUT_DP_MST);
>  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
>  
> -	if (!is_mst) {
> -		/*
> -		 * Power down sink before disabling the port, otherwise we end
> -		 * up getting interrupts from the sink on detecting link loss.
> -		 */
> -		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +	/*
> +	 * Power down sink before disabling the port, otherwise we end
> +	 * up getting interrupts from the sink on detecting link loss.
> +	 */
> +	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +
> +	if (!is_mst)
>  		intel_ddi_disable_pipe_clock(old_crtc_state);
> -	}
>  
>  	intel_disable_ddi_buf(encoder, old_crtc_state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 9731c3c1d3f2..94549848653a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -390,7 +390,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  
>  	intel_mst->connector = NULL;
>  	if (intel_dp->active_mst_links == 0) {
> -		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  		intel_dig_port->base.post_disable(&intel_dig_port->base,
>  						  old_crtc_state, NULL);
>  		intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> -- 
> 2.24.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
@ 2019-11-28 18:40     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 18:40 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Fri, Nov 22, 2019 at 04:54:58PM -0800, José Roberto de Souza wrote:
> For TGL the step to turn off the transcoder clock was moved to after
> the complete shutdown of DDI. Only the MST slave transcoders should
> disable the clock before that.
> 
> BSpec: 49190
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c    |  9 ++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++++++---
>  2 files changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index cfcaa7c81575..aa0249333175 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3813,7 +3813,7 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  	 */
>  	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  
> -	if (!is_mst)
> +	if (INTEL_GEN(dev_priv) < 12 && !is_mst)
>  		intel_ddi_disable_pipe_clock(old_crtc_state);
>  
>  	intel_disable_ddi_buf(encoder, old_crtc_state);
> @@ -3826,6 +3826,13 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  		intel_display_power_put_unchecked(dev_priv,
>  						  dig_port->ddi_io_power_domain);
>  
> +	/*
> +	 * From TGL BSpec "If single stream or multi-stream master transcoder:
> +	 * Configure Transcoder Clock select to direct no clock to the
> +	 * transcoder"
> +	 */

Not really convinced these comments add anything the code isn't already saying.

> +	if (INTEL_GEN(dev_priv) >= 12)
> +		intel_ddi_disable_pipe_clock(old_crtc_state);

That's much later than the bspec sequence suggests.

>  	intel_ddi_clk_disable(encoder);
>  	tgl_clear_psr2_transcoder_exitline(old_crtc_state);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 94549848653a..53afe3e179f7 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -369,8 +369,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = &intel_dig_port->dp;
>  	struct intel_connector *connector =
>  		to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>  
> -	intel_ddi_disable_pipe_clock(old_crtc_state);
> +	intel_dp->active_mst_links--;
> +
> +	/*
> +	 * From TGL BSpec "If multi-stream slave transcoder: Configure
> +	 * Transcoder Clock Select to direct no clock to the transcoder"
> +	 *
> +	 * From older GENs BSpec "Configure Transcoder Clock Select to direct
> +	 * no clock to the transcoder"
> +	 */
> +	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)

Maybe we should add 'last_mst_stream' to mirror the 'first_mst_stream'
in the enable code?

> +		intel_ddi_disable_pipe_clock(old_crtc_state);
>  
>  	/* this can fail */
>  	drm_dp_check_act_status(&intel_dp->mst_mgr);
> @@ -386,8 +397,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
>  				     false);
>  
> -	intel_dp->active_mst_links--;
> -
>  	intel_mst->connector = NULL;
>  	if (intel_dp->active_mst_links == 0) {
>  		intel_dig_port->base.post_disable(&intel_dig_port->base,
> -- 
> 2.24.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
@ 2019-11-28 18:40     ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-11-28 18:40 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Fri, Nov 22, 2019 at 04:54:58PM -0800, José Roberto de Souza wrote:
> For TGL the step to turn off the transcoder clock was moved to after
> the complete shutdown of DDI. Only the MST slave transcoders should
> disable the clock before that.
> 
> BSpec: 49190
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c    |  9 ++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++++++---
>  2 files changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index cfcaa7c81575..aa0249333175 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3813,7 +3813,7 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  	 */
>  	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  
> -	if (!is_mst)
> +	if (INTEL_GEN(dev_priv) < 12 && !is_mst)
>  		intel_ddi_disable_pipe_clock(old_crtc_state);
>  
>  	intel_disable_ddi_buf(encoder, old_crtc_state);
> @@ -3826,6 +3826,13 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
>  		intel_display_power_put_unchecked(dev_priv,
>  						  dig_port->ddi_io_power_domain);
>  
> +	/*
> +	 * From TGL BSpec "If single stream or multi-stream master transcoder:
> +	 * Configure Transcoder Clock select to direct no clock to the
> +	 * transcoder"
> +	 */

Not really convinced these comments add anything the code isn't already saying.

> +	if (INTEL_GEN(dev_priv) >= 12)
> +		intel_ddi_disable_pipe_clock(old_crtc_state);

That's much later than the bspec sequence suggests.

>  	intel_ddi_clk_disable(encoder);
>  	tgl_clear_psr2_transcoder_exitline(old_crtc_state);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 94549848653a..53afe3e179f7 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -369,8 +369,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = &intel_dig_port->dp;
>  	struct intel_connector *connector =
>  		to_intel_connector(old_conn_state->connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>  
> -	intel_ddi_disable_pipe_clock(old_crtc_state);
> +	intel_dp->active_mst_links--;
> +
> +	/*
> +	 * From TGL BSpec "If multi-stream slave transcoder: Configure
> +	 * Transcoder Clock Select to direct no clock to the transcoder"
> +	 *
> +	 * From older GENs BSpec "Configure Transcoder Clock Select to direct
> +	 * no clock to the transcoder"
> +	 */
> +	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)

Maybe we should add 'last_mst_stream' to mirror the 'first_mst_stream'
in the enable code?

> +		intel_ddi_disable_pipe_clock(old_crtc_state);
>  
>  	/* this can fail */
>  	drm_dp_check_act_status(&intel_dp->mst_mgr);
> @@ -386,8 +397,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
>  				     false);
>  
> -	intel_dp->active_mst_links--;
> -
>  	intel_mst->connector = NULL;
>  	if (intel_dp->active_mst_links == 0) {
>  		intel_dig_port->base.post_disable(&intel_dig_port->base,
> -- 
> 2.24.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-12-02 22:03               ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-12-02 22:03 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de
> > > > > Souza
> > > > > wrote:
> > > > > > On TGL the blending of all the streams have moved from DDI
> > > > > > to
> > > > > > transcoder, so now every transcoder working over the same
> > > > > > MST
> > > > > > port
> > > > > > must
> > > > > > send its stream to a master transcoder and master will send
> > > > > > to
> > > > > > DDI
> > > > > > respecting the time slots.
> > > > > > 
> > > > > > A previous approach was using the lowest pipe/transcoder as
> > > > > > master
> > > > > > transcoder but as the comment in
> > > > > > skl_commit_modeset_enables()
> > > > > > states,
> > > > > > that is not always true.
> > > > > > 
> > > > > > So here promoting the first pipe/transcoder of the stream
> > > > > > as
> > > > > > master.
> > > > > > That caused several other problems as during the commit
> > > > > > phase
> > > > > > the
> > > > > > state computed should not be changed.
> > > > > > 
> > > > > > So the master transcoder is store into intel_dp and the
> > > > > > modeset
> > > > > > in
> > > > > > slave pipes/transcoders is forced using
> > > > > > mst_master_trans_pending.
> > > > > > 
> > > > > > v2:
> > > > > > - added missing config compute to trigger fullmodeset in
> > > > > > slave
> > > > > > transcoders
> > > > > > 
> > > > > > BSpec: 50493
> > > > > > BSpec: 49190
> > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58
> > > > > > ++++++-
> > > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > > +++++++++++++++++-
> > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > @@ -35,6 +35,7 @@
> > > > > >  #include "intel_display_types.h"
> > > > > >  #include "intel_dp.h"
> > > > > >  #include "intel_dp_link_training.h"
> > > > > > +#include "intel_dp_mst.h"
> > > > > >  #include "intel_dpio_phy.h"
> > > > > >  #include "intel_dsi.h"
> > > > > >  #include "intel_fifo_underrun.h"
> > > > > > @@ -1903,8 +1904,13 @@
> > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > struct intel_crtc_state *crtc_state)
> > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > >  
> > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > -			temp |=
> > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > +			enum transcoder master;
> > > > > > +
> > > > > > +			master =
> > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > 
> > > > > Why isn't that just stored in the crtc state like everything
> > > > > else?
> > > > > 
> > > > > I'm thinking we should maybe do it just like port sync and
> > > > > have
> > > > > both
> > > > > master + slave_mask. That way it should be pretty trivial to
> > > > > add
> > > > > all
> > > > > the relevant crtcs to the state when needed.
> > > > 
> > > > I guess port sync is not doing the right thing and it could
> > > > cause
> > > > underruns.
> > > > When it is going to enable the master CRTC of the port sync it
> > > > forcibly
> > > > enables the slave first, what could cause underruns because of
> > > > overlap
> > > > in ddb allocations(that is what I understood from the comment
> > > > in
> > > > skl_commit_modeset_enables()).
> > > 
> > > Not necessarily just underruns but even a system hang. The fix
> > > should
> > > be
> > > a trivial "check the slave for ddb overlap as well", but
> > > apparently I
> > > failed at convicing people to do that.
> > > 
> > > I've actually been pondering about decoupling the plane updates
> > > from
> > > the crtc enable stuff entirely. At least theoretically crtc
> > > enable
> > > should be able to excute in any order as long we don't enable any
> > > new planes.
> > > 
> > > But none of that really matters for the discussion at hand.
> > > Though
> > > there are other problems with the port sync stuff that would need
> > > to be handled better. Eg. I think it now adds both crtcs to the
> > > state
> > > always which is going to cut the fps in half. Also the place
> > > where
> > > it does that stuff is rather suspicious. All that stuff should be
> > > somewhere a bit higher up IMO.
> > > 
> > > > So for MST we only know who is the master in the commit phase
> > > > and
> > > > at
> > > > this point we should not modify the computed state.
> > > 
> > > I'm not suggesting modifying anything during commit phase. I
> > > think
> > > you are effectiely doing that right now by stuffing that mst
> > > master
> > > transcoder into intel_dp.
> > 
> > Sorry, I still don't get what approach are you suggesting here.
> > 
> > If we can't modify the state in the commit phase, adding
> > mst_master_transcoder in the CRTC state will not be possible while
> > respecting the order imposed by ddb allocations.
> 
> The ddb allocation ordering only comes into play when there are
> already active pipes. It should always be possible to not enable
> the slaves until the master has been shuffled into place in the 
> ddb and enabled.

This sounds contradictory to what you answered here: 
https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html

Will need to some testing to get the steps but I was able consistent to
get to state were doing a full modeset in pipe A(mst master) caused the
pipe B(mst slave) to enabled first because of the ddb allocations.

So can I or not do something like port sync does? And force the enable
of master before the slaves? If possible, the comment in
skl_commit_modeset_enables() will need some changes.


> 
> > > > > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > > > > +			temp |=
> > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > > > > +		}
> > > > > >  	} else {
> > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > index 801b975c7d39..35a59108194e 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -46,6 +46,7 @@
> > > > > >  #include "display/intel_crt.h"
> > > > > >  #include "display/intel_ddi.h"
> > > > > >  #include "display/intel_dp.h"
> > > > > > +#include "display/intel_dp_mst.h"
> > > > > >  #include "display/intel_dsi.h"
> > > > > >  #include "display/intel_dvo.h"
> > > > > >  #include "display/intel_gmbus.h"
> > > > > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const
> > > > > > struct
> > > > > > intel_atomic_state *state,
> > > > > >  	return encoder;
> > > > > >  }
> > > > > >  
> > > > > > +/*
> > > > > > + * Finds the encoder associated with the given CRTC. This
> > > > > > can
> > > > > > only
> > > > > > be
> > > > > > + * used when we know that the CRTC isn't feeding multiple
> > > > > > encoders!
> > > > > > + */
> > > > > > +static struct intel_encoder *
> > > > > > +intel_get_crtc_old_encoder(const struct intel_atomic_state
> > > > > > *state,
> > > > > > +			   const struct intel_crtc_state
> > > > > > *crtc_state)
> > > > > > +{
> > > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > > > uapi.crtc);
> > > > > > +	const struct drm_connector_state *connector_state;
> > > > > > +	const struct drm_connector *connector;
> > > > > > +	struct intel_encoder *encoder = NULL;
> > > > > > +	int num_encoders = 0;
> > > > > > +	int i;
> > > > > > +
> > > > > > +	for_each_old_connector_in_state(&state->base,
> > > > > > connector,
> > > > > > +					connector_state, i) {
> > > > > > +		if (connector_state->crtc != &crtc->base)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		encoder = to_intel_encoder(connector_state-
> > > > > > > best_encoder);
> > > > > > +		num_encoders++;
> > > > > > +	}
> > > > > > +
> > > > > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > > > > +	     num_encoders, pipe_name(crtc->pipe));
> > > > > > +
> > > > > > +	return encoder;
> > > > > > +}
> > > > > 
> > > > > Argh. I was hoping to kill the other one of these. Got it
> > > > > down to
> > > > > 1
> > > > > remaining user now I think.
> > > > > 
> > > > > > +
> > > > > >  /*
> > > > > >   * Enable PCH resources required for PCH ports:
> > > > > >   *   - PCH PLLs
> > > > > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const
> > > > > > struct
> > > > > > intel_crtc_state *current_config,
> > > > > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > > > > >  #undef PIPE_CONF_QUIRK
> > > > > >  
> > > > > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > > > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > > > > mst_master_trans\n",
> > > > > > +			      crtc->base.base.id, crtc-
> > > > > > > base.name);
> > > > > > +		ret = false;
> > > > > > +	}
> > > > > > +
> > > > > >  	return ret;
> > > > > >  }
> > > > > >  
> > > > > > @@ -14449,22 +14486,35 @@ static void
> > > > > > intel_commit_modeset_disables(struct intel_atomic_state
> > > > > > *state)
> > > > > >  	struct intel_crtc *crtc;
> > > > > >  	int i;
> > > > > >  
> > > > > > -	/* Only disable port sync slaves */
> > > > > > +	/* Only disable port sync and MST slaves */
> > > > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > > > old_crtc_state,
> > > > > >  					    new_crtc_state, i)
> > > > > > {
> > > > > >  		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > > > > active)
> > > > > >  			continue;
> > > > > >  
> > > > > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > > > > +		    !intel_crtc_has_type(old_crtc_state,
> > > > > > INTEL_OUTPUT_DP_MST))
> > > > > > +			continue;
> > > > > > +
> > > > > >  		/* In case of Transcoder port Sync master slave
> > > > > > CRTCs
> > > > > > can be
> > > > > >  		 * assigned in any order and we need to make
> > > > > > sure that
> > > > > >  		 * slave CRTCs are disabled first and then
> > > > > > master CRTC
> > > > > > since
> > > > > >  		 * Slave vblanks are masked till Master
> > > > > > Vblanks.
> > > > > >  		 */
> > > > > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > > > > -			continue;
> > > > > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > > > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > > > > +		    is_trans_port_sync_master(new_crtc_state))
> > > > > >  			continue;
> > > > > >  
> > > > > > +		if (intel_crtc_has_type(old_crtc_state,
> > > > > > INTEL_OUTPUT_DP_MST)) {
> > > > > > +			struct intel_encoder *encoder;
> > > > > > +
> > > > > > +			encoder =
> > > > > > intel_get_crtc_old_encoder(state,
> > > > > > +							     ol
> > > > > > d_crtc_s
> > > > > > tate);
> > > > > > +			if
> > > > > > (intel_dp_mst_master_trans_get(encoder) ==
> > > > > > +			    old_crtc_state->cpu_transcoder)
> > > > > > +				continue;
> > > > > > +		}
> > > > > > +
> > > > > >  		intel_pre_plane_update(old_crtc_state,
> > > > > > new_crtc_state);
> > > > > >  		intel_old_crtc_state_disables(state,
> > > > > > old_crtc_state,
> > > > > >  					      new_crtc_state,
> > > > > > crtc);
> > > > > > diff --git
> > > > > > a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > index 83ea04149b77..23d747cdca64 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > > > > >  	/* Pointer to master transcoder in case of tiled
> > > > > > displays */
> > > > > >  	enum transcoder master_transcoder;
> > > > > >  
> > > > > > +	bool mst_master_trans_pending;
> > > > > > +
> > > > > >  	/* Bitmask to indicate slaves attached */
> > > > > >  	u8 sync_mode_slaves_mask;
> > > > > >  };
> > > > > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > > > > >  	bool can_mst; /* this port supports mst */
> > > > > >  	bool is_mst;
> > > > > >  	int active_mst_links;
> > > > > > +	enum transcoder mst_master_transcoder; /* Only used in
> > > > > > TGL+ */
> > > > > >  
> > > > > >  	/*
> > > > > >  	 * DP_TP_* registers may be either on port or
> > > > > > transcoder
> > > > > > register space.
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > index 3123958e2081..ceff6901451a 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > > > > intel_digital_port *intel_dig_port,
> > > > > >  	intel_dp->reset_link_params = true;
> > > > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > > > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > > > > >  
> > > > > >  	/* Preserve the current hw state. */
> > > > > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > index f8a350359346..9731c3c1d3f2 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > @@ -87,6 +87,47 @@ static int
> > > > > > intel_dp_mst_compute_link_config(struct intel_encoder
> > > > > > *encoder,
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  
> > > > > > +static int
> > > > > > +intel_dp_mst_master_trans_compute(struct intel_encoder
> > > > > > *encoder,
> > > > > > +				  struct intel_crtc_state
> > > > > > *pipe_config,
> > > > > > +				  struct drm_connector_state
> > > > > > *conn_state)
> > > > > > +{
> > > > > > +	struct intel_atomic_state *state =
> > > > > > to_intel_atomic_state(pipe_config->uapi.state);
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > > > > base.dev);
> > > > > > +	struct intel_crtc_state *new_crtc_state;
> > > > > > +	struct intel_crtc *crtc;
> > > > > > +	enum transcoder master;
> > > > > > +	int i;
> > > > > > +
> > > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	if (!conn_state->crtc)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > > > > +	if (master == INVALID_TRANSCODER)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	for_each_new_intel_crtc_in_state(state, crtc,
> > > > > > new_crtc_state,
> > > > > > i) {
> > > > > > +		/*
> > > > > > +		 * cpu_transcoder is set when computing CRTC
> > > > > > state if
> > > > > > it will
> > > > > > +		 * be disabled it will not happen, so checking
> > > > > > pipe
> > > > > > instead
> > > > > > +		 */
> > > > > > +		if (crtc->pipe != (enum pipe)master)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		if
> > > > > > (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > > > > > uapi) &&
> > > > > > +		    new_crtc_state->uapi.enable)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		pipe_config->mst_master_trans_pending = true;
> > > > > > +		break;
> > > > > > +	}
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > >  static int intel_dp_mst_compute_config(struct
> > > > > > intel_encoder
> > > > > > *encoder,
> > > > > >  				       struct intel_crtc_state
> > > > > > *pipe_config,
> > > > > >  				       struct
> > > > > > drm_connector_state
> > > > > > *conn_state)
> > > > > > @@ -154,6 +195,95 @@ static int
> > > > > > intel_dp_mst_compute_config(struct
> > > > > > intel_encoder *encoder,
> > > > > >  
> > > > > >  	intel_ddi_compute_min_voltage_level(dev_priv,
> > > > > > pipe_config);
> > > > > >  
> > > > > > +	ret = intel_dp_mst_master_trans_compute(encoder,
> > > > > > pipe_config,
> > > > > > +						conn_state);
> > > > > > +	if (ret)
> > > > > > +		return ret;
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static int
> > > > > > +intel_dp_mst_atomic_master_trans_check(struct
> > > > > > drm_connector
> > > > > > *connector,
> > > > > > +				       struct drm_atomic_state
> > > > > > *state)
> > > > > > +{
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > > > > > dev);
> > > > > > +	struct intel_connector *intel_conn =
> > > > > > to_intel_connector(connector);
> > > > > > +	struct drm_connector_state *new_conn_state,
> > > > > > *old_conn_state;
> > > > > > +	struct drm_connector_list_iter conn_list_iter;
> > > > > > +	struct intel_crtc_state *intel_crtc_state;
> > > > > > +	struct drm_crtc_state *crtc_state;
> > > > > > +	struct drm_connector *conn_iter;
> > > > > > +
> > > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	new_conn_state =
> > > > > > drm_atomic_get_new_connector_state(state,
> > > > > > connector);
> > > > > > +	old_conn_state =
> > > > > > drm_atomic_get_old_connector_state(state,
> > > > > > connector);
> > > > > > +
> > > > > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * 3 cases that needs be handled here:
> > > > > > +	 * - connector going from disabled to enabled
> > > > > > +	 * - connector going from enabled to disabled:
> > > > > > +	 * if this transcoder was the master, all slaves needs
> > > > > > a
> > > > > > modeset
> > > > > > +	 * - connector going from enabled to enabled but it
> > > > > > needs a
> > > > > > modeset:
> > > > > > +	 * if this transcoder was the master, all slaves also
> > > > > > needs a
> > > > > > modeset
> > > > > > +	 */
> > > > > > +
> > > > > > +	/* disabled -> enabled */
> > > > > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	/* enabled -> enabled(modeset)? */
> > > > > > +	if (new_conn_state->crtc) {
> > > > > > +		crtc_state =
> > > > > > drm_atomic_get_new_crtc_state(state,
> > > > > > new_conn_state->crtc);
> > > > > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > > > > +			return 0;
> > > > > > +	}
> > > > > > +
> > > > > > +	/* handling enabled -> enabled(modeset) and enabled ->
> > > > > > disabled
> > > > > > */
> > > > > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > > > > old_conn_state->crtc);
> > > > > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > > > > +
> > > > > > +	/* If not master, nothing else needs to be handled */
> > > > > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > > > > +	    intel_crtc_state->cpu_transcoder)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	/* Is master, mark all other CRTCs as needing a modeset
> > > > > > */
> > > > > > +	drm_connector_list_iter_begin(state->dev,
> > > > > > &conn_list_iter);
> > > > > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter)
> > > > > > {
> > > > > > +		struct intel_connector *intel_conn_iter;
> > > > > > +		struct drm_connector_state *conn_iter_state;
> > > > > > +
> > > > > > +		intel_conn_iter =
> > > > > > to_intel_connector(conn_iter);
> > > > > > +		if (intel_conn_iter->mst_port != intel_conn-
> > > > > > > mst_port)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		conn_iter_state =
> > > > > > drm_atomic_get_connector_state(state,
> > > > > > +								
> > > > > >  conn_i
> > > > > > ter);
> > > > > > +		if (IS_ERR(conn_iter_state)) {
> > > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > > iter);
> > > > > > +			return PTR_ERR(conn_iter_state);
> > > > > > +		}
> > > > > > +
> > > > > > +		if (!conn_iter_state->crtc)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > > > > conn_iter_state->crtc);
> > > > > > +		if (IS_ERR(crtc_state)) {
> > > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > > iter);
> > > > > > +			return PTR_ERR(conn_iter_state);
> > > > > > +		}
> > > > > > +
> > > > > > +		intel_crtc_state =
> > > > > > to_intel_crtc_state(crtc_state);
> > > > > > +		crtc_state->mode_changed = true;
> > > > > > +	}
> > > > > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > > > > +
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  
> > > > > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct
> > > > > > drm_connector
> > > > > > *connector,
> > > > > >  	if (ret)
> > > > > >  		return ret;
> > > > > >  
> > > > > > +	ret = intel_dp_mst_atomic_master_trans_check(connector,
> > > > > > state);
> > > > > > +	if (ret)
> > > > > > +		return ret;
> > > > > > +
> > > > > >  	if (!old_conn_state->crtc)
> > > > > >  		return 0;
> > > > > >  
> > > > > > @@ -259,6 +393,7 @@ static void
> > > > > > intel_mst_post_disable_dp(struct
> > > > > > intel_encoder *encoder,
> > > > > >  		intel_dp_sink_dpms(intel_dp,
> > > > > > DRM_MODE_DPMS_OFF);
> > > > > >  		intel_dig_port-
> > > > > > > base.post_disable(&intel_dig_port-
> > > > > > > base,
> > > > > >  						  old_crtc_stat
> > > > > > e,
> > > > > > NULL);
> > > > > > +		intel_dp->mst_master_transcoder =
> > > > > > INVALID_TRANSCODER;
> > > > > >  	}
> > > > > >  
> > > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > > > active_mst_links);
> > > > > > @@ -314,8 +449,11 @@ static void
> > > > > > intel_mst_pre_enable_dp(struct
> > > > > > intel_encoder *encoder,
> > > > > >  
> > > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > > > active_mst_links);
> > > > > >  
> > > > > > -	if (first_mst_stream)
> > > > > > +	if (first_mst_stream) {
> > > > > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > > > > INVALID_TRANSCODER);
> > > > > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > > > > > cpu_transcoder;
> > > > > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > > > > +	}
> > > > > >  
> > > > > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr,
> > > > > > connector-
> > > > > > > port, true);
> > > > > >  
> > > > > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > > > > intel_digital_port *intel_dig_port)
> > > > > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > > > > >  	/* encoders will get killed by normal cleanup */
> > > > > >  }
> > > > > > +
> > > > > > +enum transcoder
> > > > > > +intel_dp_mst_master_trans_get(struct intel_encoder
> > > > > > *encoder)
> > > > > > +{
> > > > > > +	struct intel_dp_mst_encoder *intel_mst =
> > > > > > enc_to_mst(&encoder-
> > > > > > > base);
> > > > > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > > > > +
> > > > > > +	return intel_dp->mst_master_transcoder;
> > > > > > +}
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > index f660ad80db04..e6f28a517182 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > @@ -7,9 +7,11 @@
> > > > > >  #define __INTEL_DP_MST_H__
> > > > > >  
> > > > > >  struct intel_digital_port;
> > > > > > +struct intel_encoder;
> > > > > >  
> > > > > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > > > > *intel_dig_port, int conn_id);
> > > > > >  void intel_dp_mst_encoder_cleanup(struct
> > > > > > intel_digital_port
> > > > > > *intel_dig_port);
> > > > > >  int intel_dp_mst_encoder_active_links(struct
> > > > > > intel_digital_port
> > > > > > *intel_dig_port);
> > > > > > +enum transcoder intel_dp_mst_master_trans_get(struct
> > > > > > intel_encoder
> > > > > > *encoder);
> > > > > >  
> > > > > >  #endif /* __INTEL_DP_MST_H__ */
> > > > > > -- 
> > > > > > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
@ 2019-12-02 22:03               ` Souza, Jose
  0 siblings, 0 replies; 65+ messages in thread
From: Souza, Jose @ 2019-12-02 22:03 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de
> > > > > Souza
> > > > > wrote:
> > > > > > On TGL the blending of all the streams have moved from DDI
> > > > > > to
> > > > > > transcoder, so now every transcoder working over the same
> > > > > > MST
> > > > > > port
> > > > > > must
> > > > > > send its stream to a master transcoder and master will send
> > > > > > to
> > > > > > DDI
> > > > > > respecting the time slots.
> > > > > > 
> > > > > > A previous approach was using the lowest pipe/transcoder as
> > > > > > master
> > > > > > transcoder but as the comment in
> > > > > > skl_commit_modeset_enables()
> > > > > > states,
> > > > > > that is not always true.
> > > > > > 
> > > > > > So here promoting the first pipe/transcoder of the stream
> > > > > > as
> > > > > > master.
> > > > > > That caused several other problems as during the commit
> > > > > > phase
> > > > > > the
> > > > > > state computed should not be changed.
> > > > > > 
> > > > > > So the master transcoder is store into intel_dp and the
> > > > > > modeset
> > > > > > in
> > > > > > slave pipes/transcoders is forced using
> > > > > > mst_master_trans_pending.
> > > > > > 
> > > > > > v2:
> > > > > > - added missing config compute to trigger fullmodeset in
> > > > > > slave
> > > > > > transcoders
> > > > > > 
> > > > > > BSpec: 50493
> > > > > > BSpec: 49190
> > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58
> > > > > > ++++++-
> > > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > > +++++++++++++++++-
> > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > @@ -35,6 +35,7 @@
> > > > > >  #include "intel_display_types.h"
> > > > > >  #include "intel_dp.h"
> > > > > >  #include "intel_dp_link_training.h"
> > > > > > +#include "intel_dp_mst.h"
> > > > > >  #include "intel_dpio_phy.h"
> > > > > >  #include "intel_dsi.h"
> > > > > >  #include "intel_fifo_underrun.h"
> > > > > > @@ -1903,8 +1904,13 @@
> > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > struct intel_crtc_state *crtc_state)
> > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > >  
> > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > -			temp |=
> > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > +			enum transcoder master;
> > > > > > +
> > > > > > +			master =
> > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > 
> > > > > Why isn't that just stored in the crtc state like everything
> > > > > else?
> > > > > 
> > > > > I'm thinking we should maybe do it just like port sync and
> > > > > have
> > > > > both
> > > > > master + slave_mask. That way it should be pretty trivial to
> > > > > add
> > > > > all
> > > > > the relevant crtcs to the state when needed.
> > > > 
> > > > I guess port sync is not doing the right thing and it could
> > > > cause
> > > > underruns.
> > > > When it is going to enable the master CRTC of the port sync it
> > > > forcibly
> > > > enables the slave first, what could cause underruns because of
> > > > overlap
> > > > in ddb allocations(that is what I understood from the comment
> > > > in
> > > > skl_commit_modeset_enables()).
> > > 
> > > Not necessarily just underruns but even a system hang. The fix
> > > should
> > > be
> > > a trivial "check the slave for ddb overlap as well", but
> > > apparently I
> > > failed at convicing people to do that.
> > > 
> > > I've actually been pondering about decoupling the plane updates
> > > from
> > > the crtc enable stuff entirely. At least theoretically crtc
> > > enable
> > > should be able to excute in any order as long we don't enable any
> > > new planes.
> > > 
> > > But none of that really matters for the discussion at hand.
> > > Though
> > > there are other problems with the port sync stuff that would need
> > > to be handled better. Eg. I think it now adds both crtcs to the
> > > state
> > > always which is going to cut the fps in half. Also the place
> > > where
> > > it does that stuff is rather suspicious. All that stuff should be
> > > somewhere a bit higher up IMO.
> > > 
> > > > So for MST we only know who is the master in the commit phase
> > > > and
> > > > at
> > > > this point we should not modify the computed state.
> > > 
> > > I'm not suggesting modifying anything during commit phase. I
> > > think
> > > you are effectiely doing that right now by stuffing that mst
> > > master
> > > transcoder into intel_dp.
> > 
> > Sorry, I still don't get what approach are you suggesting here.
> > 
> > If we can't modify the state in the commit phase, adding
> > mst_master_transcoder in the CRTC state will not be possible while
> > respecting the order imposed by ddb allocations.
> 
> The ddb allocation ordering only comes into play when there are
> already active pipes. It should always be possible to not enable
> the slaves until the master has been shuffled into place in the 
> ddb and enabled.

This sounds contradictory to what you answered here: 
https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html

Will need to some testing to get the steps but I was able consistent to
get to state were doing a full modeset in pipe A(mst master) caused the
pipe B(mst slave) to enabled first because of the ddb allocations.

So can I or not do something like port sync does? And force the enable
of master before the slaves? If possible, the comment in
skl_commit_modeset_enables() will need some changes.


> 
> > > > > > +			WARN_ON(master == INVALID_TRANSCODER);
> > > > > > +			temp |=
> > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(master);
> > > > > > +		}
> > > > > >  	} else {
> > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
> > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > index 801b975c7d39..35a59108194e 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -46,6 +46,7 @@
> > > > > >  #include "display/intel_crt.h"
> > > > > >  #include "display/intel_ddi.h"
> > > > > >  #include "display/intel_dp.h"
> > > > > > +#include "display/intel_dp_mst.h"
> > > > > >  #include "display/intel_dsi.h"
> > > > > >  #include "display/intel_dvo.h"
> > > > > >  #include "display/intel_gmbus.h"
> > > > > > @@ -5365,6 +5366,36 @@ intel_get_crtc_new_encoder(const
> > > > > > struct
> > > > > > intel_atomic_state *state,
> > > > > >  	return encoder;
> > > > > >  }
> > > > > >  
> > > > > > +/*
> > > > > > + * Finds the encoder associated with the given CRTC. This
> > > > > > can
> > > > > > only
> > > > > > be
> > > > > > + * used when we know that the CRTC isn't feeding multiple
> > > > > > encoders!
> > > > > > + */
> > > > > > +static struct intel_encoder *
> > > > > > +intel_get_crtc_old_encoder(const struct intel_atomic_state
> > > > > > *state,
> > > > > > +			   const struct intel_crtc_state
> > > > > > *crtc_state)
> > > > > > +{
> > > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > > > uapi.crtc);
> > > > > > +	const struct drm_connector_state *connector_state;
> > > > > > +	const struct drm_connector *connector;
> > > > > > +	struct intel_encoder *encoder = NULL;
> > > > > > +	int num_encoders = 0;
> > > > > > +	int i;
> > > > > > +
> > > > > > +	for_each_old_connector_in_state(&state->base,
> > > > > > connector,
> > > > > > +					connector_state, i) {
> > > > > > +		if (connector_state->crtc != &crtc->base)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		encoder = to_intel_encoder(connector_state-
> > > > > > > best_encoder);
> > > > > > +		num_encoders++;
> > > > > > +	}
> > > > > > +
> > > > > > +	WARN(num_encoders != 1, "%d encoders for pipe %c\n",
> > > > > > +	     num_encoders, pipe_name(crtc->pipe));
> > > > > > +
> > > > > > +	return encoder;
> > > > > > +}
> > > > > 
> > > > > Argh. I was hoping to kill the other one of these. Got it
> > > > > down to
> > > > > 1
> > > > > remaining user now I think.
> > > > > 
> > > > > > +
> > > > > >  /*
> > > > > >   * Enable PCH resources required for PCH ports:
> > > > > >   *   - PCH PLLs
> > > > > > @@ -13365,6 +13396,12 @@ intel_pipe_config_compare(const
> > > > > > struct
> > > > > > intel_crtc_state *current_config,
> > > > > >  #undef PIPE_CONF_CHECK_COLOR_LUT
> > > > > >  #undef PIPE_CONF_QUIRK
> > > > > >  
> > > > > > +	if (fastset && pipe_config->mst_master_trans_pending) {
> > > > > > +		DRM_DEBUG_KMS("[CRTC:%d:%s] fastset mismatch in
> > > > > > mst_master_trans\n",
> > > > > > +			      crtc->base.base.id, crtc-
> > > > > > > base.name);
> > > > > > +		ret = false;
> > > > > > +	}
> > > > > > +
> > > > > >  	return ret;
> > > > > >  }
> > > > > >  
> > > > > > @@ -14449,22 +14486,35 @@ static void
> > > > > > intel_commit_modeset_disables(struct intel_atomic_state
> > > > > > *state)
> > > > > >  	struct intel_crtc *crtc;
> > > > > >  	int i;
> > > > > >  
> > > > > > -	/* Only disable port sync slaves */
> > > > > > +	/* Only disable port sync and MST slaves */
> > > > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc,
> > > > > > old_crtc_state,
> > > > > >  					    new_crtc_state, i)
> > > > > > {
> > > > > >  		if (!needs_modeset(new_crtc_state) || !crtc-
> > > > > > > active)
> > > > > >  			continue;
> > > > > >  
> > > > > > +		if (!is_trans_port_sync_mode(new_crtc_state) &&
> > > > > > +		    !intel_crtc_has_type(old_crtc_state,
> > > > > > INTEL_OUTPUT_DP_MST))
> > > > > > +			continue;
> > > > > > +
> > > > > >  		/* In case of Transcoder port Sync master slave
> > > > > > CRTCs
> > > > > > can be
> > > > > >  		 * assigned in any order and we need to make
> > > > > > sure that
> > > > > >  		 * slave CRTCs are disabled first and then
> > > > > > master CRTC
> > > > > > since
> > > > > >  		 * Slave vblanks are masked till Master
> > > > > > Vblanks.
> > > > > >  		 */
> > > > > > -		if (!is_trans_port_sync_mode(old_crtc_state))
> > > > > > -			continue;
> > > > > > -		if (is_trans_port_sync_master(old_crtc_state))
> > > > > > +		if (is_trans_port_sync_mode(new_crtc_state) &&
> > > > > > +		    is_trans_port_sync_master(new_crtc_state))
> > > > > >  			continue;
> > > > > >  
> > > > > > +		if (intel_crtc_has_type(old_crtc_state,
> > > > > > INTEL_OUTPUT_DP_MST)) {
> > > > > > +			struct intel_encoder *encoder;
> > > > > > +
> > > > > > +			encoder =
> > > > > > intel_get_crtc_old_encoder(state,
> > > > > > +							     ol
> > > > > > d_crtc_s
> > > > > > tate);
> > > > > > +			if
> > > > > > (intel_dp_mst_master_trans_get(encoder) ==
> > > > > > +			    old_crtc_state->cpu_transcoder)
> > > > > > +				continue;
> > > > > > +		}
> > > > > > +
> > > > > >  		intel_pre_plane_update(old_crtc_state,
> > > > > > new_crtc_state);
> > > > > >  		intel_old_crtc_state_disables(state,
> > > > > > old_crtc_state,
> > > > > >  					      new_crtc_state,
> > > > > > crtc);
> > > > > > diff --git
> > > > > > a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > index 83ea04149b77..23d747cdca64 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > @@ -1052,6 +1052,8 @@ struct intel_crtc_state {
> > > > > >  	/* Pointer to master transcoder in case of tiled
> > > > > > displays */
> > > > > >  	enum transcoder master_transcoder;
> > > > > >  
> > > > > > +	bool mst_master_trans_pending;
> > > > > > +
> > > > > >  	/* Bitmask to indicate slaves attached */
> > > > > >  	u8 sync_mode_slaves_mask;
> > > > > >  };
> > > > > > @@ -1284,6 +1286,7 @@ struct intel_dp {
> > > > > >  	bool can_mst; /* this port supports mst */
> > > > > >  	bool is_mst;
> > > > > >  	int active_mst_links;
> > > > > > +	enum transcoder mst_master_transcoder; /* Only used in
> > > > > > TGL+ */
> > > > > >  
> > > > > >  	/*
> > > > > >  	 * DP_TP_* registers may be either on port or
> > > > > > transcoder
> > > > > > register space.
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > index 3123958e2081..ceff6901451a 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > @@ -7424,6 +7424,7 @@ intel_dp_init_connector(struct
> > > > > > intel_digital_port *intel_dig_port,
> > > > > >  	intel_dp->reset_link_params = true;
> > > > > >  	intel_dp->pps_pipe = INVALID_PIPE;
> > > > > >  	intel_dp->active_pipe = INVALID_PIPE;
> > > > > > +	intel_dp->mst_master_transcoder = INVALID_TRANSCODER;
> > > > > >  
> > > > > >  	/* Preserve the current hw state. */
> > > > > >  	intel_dp->DP = I915_READ(intel_dp->output_reg);
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > index f8a350359346..9731c3c1d3f2 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > @@ -87,6 +87,47 @@ static int
> > > > > > intel_dp_mst_compute_link_config(struct intel_encoder
> > > > > > *encoder,
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  
> > > > > > +static int
> > > > > > +intel_dp_mst_master_trans_compute(struct intel_encoder
> > > > > > *encoder,
> > > > > > +				  struct intel_crtc_state
> > > > > > *pipe_config,
> > > > > > +				  struct drm_connector_state
> > > > > > *conn_state)
> > > > > > +{
> > > > > > +	struct intel_atomic_state *state =
> > > > > > to_intel_atomic_state(pipe_config->uapi.state);
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > > > > base.dev);
> > > > > > +	struct intel_crtc_state *new_crtc_state;
> > > > > > +	struct intel_crtc *crtc;
> > > > > > +	enum transcoder master;
> > > > > > +	int i;
> > > > > > +
> > > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	if (!conn_state->crtc)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	master = intel_dp_mst_master_trans_get(encoder);
> > > > > > +	if (master == INVALID_TRANSCODER)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	for_each_new_intel_crtc_in_state(state, crtc,
> > > > > > new_crtc_state,
> > > > > > i) {
> > > > > > +		/*
> > > > > > +		 * cpu_transcoder is set when computing CRTC
> > > > > > state if
> > > > > > it will
> > > > > > +		 * be disabled it will not happen, so checking
> > > > > > pipe
> > > > > > instead
> > > > > > +		 */
> > > > > > +		if (crtc->pipe != (enum pipe)master)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		if
> > > > > > (!drm_atomic_crtc_needs_modeset(&new_crtc_state-
> > > > > > > uapi) &&
> > > > > > +		    new_crtc_state->uapi.enable)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		pipe_config->mst_master_trans_pending = true;
> > > > > > +		break;
> > > > > > +	}
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > >  static int intel_dp_mst_compute_config(struct
> > > > > > intel_encoder
> > > > > > *encoder,
> > > > > >  				       struct intel_crtc_state
> > > > > > *pipe_config,
> > > > > >  				       struct
> > > > > > drm_connector_state
> > > > > > *conn_state)
> > > > > > @@ -154,6 +195,95 @@ static int
> > > > > > intel_dp_mst_compute_config(struct
> > > > > > intel_encoder *encoder,
> > > > > >  
> > > > > >  	intel_ddi_compute_min_voltage_level(dev_priv,
> > > > > > pipe_config);
> > > > > >  
> > > > > > +	ret = intel_dp_mst_master_trans_compute(encoder,
> > > > > > pipe_config,
> > > > > > +						conn_state);
> > > > > > +	if (ret)
> > > > > > +		return ret;
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static int
> > > > > > +intel_dp_mst_atomic_master_trans_check(struct
> > > > > > drm_connector
> > > > > > *connector,
> > > > > > +				       struct drm_atomic_state
> > > > > > *state)
> > > > > > +{
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > > > > > dev);
> > > > > > +	struct intel_connector *intel_conn =
> > > > > > to_intel_connector(connector);
> > > > > > +	struct drm_connector_state *new_conn_state,
> > > > > > *old_conn_state;
> > > > > > +	struct drm_connector_list_iter conn_list_iter;
> > > > > > +	struct intel_crtc_state *intel_crtc_state;
> > > > > > +	struct drm_crtc_state *crtc_state;
> > > > > > +	struct drm_connector *conn_iter;
> > > > > > +
> > > > > > +	if (INTEL_GEN(dev_priv) < 12)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	new_conn_state =
> > > > > > drm_atomic_get_new_connector_state(state,
> > > > > > connector);
> > > > > > +	old_conn_state =
> > > > > > drm_atomic_get_old_connector_state(state,
> > > > > > connector);
> > > > > > +
> > > > > > +	if (!old_conn_state->crtc && !new_conn_state->crtc)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * 3 cases that needs be handled here:
> > > > > > +	 * - connector going from disabled to enabled
> > > > > > +	 * - connector going from enabled to disabled:
> > > > > > +	 * if this transcoder was the master, all slaves needs
> > > > > > a
> > > > > > modeset
> > > > > > +	 * - connector going from enabled to enabled but it
> > > > > > needs a
> > > > > > modeset:
> > > > > > +	 * if this transcoder was the master, all slaves also
> > > > > > needs a
> > > > > > modeset
> > > > > > +	 */
> > > > > > +
> > > > > > +	/* disabled -> enabled */
> > > > > > +	if (!old_conn_state->crtc && new_conn_state->crtc)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	/* enabled -> enabled(modeset)? */
> > > > > > +	if (new_conn_state->crtc) {
> > > > > > +		crtc_state =
> > > > > > drm_atomic_get_new_crtc_state(state,
> > > > > > new_conn_state->crtc);
> > > > > > +		if (!drm_atomic_crtc_needs_modeset(crtc_state))
> > > > > > +			return 0;
> > > > > > +	}
> > > > > > +
> > > > > > +	/* handling enabled -> enabled(modeset) and enabled ->
> > > > > > disabled
> > > > > > */
> > > > > > +	crtc_state = drm_atomic_get_old_crtc_state(state,
> > > > > > old_conn_state->crtc);
> > > > > > +	intel_crtc_state = to_intel_crtc_state(crtc_state);
> > > > > > +
> > > > > > +	/* If not master, nothing else needs to be handled */
> > > > > > +	if (intel_conn->mst_port->mst_master_transcoder !=
> > > > > > +	    intel_crtc_state->cpu_transcoder)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	/* Is master, mark all other CRTCs as needing a modeset
> > > > > > */
> > > > > > +	drm_connector_list_iter_begin(state->dev,
> > > > > > &conn_list_iter);
> > > > > > +	drm_for_each_connector_iter(conn_iter, &conn_list_iter)
> > > > > > {
> > > > > > +		struct intel_connector *intel_conn_iter;
> > > > > > +		struct drm_connector_state *conn_iter_state;
> > > > > > +
> > > > > > +		intel_conn_iter =
> > > > > > to_intel_connector(conn_iter);
> > > > > > +		if (intel_conn_iter->mst_port != intel_conn-
> > > > > > > mst_port)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		conn_iter_state =
> > > > > > drm_atomic_get_connector_state(state,
> > > > > > +								
> > > > > >  conn_i
> > > > > > ter);
> > > > > > +		if (IS_ERR(conn_iter_state)) {
> > > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > > iter);
> > > > > > +			return PTR_ERR(conn_iter_state);
> > > > > > +		}
> > > > > > +
> > > > > > +		if (!conn_iter_state->crtc)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		crtc_state = drm_atomic_get_crtc_state(state,
> > > > > > conn_iter_state->crtc);
> > > > > > +		if (IS_ERR(crtc_state)) {
> > > > > > +			drm_connector_list_iter_end(&conn_list_
> > > > > > iter);
> > > > > > +			return PTR_ERR(conn_iter_state);
> > > > > > +		}
> > > > > > +
> > > > > > +		intel_crtc_state =
> > > > > > to_intel_crtc_state(crtc_state);
> > > > > > +		crtc_state->mode_changed = true;
> > > > > > +	}
> > > > > > +	drm_connector_list_iter_end(&conn_list_iter);
> > > > > > +
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  
> > > > > > @@ -175,6 +305,10 @@ intel_dp_mst_atomic_check(struct
> > > > > > drm_connector
> > > > > > *connector,
> > > > > >  	if (ret)
> > > > > >  		return ret;
> > > > > >  
> > > > > > +	ret = intel_dp_mst_atomic_master_trans_check(connector,
> > > > > > state);
> > > > > > +	if (ret)
> > > > > > +		return ret;
> > > > > > +
> > > > > >  	if (!old_conn_state->crtc)
> > > > > >  		return 0;
> > > > > >  
> > > > > > @@ -259,6 +393,7 @@ static void
> > > > > > intel_mst_post_disable_dp(struct
> > > > > > intel_encoder *encoder,
> > > > > >  		intel_dp_sink_dpms(intel_dp,
> > > > > > DRM_MODE_DPMS_OFF);
> > > > > >  		intel_dig_port-
> > > > > > > base.post_disable(&intel_dig_port-
> > > > > > > base,
> > > > > >  						  old_crtc_stat
> > > > > > e,
> > > > > > NULL);
> > > > > > +		intel_dp->mst_master_transcoder =
> > > > > > INVALID_TRANSCODER;
> > > > > >  	}
> > > > > >  
> > > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > > > active_mst_links);
> > > > > > @@ -314,8 +449,11 @@ static void
> > > > > > intel_mst_pre_enable_dp(struct
> > > > > > intel_encoder *encoder,
> > > > > >  
> > > > > >  	DRM_DEBUG_KMS("active links %d\n", intel_dp-
> > > > > > > active_mst_links);
> > > > > >  
> > > > > > -	if (first_mst_stream)
> > > > > > +	if (first_mst_stream) {
> > > > > > +		WARN_ON(intel_dp->mst_master_transcoder !=
> > > > > > INVALID_TRANSCODER);
> > > > > > +		intel_dp->mst_master_transcoder = pipe_config-
> > > > > > > cpu_transcoder;
> > > > > >  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > > > > > +	}
> > > > > >  
> > > > > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr,
> > > > > > connector-
> > > > > > > port, true);
> > > > > >  
> > > > > > @@ -717,3 +855,12 @@ intel_dp_mst_encoder_cleanup(struct
> > > > > > intel_digital_port *intel_dig_port)
> > > > > >  	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
> > > > > >  	/* encoders will get killed by normal cleanup */
> > > > > >  }
> > > > > > +
> > > > > > +enum transcoder
> > > > > > +intel_dp_mst_master_trans_get(struct intel_encoder
> > > > > > *encoder)
> > > > > > +{
> > > > > > +	struct intel_dp_mst_encoder *intel_mst =
> > > > > > enc_to_mst(&encoder-
> > > > > > > base);
> > > > > > +	struct intel_dp *intel_dp = &intel_mst->primary->dp;
> > > > > > +
> > > > > > +	return intel_dp->mst_master_transcoder;
> > > > > > +}
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > index f660ad80db04..e6f28a517182 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> > > > > > @@ -7,9 +7,11 @@
> > > > > >  #define __INTEL_DP_MST_H__
> > > > > >  
> > > > > >  struct intel_digital_port;
> > > > > > +struct intel_encoder;
> > > > > >  
> > > > > >  int intel_dp_mst_encoder_init(struct intel_digital_port
> > > > > > *intel_dig_port, int conn_id);
> > > > > >  void intel_dp_mst_encoder_cleanup(struct
> > > > > > intel_digital_port
> > > > > > *intel_dig_port);
> > > > > >  int intel_dp_mst_encoder_active_links(struct
> > > > > > intel_digital_port
> > > > > > *intel_dig_port);
> > > > > > +enum transcoder intel_dp_mst_master_trans_get(struct
> > > > > > intel_encoder
> > > > > > *encoder);
> > > > > >  
> > > > > >  #endif /* __INTEL_DP_MST_H__ */
> > > > > > -- 
> > > > > > 2.24.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
  2019-12-02 22:03               ` [Intel-gfx] " Souza, Jose
  (?)
@ 2019-12-03 12:47               ` Ville Syrjälä
  2019-12-03 22:12                 ` Souza, Jose
  -1 siblings, 1 reply; 65+ messages in thread
From: Ville Syrjälä @ 2019-12-03 12:47 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Mon, Dec 02, 2019 at 10:03:38PM +0000, Souza, Jose wrote:
> On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> > On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de
> > > > > > Souza
> > > > > > wrote:
> > > > > > > On TGL the blending of all the streams have moved from DDI
> > > > > > > to
> > > > > > > transcoder, so now every transcoder working over the same
> > > > > > > MST
> > > > > > > port
> > > > > > > must
> > > > > > > send its stream to a master transcoder and master will send
> > > > > > > to
> > > > > > > DDI
> > > > > > > respecting the time slots.
> > > > > > > 
> > > > > > > A previous approach was using the lowest pipe/transcoder as
> > > > > > > master
> > > > > > > transcoder but as the comment in
> > > > > > > skl_commit_modeset_enables()
> > > > > > > states,
> > > > > > > that is not always true.
> > > > > > > 
> > > > > > > So here promoting the first pipe/transcoder of the stream
> > > > > > > as
> > > > > > > master.
> > > > > > > That caused several other problems as during the commit
> > > > > > > phase
> > > > > > > the
> > > > > > > state computed should not be changed.
> > > > > > > 
> > > > > > > So the master transcoder is store into intel_dp and the
> > > > > > > modeset
> > > > > > > in
> > > > > > > slave pipes/transcoders is forced using
> > > > > > > mst_master_trans_pending.
> > > > > > > 
> > > > > > > v2:
> > > > > > > - added missing config compute to trigger fullmodeset in
> > > > > > > slave
> > > > > > > transcoders
> > > > > > > 
> > > > > > > BSpec: 50493
> > > > > > > BSpec: 49190
> > > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58
> > > > > > > ++++++-
> > > > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > > > +++++++++++++++++-
> > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > @@ -35,6 +35,7 @@
> > > > > > >  #include "intel_display_types.h"
> > > > > > >  #include "intel_dp.h"
> > > > > > >  #include "intel_dp_link_training.h"
> > > > > > > +#include "intel_dp_mst.h"
> > > > > > >  #include "intel_dpio_phy.h"
> > > > > > >  #include "intel_dsi.h"
> > > > > > >  #include "intel_fifo_underrun.h"
> > > > > > > @@ -1903,8 +1904,13 @@
> > > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > > struct intel_crtc_state *crtc_state)
> > > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
> > > > > > >  
> > > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > > -			temp |=
> > > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state->cpu_transcoder);
> > > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > > +			enum transcoder master;
> > > > > > > +
> > > > > > > +			master =
> > > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > > 
> > > > > > Why isn't that just stored in the crtc state like everything
> > > > > > else?
> > > > > > 
> > > > > > I'm thinking we should maybe do it just like port sync and
> > > > > > have
> > > > > > both
> > > > > > master + slave_mask. That way it should be pretty trivial to
> > > > > > add
> > > > > > all
> > > > > > the relevant crtcs to the state when needed.
> > > > > 
> > > > > I guess port sync is not doing the right thing and it could
> > > > > cause
> > > > > underruns.
> > > > > When it is going to enable the master CRTC of the port sync it
> > > > > forcibly
> > > > > enables the slave first, what could cause underruns because of
> > > > > overlap
> > > > > in ddb allocations(that is what I understood from the comment
> > > > > in
> > > > > skl_commit_modeset_enables()).
> > > > 
> > > > Not necessarily just underruns but even a system hang. The fix
> > > > should
> > > > be
> > > > a trivial "check the slave for ddb overlap as well", but
> > > > apparently I
> > > > failed at convicing people to do that.
> > > > 
> > > > I've actually been pondering about decoupling the plane updates
> > > > from
> > > > the crtc enable stuff entirely. At least theoretically crtc
> > > > enable
> > > > should be able to excute in any order as long we don't enable any
> > > > new planes.
> > > > 
> > > > But none of that really matters for the discussion at hand.
> > > > Though
> > > > there are other problems with the port sync stuff that would need
> > > > to be handled better. Eg. I think it now adds both crtcs to the
> > > > state
> > > > always which is going to cut the fps in half. Also the place
> > > > where
> > > > it does that stuff is rather suspicious. All that stuff should be
> > > > somewhere a bit higher up IMO.
> > > > 
> > > > > So for MST we only know who is the master in the commit phase
> > > > > and
> > > > > at
> > > > > this point we should not modify the computed state.
> > > > 
> > > > I'm not suggesting modifying anything during commit phase. I
> > > > think
> > > > you are effectiely doing that right now by stuffing that mst
> > > > master
> > > > transcoder into intel_dp.
> > > 
> > > Sorry, I still don't get what approach are you suggesting here.
> > > 
> > > If we can't modify the state in the commit phase, adding
> > > mst_master_transcoder in the CRTC state will not be possible while
> > > respecting the order imposed by ddb allocations.
> > 
> > The ddb allocation ordering only comes into play when there are
> > already active pipes. It should always be possible to not enable
> > the slaves until the master has been shuffled into place in the 
> > ddb and enabled.
> 
> This sounds contradictory to what you answered here: 
> https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html
> 
> Will need to some testing to get the steps but I was able consistent to
> get to state were doing a full modeset in pipe A(mst master) caused the
> pipe B(mst slave) to enabled first because of the ddb allocations.
> 
> So can I or not do something like port sync does? And force the enable
> of master before the slaves? If possible, the comment in
> skl_commit_modeset_enables() will need some changes.

I suspect for the mst stuff we should do:

while_dirty_mst_masters() {
	if (!ddb_overlap)
		enable();
}
while_dirty_mst_slaves() {
	if (!ddb_overlap)
		enable();
}

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

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
  2019-12-03 12:47               ` Ville Syrjälä
@ 2019-12-03 22:12                 ` Souza, Jose
  2019-12-04 10:55                   ` Ville Syrjälä
  0 siblings, 1 reply; 65+ messages in thread
From: Souza, Jose @ 2019-12-03 22:12 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Tue, 2019-12-03 at 14:47 +0200, Ville Syrjälä wrote:
> On Mon, Dec 02, 2019 at 10:03:38PM +0000, Souza, Jose wrote:
> > On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> > > On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > > > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de
> > > > > > > Souza
> > > > > > > wrote:
> > > > > > > > On TGL the blending of all the streams have moved from
> > > > > > > > DDI
> > > > > > > > to
> > > > > > > > transcoder, so now every transcoder working over the
> > > > > > > > same
> > > > > > > > MST
> > > > > > > > port
> > > > > > > > must
> > > > > > > > send its stream to a master transcoder and master will
> > > > > > > > send
> > > > > > > > to
> > > > > > > > DDI
> > > > > > > > respecting the time slots.
> > > > > > > > 
> > > > > > > > A previous approach was using the lowest
> > > > > > > > pipe/transcoder as
> > > > > > > > master
> > > > > > > > transcoder but as the comment in
> > > > > > > > skl_commit_modeset_enables()
> > > > > > > > states,
> > > > > > > > that is not always true.
> > > > > > > > 
> > > > > > > > So here promoting the first pipe/transcoder of the
> > > > > > > > stream
> > > > > > > > as
> > > > > > > > master.
> > > > > > > > That caused several other problems as during the commit
> > > > > > > > phase
> > > > > > > > the
> > > > > > > > state computed should not be changed.
> > > > > > > > 
> > > > > > > > So the master transcoder is store into intel_dp and the
> > > > > > > > modeset
> > > > > > > > in
> > > > > > > > slave pipes/transcoders is forced using
> > > > > > > > mst_master_trans_pending.
> > > > > > > > 
> > > > > > > > v2:
> > > > > > > > - added missing config compute to trigger fullmodeset
> > > > > > > > in
> > > > > > > > slave
> > > > > > > > transcoders
> > > > > > > > 
> > > > > > > > BSpec: 50493
> > > > > > > > BSpec: 49190
> > > > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > > > Signed-off-by: José Roberto de Souza <
> > > > > > > > jose.souza@intel.com>
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58
> > > > > > > > ++++++-
> > > > > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > > > > +++++++++++++++++-
> > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > @@ -35,6 +35,7 @@
> > > > > > > >  #include "intel_display_types.h"
> > > > > > > >  #include "intel_dp.h"
> > > > > > > >  #include "intel_dp_link_training.h"
> > > > > > > > +#include "intel_dp_mst.h"
> > > > > > > >  #include "intel_dpio_phy.h"
> > > > > > > >  #include "intel_dsi.h"
> > > > > > > >  #include "intel_fifo_underrun.h"
> > > > > > > > @@ -1903,8 +1904,13 @@
> > > > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > > > struct intel_crtc_state *crtc_state)
> > > > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state-
> > > > > > > > >lane_count);
> > > > > > > >  
> > > > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > > > -			temp |=
> > > > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state-
> > > > > > > > >cpu_transcoder);
> > > > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > > > +			enum transcoder master;
> > > > > > > > +
> > > > > > > > +			master =
> > > > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > > > 
> > > > > > > Why isn't that just stored in the crtc state like
> > > > > > > everything
> > > > > > > else?
> > > > > > > 
> > > > > > > I'm thinking we should maybe do it just like port sync
> > > > > > > and
> > > > > > > have
> > > > > > > both
> > > > > > > master + slave_mask. That way it should be pretty trivial
> > > > > > > to
> > > > > > > add
> > > > > > > all
> > > > > > > the relevant crtcs to the state when needed.
> > > > > > 
> > > > > > I guess port sync is not doing the right thing and it could
> > > > > > cause
> > > > > > underruns.
> > > > > > When it is going to enable the master CRTC of the port sync
> > > > > > it
> > > > > > forcibly
> > > > > > enables the slave first, what could cause underruns because
> > > > > > of
> > > > > > overlap
> > > > > > in ddb allocations(that is what I understood from the
> > > > > > comment
> > > > > > in
> > > > > > skl_commit_modeset_enables()).
> > > > > 
> > > > > Not necessarily just underruns but even a system hang. The
> > > > > fix
> > > > > should
> > > > > be
> > > > > a trivial "check the slave for ddb overlap as well", but
> > > > > apparently I
> > > > > failed at convicing people to do that.
> > > > > 
> > > > > I've actually been pondering about decoupling the plane
> > > > > updates
> > > > > from
> > > > > the crtc enable stuff entirely. At least theoretically crtc
> > > > > enable
> > > > > should be able to excute in any order as long we don't enable
> > > > > any
> > > > > new planes.
> > > > > 
> > > > > But none of that really matters for the discussion at hand.
> > > > > Though
> > > > > there are other problems with the port sync stuff that would
> > > > > need
> > > > > to be handled better. Eg. I think it now adds both crtcs to
> > > > > the
> > > > > state
> > > > > always which is going to cut the fps in half. Also the place
> > > > > where
> > > > > it does that stuff is rather suspicious. All that stuff
> > > > > should be
> > > > > somewhere a bit higher up IMO.
> > > > > 
> > > > > > So for MST we only know who is the master in the commit
> > > > > > phase
> > > > > > and
> > > > > > at
> > > > > > this point we should not modify the computed state.
> > > > > 
> > > > > I'm not suggesting modifying anything during commit phase. I
> > > > > think
> > > > > you are effectiely doing that right now by stuffing that mst
> > > > > master
> > > > > transcoder into intel_dp.
> > > > 
> > > > Sorry, I still don't get what approach are you suggesting here.
> > > > 
> > > > If we can't modify the state in the commit phase, adding
> > > > mst_master_transcoder in the CRTC state will not be possible
> > > > while
> > > > respecting the order imposed by ddb allocations.
> > > 
> > > The ddb allocation ordering only comes into play when there are
> > > already active pipes. It should always be possible to not enable
> > > the slaves until the master has been shuffled into place in the 
> > > ddb and enabled.
> > 
> > This sounds contradictory to what you answered here: 
> > https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html
> > 
> > Will need to some testing to get the steps but I was able
> > consistent to
> > get to state were doing a full modeset in pipe A(mst master) caused
> > the
> > pipe B(mst slave) to enabled first because of the ddb allocations.
> > 
> > So can I or not do something like port sync does? And force the
> > enable
> > of master before the slaves? If possible, the comment in
> > skl_commit_modeset_enables() will need some changes.
> 
> I suspect for the mst stuff we should do:
> 
> while_dirty_mst_masters() {
> 	if (!ddb_overlap)
> 		enable();
> }
> while_dirty_mst_slaves() {
> 	if (!ddb_overlap)
> 		enable();
> }

What about this case?

Pipe/transcoder A and B in the same MST stream

# old state - DDB allocation: AABBB
mst master = transcoder A(computed in atomic check phase)
entries[0].start = 0
entries[0].end = 1
entries[1].start = 2
entries[1].end = 4

# new state - DDB allocation: AAABBB
mst master = transcoder A(computed in atomic check phase)
entries[0].start = 0
entries[0].end = 2
entries[1].start = 3
entries[1].end = 5

while_dirty_mst_masters()
	first iteration: pipe A will overlap with old pipe B DDB
allocation
	second iteration: pipe B is slave of A
	third iteration: ?


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

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

* Re: [Intel-gfx] [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
  2019-11-28 18:40     ` [Intel-gfx] " Ville Syrjälä
  (?)
@ 2019-12-03 23:29     ` Souza, Jose
  2019-12-04 10:56       ` Ville Syrjälä
  -1 siblings, 1 reply; 65+ messages in thread
From: Souza, Jose @ 2019-12-03 23:29 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Thu, 2019-11-28 at 20:40 +0200, Ville Syrjälä wrote:
> On Fri, Nov 22, 2019 at 04:54:58PM -0800, José Roberto de Souza
> wrote:
> > For TGL the step to turn off the transcoder clock was moved to
> > after
> > the complete shutdown of DDI. Only the MST slave transcoders should
> > disable the clock before that.
> > 
> > BSpec: 49190
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c    |  9 ++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++++++---
> >  2 files changed, 20 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index cfcaa7c81575..aa0249333175 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3813,7 +3813,7 @@ static void intel_ddi_post_disable_dp(struct
> > intel_encoder *encoder,
> >  	 */
> >  	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> >  
> > -	if (!is_mst)
> > +	if (INTEL_GEN(dev_priv) < 12 && !is_mst)
> >  		intel_ddi_disable_pipe_clock(old_crtc_state);
> >  
> >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > @@ -3826,6 +3826,13 @@ static void intel_ddi_post_disable_dp(struct
> > intel_encoder *encoder,
> >  		intel_display_power_put_unchecked(dev_priv,
> >  						  dig_port-
> > >ddi_io_power_domain);
> >  
> > +	/*
> > +	 * From TGL BSpec "If single stream or multi-stream master
> > transcoder:
> > +	 * Configure Transcoder Clock select to direct no clock to the
> > +	 * transcoder"
> > +	 */
> 
> Not really convinced these comments add anything the code isn't
> already saying.

We have added similar comments in tgl_ddi_pre_enable_dp(), it helps
tracks the code with BSpec steps.

> 
> > +	if (INTEL_GEN(dev_priv) >= 12)
> > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> 
> That's much later than the bspec sequence suggests.

Oh, thanks.
Yeah it should right after intel_disable_ddi_buf()

> 
> >  	intel_ddi_clk_disable(encoder);
> >  	tgl_clear_psr2_transcoder_exitline(old_crtc_state);
> >  }
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 94549848653a..53afe3e179f7 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -369,8 +369,19 @@ static void intel_mst_post_disable_dp(struct
> > intel_encoder *encoder,
> >  	struct intel_dp *intel_dp = &intel_dig_port->dp;
> >  	struct intel_connector *connector =
> >  		to_intel_connector(old_conn_state->connector);
> > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > >base.dev);
> >  
> > -	intel_ddi_disable_pipe_clock(old_crtc_state);
> > +	intel_dp->active_mst_links--;
> > +
> > +	/*
> > +	 * From TGL BSpec "If multi-stream slave transcoder: Configure
> > +	 * Transcoder Clock Select to direct no clock to the
> > transcoder"
> > +	 *
> > +	 * From older GENs BSpec "Configure Transcoder Clock Select to
> > direct
> > +	 * no clock to the transcoder"
> > +	 */
> > +	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)
> 
> Maybe we should add 'last_mst_stream' to mirror the
> 'first_mst_stream'
> in the enable code?

Sounds good

> 
> > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> >  
> >  	/* this can fail */
> >  	drm_dp_check_act_status(&intel_dp->mst_mgr);
> > @@ -386,8 +397,6 @@ static void intel_mst_post_disable_dp(struct
> > intel_encoder *encoder,
> >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector-
> > >port,
> >  				     false);
> >  
> > -	intel_dp->active_mst_links--;
> > -
> >  	intel_mst->connector = NULL;
> >  	if (intel_dp->active_mst_links == 0) {
> >  		intel_dig_port->base.post_disable(&intel_dig_port-
> > >base,
> > -- 
> > 2.24.0
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
  2019-12-03 22:12                 ` Souza, Jose
@ 2019-12-04 10:55                   ` Ville Syrjälä
  2019-12-04 18:48                     ` Souza, Jose
  0 siblings, 1 reply; 65+ messages in thread
From: Ville Syrjälä @ 2019-12-04 10:55 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Tue, Dec 03, 2019 at 10:12:47PM +0000, Souza, Jose wrote:
> On Tue, 2019-12-03 at 14:47 +0200, Ville Syrjälä wrote:
> > On Mon, Dec 02, 2019 at 10:03:38PM +0000, Souza, Jose wrote:
> > > On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> > > > On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > > > > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > > > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose wrote:
> > > > > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José Roberto de
> > > > > > > > Souza
> > > > > > > > wrote:
> > > > > > > > > On TGL the blending of all the streams have moved from
> > > > > > > > > DDI
> > > > > > > > > to
> > > > > > > > > transcoder, so now every transcoder working over the
> > > > > > > > > same
> > > > > > > > > MST
> > > > > > > > > port
> > > > > > > > > must
> > > > > > > > > send its stream to a master transcoder and master will
> > > > > > > > > send
> > > > > > > > > to
> > > > > > > > > DDI
> > > > > > > > > respecting the time slots.
> > > > > > > > > 
> > > > > > > > > A previous approach was using the lowest
> > > > > > > > > pipe/transcoder as
> > > > > > > > > master
> > > > > > > > > transcoder but as the comment in
> > > > > > > > > skl_commit_modeset_enables()
> > > > > > > > > states,
> > > > > > > > > that is not always true.
> > > > > > > > > 
> > > > > > > > > So here promoting the first pipe/transcoder of the
> > > > > > > > > stream
> > > > > > > > > as
> > > > > > > > > master.
> > > > > > > > > That caused several other problems as during the commit
> > > > > > > > > phase
> > > > > > > > > the
> > > > > > > > > state computed should not be changed.
> > > > > > > > > 
> > > > > > > > > So the master transcoder is store into intel_dp and the
> > > > > > > > > modeset
> > > > > > > > > in
> > > > > > > > > slave pipes/transcoders is forced using
> > > > > > > > > mst_master_trans_pending.
> > > > > > > > > 
> > > > > > > > > v2:
> > > > > > > > > - added missing config compute to trigger fullmodeset
> > > > > > > > > in
> > > > > > > > > slave
> > > > > > > > > transcoders
> > > > > > > > > 
> > > > > > > > > BSpec: 50493
> > > > > > > > > BSpec: 49190
> > > > > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > > > > Signed-off-by: José Roberto de Souza <
> > > > > > > > > jose.souza@intel.com>
> > > > > > > > > ---
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  10 +-
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  58
> > > > > > > > > ++++++-
> > > > > > > > >  .../drm/i915/display/intel_display_types.h    |   3 +
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   1 +
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 149
> > > > > > > > > +++++++++++++++++-
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   2 +
> > > > > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > > > > 
> > > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > @@ -35,6 +35,7 @@
> > > > > > > > >  #include "intel_display_types.h"
> > > > > > > > >  #include "intel_dp.h"
> > > > > > > > >  #include "intel_dp_link_training.h"
> > > > > > > > > +#include "intel_dp_mst.h"
> > > > > > > > >  #include "intel_dpio_phy.h"
> > > > > > > > >  #include "intel_dsi.h"
> > > > > > > > >  #include "intel_fifo_underrun.h"
> > > > > > > > > @@ -1903,8 +1904,13 @@
> > > > > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > > > > struct intel_crtc_state *crtc_state)
> > > > > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state-
> > > > > > > > > >lane_count);
> > > > > > > > >  
> > > > > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > > > > -			temp |=
> > > > > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state-
> > > > > > > > > >cpu_transcoder);
> > > > > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > > > > +			enum transcoder master;
> > > > > > > > > +
> > > > > > > > > +			master =
> > > > > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > > > > 
> > > > > > > > Why isn't that just stored in the crtc state like
> > > > > > > > everything
> > > > > > > > else?
> > > > > > > > 
> > > > > > > > I'm thinking we should maybe do it just like port sync
> > > > > > > > and
> > > > > > > > have
> > > > > > > > both
> > > > > > > > master + slave_mask. That way it should be pretty trivial
> > > > > > > > to
> > > > > > > > add
> > > > > > > > all
> > > > > > > > the relevant crtcs to the state when needed.
> > > > > > > 
> > > > > > > I guess port sync is not doing the right thing and it could
> > > > > > > cause
> > > > > > > underruns.
> > > > > > > When it is going to enable the master CRTC of the port sync
> > > > > > > it
> > > > > > > forcibly
> > > > > > > enables the slave first, what could cause underruns because
> > > > > > > of
> > > > > > > overlap
> > > > > > > in ddb allocations(that is what I understood from the
> > > > > > > comment
> > > > > > > in
> > > > > > > skl_commit_modeset_enables()).
> > > > > > 
> > > > > > Not necessarily just underruns but even a system hang. The
> > > > > > fix
> > > > > > should
> > > > > > be
> > > > > > a trivial "check the slave for ddb overlap as well", but
> > > > > > apparently I
> > > > > > failed at convicing people to do that.
> > > > > > 
> > > > > > I've actually been pondering about decoupling the plane
> > > > > > updates
> > > > > > from
> > > > > > the crtc enable stuff entirely. At least theoretically crtc
> > > > > > enable
> > > > > > should be able to excute in any order as long we don't enable
> > > > > > any
> > > > > > new planes.
> > > > > > 
> > > > > > But none of that really matters for the discussion at hand.
> > > > > > Though
> > > > > > there are other problems with the port sync stuff that would
> > > > > > need
> > > > > > to be handled better. Eg. I think it now adds both crtcs to
> > > > > > the
> > > > > > state
> > > > > > always which is going to cut the fps in half. Also the place
> > > > > > where
> > > > > > it does that stuff is rather suspicious. All that stuff
> > > > > > should be
> > > > > > somewhere a bit higher up IMO.
> > > > > > 
> > > > > > > So for MST we only know who is the master in the commit
> > > > > > > phase
> > > > > > > and
> > > > > > > at
> > > > > > > this point we should not modify the computed state.
> > > > > > 
> > > > > > I'm not suggesting modifying anything during commit phase. I
> > > > > > think
> > > > > > you are effectiely doing that right now by stuffing that mst
> > > > > > master
> > > > > > transcoder into intel_dp.
> > > > > 
> > > > > Sorry, I still don't get what approach are you suggesting here.
> > > > > 
> > > > > If we can't modify the state in the commit phase, adding
> > > > > mst_master_transcoder in the CRTC state will not be possible
> > > > > while
> > > > > respecting the order imposed by ddb allocations.
> > > > 
> > > > The ddb allocation ordering only comes into play when there are
> > > > already active pipes. It should always be possible to not enable
> > > > the slaves until the master has been shuffled into place in the 
> > > > ddb and enabled.
> > > 
> > > This sounds contradictory to what you answered here: 
> > > https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html
> > > 
> > > Will need to some testing to get the steps but I was able
> > > consistent to
> > > get to state were doing a full modeset in pipe A(mst master) caused
> > > the
> > > pipe B(mst slave) to enabled first because of the ddb allocations.
> > > 
> > > So can I or not do something like port sync does? And force the
> > > enable
> > > of master before the slaves? If possible, the comment in
> > > skl_commit_modeset_enables() will need some changes.
> > 
> > I suspect for the mst stuff we should do:
> > 
> > while_dirty_mst_masters() {
> > 	if (!ddb_overlap)
> > 		enable();
> > }
> > while_dirty_mst_slaves() {
> > 	if (!ddb_overlap)
> > 		enable();
> > }
> 
> What about this case?
> 
> Pipe/transcoder A and B in the same MST stream
> 
> # old state - DDB allocation: AABBB
> mst master = transcoder A(computed in atomic check phase)
> entries[0].start = 0
> entries[0].end = 1
> entries[1].start = 2
> entries[1].end = 4
> 
> # new state - DDB allocation: AAABBB
> mst master = transcoder A(computed in atomic check phase)
> entries[0].start = 0
> entries[0].end = 2
> entries[1].start = 3
> entries[1].end = 5
> 
> while_dirty_mst_masters()
> 	first iteration: pipe A will overlap with old pipe B DDB

There won't be an old DDB allocation for a pipe if it's going
trough a modeset.

> allocation
> 	second iteration: pipe B is slave of A
> 	third iteration: ?
> 
> 
> > 

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

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

* Re: [Intel-gfx] [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off
  2019-12-03 23:29     ` Souza, Jose
@ 2019-12-04 10:56       ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-12-04 10:56 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx

On Tue, Dec 03, 2019 at 11:29:49PM +0000, Souza, Jose wrote:
> On Thu, 2019-11-28 at 20:40 +0200, Ville Syrjälä wrote:
> > On Fri, Nov 22, 2019 at 04:54:58PM -0800, José Roberto de Souza
> > wrote:
> > > For TGL the step to turn off the transcoder clock was moved to
> > > after
> > > the complete shutdown of DDI. Only the MST slave transcoders should
> > > disable the clock before that.
> > > 
> > > BSpec: 49190
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c    |  9 ++++++++-
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++++++---
> > >  2 files changed, 20 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index cfcaa7c81575..aa0249333175 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -3813,7 +3813,7 @@ static void intel_ddi_post_disable_dp(struct
> > > intel_encoder *encoder,
> > >  	 */
> > >  	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> > >  
> > > -	if (!is_mst)
> > > +	if (INTEL_GEN(dev_priv) < 12 && !is_mst)
> > >  		intel_ddi_disable_pipe_clock(old_crtc_state);
> > >  
> > >  	intel_disable_ddi_buf(encoder, old_crtc_state);
> > > @@ -3826,6 +3826,13 @@ static void intel_ddi_post_disable_dp(struct
> > > intel_encoder *encoder,
> > >  		intel_display_power_put_unchecked(dev_priv,
> > >  						  dig_port-
> > > >ddi_io_power_domain);
> > >  
> > > +	/*
> > > +	 * From TGL BSpec "If single stream or multi-stream master
> > > transcoder:
> > > +	 * Configure Transcoder Clock select to direct no clock to the
> > > +	 * transcoder"
> > > +	 */
> > 
> > Not really convinced these comments add anything the code isn't
> > already saying.
> 
> We have added similar comments in tgl_ddi_pre_enable_dp(), it helps
> tracks the code with BSpec steps.

Just noise IMO. If the code isn't self explanatory then it should be
fixed instead.

> 
> > 
> > > +	if (INTEL_GEN(dev_priv) >= 12)
> > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > 
> > That's much later than the bspec sequence suggests.
> 
> Oh, thanks.
> Yeah it should right after intel_disable_ddi_buf()
> 
> > 
> > >  	intel_ddi_clk_disable(encoder);
> > >  	tgl_clear_psr2_transcoder_exitline(old_crtc_state);
> > >  }
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > index 94549848653a..53afe3e179f7 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > @@ -369,8 +369,19 @@ static void intel_mst_post_disable_dp(struct
> > > intel_encoder *encoder,
> > >  	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > >  	struct intel_connector *connector =
> > >  		to_intel_connector(old_conn_state->connector);
> > > +	struct drm_i915_private *dev_priv = to_i915(connector-
> > > >base.dev);
> > >  
> > > -	intel_ddi_disable_pipe_clock(old_crtc_state);
> > > +	intel_dp->active_mst_links--;
> > > +
> > > +	/*
> > > +	 * From TGL BSpec "If multi-stream slave transcoder: Configure
> > > +	 * Transcoder Clock Select to direct no clock to the
> > > transcoder"
> > > +	 *
> > > +	 * From older GENs BSpec "Configure Transcoder Clock Select to
> > > direct
> > > +	 * no clock to the transcoder"
> > > +	 */
> > > +	if (INTEL_GEN(dev_priv) < 12 || intel_dp->active_mst_links)
> > 
> > Maybe we should add 'last_mst_stream' to mirror the
> > 'first_mst_stream'
> > in the enable code?
> 
> Sounds good
> 
> > 
> > > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > >  
> > >  	/* this can fail */
> > >  	drm_dp_check_act_status(&intel_dp->mst_mgr);
> > > @@ -386,8 +397,6 @@ static void intel_mst_post_disable_dp(struct
> > > intel_encoder *encoder,
> > >  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector-
> > > >port,
> > >  				     false);
> > >  
> > > -	intel_dp->active_mst_links--;
> > > -
> > >  	intel_mst->connector = NULL;
> > >  	if (intel_dp->active_mst_links == 0) {
> > >  		intel_dig_port->base.post_disable(&intel_dig_port-
> > > >base,
> > > -- 
> > > 2.24.0
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
  2019-12-04 10:55                   ` Ville Syrjälä
@ 2019-12-04 18:48                     ` Souza, Jose
  2019-12-04 19:03                       ` Ville Syrjälä
  0 siblings, 1 reply; 65+ messages in thread
From: Souza, Jose @ 2019-12-04 18:48 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, De Marchi, Lucas

On Wed, 2019-12-04 at 12:55 +0200, Ville Syrjälä wrote:
> On Tue, Dec 03, 2019 at 10:12:47PM +0000, Souza, Jose wrote:
> > On Tue, 2019-12-03 at 14:47 +0200, Ville Syrjälä wrote:
> > > On Mon, Dec 02, 2019 at 10:03:38PM +0000, Souza, Jose wrote:
> > > > On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> > > > > On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > > > > > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > > > > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose
> > > > > > > wrote:
> > > > > > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José
> > > > > > > > > Roberto de
> > > > > > > > > Souza
> > > > > > > > > wrote:
> > > > > > > > > > On TGL the blending of all the streams have moved
> > > > > > > > > > from
> > > > > > > > > > DDI
> > > > > > > > > > to
> > > > > > > > > > transcoder, so now every transcoder working over
> > > > > > > > > > the
> > > > > > > > > > same
> > > > > > > > > > MST
> > > > > > > > > > port
> > > > > > > > > > must
> > > > > > > > > > send its stream to a master transcoder and master
> > > > > > > > > > will
> > > > > > > > > > send
> > > > > > > > > > to
> > > > > > > > > > DDI
> > > > > > > > > > respecting the time slots.
> > > > > > > > > > 
> > > > > > > > > > A previous approach was using the lowest
> > > > > > > > > > pipe/transcoder as
> > > > > > > > > > master
> > > > > > > > > > transcoder but as the comment in
> > > > > > > > > > skl_commit_modeset_enables()
> > > > > > > > > > states,
> > > > > > > > > > that is not always true.
> > > > > > > > > > 
> > > > > > > > > > So here promoting the first pipe/transcoder of the
> > > > > > > > > > stream
> > > > > > > > > > as
> > > > > > > > > > master.
> > > > > > > > > > That caused several other problems as during the
> > > > > > > > > > commit
> > > > > > > > > > phase
> > > > > > > > > > the
> > > > > > > > > > state computed should not be changed.
> > > > > > > > > > 
> > > > > > > > > > So the master transcoder is store into intel_dp and
> > > > > > > > > > the
> > > > > > > > > > modeset
> > > > > > > > > > in
> > > > > > > > > > slave pipes/transcoders is forced using
> > > > > > > > > > mst_master_trans_pending.
> > > > > > > > > > 
> > > > > > > > > > v2:
> > > > > > > > > > - added missing config compute to trigger
> > > > > > > > > > fullmodeset
> > > > > > > > > > in
> > > > > > > > > > slave
> > > > > > > > > > transcoders
> > > > > > > > > > 
> > > > > > > > > > BSpec: 50493
> > > > > > > > > > BSpec: 49190
> > > > > > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > > > > > Signed-off-by: José Roberto de Souza <
> > > > > > > > > > jose.souza@intel.com>
> > > > > > > > > > ---
> > > > > > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  1
> > > > > > > > > > 0 +-
> > > > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  5
> > > > > > > > > > 8
> > > > > > > > > > ++++++-
> > > > > > > > > >  .../drm/i915/display/intel_display_types.h    |   
> > > > > > > > > > 3 +
> > > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   
> > > > > > > > > > 1 +
> > > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   |
> > > > > > > > > > 149
> > > > > > > > > > +++++++++++++++++-
> > > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   
> > > > > > > > > > 2 +
> > > > > > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > > > > > 
> > > > > > > > > > diff --git
> > > > > > > > > > a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > @@ -35,6 +35,7 @@
> > > > > > > > > >  #include "intel_display_types.h"
> > > > > > > > > >  #include "intel_dp.h"
> > > > > > > > > >  #include "intel_dp_link_training.h"
> > > > > > > > > > +#include "intel_dp_mst.h"
> > > > > > > > > >  #include "intel_dpio_phy.h"
> > > > > > > > > >  #include "intel_dsi.h"
> > > > > > > > > >  #include "intel_fifo_underrun.h"
> > > > > > > > > > @@ -1903,8 +1904,13 @@
> > > > > > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > > > > > struct intel_crtc_state *crtc_state)
> > > > > > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state-
> > > > > > > > > > > lane_count);
> > > > > > > > > >  
> > > > > > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > > > > > -			temp |=
> > > > > > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state-
> > > > > > > > > > > cpu_transcoder);
> > > > > > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > > > > > +			enum transcoder master;
> > > > > > > > > > +
> > > > > > > > > > +			master =
> > > > > > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > > > > > 
> > > > > > > > > Why isn't that just stored in the crtc state like
> > > > > > > > > everything
> > > > > > > > > else?
> > > > > > > > > 
> > > > > > > > > I'm thinking we should maybe do it just like port
> > > > > > > > > sync
> > > > > > > > > and
> > > > > > > > > have
> > > > > > > > > both
> > > > > > > > > master + slave_mask. That way it should be pretty
> > > > > > > > > trivial
> > > > > > > > > to
> > > > > > > > > add
> > > > > > > > > all
> > > > > > > > > the relevant crtcs to the state when needed.
> > > > > > > > 
> > > > > > > > I guess port sync is not doing the right thing and it
> > > > > > > > could
> > > > > > > > cause
> > > > > > > > underruns.
> > > > > > > > When it is going to enable the master CRTC of the port
> > > > > > > > sync
> > > > > > > > it
> > > > > > > > forcibly
> > > > > > > > enables the slave first, what could cause underruns
> > > > > > > > because
> > > > > > > > of
> > > > > > > > overlap
> > > > > > > > in ddb allocations(that is what I understood from the
> > > > > > > > comment
> > > > > > > > in
> > > > > > > > skl_commit_modeset_enables()).
> > > > > > > 
> > > > > > > Not necessarily just underruns but even a system hang.
> > > > > > > The
> > > > > > > fix
> > > > > > > should
> > > > > > > be
> > > > > > > a trivial "check the slave for ddb overlap as well", but
> > > > > > > apparently I
> > > > > > > failed at convicing people to do that.
> > > > > > > 
> > > > > > > I've actually been pondering about decoupling the plane
> > > > > > > updates
> > > > > > > from
> > > > > > > the crtc enable stuff entirely. At least theoretically
> > > > > > > crtc
> > > > > > > enable
> > > > > > > should be able to excute in any order as long we don't
> > > > > > > enable
> > > > > > > any
> > > > > > > new planes.
> > > > > > > 
> > > > > > > But none of that really matters for the discussion at
> > > > > > > hand.
> > > > > > > Though
> > > > > > > there are other problems with the port sync stuff that
> > > > > > > would
> > > > > > > need
> > > > > > > to be handled better. Eg. I think it now adds both crtcs
> > > > > > > to
> > > > > > > the
> > > > > > > state
> > > > > > > always which is going to cut the fps in half. Also the
> > > > > > > place
> > > > > > > where
> > > > > > > it does that stuff is rather suspicious. All that stuff
> > > > > > > should be
> > > > > > > somewhere a bit higher up IMO.
> > > > > > > 
> > > > > > > > So for MST we only know who is the master in the commit
> > > > > > > > phase
> > > > > > > > and
> > > > > > > > at
> > > > > > > > this point we should not modify the computed state.
> > > > > > > 
> > > > > > > I'm not suggesting modifying anything during commit
> > > > > > > phase. I
> > > > > > > think
> > > > > > > you are effectiely doing that right now by stuffing that
> > > > > > > mst
> > > > > > > master
> > > > > > > transcoder into intel_dp.
> > > > > > 
> > > > > > Sorry, I still don't get what approach are you suggesting
> > > > > > here.
> > > > > > 
> > > > > > If we can't modify the state in the commit phase, adding
> > > > > > mst_master_transcoder in the CRTC state will not be
> > > > > > possible
> > > > > > while
> > > > > > respecting the order imposed by ddb allocations.
> > > > > 
> > > > > The ddb allocation ordering only comes into play when there
> > > > > are
> > > > > already active pipes. It should always be possible to not
> > > > > enable
> > > > > the slaves until the master has been shuffled into place in
> > > > > the 
> > > > > ddb and enabled.
> > > > 
> > > > This sounds contradictory to what you answered here: 
> > > > https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html
> > > > 
> > > > Will need to some testing to get the steps but I was able
> > > > consistent to
> > > > get to state were doing a full modeset in pipe A(mst master)
> > > > caused
> > > > the
> > > > pipe B(mst slave) to enabled first because of the ddb
> > > > allocations.
> > > > 
> > > > So can I or not do something like port sync does? And force the
> > > > enable
> > > > of master before the slaves? If possible, the comment in
> > > > skl_commit_modeset_enables() will need some changes.
> > > 
> > > I suspect for the mst stuff we should do:
> > > 
> > > while_dirty_mst_masters() {
> > > 	if (!ddb_overlap)
> > > 		enable();
> > > }
> > > while_dirty_mst_slaves() {
> > > 	if (!ddb_overlap)
> > > 		enable();
> > > }
> > 
> > What about this case?
> > 
> > Pipe/transcoder A and B in the same MST stream
> > 
> > # old state - DDB allocation: AABBB
> > mst master = transcoder A(computed in atomic check phase)
> > entries[0].start = 0
> > entries[0].end = 1
> > entries[1].start = 2
> > entries[1].end = 4
> > 
> > # new state - DDB allocation: AAABBB
> > mst master = transcoder A(computed in atomic check phase)
> > entries[0].start = 0
> > entries[0].end = 2
> > entries[1].start = 3
> > entries[1].end = 5
> > 
> > while_dirty_mst_masters()
> > 	first iteration: pipe A will overlap with old pipe B DDB
> 
> There won't be an old DDB allocation for a pipe if it's going
> trough a modeset.

Just added some debug messages to skl_commit_modeset_enables(), changed
the resolution of the 2 pipes enabled in the same MST stream and
old_crtc_state->wm.skl.ddb is set kept set with the old values.

So should we fix that first loop in skl_commit_modeset_enables()?

for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i)
	/* ignore allocations for crtc's that have been turned off. */
	if (!needs_modeset(new_crtc_state) && new_crtc_state-
>hw.active)
		entries[i] = old_crtc_state->wm.skl.ddb;


In this case there is not difference between old_crtc_state->wm.skl.ddb 
or new_crtc_state->wm.skl.ddb, so maybe also change to new_crtc_state?

> 
> > allocation
> > 	second iteration: pipe B is slave of A
> > 	third iteration: ?
> > 
> > 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream
  2019-12-04 18:48                     ` Souza, Jose
@ 2019-12-04 19:03                       ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2019-12-04 19:03 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx, De Marchi, Lucas

On Wed, Dec 04, 2019 at 06:48:42PM +0000, Souza, Jose wrote:
> On Wed, 2019-12-04 at 12:55 +0200, Ville Syrjälä wrote:
> > On Tue, Dec 03, 2019 at 10:12:47PM +0000, Souza, Jose wrote:
> > > On Tue, 2019-12-03 at 14:47 +0200, Ville Syrjälä wrote:
> > > > On Mon, Dec 02, 2019 at 10:03:38PM +0000, Souza, Jose wrote:
> > > > > On Thu, 2019-11-28 at 14:06 +0200, Ville Syrjälä wrote:
> > > > > > On Thu, Nov 28, 2019 at 01:14:37AM +0000, Souza, Jose wrote:
> > > > > > > On Wed, 2019-11-27 at 21:59 +0200, Ville Syrjälä wrote:
> > > > > > > > On Tue, Nov 26, 2019 at 08:30:31PM +0000, Souza, Jose
> > > > > > > > wrote:
> > > > > > > > > On Tue, 2019-11-26 at 22:05 +0200, Ville Syrjälä wrote:
> > > > > > > > > > On Fri, Nov 22, 2019 at 04:54:55PM -0800, José
> > > > > > > > > > Roberto de
> > > > > > > > > > Souza
> > > > > > > > > > wrote:
> > > > > > > > > > > On TGL the blending of all the streams have moved
> > > > > > > > > > > from
> > > > > > > > > > > DDI
> > > > > > > > > > > to
> > > > > > > > > > > transcoder, so now every transcoder working over
> > > > > > > > > > > the
> > > > > > > > > > > same
> > > > > > > > > > > MST
> > > > > > > > > > > port
> > > > > > > > > > > must
> > > > > > > > > > > send its stream to a master transcoder and master
> > > > > > > > > > > will
> > > > > > > > > > > send
> > > > > > > > > > > to
> > > > > > > > > > > DDI
> > > > > > > > > > > respecting the time slots.
> > > > > > > > > > > 
> > > > > > > > > > > A previous approach was using the lowest
> > > > > > > > > > > pipe/transcoder as
> > > > > > > > > > > master
> > > > > > > > > > > transcoder but as the comment in
> > > > > > > > > > > skl_commit_modeset_enables()
> > > > > > > > > > > states,
> > > > > > > > > > > that is not always true.
> > > > > > > > > > > 
> > > > > > > > > > > So here promoting the first pipe/transcoder of the
> > > > > > > > > > > stream
> > > > > > > > > > > as
> > > > > > > > > > > master.
> > > > > > > > > > > That caused several other problems as during the
> > > > > > > > > > > commit
> > > > > > > > > > > phase
> > > > > > > > > > > the
> > > > > > > > > > > state computed should not be changed.
> > > > > > > > > > > 
> > > > > > > > > > > So the master transcoder is store into intel_dp and
> > > > > > > > > > > the
> > > > > > > > > > > modeset
> > > > > > > > > > > in
> > > > > > > > > > > slave pipes/transcoders is forced using
> > > > > > > > > > > mst_master_trans_pending.
> > > > > > > > > > > 
> > > > > > > > > > > v2:
> > > > > > > > > > > - added missing config compute to trigger
> > > > > > > > > > > fullmodeset
> > > > > > > > > > > in
> > > > > > > > > > > slave
> > > > > > > > > > > transcoders
> > > > > > > > > > > 
> > > > > > > > > > > BSpec: 50493
> > > > > > > > > > > BSpec: 49190
> > > > > > > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > > > > > > Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> > > > > > > > > > > Signed-off-by: José Roberto de Souza <
> > > > > > > > > > > jose.souza@intel.com>
> > > > > > > > > > > ---
> > > > > > > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  1
> > > > > > > > > > > 0 +-
> > > > > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |  5
> > > > > > > > > > > 8
> > > > > > > > > > > ++++++-
> > > > > > > > > > >  .../drm/i915/display/intel_display_types.h    |   
> > > > > > > > > > > 3 +
> > > > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c       |   
> > > > > > > > > > > 1 +
> > > > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   |
> > > > > > > > > > > 149
> > > > > > > > > > > +++++++++++++++++-
> > > > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp_mst.h   |   
> > > > > > > > > > > 2 +
> > > > > > > > > > >  6 files changed, 216 insertions(+), 7 deletions(-)
> > > > > > > > > > > 
> > > > > > > > > > > diff --git
> > > > > > > > > > > a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > > index a976606d21c7..d2f0d393d3ee 100644
> > > > > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > > > > @@ -35,6 +35,7 @@
> > > > > > > > > > >  #include "intel_display_types.h"
> > > > > > > > > > >  #include "intel_dp.h"
> > > > > > > > > > >  #include "intel_dp_link_training.h"
> > > > > > > > > > > +#include "intel_dp_mst.h"
> > > > > > > > > > >  #include "intel_dpio_phy.h"
> > > > > > > > > > >  #include "intel_dsi.h"
> > > > > > > > > > >  #include "intel_fifo_underrun.h"
> > > > > > > > > > > @@ -1903,8 +1904,13 @@
> > > > > > > > > > > intel_ddi_transcoder_func_reg_val_get(const
> > > > > > > > > > > struct intel_crtc_state *crtc_state)
> > > > > > > > > > >  		temp |= TRANS_DDI_MODE_SELECT_DP_MST;
> > > > > > > > > > >  		temp |= DDI_PORT_WIDTH(crtc_state-
> > > > > > > > > > > > lane_count);
> > > > > > > > > > >  
> > > > > > > > > > > -		if (INTEL_GEN(dev_priv) >= 12)
> > > > > > > > > > > -			temp |=
> > > > > > > > > > > TRANS_DDI_MST_TRANSPORT_SELECT(crtc_state-
> > > > > > > > > > > > cpu_transcoder);
> > > > > > > > > > > +		if (INTEL_GEN(dev_priv) >= 12) {
> > > > > > > > > > > +			enum transcoder master;
> > > > > > > > > > > +
> > > > > > > > > > > +			master =
> > > > > > > > > > > intel_dp_mst_master_trans_get(encoder);
> > > > > > > > > > 
> > > > > > > > > > Why isn't that just stored in the crtc state like
> > > > > > > > > > everything
> > > > > > > > > > else?
> > > > > > > > > > 
> > > > > > > > > > I'm thinking we should maybe do it just like port
> > > > > > > > > > sync
> > > > > > > > > > and
> > > > > > > > > > have
> > > > > > > > > > both
> > > > > > > > > > master + slave_mask. That way it should be pretty
> > > > > > > > > > trivial
> > > > > > > > > > to
> > > > > > > > > > add
> > > > > > > > > > all
> > > > > > > > > > the relevant crtcs to the state when needed.
> > > > > > > > > 
> > > > > > > > > I guess port sync is not doing the right thing and it
> > > > > > > > > could
> > > > > > > > > cause
> > > > > > > > > underruns.
> > > > > > > > > When it is going to enable the master CRTC of the port
> > > > > > > > > sync
> > > > > > > > > it
> > > > > > > > > forcibly
> > > > > > > > > enables the slave first, what could cause underruns
> > > > > > > > > because
> > > > > > > > > of
> > > > > > > > > overlap
> > > > > > > > > in ddb allocations(that is what I understood from the
> > > > > > > > > comment
> > > > > > > > > in
> > > > > > > > > skl_commit_modeset_enables()).
> > > > > > > > 
> > > > > > > > Not necessarily just underruns but even a system hang.
> > > > > > > > The
> > > > > > > > fix
> > > > > > > > should
> > > > > > > > be
> > > > > > > > a trivial "check the slave for ddb overlap as well", but
> > > > > > > > apparently I
> > > > > > > > failed at convicing people to do that.
> > > > > > > > 
> > > > > > > > I've actually been pondering about decoupling the plane
> > > > > > > > updates
> > > > > > > > from
> > > > > > > > the crtc enable stuff entirely. At least theoretically
> > > > > > > > crtc
> > > > > > > > enable
> > > > > > > > should be able to excute in any order as long we don't
> > > > > > > > enable
> > > > > > > > any
> > > > > > > > new planes.
> > > > > > > > 
> > > > > > > > But none of that really matters for the discussion at
> > > > > > > > hand.
> > > > > > > > Though
> > > > > > > > there are other problems with the port sync stuff that
> > > > > > > > would
> > > > > > > > need
> > > > > > > > to be handled better. Eg. I think it now adds both crtcs
> > > > > > > > to
> > > > > > > > the
> > > > > > > > state
> > > > > > > > always which is going to cut the fps in half. Also the
> > > > > > > > place
> > > > > > > > where
> > > > > > > > it does that stuff is rather suspicious. All that stuff
> > > > > > > > should be
> > > > > > > > somewhere a bit higher up IMO.
> > > > > > > > 
> > > > > > > > > So for MST we only know who is the master in the commit
> > > > > > > > > phase
> > > > > > > > > and
> > > > > > > > > at
> > > > > > > > > this point we should not modify the computed state.
> > > > > > > > 
> > > > > > > > I'm not suggesting modifying anything during commit
> > > > > > > > phase. I
> > > > > > > > think
> > > > > > > > you are effectiely doing that right now by stuffing that
> > > > > > > > mst
> > > > > > > > master
> > > > > > > > transcoder into intel_dp.
> > > > > > > 
> > > > > > > Sorry, I still don't get what approach are you suggesting
> > > > > > > here.
> > > > > > > 
> > > > > > > If we can't modify the state in the commit phase, adding
> > > > > > > mst_master_transcoder in the CRTC state will not be
> > > > > > > possible
> > > > > > > while
> > > > > > > respecting the order imposed by ddb allocations.
> > > > > > 
> > > > > > The ddb allocation ordering only comes into play when there
> > > > > > are
> > > > > > already active pipes. It should always be possible to not
> > > > > > enable
> > > > > > the slaves until the master has been shuffled into place in
> > > > > > the 
> > > > > > ddb and enabled.
> > > > > 
> > > > > This sounds contradictory to what you answered here: 
> > > > > https://lists.freedesktop.org/archives/intel-gfx/2019-November/221608.html
> > > > > 
> > > > > Will need to some testing to get the steps but I was able
> > > > > consistent to
> > > > > get to state were doing a full modeset in pipe A(mst master)
> > > > > caused
> > > > > the
> > > > > pipe B(mst slave) to enabled first because of the ddb
> > > > > allocations.
> > > > > 
> > > > > So can I or not do something like port sync does? And force the
> > > > > enable
> > > > > of master before the slaves? If possible, the comment in
> > > > > skl_commit_modeset_enables() will need some changes.
> > > > 
> > > > I suspect for the mst stuff we should do:
> > > > 
> > > > while_dirty_mst_masters() {
> > > > 	if (!ddb_overlap)
> > > > 		enable();
> > > > }
> > > > while_dirty_mst_slaves() {
> > > > 	if (!ddb_overlap)
> > > > 		enable();
> > > > }
> > > 
> > > What about this case?
> > > 
> > > Pipe/transcoder A and B in the same MST stream
> > > 
> > > # old state - DDB allocation: AABBB
> > > mst master = transcoder A(computed in atomic check phase)
> > > entries[0].start = 0
> > > entries[0].end = 1
> > > entries[1].start = 2
> > > entries[1].end = 4
> > > 
> > > # new state - DDB allocation: AAABBB
> > > mst master = transcoder A(computed in atomic check phase)
> > > entries[0].start = 0
> > > entries[0].end = 2
> > > entries[1].start = 3
> > > entries[1].end = 5
> > > 
> > > while_dirty_mst_masters()
> > > 	first iteration: pipe A will overlap with old pipe B DDB
> > 
> > There won't be an old DDB allocation for a pipe if it's going
> > trough a modeset.
> 
> Just added some debug messages to skl_commit_modeset_enables(), changed
> the resolution of the 2 pipes enabled in the same MST stream and
> old_crtc_state->wm.skl.ddb is set kept set with the old values.
> 
> So should we fix that first loop in skl_commit_modeset_enables()?
> 
> for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> new_crtc_state, i)
> 	/* ignore allocations for crtc's that have been turned off. */
> 	if (!needs_modeset(new_crtc_state) && new_crtc_state-
> >hw.active)
> 		entries[i] = old_crtc_state->wm.skl.ddb;

I thought this is what it already did, but I guess I was wrong. Yes,
I think this is what it should do.

> In this case there is not difference between old_crtc_state->wm.skl.ddb 
> or new_crtc_state->wm.skl.ddb, so maybe also change to new_crtc_state?

I think it's better to keep using the old crtc state here. Just in case
someone comes up with a good reason to do ddb reallocation across pipes
when there isn't a modeset.

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

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

end of thread, other threads:[~2019-12-04 19:03 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-23  0:54 [PATCH 1/7] drm/i915/display: Refactor intel_commit_modeset_disables() José Roberto de Souza
2019-11-23  0:54 ` [Intel-gfx] " José Roberto de Souza
2019-11-23  0:54 ` [PATCH 2/7] drm/i915/display: Check the old state to find port sync slave José Roberto de Souza
2019-11-23  0:54   ` [Intel-gfx] " José Roberto de Souza
2019-11-26 19:41   ` Ville Syrjälä
2019-11-26 19:41     ` [Intel-gfx] " Ville Syrjälä
2019-11-23  0:54 ` [PATCH 3/7] drm/i915/tgl: Select master trasconder for MST stream José Roberto de Souza
2019-11-23  0:54   ` [Intel-gfx] " José Roberto de Souza
2019-11-26 20:05   ` Ville Syrjälä
2019-11-26 20:05     ` [Intel-gfx] " Ville Syrjälä
2019-11-26 20:30     ` Souza, Jose
2019-11-26 20:30       ` [Intel-gfx] " Souza, Jose
2019-11-27 19:59       ` Ville Syrjälä
2019-11-27 19:59         ` [Intel-gfx] " Ville Syrjälä
2019-11-28  1:14         ` Souza, Jose
2019-11-28  1:14           ` [Intel-gfx] " Souza, Jose
2019-11-28 12:06           ` Ville Syrjälä
2019-11-28 12:06             ` [Intel-gfx] " Ville Syrjälä
2019-12-02 22:03             ` Souza, Jose
2019-12-02 22:03               ` [Intel-gfx] " Souza, Jose
2019-12-03 12:47               ` Ville Syrjälä
2019-12-03 22:12                 ` Souza, Jose
2019-12-04 10:55                   ` Ville Syrjälä
2019-12-04 18:48                     ` Souza, Jose
2019-12-04 19:03                       ` Ville Syrjälä
2019-11-23  0:54 ` [PATCH 4/7] drm/i915/dp: Power down sink before disable pipe/transcoder clock José Roberto de Souza
2019-11-23  0:54   ` [Intel-gfx] " José Roberto de Souza
2019-11-26 20:15   ` Ville Syrjälä
2019-11-26 20:15     ` [Intel-gfx] " Ville Syrjälä
2019-11-26 22:12     ` Souza, Jose
2019-11-26 22:12       ` [Intel-gfx] " Souza, Jose
2019-11-27 19:24       ` Ville Syrjälä
2019-11-27 19:24         ` [Intel-gfx] " Ville Syrjälä
2019-11-28  1:08         ` Souza, Jose
2019-11-28  1:08           ` [Intel-gfx] " Souza, Jose
2019-11-28 18:30           ` Ville Syrjälä
2019-11-28 18:30             ` [Intel-gfx] " Ville Syrjälä
2019-11-23  0:54 ` [PATCH 5/7] drm/i915/display/mst: Move DPMS_OFF call to post_disable José Roberto de Souza
2019-11-23  0:54   ` [Intel-gfx] " José Roberto de Souza
2019-11-28 18:31   ` Ville Syrjälä
2019-11-28 18:31     ` [Intel-gfx] " Ville Syrjälä
2019-11-23  0:54 ` [PATCH 6/7] drm/i915/display/tgl: Fix the order of the step to turn transcoder clock off José Roberto de Souza
2019-11-23  0:54   ` [Intel-gfx] " José Roberto de Souza
2019-11-28 18:40   ` Ville Syrjälä
2019-11-28 18:40     ` [Intel-gfx] " Ville Syrjälä
2019-12-03 23:29     ` Souza, Jose
2019-12-04 10:56       ` Ville Syrjälä
2019-11-23  0:54 ` [PATCH 7/7] drm/display/dp: Fix MST disable sequences José Roberto de Souza
2019-11-23  0:54   ` [Intel-gfx] " José Roberto de Souza
2019-11-23  1:28 ` ✓ Fi.CI.BAT: success for series starting with [1/7] drm/i915/display: Refactor intel_commit_modeset_disables() Patchwork
2019-11-23  1:28   ` [Intel-gfx] " Patchwork
2019-11-24  7:11 ` ✓ Fi.CI.IGT: " Patchwork
2019-11-24  7:11   ` [Intel-gfx] " Patchwork
2019-11-26 19:40 ` [PATCH 1/7] " Ville Syrjälä
2019-11-26 19:40   ` [Intel-gfx] " Ville Syrjälä
2019-11-26 22:03   ` Souza, Jose
2019-11-26 22:03     ` [Intel-gfx] " Souza, Jose
2019-11-26 22:49     ` Matt Roper
2019-11-26 22:49       ` [Intel-gfx] " Matt Roper
2019-11-26 23:03       ` Souza, Jose
2019-11-26 23:03         ` [Intel-gfx] " Souza, Jose
2019-11-27 18:49       ` Lucas De Marchi
2019-11-27 18:49         ` [Intel-gfx] " Lucas De Marchi
2019-11-27 19:11     ` Ville Syrjälä
2019-11-27 19:11       ` [Intel-gfx] " 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.