[Intel-gfx] [PATCH 09/13] drm/i915: Stash DRRS state under intel_crtc

Ville Syrjälä ville.syrjala at linux.intel.com
Thu Mar 10 11:12:42 UTC 2022


On Thu, Mar 10, 2022 at 12:53:58PM +0200, Jani Nikula wrote:
> On Thu, 10 Mar 2022, Ville Syrjala <ville.syrjala at linux.intel.com> wrote:
> > From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> >
> > Get rid of the ugly intel_dp dependency, and one more crtc->config
> > usage by storing the DRRS state under intel_crtc. intel_drrs_enable()
> > copies what it needs from the crtc state, after which DRRS can be
> > blissfully ignorant of anything going on around it.
> >
> > This also lets multiple pipes do DRRS simultanously and entirely
> > independently.
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> Ugh. What an annoying patch to review! :/
> 
> Overall it all looks sane and the direction is good, I had some
> nitpicks, and I didn't spot any mistakes. Dunno how easy it would be to
> split this up to smaller chunks and whether it would be worth the
> effort.

I couldn't immediately think of a nice way to split it. But
after further thought maybe I could try to eg. do the intel_dp
elimination first, and then move stuff into the crtc. I'll give
that a go...

> 
> Tentatively
> 
> Reviewed-by: Jani Nikula <jani.nikula at intel.com>
> 
> but my confidence level for spotting subtle mistakes in this one aren't
> high I'm afraid.
> 
> > ---
> >  drivers/gpu/drm/i915/display/intel_crtc.c     |   2 +
> >  drivers/gpu/drm/i915/display/intel_ddi.c      |   8 +-
> >  drivers/gpu/drm/i915/display/intel_display.c  |   2 +-
> >  .../drm/i915/display/intel_display_debugfs.c  |  97 ++----
> >  .../drm/i915/display/intel_display_types.h    |  14 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |   4 +-
> >  drivers/gpu/drm/i915/display/intel_drrs.c     | 300 +++++++-----------
> >  drivers/gpu/drm/i915/display/intel_drrs.h     |  20 +-
> >  drivers/gpu/drm/i915/i915_drv.h               |  15 -
> >  9 files changed, 171 insertions(+), 291 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> > index 65827481c1b1..f655c1622877 100644
> > --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> > +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> > @@ -24,6 +24,7 @@
> >  #include "intel_display_debugfs.h"
> >  #include "intel_display_trace.h"
> >  #include "intel_display_types.h"
> > +#include "intel_drrs.h"
> >  #include "intel_dsi.h"
> >  #include "intel_pipe_crc.h"
> >  #include "intel_psr.h"
> > @@ -367,6 +368,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
> >  
> >  	intel_color_init(crtc);
> >  
> > +	intel_crtc_drrs_init(crtc);
> >  	intel_crtc_crc_init(crtc);
> >  
> >  	cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE);
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 3e6d86a54850..a3bf4e876fb4 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -2820,7 +2820,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
> >  	if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
> >  		intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
> >  
> > -	intel_drrs_enable(intel_dp, crtc_state);
> > +	intel_drrs_enable(crtc_state);
> >  
> >  	if (crtc_state->has_audio)
> >  		intel_audio_codec_enable(encoder, crtc_state, conn_state);
> > @@ -2963,7 +2963,7 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,
> >  		intel_audio_codec_disable(encoder,
> >  					  old_crtc_state, old_conn_state);
> >  
> > -	intel_drrs_disable(intel_dp, old_crtc_state);
> > +	intel_drrs_disable(old_crtc_state);
> >  	intel_psr_disable(intel_dp, old_crtc_state);
> >  	intel_edp_backlight_off(old_conn_state);
> >  	/* Disable the decompression in DP Sink */
> > @@ -3013,12 +3013,12 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
> >  				     const struct intel_crtc_state *crtc_state,
> >  				     const struct drm_connector_state *conn_state)
> >  {
> > -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  
> >  	intel_ddi_set_dp_msa(crtc_state, conn_state);
> >  
> >  	intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
> > -	intel_drrs_update(intel_dp, crtc_state);
> > +	intel_drrs_update(state, crtc);
> >  
> >  	intel_backlight_update(state, encoder, crtc_state, conn_state);
> >  	drm_connector_update_privacy_screen(conn_state);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index b7c418677372..4c7c74665819 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -1229,7 +1229,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
> >  
> >  	hsw_ips_post_update(state, crtc);
> >  	intel_fbc_post_update(state, crtc);
> > -	intel_drrs_page_flip(state, crtc);
> > +	intel_drrs_page_flip(crtc);
> >  
> >  	if (needs_async_flip_vtd_wa(old_crtc_state) &&
> >  	    !needs_async_flip_vtd_wa(new_crtc_state))
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index 798bf233a60f..bbf6ebd18414 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -1143,87 +1143,44 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
> >  	return 0;
> >  }
> >  
> > -static void drrs_status_per_crtc(struct seq_file *m,
> > -				 struct drm_device *dev,
> > -				 struct intel_crtc *crtc)
> > +static int i915_drrs_status(struct seq_file *m, void *unused)
> >  {
> > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > -	struct i915_drrs *drrs = &dev_priv->drrs;
> > -	struct drm_connector *connector;
> > +	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> >  	struct drm_connector_list_iter conn_iter;
> > +	struct intel_connector *connector;
> > +	struct intel_crtc *crtc;
> >  
> > -	drm_connector_list_iter_begin(dev, &conn_iter);
> > -	drm_for_each_connector_iter(connector, &conn_iter) {
> > -		bool supported = false;
> > +	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
> > +	for_each_intel_connector_iter(connector, &conn_iter) {
> > +		seq_printf(m, "[CONNECTOR:%d:%s]:\n",
> > +			   connector->base.base.id, connector->base.name);
> >  
> > -		if (connector->state->crtc != &crtc->base)
> > -			continue;
> > -
> > -		seq_printf(m, "%s:\n", connector->name);
> > -
> > -		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP &&
> > -		    drrs->type == DRRS_TYPE_SEAMLESS)
> > -			supported = true;
> > -
> > -		seq_printf(m, "\tDRRS Supported: %s\n", str_yes_no(supported));
> > +		seq_printf(m, "\tDRRS Supported: %s\n",
> > +			   str_yes_no(connector->panel.downclock_mode));
> 
> "Supported" in the sense that the connector/panel can support it, but...

I should probably make this say static vs. seamless vs. no, so we know
what kind of DRRS one can expect.

> 
> >  	}
> >  	drm_connector_list_iter_end(&conn_iter);
> >  
> >  	seq_puts(m, "\n");
> >  
> > -	if (to_intel_crtc_state(crtc->base.state)->has_drrs) {
> > -		struct intel_panel *panel;
> > +	for_each_intel_crtc(&dev_priv->drm, crtc) {
> > +		seq_printf(m, "[CRTC:%d:%s]:\n",
> > +			   crtc->base.base.id, crtc->base.name);
> > +
> > +		mutex_lock(&crtc->drrs.mutex);
> >  
> > -		mutex_lock(&drrs->mutex);
> >  		/* DRRS Supported */
> > -		seq_puts(m, "\tDRRS Enabled: Yes\n");
> > +		seq_printf(m, "\tDRRS Enabled: %s\n",
> > +			   str_yes_no(intel_drrs_is_enabled(crtc)));
> >  
> > -		/* disable_drrs() will make drrs->dp NULL */
> > -		if (!drrs->dp) {
> > -			seq_puts(m, "Idleness DRRS: Disabled\n");
> > -			mutex_unlock(&drrs->mutex);
> > -			return;
> > -		}
> > -
> > -		panel = &drrs->dp->attached_connector->panel;
> > -		seq_printf(m, "\t\tBusy_frontbuffer_bits: 0x%X",
> > -					drrs->busy_frontbuffer_bits);
> > -
> > -		seq_puts(m, "\n\t\t");
> > +		seq_printf(m, "\tBusy_frontbuffer_bits: 0x%X",
> > +			   crtc->drrs.busy_frontbuffer_bits);
> >  
> >  		seq_printf(m, "DRRS refresh rate: %s\n",
> > -			   drrs->refresh_rate == DRRS_REFRESH_RATE_LOW ?
> > +			   crtc->drrs.refresh_rate == DRRS_REFRESH_RATE_LOW ?
> >  			   "low" : "high");
> > -		seq_puts(m, "\n\t\t");
> >  
> > -		mutex_unlock(&drrs->mutex);
> > -	} else {
> > -		/* DRRS not supported. Print the VBT parameter*/
> 
> ...this part is lost in the debug output. Seems to me the debug output
> for not supported DDRS will be that the connector supports it but it's
> not enabled on the crtc for whatever reason.
> 
> > -		seq_puts(m, "\tDRRS Enabled : No");
> > +		mutex_unlock(&crtc->drrs.mutex);
> >  	}
> > -	seq_puts(m, "\n");
> > -}
> > -
> > -static int i915_drrs_status(struct seq_file *m, void *unused)
> > -{
> > -	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> > -	struct drm_device *dev = &dev_priv->drm;
> > -	struct intel_crtc *crtc;
> > -	int active_crtc_cnt = 0;
> > -
> > -	drm_modeset_lock_all(dev);
> > -	for_each_intel_crtc(dev, crtc) {
> > -		if (crtc->base.state->active) {
> > -			active_crtc_cnt++;
> > -			seq_printf(m, "\nCRTC %d:  ", active_crtc_cnt);
> > -
> > -			drrs_status_per_crtc(m, dev, crtc);
> > -		}
> > -	}
> > -	drm_modeset_unlock_all(dev);
> > -
> > -	if (!active_crtc_cnt)
> > -		seq_puts(m, "No active crtc found\n");
> >  
> >  	return 0;
> >  }
> > @@ -1917,26 +1874,18 @@ static int i915_drrs_ctl_set(void *data, u64 val)
> >  
> >  		drm_connector_list_iter_begin(dev, &conn_iter);
> >  		drm_for_each_connector_iter(connector, &conn_iter) {
> > -			struct intel_encoder *encoder;
> > -			struct intel_dp *intel_dp;
> > -
> >  			if (!(crtc_state->uapi.connector_mask &
> >  			      drm_connector_mask(connector)))
> >  				continue;
> >  
> > -			encoder = intel_attached_encoder(to_intel_connector(connector));
> > -			if (encoder->type != INTEL_OUTPUT_EDP)
> > -				continue;
> > -
> >  			drm_dbg(&dev_priv->drm,
> >  				"Manually %sabling DRRS. %llu\n",
> >  				val ? "en" : "dis", val);
> >  
> > -			intel_dp = enc_to_intel_dp(encoder);
> >  			if (val)
> > -				intel_drrs_enable(intel_dp, crtc_state);
> > +				intel_drrs_enable(crtc_state);
> >  			else
> > -				intel_drrs_disable(intel_dp, crtc_state);
> > +				intel_drrs_disable(crtc_state);
> >  		}
> >  		drm_connector_list_iter_end(&conn_iter);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 86b2fa675124..e34800ab6924 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1252,6 +1252,11 @@ enum intel_pipe_crc_source {
> >  	INTEL_PIPE_CRC_SOURCE_MAX,
> >  };
> >  
> > +enum drrs_refresh_rate {
> > +	DRRS_REFRESH_RATE_HIGH,
> > +	DRRS_REFRESH_RATE_LOW,
> > +};
> > +
> >  #define INTEL_PIPE_CRC_ENTRIES_NR	128
> >  struct intel_pipe_crc {
> >  	spinlock_t lock;
> > @@ -1294,6 +1299,15 @@ struct intel_crtc {
> >  		} active;
> >  	} wm;
> >  
> > +	struct {
> > +		struct mutex mutex;
> > +		struct delayed_work work;
> > +		enum drrs_refresh_rate refresh_rate;
> > +		unsigned int busy_frontbuffer_bits;
> > +		enum transcoder cpu_transcoder;
> > +		struct intel_link_m_n m_n, m2_n2;
> > +	} drrs;
> > +
> >  	int scanline_offset;
> >  
> >  	struct {
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 619546441eae..725c3350c923 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -1895,8 +1895,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >  
> >  	intel_vrr_compute_config(pipe_config, conn_state);
> >  	intel_psr_compute_config(intel_dp, pipe_config, conn_state);
> > -	intel_drrs_compute_config(intel_dp, pipe_config, output_bpp,
> > -				  constant_n);
> > +	intel_drrs_compute_config(pipe_config, intel_connector,
> > +				  output_bpp, constant_n);
> >  	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
> >  	intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> > index c97b5dee8cae..246dd0c71194 100644
> > --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> > @@ -65,15 +65,14 @@ static bool can_enable_drrs(struct intel_connector *connector,
> >  		return false;
> >  
> >  	return connector->panel.downclock_mode &&
> > -		i915->drrs.type == DRRS_TYPE_SEAMLESS;
> > +		i915->vbt.drrs_type == DRRS_TYPE_SEAMLESS;
> 
> So is i915->drrs.type just an unchanged copy of i915->vbt.drrs_type the
> whole time?!

More or less. I think we skipped the assignment if we didn't find a
downclock mode. But that logic doesn't make any sense when we aim
to eliminate the single eDP connector assumption.

> This could be a prep patch perhaps.

Ack.

-- 
Ville Syrjälä
Intel


More information about the Intel-gfx mailing list