[CI,v12,3/6] drm/i915/display/icl: HW state readout for transcoder port sync config
diff mbox series

Message ID 20191018172725.1338-3-manasi.d.navare@intel.com
State New
Headers show
Series
  • [CI,v12,1/6] drm/i915/display/icl: Save Master transcoder in slave's crtc_state for Transcoder Port Sync
Related show

Commit Message

Manasi Navare Oct. 18, 2019, 5:27 p.m. UTC
After the state is committed, we readout the HW registers and compare
the HW state with the SW state that we just committed.
For Transcdoer port sync, we add master_transcoder and the
salves bitmask to the crtc_state, hence we need to read those during
the HW state readout to avoid pipe state mismatch.

v11:
* Move master trans init to get pipe_Config hooks (Ville)
v10:
* Initialize master_tarnscoder readout for all platforms (Ville)
v9:
* Initialize master_transcoder = INVALID at get config (Ville)
v8:
* Use master_select -1, address TRANS_EDP case (Ville)
* Rename master_transcoder to _readout (Lucas)
v7:
* NDont read HW state for DSI
v6:
* Go through both parts of HW readout (Maarten)
* Add a WARN if the same trans configured as
master and slave (Ville, Maarten)
v5:
* Add return INVALID in defaut case (Maarten)
v4:
* Get power domains in master loop for get_config (Ville)
v3:
* Add TRANSCODER_D (Maarten)
* v3 Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
v2:
* Add Transcoder_D and MISSING_CASE (Maarten)

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>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 61 ++++++++++++++++++++
 1 file changed, 61 insertions(+)

Comments

Manasi Navare Oct. 18, 2019, 11:11 p.m. UTC | #1
Pushed to dinq, thanks for reviews

Manasi

On Fri, Oct 18, 2019 at 10:27:22AM -0700, Manasi Navare wrote:
> After the state is committed, we readout the HW registers and compare
> the HW state with the SW state that we just committed.
> For Transcdoer port sync, we add master_transcoder and the
> salves bitmask to the crtc_state, hence we need to read those during
> the HW state readout to avoid pipe state mismatch.
> 
> v11:
> * Move master trans init to get pipe_Config hooks (Ville)
> v10:
> * Initialize master_tarnscoder readout for all platforms (Ville)
> v9:
> * Initialize master_transcoder = INVALID at get config (Ville)
> v8:
> * Use master_select -1, address TRANS_EDP case (Ville)
> * Rename master_transcoder to _readout (Lucas)
> v7:
> * NDont read HW state for DSI
> v6:
> * Go through both parts of HW readout (Maarten)
> * Add a WARN if the same trans configured as
> master and slave (Ville, Maarten)
> v5:
> * Add return INVALID in defaut case (Maarten)
> v4:
> * Get power domains in master loop for get_config (Ville)
> v3:
> * Add TRANSCODER_D (Maarten)
> * v3 Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> v2:
> * Add Transcoder_D and MISSING_CASE (Maarten)
> 
> 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>
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 61 ++++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index aef11087a0fa..f6c57255bf28 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8798,6 +8798,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
>  	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
>  	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
>  	pipe_config->shared_dpll = NULL;
> +	pipe_config->master_transcoder = INVALID_TRANSCODER;
>  
>  	ret = false;
>  
> @@ -9987,6 +9988,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
>  
>  	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
>  	pipe_config->shared_dpll = NULL;
> +	pipe_config->master_transcoder = INVALID_TRANSCODER;
>  
>  	ret = false;
>  	tmp = I915_READ(PIPECONF(crtc->pipe));
> @@ -10437,6 +10439,59 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
>  	}
>  }
>  
> +static enum transcoder transcoder_master_readout(struct drm_i915_private *dev_priv,
> +						 enum transcoder cpu_transcoder)
> +{
> +	u32 trans_port_sync, master_select;
> +
> +	trans_port_sync = I915_READ(TRANS_DDI_FUNC_CTL2(cpu_transcoder));
> +
> +	if ((trans_port_sync & PORT_SYNC_MODE_ENABLE) == 0)
> +		return INVALID_TRANSCODER;
> +
> +	master_select = trans_port_sync &
> +			PORT_SYNC_MODE_MASTER_SELECT_MASK;
> +	if (master_select == 0)
> +		return TRANSCODER_EDP;
> +	else
> +		return master_select - 1;
> +}
> +
> +static void icelake_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	u32 transcoders;
> +	enum transcoder cpu_transcoder;
> +
> +	crtc_state->master_transcoder = transcoder_master_readout(dev_priv,
> +								  crtc_state->cpu_transcoder);
> +
> +	transcoders = BIT(TRANSCODER_A) |
> +		BIT(TRANSCODER_B) |
> +		BIT(TRANSCODER_C) |
> +		BIT(TRANSCODER_D);
> +	for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
> +		enum intel_display_power_domain power_domain;
> +		intel_wakeref_t trans_wakeref;
> +
> +		power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
> +		trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
> +								   power_domain);
> +
> +		if (!trans_wakeref)
> +			continue;
> +
> +		if (transcoder_master_readout(dev_priv, cpu_transcoder) ==
> +		    crtc_state->cpu_transcoder)
> +			crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder);
> +
> +		intel_display_power_put(dev_priv, power_domain, trans_wakeref);
> +	}
> +
> +	WARN_ON(crtc_state->master_transcoder != INVALID_TRANSCODER &&
> +		crtc_state->sync_mode_slaves_mask);
> +}
> +
>  static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>  				    struct intel_crtc_state *pipe_config)
>  {
> @@ -10448,6 +10503,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>  
>  	intel_crtc_init_scalers(crtc, pipe_config);
>  
> +	pipe_config->master_transcoder = INVALID_TRANSCODER;
> +
>  	power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
>  	wf = intel_display_power_get_if_enabled(dev_priv, power_domain);
>  	if (!wf)
> @@ -10556,6 +10613,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>  		pipe_config->pixel_multiplier = 1;
>  	}
>  
> +	if (INTEL_GEN(dev_priv) >= 11 &&
> +	    !transcoder_is_dsi(pipe_config->cpu_transcoder))
> +		icelake_get_trans_port_sync_config(pipe_config);
> +
>  out:
>  	for_each_power_domain(power_domain, power_domain_mask)
>  		intel_display_power_put(dev_priv,
> -- 
> 2.19.1
>

Patch
diff mbox series

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index aef11087a0fa..f6c57255bf28 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8798,6 +8798,7 @@  static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
 	pipe_config->shared_dpll = NULL;
+	pipe_config->master_transcoder = INVALID_TRANSCODER;
 
 	ret = false;
 
@@ -9987,6 +9988,7 @@  static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
 	pipe_config->shared_dpll = NULL;
+	pipe_config->master_transcoder = INVALID_TRANSCODER;
 
 	ret = false;
 	tmp = I915_READ(PIPECONF(crtc->pipe));
@@ -10437,6 +10439,59 @@  static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 	}
 }
 
+static enum transcoder transcoder_master_readout(struct drm_i915_private *dev_priv,
+						 enum transcoder cpu_transcoder)
+{
+	u32 trans_port_sync, master_select;
+
+	trans_port_sync = I915_READ(TRANS_DDI_FUNC_CTL2(cpu_transcoder));
+
+	if ((trans_port_sync & PORT_SYNC_MODE_ENABLE) == 0)
+		return INVALID_TRANSCODER;
+
+	master_select = trans_port_sync &
+			PORT_SYNC_MODE_MASTER_SELECT_MASK;
+	if (master_select == 0)
+		return TRANSCODER_EDP;
+	else
+		return master_select - 1;
+}
+
+static void icelake_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	u32 transcoders;
+	enum transcoder cpu_transcoder;
+
+	crtc_state->master_transcoder = transcoder_master_readout(dev_priv,
+								  crtc_state->cpu_transcoder);
+
+	transcoders = BIT(TRANSCODER_A) |
+		BIT(TRANSCODER_B) |
+		BIT(TRANSCODER_C) |
+		BIT(TRANSCODER_D);
+	for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
+		enum intel_display_power_domain power_domain;
+		intel_wakeref_t trans_wakeref;
+
+		power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
+		trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
+								   power_domain);
+
+		if (!trans_wakeref)
+			continue;
+
+		if (transcoder_master_readout(dev_priv, cpu_transcoder) ==
+		    crtc_state->cpu_transcoder)
+			crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder);
+
+		intel_display_power_put(dev_priv, power_domain, trans_wakeref);
+	}
+
+	WARN_ON(crtc_state->master_transcoder != INVALID_TRANSCODER &&
+		crtc_state->sync_mode_slaves_mask);
+}
+
 static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 				    struct intel_crtc_state *pipe_config)
 {
@@ -10448,6 +10503,8 @@  static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 
 	intel_crtc_init_scalers(crtc, pipe_config);
 
+	pipe_config->master_transcoder = INVALID_TRANSCODER;
+
 	power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
 	wf = intel_display_power_get_if_enabled(dev_priv, power_domain);
 	if (!wf)
@@ -10556,6 +10613,10 @@  static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 		pipe_config->pixel_multiplier = 1;
 	}
 
+	if (INTEL_GEN(dev_priv) >= 11 &&
+	    !transcoder_is_dsi(pipe_config->cpu_transcoder))
+		icelake_get_trans_port_sync_config(pipe_config);
+
 out:
 	for_each_power_domain(power_domain, power_domain_mask)
 		intel_display_power_put(dev_priv,