[Intel-gfx] [PATCH 6/8] drm/i915: Plumb crtc_state to PSR enable/disable

Rodrigo Vivi rodrigo.vivi at gmail.com
Fri Aug 18 00:26:44 UTC 2017


On Fri, May 19, 2017 at 04:17:23PM +0300, ville.syrjala at linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> The PSR enable/disable need to know things about the crtc state, so
> plumb it through. This will become even more important when we start
> to reuse the generic infoframe code for the VSC DIP programming as the
> infoframe code wants the crtc state as well.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>


Reviewed-by: Rodrigo Vivi <rodrigo.vivi at intel.com>



> ---
>  drivers/gpu/drm/i915/intel_ddi.c |  4 +--
>  drivers/gpu/drm/i915/intel_dp.c  |  4 +--
>  drivers/gpu/drm/i915/intel_drv.h |  6 ++--
>  drivers/gpu/drm/i915/intel_psr.c | 77 +++++++++++++++++++++-------------------
>  4 files changed, 48 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 5dbbfedfbb06..6203c2da3daf 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1847,7 +1847,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder,
>  			intel_dp_stop_link_train(intel_dp);
>  
>  		intel_edp_backlight_on(intel_dp);
> -		intel_psr_enable(intel_dp);
> +		intel_psr_enable(intel_dp, pipe_config);
>  		intel_edp_drrs_enable(intel_dp, pipe_config);
>  	}
>  
> @@ -1875,7 +1875,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder,
>  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  
>  		intel_edp_drrs_disable(intel_dp, old_crtc_state);
> -		intel_psr_disable(intel_dp);
> +		intel_psr_disable(intel_dp, old_crtc_state);
>  		intel_edp_backlight_off(intel_dp);
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 62084e350f58..1784989ca478 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -2669,7 +2669,7 @@ static void intel_disable_dp(struct intel_encoder *encoder,
>  		intel_audio_codec_disable(encoder);
>  
>  	if (HAS_PSR(dev_priv) && !HAS_DDI(dev_priv))
> -		intel_psr_disable(intel_dp);
> +		intel_psr_disable(intel_dp, old_crtc_state);
>  
>  	/* Make sure the panel is off before trying to change the mode. But also
>  	 * ensure that we have vdd while we switch off the panel. */
> @@ -2901,7 +2901,7 @@ static void vlv_enable_dp(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  
>  	intel_edp_backlight_on(intel_dp);
> -	intel_psr_enable(intel_dp);
> +	intel_psr_enable(intel_dp, pipe_config);
>  }
>  
>  static void g4x_pre_enable_dp(struct intel_encoder *encoder,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index de2288f78961..a3d66ccafa5e 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1740,8 +1740,10 @@ static inline void intel_backlight_device_unregister(struct intel_connector *con
>  
>  
>  /* intel_psr.c */
> -void intel_psr_enable(struct intel_dp *intel_dp);
> -void intel_psr_disable(struct intel_dp *intel_dp);
> +void intel_psr_enable(struct intel_dp *intel_dp,
> +		      const struct intel_crtc_state *crtc_state);
> +void intel_psr_disable(struct intel_dp *intel_dp,
> +		      const struct intel_crtc_state *old_crtc_state);
>  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
>  			  unsigned frontbuffer_bits);
>  void intel_psr_flush(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
> index c3780d0d2baf..f976aa865ef9 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -103,28 +103,26 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
>  	POSTING_READ(ctl_reg);
>  }
>  
> -static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
> +static void vlv_psr_setup_vsc(struct intel_dp *intel_dp,
> +			      const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = intel_dig_port->base.base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
> -	enum pipe pipe = to_intel_crtc(crtc)->pipe;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	uint32_t val;
>  
>  	/* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
> -	val  = I915_READ(VLV_VSCSDP(pipe));
> +	val  = I915_READ(VLV_VSCSDP(crtc->pipe));
>  	val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
>  	val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
> -	I915_WRITE(VLV_VSCSDP(pipe), val);
> +	I915_WRITE(VLV_VSCSDP(crtc->pipe), val);
>  }
>  
> -static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
> +static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp,
> +				 const struct intel_crtc_state *crtc_state)
>  {
> -	struct edp_vsc_psr psr_vsc;
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = intel_dig_port->base.base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
> +	struct edp_vsc_psr psr_vsc;
>  
>  	/* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
>  	memset(&psr_vsc, 0, sizeof(psr_vsc));
> @@ -145,7 +143,8 @@ static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
>  	intel_psr_write_vsc(intel_dp, &psr_vsc);
>  }
>  
> -static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
> +static void hsw_psr_setup_vsc(struct intel_dp *intel_dp,
> +			      const struct intel_crtc_state *crtc_state)
>  {
>  	struct edp_vsc_psr psr_vsc;
>  
> @@ -233,16 +232,15 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
>  	I915_WRITE(aux_ctl_reg, aux_ctl);
>  }
>  
> -static void vlv_psr_enable_source(struct intel_dp *intel_dp)
> +static void vlv_psr_enable_source(struct intel_dp *intel_dp,
> +				  const struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct drm_crtc *crtc = dig_port->base.base.crtc;
> -	enum pipe pipe = to_intel_crtc(crtc)->pipe;
> +	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>  
>  	/* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
> -	I915_WRITE(VLV_PSRCTL(pipe),
> +	I915_WRITE(VLV_PSRCTL(crtc->pipe),
>  		   VLV_EDP_PSR_MODE_SW_TIMER |
>  		   VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
>  		   VLV_EDP_PSR_ENABLE);
> @@ -486,13 +484,13 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
>   *
>   * This function can only be called after the pipe is fully trained and enabled.
>   */
> -void intel_psr_enable(struct intel_dp *intel_dp)
> +void intel_psr_enable(struct intel_dp *intel_dp,
> +		      const struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_device *dev = intel_dig_port->base.base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
> -	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 chicken;
>  
>  	if (!HAS_PSR(dev_priv)) {
> @@ -518,11 +516,13 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  
>  	if (HAS_DDI(dev_priv)) {
>  		if (dev_priv->psr.psr2_support) {
> -			skl_psr_setup_su_vsc(intel_dp);
> +			skl_psr_setup_su_vsc(intel_dp, crtc_state);
> +
>  			chicken = PSR2_VSC_ENABLE_PROG_HEADER;
>  			if (dev_priv->psr.y_cord_support)
>  				chicken |= PSR2_ADD_VERTICAL_LINE_COUNT;
>  			I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken);
> +
>  			I915_WRITE(EDP_PSR_DEBUG_CTL,
>  				   EDP_PSR_DEBUG_MASK_MEMUP |
>  				   EDP_PSR_DEBUG_MASK_HPD |
> @@ -531,7 +531,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  				   EDP_PSR_DEBUG_MASK_DISP_REG_WRITE);
>  		} else {
>  			/* set up vsc header for psr1 */
> -			hsw_psr_setup_vsc(intel_dp);
> +			hsw_psr_setup_vsc(intel_dp, crtc_state);
> +
>  			/*
>  			 * Per Spec: Avoid continuous PSR exit by masking MEMUP
>  			 * and HPD. also mask LPSP to avoid dependency on other
> @@ -551,7 +552,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  		if (INTEL_GEN(dev_priv) >= 9)
>  			intel_psr_activate(intel_dp);
>  	} else {
> -		vlv_psr_setup_vsc(intel_dp);
> +		vlv_psr_setup_vsc(intel_dp, crtc_state);
>  
>  		/* Enable PSR on the panel */
>  		vlv_psr_enable_sink(intel_dp);
> @@ -562,7 +563,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  		 * but let it on inactive state. So we might do this prior
>  		 * to active transition, i.e. here.
>  		 */
> -		vlv_psr_enable_source(intel_dp);
> +		vlv_psr_enable_source(intel_dp, crtc_state);
>  	}
>  
>  	/*
> @@ -583,37 +584,38 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  	mutex_unlock(&dev_priv->psr.lock);
>  }
>  
> -static void vlv_psr_disable(struct intel_dp *intel_dp)
> +static void vlv_psr_disable(struct intel_dp *intel_dp,
> +			    const struct intel_crtc_state *old_crtc_state)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_device *dev = intel_dig_port->base.base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_crtc *intel_crtc =
> -		to_intel_crtc(intel_dig_port->base.base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>  	uint32_t val;
>  
>  	if (dev_priv->psr.active) {
>  		/* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
>  		if (intel_wait_for_register(dev_priv,
> -					    VLV_PSRSTAT(intel_crtc->pipe),
> +					    VLV_PSRSTAT(crtc->pipe),
>  					    VLV_EDP_PSR_IN_TRANS,
>  					    0,
>  					    1))
>  			WARN(1, "PSR transition took longer than expected\n");
>  
> -		val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
> +		val = I915_READ(VLV_PSRCTL(crtc->pipe));
>  		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
>  		val &= ~VLV_EDP_PSR_ENABLE;
>  		val &= ~VLV_EDP_PSR_MODE_MASK;
> -		I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
> +		I915_WRITE(VLV_PSRCTL(crtc->pipe), val);
>  
>  		dev_priv->psr.active = false;
>  	} else {
> -		WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
> +		WARN_ON(vlv_is_psr_active_on_pipe(dev, crtc->pipe));
>  	}
>  }
>  
> -static void hsw_psr_disable(struct intel_dp *intel_dp)
> +static void hsw_psr_disable(struct intel_dp *intel_dp,
> +			    const struct intel_crtc_state *old_crtc_state)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_device *dev = intel_dig_port->base.base.dev;
> @@ -665,7 +667,8 @@ static void hsw_psr_disable(struct intel_dp *intel_dp)
>   *
>   * This function needs to be called before disabling pipe.
>   */
> -void intel_psr_disable(struct intel_dp *intel_dp)
> +void intel_psr_disable(struct intel_dp *intel_dp,
> +		       const struct intel_crtc_state *old_crtc_state)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_device *dev = intel_dig_port->base.base.dev;
> @@ -679,9 +682,9 @@ void intel_psr_disable(struct intel_dp *intel_dp)
>  
>  	/* Disable PSR on Source */
>  	if (HAS_DDI(dev_priv))
> -		hsw_psr_disable(intel_dp);
> +		hsw_psr_disable(intel_dp, old_crtc_state);
>  	else
> -		vlv_psr_disable(intel_dp);
> +		vlv_psr_disable(intel_dp, old_crtc_state);
>  
>  	/* Disable PSR on Sink */
>  	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
> -- 
> 2.10.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list