[PATCH 3/4] drm/i915/vrr/xe2lpd: Use VRR timing generator whenever panel supports VRR
Ankit Nautiyal
ankit.k.nautiyal at intel.com
Mon May 27 11:48:27 UTC 2024
Currently VRR timing generator is used only when VRR is enabled by
userspace. From XE2LPD, gradually move away from older timing
generator and use VRR timing generator if panel supports VRR but
VRR is not enabled by the userspace.
In such a case, Flipline VMin and VMax all are set to the Vtotal of the
mode, which effectively makes the VRR timing generator work in
fixed refresh rate mode. The same is conveyed to the sink via AS SDP,
by setting the Adaptive Sync Operation mode to AVT with fixed
video frame duration.
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
drivers/gpu/drm/i915/display/intel_display.c | 4 +-
.../drm/i915/display/intel_display_types.h | 2 +-
drivers/gpu/drm/i915/display/intel_dp.c | 6 +-
drivers/gpu/drm/i915/display/intel_vrr.c | 59 ++++++++++++-------
4 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 5a506494be2b..ccf55039b1da 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1000,7 +1000,8 @@ static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state,
old_crtc_state->vrr.vmin != new_crtc_state->vrr.vmin ||
old_crtc_state->vrr.vmax != new_crtc_state->vrr.vmax ||
old_crtc_state->vrr.guardband != new_crtc_state->vrr.guardband ||
- old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full;
+ old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full ||
+ old_crtc_state->vrr.fixed_rr != new_crtc_state->vrr.fixed_rr;
}
static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
@@ -5410,6 +5411,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
if (!fastset) {
PIPE_CONF_CHECK_BOOL(vrr.enable);
+ PIPE_CONF_CHECK_BOOL(vrr.fixed_rr);
PIPE_CONF_CHECK_I(vrr.vmin);
PIPE_CONF_CHECK_I(vrr.vmax);
PIPE_CONF_CHECK_I(vrr.flipline);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 9678c2b157f6..8f02844c9fc4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1395,7 +1395,7 @@ struct intel_crtc_state {
/* Variable Refresh Rate state */
struct {
- bool enable, in_range;
+ bool enable, in_range, fixed_rr;
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
u32 vsync_end, vsync_start;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index edbc7267816b..6993c1021063 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2633,10 +2633,12 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
- /* Currently only DP_AS_SDP_AVT_DYNAMIC_VTOTAL mode supported */
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
- as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL;
+ if (crtc_state->vrr.fixed_rr)
+ as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+ else
+ as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL;
as_sdp->vtotal = adjusted_mode->vtotal;
as_sdp->target_rr = 0;
as_sdp->duration_incr_ms = 0;
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 5f3657aa8313..5d281f3c9fe4 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -137,26 +137,39 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
if (HAS_LRR(i915))
crtc_state->update_lrr = true;
- vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000,
- adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq);
- vmax = adjusted_mode->crtc_clock * 1000 /
- (adjusted_mode->crtc_htotal * info->monitor_range.min_vfreq);
+ if (!crtc_state->uapi.vrr_enabled && DISPLAY_VER(i915) >= 20) {
+ /*
+ * for LNL+ if panel supports VRR and user has not set VRR,
+ * always go for fixed average Vtotal mode.
+ */
+ crtc_state->vrr.vmin = adjusted_mode->crtc_vtotal;
+ crtc_state->vrr.vmax = adjusted_mode->crtc_vtotal;
+ crtc_state->vrr.flipline = adjusted_mode->crtc_vtotal;
+ crtc_state->vrr.fixed_rr = true;
+ } else {
- vmin = max_t(int, vmin, adjusted_mode->crtc_vtotal);
- vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal);
+ vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000,
+ adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq);
+ vmax = adjusted_mode->crtc_clock * 1000 /
+ (adjusted_mode->crtc_htotal * info->monitor_range.min_vfreq);
- if (vmin >= vmax)
- return;
+ vmin = max_t(int, vmin, adjusted_mode->crtc_vtotal);
+ vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal);
- /*
- * flipline determines the min vblank length the hardware will
- * generate, and flipline>=vmin+1, hence we reduce vmin by one
- * to make sure we can get the actual min vblank length.
- */
- crtc_state->vrr.vmin = vmin - 1;
- crtc_state->vrr.vmax = vmax;
+ if (vmin >= vmax)
+ return;
- crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
+ /*
+ * flipline determines the min vblank length the hardware will
+ * generate, and flipline>=vmin+1, hence we reduce vmin by one
+ * to make sure we can get the actual min vblank length.
+ */
+ crtc_state->vrr.vmin = vmin - 1;
+ crtc_state->vrr.vmax = vmax;
+
+ crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
+ crtc_state->vrr.fixed_rr = false;
+ }
/*
* For XE_LPD+, we use guardband and pipeline override
@@ -171,7 +184,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
crtc_state->framestart_delay - 1);
}
- if (crtc_state->uapi.vrr_enabled) {
+ if (crtc_state->uapi.vrr_enabled || crtc_state->vrr.fixed_rr) {
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
if (intel_dp_as_sdp_supported(intel_dp)) {
@@ -234,7 +247,7 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- if (!crtc_state->vrr.enable)
+ if (!crtc_state->vrr.enable || crtc_state->vrr.fixed_rr)
return;
intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
@@ -247,7 +260,7 @@ bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- if (!crtc_state->vrr.enable)
+ if (!crtc_state->vrr.enable || crtc_state->vrr.fixed_rr)
return false;
return intel_de_read(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder)) & TRANS_PUSH_SEND;
@@ -261,8 +274,9 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
- TRANS_PUSH_EN);
+ if (!crtc_state->vrr.fixed_rr)
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
+ TRANS_PUSH_EN);
if (HAS_AS_SDP(dev_priv))
intel_de_write(dev_priv,
@@ -321,6 +335,9 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
TRANS_VRR_VMAX(dev_priv, cpu_transcoder)) + 1;
crtc_state->vrr.vmin = intel_de_read(dev_priv,
TRANS_VRR_VMIN(dev_priv, cpu_transcoder)) + 1;
+ if (crtc_state->vrr.vmax == crtc_state->vrr.flipline &&
+ crtc_state->vrr.vmin == crtc_state->vrr.flipline)
+ crtc_state->vrr.fixed_rr = true;
}
if (crtc_state->vrr.enable) {
--
2.40.1
More information about the Intel-gfx-trybot
mailing list