[Intel-gfx] [PATCH 2/2] drm/i915/icl: Enable TRANSCODER PORT SYNC for tiled displays across separate ports

Manasi Navare manasi.d.navare at intel.com
Fri Mar 22 01:59:39 UTC 2019


In case of tiled displays where different tiles are displayed across
different ports, we need to synchronize the transcoders involved.
This patch implements the transcoder port sync feature for
synchronizing one master transcoder with one or more slave
transcoders. This is only enbaled in slave transcoder
and the master transcoder is unaware that it is operating
in this mode.
This has been tested with tiled display connected to ICL.

Cc: Daniel Vetter <daniel.vetter at intel.com>
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Matt Roper <matthew.d.roper at intel.com>
Cc: Jani Nikula <jani.nikula at intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare at intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 59 ++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9980a4ed8c9c..16b46a3cb3bd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4009,6 +4009,62 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
 	I915_WRITE(PIPE_CHICKEN(pipe), tmp);
 }
 
+static void icl_set_transcoder_port_sync(struct intel_atomic_state *old_intel_state,
+					 const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_crtc_state *genlock_crtc_state = NULL;
+	enum transcoder genlock_transcoder;
+	u32 trans_ddi_func_ctl2_val;
+	u8 master_select;
+
+	/*
+	 * Port Sync Mode cannot be enabled for DP MST
+	 */
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
+		return;
+
+	/*
+	 * Configure the master select and enable Transcoder Port Sync for
+	 * Slave CRTCs transcoder.
+	 */
+	if (!crtc_state->genlock_crtc)
+		return;
+
+	genlock_crtc_state = intel_atomic_get_new_crtc_state(old_intel_state,
+							     crtc_state->genlock_crtc);
+	if (WARN_ON(!genlock_crtc_state))
+		return;
+
+	genlock_transcoder = genlock_crtc_state->cpu_transcoder;
+	switch (genlock_transcoder) {
+	case TRANSCODER_A:
+		master_select = 1;
+		break;
+	case TRANSCODER_B:
+		master_select = 2;
+		break;
+	case TRANSCODER_C:
+		master_select = 3;
+		break;
+	case TRANSCODER_EDP:
+	default:
+		master_select = 0;
+		break;
+	}
+	/* Set the master select bits for Tranascoder Port Sync */
+	trans_ddi_func_ctl2_val = I915_READ(TRANS_DDI_FUNC_CTL2(crtc_state->cpu_transcoder));
+	trans_ddi_func_ctl2_val |= (PORT_SYNC_MODE_MASTER_SELECT(master_select) &
+				    PORT_SYNC_MODE_MASTER_SELECT_MASK) <<
+		PORT_SYNC_MODE_MASTER_SELECT_SHIFT;
+	/* Enable Transcoder Port Sync */
+	trans_ddi_func_ctl2_val |= PORT_SYNC_MODE_ENABLE;
+
+	I915_WRITE(TRANS_DDI_FUNC_CTL2(crtc_state->cpu_transcoder),
+		   trans_ddi_func_ctl2_val);
+}
+
 static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_state,
 				     const struct intel_crtc_state *new_crtc_state)
 {
@@ -5960,6 +6016,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (!transcoder_is_dsi(cpu_transcoder))
 		intel_set_pipe_timings(pipe_config);
 
+	if (INTEL_GEN(dev_priv) >= 11)
+		icl_set_transcoder_port_sync(old_intel_state, pipe_config);
+
 	intel_set_pipe_src_size(pipe_config);
 
 	if (cpu_transcoder != TRANSCODER_EDP &&
-- 
2.19.1



More information about the Intel-gfx mailing list