diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_vrr.c | 87 | 
1 files changed, 82 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index e0573e28014b..622a70e21737 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -246,6 +246,72 @@ void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state)  	crtc_state->mode_flags |= I915_MODE_FLAG_VRR;  } +/* + * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to + * Vtotal value. + */ +static +int intel_vrr_fixed_rr_vtotal(const struct intel_crtc_state *crtc_state) +{ +	struct intel_display *display = to_intel_display(crtc_state); +	int crtc_vtotal = crtc_state->hw.adjusted_mode.crtc_vtotal; + +	if (DISPLAY_VER(display) >= 13) +		return crtc_vtotal; +	else +		return crtc_vtotal - +			intel_vrr_real_vblank_delay(crtc_state); +} + +static +int intel_vrr_fixed_rr_vmax(const struct intel_crtc_state *crtc_state) +{ +	return intel_vrr_fixed_rr_vtotal(crtc_state); +} + +static +int intel_vrr_fixed_rr_vmin(const struct intel_crtc_state *crtc_state) +{ +	struct intel_display *display = to_intel_display(crtc_state); + +	return intel_vrr_fixed_rr_vtotal(crtc_state) - +		intel_vrr_flipline_offset(display); +} + +static +int intel_vrr_fixed_rr_flipline(const struct intel_crtc_state *crtc_state) +{ +	return intel_vrr_fixed_rr_vtotal(crtc_state); +} + +static +void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state) +{ +	struct intel_display *display = to_intel_display(crtc_state); +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + +	if (!intel_vrr_possible(crtc_state)) +		return; + +	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), +		       intel_vrr_fixed_rr_vmin(crtc_state) - 1); +	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), +		       intel_vrr_fixed_rr_vmax(crtc_state) - 1); +	intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), +		       intel_vrr_fixed_rr_flipline(crtc_state) - 1); +} + +static +void intel_vrr_compute_fixed_rr_timings(struct intel_crtc_state *crtc_state) +{ +	/* +	 * For fixed rr,  vmin = vmax = flipline. +	 * vmin is already set to crtc_vtotal set vmax and flipline the same. +	 */ +	crtc_state->vrr.vmax = crtc_state->hw.adjusted_mode.crtc_vtotal; +	crtc_state->vrr.flipline = crtc_state->hw.adjusted_mode.crtc_vtotal; +} +  static  int intel_vrr_compute_vmin(struct intel_crtc_state *crtc_state)  { @@ -314,6 +380,13 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,  	crtc_state->vrr.flipline = crtc_state->vrr.vmin; +	if (crtc_state->uapi.vrr_enabled) +		intel_vrr_compute_vrr_timings(crtc_state); +	else if (is_cmrr_frac_required(crtc_state) && is_edp) +		intel_vrr_compute_cmrr_timings(crtc_state); +	else +		intel_vrr_compute_fixed_rr_timings(crtc_state); +  	/*  	 * flipline determines the min vblank length the hardware will  	 * generate, and on ICL/TGL flipline>=vmin+1, hence we reduce @@ -321,11 +394,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,  	 */  	crtc_state->vrr.vmin -= intel_vrr_flipline_offset(display); -	if (crtc_state->uapi.vrr_enabled) -		intel_vrr_compute_vrr_timings(crtc_state); -	else if (is_cmrr_frac_required(crtc_state) && is_edp) -		intel_vrr_compute_cmrr_timings(crtc_state); -  	if (HAS_AS_SDP(display)) {  		crtc_state->vrr.vsync_start =  			(crtc_state->hw.adjusted_mode.crtc_vtotal - @@ -496,6 +564,13 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)  	if (!crtc_state->vrr.enable)  		return; +	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), +		       crtc_state->vrr.vmin - 1); +	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), +		       crtc_state->vrr.vmax - 1); +	intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), +		       crtc_state->vrr.flipline - 1); +  	intel_de_write(display, TRANS_PUSH(display, cpu_transcoder),  		       TRANS_PUSH_EN); @@ -523,6 +598,8 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)  				TRANS_VRR_STATUS(display, cpu_transcoder),  				VRR_STATUS_VRR_EN_LIVE, 1000);  	intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), 0); + +	intel_vrr_set_fixed_rr_timings(old_crtc_state);  }  static  | 
