From: Ville Syrjälä <ville.syrj...@linux.intel.com> Currently our crtc_state->vrr.{vmin.vmax,flipline} are mangled on TGL to account for the SCL delay (the hardware requires this mangling or the actual vtotals will become incorrect). Unfortunately this means that one can't simply use these values directly in many places, and instead we always have to go through functions that undo the damage first. This is all rather fragile.
Simplify our lives a bit by hiding this mangling deeper inside the low level VRR code, leaving the number stored in the crtc state actually something that humans can use. This does introduce a dependdency as intel_vrr_get_config() will now need to know the SCL value, which is read out in intel_get_transcoder_timings(). I suppose we could simply duplicate the SCL readout in both places should this become a real hinderance. For now just leave a note around the intel_get_transcoder_timings() call to remind us. Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++ drivers/gpu/drm/i915/display/intel_vrr.c | 76 +++++++++++--------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f4124c79bc83..18b9baa96241 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3901,6 +3901,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, pipe_config->framestart_delay = 1; } + /* + * intel_vrr_get_config() depends on TRANS_SET_CONTEXT_LATENCY + * readout done by intel_get_transcoder_timings(). + */ if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || DISPLAY_VER(display) >= 11) intel_get_transcoder_timings(crtc, pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 71fb64c92165..71a985d00604 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -156,25 +156,13 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(crtc_state); - /* Min vblank actually determined by flipline */ - if (DISPLAY_VER(display) >= 13) - return intel_vrr_vmin_flipline(crtc_state); - else - return intel_vrr_vmin_flipline(crtc_state) + - intel_vrr_real_vblank_delay(crtc_state); + return intel_vrr_vmin_flipline(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(crtc_state); - - if (DISPLAY_VER(display) >= 13) - return crtc_state->vrr.vmax; - else - return crtc_state->vrr.vmax + - intel_vrr_real_vblank_delay(crtc_state); + return crtc_state->vrr.vmax; } int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) @@ -258,6 +246,21 @@ void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state) crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } +static int intel_vrr_hw_value(const struct intel_crtc_state *crtc_state, + int value) +{ + struct intel_display *display = to_intel_display(crtc_state); + + /* + * On TGL vmin/vmax/flipline also need to be + * adjusted by the SCL to maintain correct vtotals. + */ + if (DISPLAY_VER(display) >= 13) + return value; + else + return value - intel_vrr_real_vblank_delay(crtc_state); +} + /* * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to * Vtotal value. @@ -265,14 +268,7 @@ void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state) static int intel_vrr_fixed_rr_hw_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); + return intel_vrr_hw_value(crtc_state, crtc_state->hw.adjusted_mode.crtc_vtotal); } static @@ -441,14 +437,6 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) crtc_state->vrr.pipeline_full = intel_vrr_guardband_to_pipeline_full(crtc_state, crtc_state->vrr.guardband); - - /* - * vmin/vmax/flipline also need to be adjusted by - * the vblank delay to maintain correct vtotals. - */ - crtc_state->vrr.vmin -= intel_vrr_real_vblank_delay(crtc_state); - crtc_state->vrr.vmax -= intel_vrr_real_vblank_delay(crtc_state); - crtc_state->vrr.flipline -= intel_vrr_real_vblank_delay(crtc_state); } } @@ -607,6 +595,21 @@ void intel_vrr_set_db_point_and_transmission_line(const struct intel_crtc_state EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start)); } +static int intel_vrr_hw_vmin(const struct intel_crtc_state *crtc_state) +{ + return intel_vrr_hw_value(crtc_state, crtc_state->vrr.vmin); +} + +static int intel_vrr_hw_vmax(const struct intel_crtc_state *crtc_state) +{ + return intel_vrr_hw_value(crtc_state, crtc_state->vrr.vmax); +} + +static int intel_vrr_hw_flipline(const struct intel_crtc_state *crtc_state) +{ + return intel_vrr_hw_value(crtc_state, crtc_state->vrr.flipline); +} + void intel_vrr_enable(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -616,11 +619,11 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) return; intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), - crtc_state->vrr.vmin - 1); + intel_vrr_hw_vmin(crtc_state) - 1); intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), - crtc_state->vrr.vmax - 1); + intel_vrr_hw_vmax(crtc_state) - 1); intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), - crtc_state->vrr.flipline - 1); + intel_vrr_hw_flipline(crtc_state) - 1); intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), TRANS_PUSH_EN); @@ -754,6 +757,13 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) crtc_state->vrr.vmin = intel_de_read(display, TRANS_VRR_VMIN(display, cpu_transcoder)) + 1; + if (DISPLAY_VER(display) < 13) { + /* undo what intel_vrr_hw_value() does when writing the values */ + crtc_state->vrr.flipline += intel_vrr_real_vblank_delay(crtc_state); + crtc_state->vrr.vmax += intel_vrr_real_vblank_delay(crtc_state); + crtc_state->vrr.vmin += intel_vrr_real_vblank_delay(crtc_state); + } + /* * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal * bits are not filled. Since for these platforms TRAN_VMIN is always -- 2.49.1