diff mbox series

[2/6] drm/i915/display/icl: Enable TRANSCODER PORT SYNC for tiled displays across separate ports

Message ID 20190909034325.20006-3-manasi.d.navare@intel.com (mailing list archive)
State New, archived
Headers show
Series Remaining patches to enable Transcoder Port Sync for tiled displays | expand

Commit Message

Navare, Manasi Sept. 9, 2019, 3:43 a.m. UTC
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.

v4:
Rebase
v3:
* Check of DP_MST moved to atomic_check (Maarten)
v2:
* Do not use RMW, just write to the register in commit (Jani N)

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

Comments

Maarten Lankhorst Sept. 17, 2019, 2:52 p.m. UTC | #1
Op 09-09-2019 om 05:43 schreef Manasi Navare:
> 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.
>
> v4:
> Rebase
> v3:
> * Check of DP_MST moved to atomic_check (Maarten)
> v2:
> * Do not use RMW, just write to the register in commit (Jani N)
>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 43 ++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8942c905ae66..b8f7a919b6d3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -4380,6 +4380,46 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
>  	I915_WRITE(PIPE_CHICKEN(pipe), tmp);
>  }
>  
> +static void icl_enable_trans_port_sync(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);
> +	u32 trans_ddi_func_ctl2_val;
> +	u8 master_select;
> +
> +	/*
> +	 * Configure the master select and enable Transcoder Port Sync for
> +	 * Slave CRTCs transcoder.
> +	 */
> +	if (crtc_state->master_transcoder == INVALID_TRANSCODER)
> +		return;
> +
> +	switch (crtc_state->master_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;
> +	}
default should use MISSING_CASE() Otherwise looks good.
> +	/* Set the master select bits for Tranascoder Port Sync */
> +	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)
>  {
> @@ -6448,6 +6488,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_enable_trans_port_sync(pipe_config);
> +
>  	intel_set_pipe_src_size(pipe_config);
>  
>  	if (cpu_transcoder != TRANSCODER_EDP &&
Maarten Lankhorst Sept. 17, 2019, 2:52 p.m. UTC | #2
Op 09-09-2019 om 05:43 schreef Manasi Navare:
> 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.
>
> v4:
> Rebase
> v3:
> * Check of DP_MST moved to atomic_check (Maarten)
> v2:
> * Do not use RMW, just write to the register in commit (Jani N)
>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 43 ++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8942c905ae66..b8f7a919b6d3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -4380,6 +4380,46 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
>  	I915_WRITE(PIPE_CHICKEN(pipe), tmp);
>  }
>  
> +static void icl_enable_trans_port_sync(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);
> +	u32 trans_ddi_func_ctl2_val;
> +	u8 master_select;
> +
> +	/*
> +	 * Configure the master select and enable Transcoder Port Sync for
> +	 * Slave CRTCs transcoder.
> +	 */
> +	if (crtc_state->master_transcoder == INVALID_TRANSCODER)
> +		return;
> +
> +	switch (crtc_state->master_transcoder) {
> +	case TRANSCODER_A:
> +		master_select = 1;
> +		break;
> +	case TRANSCODER_B:
> +		master_select = 2;
> +		break;
> +	case TRANSCODER_C:
> +		master_select = 3;
> +		break;
TRANSCODER_D btw?
> +	case TRANSCODER_EDP:
> +	default:
> +		master_select = 0;
> +		break;
> +	}
> +	/* Set the master select bits for Tranascoder Port Sync */
> +	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)
>  {
> @@ -6448,6 +6488,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_enable_trans_port_sync(pipe_config);
> +
>  	intel_set_pipe_src_size(pipe_config);
>  
>  	if (cpu_transcoder != TRANSCODER_EDP &&
Navare, Manasi Sept. 17, 2019, 4:55 p.m. UTC | #3
On Tue, Sep 17, 2019 at 04:52:54PM +0200, Maarten Lankhorst wrote:
> Op 09-09-2019 om 05:43 schreef Manasi Navare:
> > 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.
> >
> > v4:
> > Rebase
> > v3:
> > * Check of DP_MST moved to atomic_check (Maarten)
> > v2:
> > * Do not use RMW, just write to the register in commit (Jani N)
> >
> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: Matt Roper <matthew.d.roper@intel.com>
> > Cc: Jani Nikula <jani.nikula@intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 43 ++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 8942c905ae66..b8f7a919b6d3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -4380,6 +4380,46 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
> >  	I915_WRITE(PIPE_CHICKEN(pipe), tmp);
> >  }
> >  
> > +static void icl_enable_trans_port_sync(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);
> > +	u32 trans_ddi_func_ctl2_val;
> > +	u8 master_select;
> > +
> > +	/*
> > +	 * Configure the master select and enable Transcoder Port Sync for
> > +	 * Slave CRTCs transcoder.
> > +	 */
> > +	if (crtc_state->master_transcoder == INVALID_TRANSCODER)
> > +		return;
> > +
> > +	switch (crtc_state->master_transcoder) {
> > +	case TRANSCODER_A:
> > +		master_select = 1;
> > +		break;
> > +	case TRANSCODER_B:
> > +		master_select = 2;
> > +		break;
> > +	case TRANSCODER_C:
> > +		master_select = 3;
> > +		break;
> TRANSCODER_D btw?

Yes will add that

Manasi

> > +	case TRANSCODER_EDP:
> > +	default:
> > +		master_select = 0;
> > +		break;
> > +	}
> > +	/* Set the master select bits for Tranascoder Port Sync */
> > +	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)
> >  {
> > @@ -6448,6 +6488,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_enable_trans_port_sync(pipe_config);
> > +
> >  	intel_set_pipe_src_size(pipe_config);
> >  
> >  	if (cpu_transcoder != TRANSCODER_EDP &&
> 
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8942c905ae66..b8f7a919b6d3 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4380,6 +4380,46 @@  static void icl_set_pipe_chicken(struct intel_crtc *crtc)
 	I915_WRITE(PIPE_CHICKEN(pipe), tmp);
 }
 
+static void icl_enable_trans_port_sync(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);
+	u32 trans_ddi_func_ctl2_val;
+	u8 master_select;
+
+	/*
+	 * Configure the master select and enable Transcoder Port Sync for
+	 * Slave CRTCs transcoder.
+	 */
+	if (crtc_state->master_transcoder == INVALID_TRANSCODER)
+		return;
+
+	switch (crtc_state->master_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 = (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)
 {
@@ -6448,6 +6488,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_enable_trans_port_sync(pipe_config);
+
 	intel_set_pipe_src_size(pipe_config);
 
 	if (cpu_transcoder != TRANSCODER_EDP &&