All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
To: "José Roberto de Souza" <jose.souza@intel.com>,
	intel-gfx@lists.freedesktop.org
Cc: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
Subject: Re: [Intel-gfx] [PATCH v3 2/3] drm/i915/display: Only keep PSR enabled if there is active planes
Date: Wed, 22 Sep 2021 19:28:43 +0300	[thread overview]
Message-ID: <51b29ee9-7927-7b0d-eb86-b8cff7775ffc@intel.com> (raw)
In-Reply-To: <20210921004113.261827-2-jose.souza@intel.com>

Looks good to me.
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>

On 9/21/21 3:41 AM, José Roberto de Souza wrote:
> PSR always had a requirement to only be enabled if there is active
> planes but not following that never caused any issues.
> But that changes in Alderlake-P, leaving PSR enabled without
> active planes causes transcoder/port underruns.
> 
> Similar behavior was fixed during the pipe disable sequence by
> commit 84030adb9e27 ("drm/i915/display: Disable audio, DRRS and PSR before planes").
> 
> intel_dp_compute_psr_vsc_sdp() had to move from
> intel_psr_enable_locked() to intel_psr_compute_config() because we
> need to be able to disable/enable PSR from atomic states without
> connector and encoder state.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_ddi.c      |   2 -
>   drivers/gpu/drm/i915/display/intel_display.c  |  14 +-
>   .../drm/i915/display/intel_display_types.h    |   3 +-
>   drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
>   drivers/gpu/drm/i915/display/intel_dp.h       |   2 +-
>   drivers/gpu/drm/i915/display/intel_psr.c      | 140 ++++++++++--------
>   drivers/gpu/drm/i915/display/intel_psr.h      |  11 +-
>   7 files changed, 98 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bba0ab99836b1..a4667741d3548 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3034,7 +3034,6 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
>   		intel_dp_stop_link_train(intel_dp, crtc_state);
>   
>   	intel_edp_backlight_on(crtc_state, conn_state);
> -	intel_psr_enable(intel_dp, crtc_state, conn_state);
>   
>   	if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
>   		intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
> @@ -3255,7 +3254,6 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
>   
>   	intel_ddi_set_dp_msa(crtc_state, conn_state);
>   
> -	intel_psr_update(intel_dp, crtc_state, conn_state);
>   	intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
>   	intel_drrs_update(intel_dp, crtc_state);
>   
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index f6c0c595f6313..ddcd8d6efc788 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8093,10 +8093,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>   		if (bp_gamma)
>   			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma);
>   
> -		PIPE_CONF_CHECK_BOOL(has_psr);
> -		PIPE_CONF_CHECK_BOOL(has_psr2);
> -		PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
> -		PIPE_CONF_CHECK_I(dc3co_exitline);
> +		if (current_config->active_planes) {
> +			PIPE_CONF_CHECK_BOOL(has_psr);
> +			PIPE_CONF_CHECK_BOOL(has_psr2);
> +			PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
> +			PIPE_CONF_CHECK_I(dc3co_exitline);
> +		}
>   	}
>   
>   	PIPE_CONF_CHECK_BOOL(double_wide);
> @@ -8153,7 +8155,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>   		PIPE_CONF_CHECK_I(min_voltage_level);
>   	}
>   
> -	if (fastset && (current_config->has_psr || pipe_config->has_psr))
> +	if (current_config->has_psr || pipe_config->has_psr)
>   		PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable,
>   					    ~intel_hdmi_infoframe_enable(DP_SDP_VSC));
>   	else
> @@ -10207,6 +10209,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>   		intel_encoders_update_prepare(state);
>   
>   	intel_dbuf_pre_plane_update(state);
> +	intel_psr_pre_plane_update(state);
>   
>   	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
>   		if (new_crtc_state->uapi.async_flip)
> @@ -10270,6 +10273,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>   	}
>   
>   	intel_dbuf_post_plane_update(state);
> +	intel_psr_post_plane_update(state);
>   
>   	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
>   		intel_post_plane_update(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 e9e806d90eec4..c900bfbb7cc52 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1056,12 +1056,14 @@ struct intel_crtc_state {
>   	struct intel_link_m_n dp_m2_n2;
>   	bool has_drrs;
>   
> +	/* PSR is supported but might not be enabled due the lack of enabled planes */
>   	bool has_psr;
>   	bool has_psr2;
>   	bool enable_psr2_sel_fetch;
>   	bool req_psr2_sdp_prior_scanline;
>   	u32 dc3co_exitline;
>   	u16 su_y_granularity;
> +	struct drm_dp_vsc_sdp psr_vsc;
>   
>   	/*
>   	 * Frequence the dpll for the port should run at. Differs from the
> @@ -1525,7 +1527,6 @@ struct intel_psr {
>   	u32 dc3co_exitline;
>   	u32 dc3co_exit_delay;
>   	struct delayed_work dc3co_work;
> -	struct drm_dp_vsc_sdp vsc;
>   };
>   
>   struct intel_dp {
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 7559911c140a7..378008873e039 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1674,7 +1674,7 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
>   {
>   	vsc->sdp_type = DP_SDP_VSC;
>   
> -	if (intel_dp->psr.psr2_enabled) {
> +	if (crtc_state->has_psr2) {
>   		if (intel_dp->psr.colorimetry_support &&
>   		    intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
>   			/* [PSR2, +Colorimetry] */
> @@ -1828,7 +1828,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>   		g4x_dp_set_clock(encoder, pipe_config);
>   
>   	intel_vrr_compute_config(pipe_config, conn_state);
> -	intel_psr_compute_config(intel_dp, pipe_config);
> +	intel_psr_compute_config(intel_dp, pipe_config, conn_state);
>   	intel_drrs_compute_config(intel_dp, pipe_config, output_bpp,
>   				  constant_n);
>   	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
> @@ -2888,7 +2888,7 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
>   
>   void intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
>   			    const struct intel_crtc_state *crtc_state,
> -			    struct drm_dp_vsc_sdp *vsc)
> +			    const struct drm_dp_vsc_sdp *vsc)
>   {
>   	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
>   	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index 94b568704b22b..3343c25916807 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -88,7 +88,7 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
>   				  struct drm_dp_vsc_sdp *vsc);
>   void intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
>   			    const struct intel_crtc_state *crtc_state,
> -			    struct drm_dp_vsc_sdp *vsc);
> +			    const struct drm_dp_vsc_sdp *vsc);
>   void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
>   			     const struct intel_crtc_state *crtc_state,
>   			     const struct drm_connector_state *conn_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index c1894b056d6c1..8ceb22c5a1a6b 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -949,7 +949,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>   }
>   
>   void intel_psr_compute_config(struct intel_dp *intel_dp,
> -			      struct intel_crtc_state *crtc_state)
> +			      struct intel_crtc_state *crtc_state,
> +			      struct drm_connector_state *conn_state)
>   {
>   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>   	const struct drm_display_mode *adjusted_mode =
> @@ -1001,7 +1002,10 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
>   
>   	crtc_state->has_psr = true;
>   	crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state);
> +
>   	crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
> +	intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
> +				     &crtc_state->psr_vsc);
>   }
>   
>   void intel_psr_get_config(struct intel_encoder *encoder,
> @@ -1181,8 +1185,7 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
>   }
>   
>   static void intel_psr_enable_locked(struct intel_dp *intel_dp,
> -				    const struct intel_crtc_state *crtc_state,
> -				    const struct drm_connector_state *conn_state)
> +				    const struct intel_crtc_state *crtc_state)
>   {
>   	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> @@ -1209,9 +1212,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
>   
>   	drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
>   		    intel_dp->psr.psr2_enabled ? "2" : "1");
> -	intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
> -				     &intel_dp->psr.vsc);
> -	intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc);
> +	intel_write_dp_vsc_sdp(encoder, crtc_state, &crtc_state->psr_vsc);
>   	intel_snps_phy_update_psr_power_state(dev_priv, phy, true);
>   	intel_psr_enable_sink(intel_dp);
>   	intel_psr_enable_source(intel_dp);
> @@ -1221,33 +1222,6 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
>   	intel_psr_activate(intel_dp);
>   }
>   
> -/**
> - * intel_psr_enable - Enable PSR
> - * @intel_dp: Intel DP
> - * @crtc_state: new CRTC state
> - * @conn_state: new CONNECTOR state
> - *
> - * This function can only be called after the pipe is fully trained and enabled.
> - */
> -void intel_psr_enable(struct intel_dp *intel_dp,
> -		      const struct intel_crtc_state *crtc_state,
> -		      const struct drm_connector_state *conn_state)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	if (!CAN_PSR(intel_dp))
> -		return;
> -
> -	if (!crtc_state->has_psr)
> -		return;
> -
> -	drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp);
> -
> -	mutex_lock(&intel_dp->psr.lock);
> -	intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
> -	mutex_unlock(&intel_dp->psr.lock);
> -}
> -
>   static void intel_psr_exit(struct intel_dp *intel_dp)
>   {
>   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> @@ -1719,48 +1693,92 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
>   	return 0;
>   }
>   
> -/**
> - * intel_psr_update - Update PSR state
> - * @intel_dp: Intel DP
> - * @crtc_state: new CRTC state
> - * @conn_state: new CONNECTOR state
> - *
> - * This functions will update PSR states, disabling, enabling or switching PSR
> - * version when executing fastsets. For full modeset, intel_psr_disable() and
> - * intel_psr_enable() should be called instead.
> - */
> -void intel_psr_update(struct intel_dp *intel_dp,
> -		      const struct intel_crtc_state *crtc_state,
> -		      const struct drm_connector_state *conn_state)
> +static void _intel_psr_pre_plane_update(const struct intel_atomic_state *state,
> +					const struct intel_crtc_state *crtc_state)
>   {
> -	struct intel_psr *psr = &intel_dp->psr;
> -	bool enable, psr2_enable;
> +	struct intel_encoder *encoder;
>   
> -	if (!CAN_PSR(intel_dp))
> +	for_each_intel_encoder_mask_with_psr(state->base.dev, encoder,
> +					     crtc_state->uapi.encoder_mask) {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +		struct intel_psr *psr = &intel_dp->psr;
> +		bool needs_to_disable = false;
> +
> +		mutex_lock(&psr->lock);
> +
> +		/*
> +		 * Reasons to disable:
> +		 * - PSR disabled in new state
> +		 * - All planes will go inactive
> +		 * - Changing between PSR versions
> +		 */
> +		needs_to_disable |= !crtc_state->has_psr;
> +		needs_to_disable |= !crtc_state->active_planes;
> +		needs_to_disable |= crtc_state->has_psr2 != psr->psr2_enabled;
> +
> +		if (psr->enabled && needs_to_disable)
> +			intel_psr_disable_locked(intel_dp);
> +
> +		mutex_unlock(&psr->lock);
> +	}
> +}
> +
> +void intel_psr_pre_plane_update(const struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc_state *crtc_state;
> +	struct intel_crtc *crtc;
> +	int i;
> +
> +	if (!HAS_PSR(dev_priv))
>   		return;
>   
> -	mutex_lock(&intel_dp->psr.lock);
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
> +		_intel_psr_pre_plane_update(state, crtc_state);
> +}
>   
> -	enable = crtc_state->has_psr;
> -	psr2_enable = crtc_state->has_psr2;
> +static void _intel_psr_post_plane_update(const struct intel_atomic_state *state,
> +					 const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_encoder *encoder;
> +
> +	if (!crtc_state->has_psr)
> +		return;
> +
> +	for_each_intel_encoder_mask_with_psr(state->base.dev, encoder,
> +					     crtc_state->uapi.encoder_mask) {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +		struct intel_psr *psr = &intel_dp->psr;
> +
> +		mutex_lock(&psr->lock);
> +
> +		drm_WARN_ON(&dev_priv->drm, psr->enabled && !crtc_state->active_planes);
> +
> +		/* Only enable if there is active planes */
> +		if (!psr->enabled && crtc_state->active_planes)
> +			intel_psr_enable_locked(intel_dp, crtc_state);
>   
> -	if (enable == psr->enabled && psr2_enable == psr->psr2_enabled &&
> -	    crtc_state->enable_psr2_sel_fetch == psr->psr2_sel_fetch_enabled) {
>   		/* Force a PSR exit when enabling CRC to avoid CRC timeouts */
>   		if (crtc_state->crc_enabled && psr->enabled)
>   			psr_force_hw_tracking_exit(intel_dp);
>   
> -		goto unlock;
> +		mutex_unlock(&psr->lock);
>   	}
> +}
>   
> -	if (psr->enabled)
> -		intel_psr_disable_locked(intel_dp);
> +void intel_psr_post_plane_update(const struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc_state *crtc_state;
> +	struct intel_crtc *crtc;
> +	int i;
>   
> -	if (enable)
> -		intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
> +	if (!HAS_PSR(dev_priv))
> +		return;
>   
> -unlock:
> -	mutex_unlock(&intel_dp->psr.lock);
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
> +		_intel_psr_post_plane_update(state, crtc_state);
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
> index 641521b101c82..2ca50df1f4fba 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -20,14 +20,10 @@ struct intel_plane;
>   struct intel_encoder;
>   
>   void intel_psr_init_dpcd(struct intel_dp *intel_dp);
> -void intel_psr_enable(struct intel_dp *intel_dp,
> -		      const struct intel_crtc_state *crtc_state,
> -		      const struct drm_connector_state *conn_state);
> +void intel_psr_pre_plane_update(const struct intel_atomic_state *state);
> +void intel_psr_post_plane_update(const struct intel_atomic_state *state);
>   void intel_psr_disable(struct intel_dp *intel_dp,
>   		       const struct intel_crtc_state *old_crtc_state);
> -void intel_psr_update(struct intel_dp *intel_dp,
> -		      const struct intel_crtc_state *crtc_state,
> -		      const struct drm_connector_state *conn_state);
>   int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
>   void intel_psr_invalidate(struct drm_i915_private *dev_priv,
>   			  unsigned frontbuffer_bits,
> @@ -37,7 +33,8 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
>   		     enum fb_op_origin origin);
>   void intel_psr_init(struct intel_dp *intel_dp);
>   void intel_psr_compute_config(struct intel_dp *intel_dp,
> -			      struct intel_crtc_state *crtc_state);
> +			      struct intel_crtc_state *crtc_state,
> +			      struct drm_connector_state *conn_state);
>   void intel_psr_get_config(struct intel_encoder *encoder,
>   			  struct intel_crtc_state *pipe_config);
>   void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir);
> 

  parent reply	other threads:[~2021-09-22 16:29 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-21  0:41 [Intel-gfx] [PATCH v3 1/3] drm/i915/display: Disable frontbuffer rendering when PSR2 selective fetch is enabled José Roberto de Souza
2021-09-21  0:41 ` [Intel-gfx] [PATCH v3 2/3] drm/i915/display: Only keep PSR enabled if there is active planes José Roberto de Souza
2021-09-22 16:28   ` Gwan-gyeong Mun
2021-09-22 16:28   ` Gwan-gyeong Mun [this message]
2021-09-21  0:41 ` [Intel-gfx] [PATCH v3 3/3] drm/i915/display/psr: Do full fetch when handling biplanar formats José Roberto de Souza
2021-09-22  8:28   ` Manna, Animesh
2021-09-22 12:08     ` Gwan-gyeong Mun
2021-09-22 14:17       ` Souza, Jose
2021-09-21  1:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v3,1/3] drm/i915/display: Disable frontbuffer rendering when PSR2 selective fetch is enabled Patchwork
2021-09-21  1:06 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-09-21  1:36 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51b29ee9-7927-7b0d-eb86-b8cff7775ffc@intel.com \
    --to=gwan-gyeong.mun@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jose.souza@intel.com \
    --cc=ville.syrjala@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.