From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:30 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:30 +0530 Subject: [PATCH 01/13] drm/i915/vrr: Remove unwanted comment In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-2-ankit.k.nautiyal@intel.com> The comment about fixed average vtotal is incorrect. Remove it. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index adb51609d0a3..532abdb334b2 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -276,11 +276,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, */ crtc_state->vrr.vmin -= intel_vrr_flipline_offset(display); - /* - * When panel is VRR capable and userspace has - * not enabled adaptive sync mode then Fixed Average - * Vtotal mode should be enabled. - */ if (crtc_state->uapi.vrr_enabled) { crtc_state->vrr.enable = true; crtc_state->mode_flags |= I915_MODE_FLAG_VRR; -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:29 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:29 +0530 Subject: [PATCH 00/13] Prepare to transition to VRR TG Message-ID: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Refactor existing VRR to prepare for introducing fixed rr: -Always compute the vrr state based on actual uapi.vrr_enable knob. So when that knob is disabled we always compute vmin=flipline=vmax. -Update intel_vrr_{enable,disable}() to just flip between the fixed and variable timings in vmin/flipline/vmax. -Always set vmin=crtc_vtotal instead of the using the current refresh rate based approach. That way we never need to change anything to do with the guardband. -Disable CMRR for now since it complicates the toggle between fixed and variable timings. Ankit Nautiyal (13): drm/i915/vrr: Remove unwanted comment drm/i915:vrr: Separate out functions to compute vmin and vmax drm/i915/vrr: Make helpers for cmrr and vrr timings drm/i915/vrr: Simplify CMRR Enable Check in intel_vrr_get_config drm/i915/vrr: Introduce new field for VRR mode drm/i915/vrr: Fill VRR timing generator mode for CMRR and VRR drm/i915/display: Remove vrr.enable and instead check vrr.mode != NONE drm/i915/display: Absorb cmrr attributes into vrr struct drm/i915/display: Add vrr mode to crtc_state dump drm/i915/vrr: Disable CMRR drm/i915/display: Update intel_crtc_vrr_{enable/disable} drm/i915/vrr: Use crtc_vtotal for vmin drm/i915/vrr: Prepare for fixed refresh rate timings .../drm/i915/display/intel_crtc_state_dump.c | 19 +- drivers/gpu/drm/i915/display/intel_ddi.c | 3 +- drivers/gpu/drm/i915/display/intel_display.c | 47 ++-- .../drm/i915/display/intel_display_types.h | 16 +- drivers/gpu/drm/i915/display/intel_dp.c | 4 +- drivers/gpu/drm/i915/display/intel_dsb.c | 2 +- .../drm/i915/display/intel_modeset_setup.c | 3 +- drivers/gpu/drm/i915/display/intel_psr.c | 5 +- drivers/gpu/drm/i915/display/intel_vrr.c | 200 +++++++++++++----- drivers/gpu/drm/i915/display/intel_vrr.h | 1 + drivers/gpu/drm/i915/display/skl_watermark.c | 3 +- 11 files changed, 210 insertions(+), 93 deletions(-) -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:31 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:31 +0530 Subject: [PATCH 02/13] drm/i915:vrr: Separate out functions to compute vmin and vmax In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-3-ankit.k.nautiyal@intel.com> Make helpers to compute vmin and vmax. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 39 +++++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 532abdb334b2..e1bac7d24e18 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -222,6 +222,35 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required) return vtotal; } +static +int intel_vrr_compute_vmin(struct intel_connector *connector, + struct drm_display_mode *adjusted_mode) +{ + int vmin; + const struct drm_display_info *info = &connector->base.display_info; + + vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000, + adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq); + vmin = max_t(int, vmin, adjusted_mode->crtc_vtotal); + + return vmin; +} + +static +int intel_vrr_compute_vmax(struct intel_connector *connector, + struct drm_display_mode *adjusted_mode) +{ + int vmax; + const struct drm_display_info *info = &connector->base.display_info; + + vmax = adjusted_mode->crtc_clock * 1000 / + (adjusted_mode->crtc_htotal * info->monitor_range.min_vfreq); + + vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal); + + return vmax; +} + void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -232,7 +261,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, struct intel_dp *intel_dp = intel_attached_dp(connector); bool is_edp = intel_dp_is_edp(intel_dp); struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - const struct drm_display_info *info = &connector->base.display_info; int vmin, vmax; /* @@ -253,13 +281,8 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, if (HAS_LRR(display)) 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); - - vmin = max_t(int, vmin, adjusted_mode->crtc_vtotal); - vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal); + vmin = intel_vrr_compute_vmin(connector, adjusted_mode); + vmax = intel_vrr_compute_vmax(connector, adjusted_mode); if (vmin >= vmax) return; -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:32 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:32 +0530 Subject: [PATCH 03/13] drm/i915/vrr: Make helpers for cmrr and vrr timings In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-4-ankit.k.nautiyal@intel.com> Separate out functions for computing cmrr and vrr timings. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 45 +++++++++++++++--------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index e1bac7d24e18..f8ae3dc6a304 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -222,6 +222,30 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required) return vtotal; } +static +void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state) +{ + crtc_state->vrr.enable = true; + crtc_state->cmrr.enable = true; + /* + * TODO: Compute precise target refresh rate to determine + * if video_mode_required should be true. Currently set to + * false due to uncertainty about the precise target + * refresh Rate. + */ + crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false); + crtc_state->vrr.vmin = crtc_state->vrr.vmax; + crtc_state->vrr.flipline = crtc_state->vrr.vmin; + crtc_state->mode_flags |= I915_MODE_FLAG_VRR; +} + +static +void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state) +{ + crtc_state->vrr.enable = true; + crtc_state->mode_flags |= I915_MODE_FLAG_VRR; +} + static int intel_vrr_compute_vmin(struct intel_connector *connector, struct drm_display_mode *adjusted_mode) @@ -299,23 +323,10 @@ 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) { - crtc_state->vrr.enable = true; - crtc_state->mode_flags |= I915_MODE_FLAG_VRR; - } else if (is_cmrr_frac_required(crtc_state) && is_edp) { - crtc_state->vrr.enable = true; - crtc_state->cmrr.enable = true; - /* - * TODO: Compute precise target refresh rate to determine - * if video_mode_required should be true. Currently set to - * false due to uncertainty about the precise target - * refresh Rate. - */ - crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false); - crtc_state->vrr.vmin = crtc_state->vrr.vmax; - crtc_state->vrr.flipline = crtc_state->vrr.vmin; - crtc_state->mode_flags |= I915_MODE_FLAG_VRR; - } + 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 = -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:33 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:33 +0530 Subject: [PATCH 04/13] drm/i915/vrr: Simplify CMRR Enable Check in intel_vrr_get_config In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-5-ankit.k.nautiyal@intel.com> Combine the CMRR capability and enable check into a single condition. Set crtc_state->cmrr.enable directly within the combined condition. This will make way to absorb cmrr members in vrr struct. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index f8ae3dc6a304..6f314e209e96 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -503,10 +503,9 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) TRANS_VRR_CTL(display, cpu_transcoder)); crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE; - if (HAS_CMRR(display)) - crtc_state->cmrr.enable = (trans_vrr_ctl & VRR_CTL_CMRR_ENABLE); - if (crtc_state->cmrr.enable) { + if (HAS_CMRR(display) && trans_vrr_ctl & VRR_CTL_CMRR_ENABLE) { + crtc_state->cmrr.enable = true; crtc_state->cmrr.cmrr_n = intel_de_read64_2x32(display, TRANS_CMRR_N_LO(display, cpu_transcoder), TRANS_CMRR_N_HI(display, cpu_transcoder)); -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:34 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:34 +0530 Subject: [PATCH 05/13] drm/i915/vrr: Introduce new field for VRR mode In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-6-ankit.k.nautiyal@intel.com> The VRR timing generator can be used in multiple modes of operation: dynamic refresh rate (VRR), content-matched refresh rate (CMRR), and fixed refresh rate (Fixed_RR). Currently, VRR and CMRR modes are supported, with Fixed_RR mode forthcoming. To track the different operational modes of the VRR timing generator, introduce a new member 'mode' to the VRR struct. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display_types.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index cb51b7936f93..3195c9f33028 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -935,6 +935,12 @@ void intel_io_mmio_fw_write(void *ctx, i915_reg_t reg, u32 val); typedef void (*intel_io_reg_write)(void *ctx, i915_reg_t reg, u32 val); +enum intel_vrrtg_mode { + INTEL_VRRTG_MODE_NONE, + INTEL_VRRTG_MODE_VRR, + INTEL_VRRTG_MODE_CMRR, +}; + struct intel_crtc_state { /* * uapi (drm) state. This is the software state shown to userspace. @@ -1306,6 +1312,7 @@ struct intel_crtc_state { u8 pipeline_full; u16 flipline, vmin, vmax, guardband; u32 vsync_end, vsync_start; + enum intel_vrrtg_mode mode; } vrr; /* Content Match Refresh Rate state */ -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:35 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:35 +0530 Subject: [PATCH 06/13] drm/i915/vrr: Fill VRR timing generator mode for CMRR and VRR In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-7-ankit.k.nautiyal@intel.com> Fill vrr.mode during compute_config and update intel_vrr_get_config() to read vrr.mode based on CMRR and VRR enable conditions. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/i915/display/intel_vrr.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 60867b5b03ec..861929aea4b9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5803,6 +5803,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, if (!fastset) { PIPE_CONF_CHECK_BOOL(vrr.enable); + PIPE_CONF_CHECK_X(vrr.mode); 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_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 6f314e209e96..ded5466c5214 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -227,6 +227,7 @@ void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state) { crtc_state->vrr.enable = true; crtc_state->cmrr.enable = true; + crtc_state->vrr.mode = INTEL_VRRTG_MODE_CMRR; /* * TODO: Compute precise target refresh rate to determine * if video_mode_required should be true. Currently set to @@ -243,6 +244,7 @@ static void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state) { crtc_state->vrr.enable = true; + crtc_state->vrr.mode = INTEL_VRRTG_MODE_VRR; crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } @@ -506,12 +508,15 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) if (HAS_CMRR(display) && trans_vrr_ctl & VRR_CTL_CMRR_ENABLE) { crtc_state->cmrr.enable = true; + crtc_state->vrr.mode = INTEL_VRRTG_MODE_CMRR; crtc_state->cmrr.cmrr_n = intel_de_read64_2x32(display, TRANS_CMRR_N_LO(display, cpu_transcoder), TRANS_CMRR_N_HI(display, cpu_transcoder)); crtc_state->cmrr.cmrr_m = intel_de_read64_2x32(display, TRANS_CMRR_M_LO(display, cpu_transcoder), TRANS_CMRR_M_HI(display, cpu_transcoder)); + } else if (trans_vrr_ctl & VRR_CTL_VRR_ENABLE) { + crtc_state->vrr.mode = INTEL_VRRTG_MODE_VRR; } if (DISPLAY_VER(display) >= 13) -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:36 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:36 +0530 Subject: [PATCH 07/13] drm/i915/display: Remove vrr.enable and instead check vrr.mode != NONE In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-8-ankit.k.nautiyal@intel.com> Since we now have vrr.mode to track the mode in which the VRR timing generator is running, we no longer need member vrr.enable. Replace the check for vrr.enable and use a helper to check vrr.mode != NONE. Signed-off-by: Ankit Nautiyal --- .../drm/i915/display/intel_crtc_state_dump.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++- drivers/gpu/drm/i915/display/intel_display.c | 11 +++++------ .../drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dsb.c | 2 +- .../drm/i915/display/intel_modeset_setup.c | 3 ++- drivers/gpu/drm/i915/display/intel_psr.c | 5 +++-- drivers/gpu/drm/i915/display/intel_vrr.c | 19 ++++++++++--------- drivers/gpu/drm/i915/display/intel_vrr.h | 1 + drivers/gpu/drm/i915/display/skl_watermark.c | 3 ++- 11 files changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 36076e8d639b..56a43f3fc7f6 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -293,7 +293,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->framestart_delay, pipe_config->msa_timing_delay); drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", - str_yes_no(pipe_config->vrr.enable), + str_yes_no(intel_vrr_is_enabled(pipe_config)), pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dc319f37b1be..f440299da637 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -77,6 +77,7 @@ #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vdsc_regs.h" +#include "intel_vrr.h" #include "skl_scaler.h" #include "skl_universal_plane.h" @@ -2280,7 +2281,7 @@ static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel { struct intel_display *display = to_intel_display(intel_dp); - if (!crtc_state->vrr.enable) + if (!intel_vrr_is_enabled(crtc_state)) return; if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 861929aea4b9..ba7194add02c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1130,8 +1130,8 @@ static bool intel_crtc_vrr_enabling(struct intel_atomic_state *state, if (!new_crtc_state->hw.active) return false; - return is_enabling(vrr.enable, old_crtc_state, new_crtc_state) || - (new_crtc_state->vrr.enable && + return is_enabling(vrr.mode, old_crtc_state, new_crtc_state) || + (intel_vrr_is_enabled(new_crtc_state) && (new_crtc_state->update_m_n || new_crtc_state->update_lrr || vrr_params_changed(old_crtc_state, new_crtc_state))); } @@ -1147,8 +1147,8 @@ bool intel_crtc_vrr_disabling(struct intel_atomic_state *state, if (!old_crtc_state->hw.active) return false; - return is_disabling(vrr.enable, old_crtc_state, new_crtc_state) || - (old_crtc_state->vrr.enable && + return is_disabling(vrr.mode, old_crtc_state, new_crtc_state) || + (intel_vrr_is_enabled(old_crtc_state) && (new_crtc_state->update_m_n || new_crtc_state->update_lrr || vrr_params_changed(old_crtc_state, new_crtc_state))); } @@ -5802,7 +5802,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(splitter.pixel_overlap); if (!fastset) { - PIPE_CONF_CHECK_BOOL(vrr.enable); PIPE_CONF_CHECK_X(vrr.mode); PIPE_CONF_CHECK_I(vrr.vmin); PIPE_CONF_CHECK_I(vrr.vmax); @@ -7280,7 +7279,7 @@ static void intel_update_crtc(struct intel_atomic_state *state, if (intel_crtc_vrr_enabling(state, crtc) || new_crtc_state->update_m_n || new_crtc_state->update_lrr) intel_crtc_update_active_timings(new_crtc_state, - new_crtc_state->vrr.enable); + intel_vrr_is_enabled(new_crtc_state)); /* * We usually enable FIFO underrun interrupts as part of the diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3195c9f33028..c553274c2af8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1308,7 +1308,7 @@ struct intel_crtc_state { /* Variable Refresh Rate state */ struct { - bool enable, in_range; + bool in_range; 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 80214a559013..7864a4908399 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2924,7 +2924,7 @@ static bool can_enable_drrs(struct intel_connector *connector, { struct drm_i915_private *i915 = to_i915(connector->base.dev); - if (pipe_config->vrr.enable) + if (intel_vrr_is_enabled(pipe_config)) return false; /* diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 2f2812c23972..78be517352e6 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -106,7 +106,7 @@ static bool pre_commit_is_vrr_active(struct intel_atomic_state *state, return false; /* VRR will have been disabled during intel_pre_plane_update() */ - return old_crtc_state->vrr.enable && !intel_crtc_vrr_disabling(state, crtc); + return intel_vrr_is_enabled(old_crtc_state) && !intel_crtc_vrr_disabling(state, crtc); } static int dsb_vblank_delay(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 10cdfdad82e4..9b18599d8b7e 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -31,6 +31,7 @@ #include "intel_pmdemand.h" #include "intel_tc.h" #include "intel_vblank.h" +#include "intel_vrr.h" #include "intel_wm.h" #include "skl_watermark.h" @@ -859,7 +860,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) crtc_state->inherited = true; intel_crtc_update_active_timings(crtc_state, - crtc_state->vrr.enable); + intel_vrr_is_enabled(crtc_state)); intel_crtc_copy_hw_to_uapi_state(crtc_state); } diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 2bdb6c9c2283..6fcb8d4a1c39 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -44,6 +44,7 @@ #include "intel_psr.h" #include "intel_psr_regs.h" #include "intel_snps_phy.h" +#include "intel_vrr.h" #include "skl_universal_plane.h" /** @@ -1484,7 +1485,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, } /* Wa_16011303918:adl-p */ - if (crtc_state->vrr.enable && + if (intel_vrr_is_enabled(crtc_state) && IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) { drm_dbg_kms(display->drm, "PSR2 not enabled, not compatible with HW stepping + VRR\n"); @@ -1689,7 +1690,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, /* * Currently PSR/PR doesn't work reliably with VRR enabled. */ - if (crtc_state->vrr.enable) + if (intel_vrr_is_enabled(crtc_state)) return; crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp, diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index ded5466c5214..5c00eef64bfd 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -225,7 +225,6 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required) static void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state) { - crtc_state->vrr.enable = true; crtc_state->cmrr.enable = true; crtc_state->vrr.mode = INTEL_VRRTG_MODE_CMRR; /* @@ -243,7 +242,6 @@ void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state) static void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state) { - crtc_state->vrr.enable = true; crtc_state->vrr.mode = INTEL_VRRTG_MODE_VRR; crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } @@ -277,6 +275,11 @@ int intel_vrr_compute_vmax(struct intel_connector *connector, return vmax; } +bool intel_vrr_is_enabled(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->vrr.mode != INTEL_VRRTG_MODE_NONE; +} + void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -433,7 +436,7 @@ void intel_vrr_send_push(struct intel_dsb *dsb, struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (!crtc_state->vrr.enable) + if (!intel_vrr_is_enabled(crtc_state)) return; if (dsb) @@ -452,7 +455,7 @@ bool intel_vrr_is_push_sent(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 (!crtc_state->vrr.enable) + if (!intel_vrr_is_enabled(crtc_state)) return false; return intel_de_read(display, TRANS_PUSH(display, cpu_transcoder)) & TRANS_PUSH_SEND; @@ -463,7 +466,7 @@ void intel_vrr_enable(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 (!crtc_state->vrr.enable) + if (!intel_vrr_is_enabled(crtc_state)) return; intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), @@ -484,7 +487,7 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) struct intel_display *display = to_intel_display(old_crtc_state); enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; - if (!old_crtc_state->vrr.enable) + if (!intel_vrr_is_enabled(old_crtc_state)) return; intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), @@ -504,8 +507,6 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) trans_vrr_ctl = intel_de_read(display, TRANS_VRR_CTL(display, cpu_transcoder)); - crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE; - if (HAS_CMRR(display) && trans_vrr_ctl & VRR_CTL_CMRR_ENABLE) { crtc_state->cmrr.enable = true; crtc_state->vrr.mode = INTEL_VRRTG_MODE_CMRR; @@ -546,6 +547,6 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) } } - if (crtc_state->vrr.enable) + if (intel_vrr_is_enabled(crtc_state)) crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 899cbf40f880..736bf7777abe 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -33,5 +33,6 @@ int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state); int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state); +bool intel_vrr_is_enabled(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_VRR_H__ */ diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 45fe4aaeb450..1e08c0fb03ca 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -23,6 +23,7 @@ #include "intel_fb.h" #include "intel_fixed.h" #include "intel_pcode.h" +#include "intel_vrr.h" #include "intel_wm.h" #include "skl_universal_plane_regs.h" #include "skl_watermark.h" @@ -3012,7 +3013,7 @@ intel_program_dpkgc_latency(struct intel_atomic_state *state) return; for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { - if (!new_crtc_state->vrr.enable || + if (!intel_vrr_is_enabled(new_crtc_state) || (new_crtc_state->vrr.vmin == new_crtc_state->vrr.vmax && new_crtc_state->vrr.vmin == new_crtc_state->vrr.flipline)) fixed_refresh_rate = true; -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:37 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:37 +0530 Subject: [PATCH 08/13] drm/i915/display: Absorb cmrr attributes into vrr struct In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-9-ankit.k.nautiyal@intel.com> Since cmrr is now one of the mode of operation of VRR timing generator, move its elements in the vrr struct. Replace cmrr.enable with vrr.mode INTEL_VRRTG_MODE_CMRR and move cmrr_m and cmrr_n in vrr struct. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 19 +++++--------- .../drm/i915/display/intel_display_types.h | 7 +---- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_vrr.c | 26 +++++++++---------- 4 files changed, 20 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ba7194add02c..2013366a8374 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1109,14 +1109,9 @@ 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; -} - -static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state, - const struct intel_crtc_state *new_crtc_state) -{ - return old_crtc_state->cmrr.cmrr_m != new_crtc_state->cmrr.cmrr_m || - old_crtc_state->cmrr.cmrr_n != new_crtc_state->cmrr.cmrr_n; + old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full || + old_crtc_state->vrr.cmrr_m != new_crtc_state->vrr.cmrr_m || + old_crtc_state->vrr.cmrr_n != new_crtc_state->vrr.cmrr_n; } static bool intel_crtc_vrr_enabling(struct intel_atomic_state *state, @@ -5810,9 +5805,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(vrr.guardband); PIPE_CONF_CHECK_I(vrr.vsync_start); PIPE_CONF_CHECK_I(vrr.vsync_end); - PIPE_CONF_CHECK_LLI(cmrr.cmrr_m); - PIPE_CONF_CHECK_LLI(cmrr.cmrr_n); - PIPE_CONF_CHECK_BOOL(cmrr.enable); + PIPE_CONF_CHECK_LLI(vrr.cmrr_m); + PIPE_CONF_CHECK_LLI(vrr.cmrr_n); } #undef PIPE_CONF_CHECK_X @@ -7225,8 +7219,7 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, intel_crtc_needs_fastset(new_crtc_state)) icl_set_pipe_chicken(new_crtc_state); - if (vrr_params_changed(old_crtc_state, new_crtc_state) || - cmrr_params_changed(old_crtc_state, new_crtc_state)) + if (vrr_params_changed(old_crtc_state, new_crtc_state)) intel_vrr_set_transcoder_timings(new_crtc_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c553274c2af8..338cfd99e5d3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1313,14 +1313,9 @@ struct intel_crtc_state { u16 flipline, vmin, vmax, guardband; u32 vsync_end, vsync_start; enum intel_vrrtg_mode mode; + u64 cmrr_n, cmrr_m; /* Content Match Refresh Rate M and N */ } vrr; - /* Content Match Refresh Rate state */ - struct { - bool enable; - u64 cmrr_n, cmrr_m; - } cmrr; - /* Stream Splitter for eDP MSO */ struct { bool enable; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7864a4908399..2a9c8b03dd2a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2836,7 +2836,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->duration_incr_ms = 0; as_sdp->vtotal = intel_vrr_vmin_vtotal(crtc_state); - if (crtc_state->cmrr.enable) { + if (crtc_state->vrr.mode == INTEL_VRRTG_MODE_CMRR) { as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED; as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode); as_sdp->target_rr_divider = true; diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 5c00eef64bfd..dc4923d49c29 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -212,12 +212,12 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required) multiplier_n = 1000; } - crtc_state->cmrr.cmrr_n = mul_u32_u32(desired_refresh_rate * adjusted_mode->crtc_htotal, - multiplier_n); + crtc_state->vrr.cmrr_n = mul_u32_u32(desired_refresh_rate * adjusted_mode->crtc_htotal, + multiplier_n); vtotal = DIV_ROUND_UP_ULL(mul_u32_u32(adjusted_mode->crtc_clock * 1000, multiplier_n), - crtc_state->cmrr.cmrr_n); + crtc_state->vrr.cmrr_n); adjusted_pixel_rate = mul_u32_u32(adjusted_mode->crtc_clock * 1000, multiplier_m); - crtc_state->cmrr.cmrr_m = do_div(adjusted_pixel_rate, crtc_state->cmrr.cmrr_n); + crtc_state->vrr.cmrr_m = do_div(adjusted_pixel_rate, crtc_state->vrr.cmrr_n); return vtotal; } @@ -225,7 +225,6 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required) static void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state) { - crtc_state->cmrr.enable = true; crtc_state->vrr.mode = INTEL_VRRTG_MODE_CMRR; /* * TODO: Compute precise target refresh rate to determine @@ -403,15 +402,15 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) return; } - if (crtc_state->cmrr.enable) { + if (crtc_state->vrr.mode == INTEL_VRRTG_MODE_CMRR) { intel_de_write(display, TRANS_CMRR_M_HI(display, cpu_transcoder), - upper_32_bits(crtc_state->cmrr.cmrr_m)); + upper_32_bits(crtc_state->vrr.cmrr_m)); intel_de_write(display, TRANS_CMRR_M_LO(display, cpu_transcoder), - lower_32_bits(crtc_state->cmrr.cmrr_m)); + lower_32_bits(crtc_state->vrr.cmrr_m)); intel_de_write(display, TRANS_CMRR_N_HI(display, cpu_transcoder), - upper_32_bits(crtc_state->cmrr.cmrr_n)); + upper_32_bits(crtc_state->vrr.cmrr_n)); intel_de_write(display, TRANS_CMRR_N_LO(display, cpu_transcoder), - lower_32_bits(crtc_state->cmrr.cmrr_n)); + lower_32_bits(crtc_state->vrr.cmrr_n)); } intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), @@ -472,7 +471,7 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), TRANS_PUSH_EN); - if (crtc_state->cmrr.enable) { + if (crtc_state->vrr.mode == INTEL_VRRTG_MODE_CMRR) { intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE | trans_vrr_ctl(crtc_state)); @@ -508,12 +507,11 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) TRANS_VRR_CTL(display, cpu_transcoder)); if (HAS_CMRR(display) && trans_vrr_ctl & VRR_CTL_CMRR_ENABLE) { - crtc_state->cmrr.enable = true; crtc_state->vrr.mode = INTEL_VRRTG_MODE_CMRR; - crtc_state->cmrr.cmrr_n = + crtc_state->vrr.cmrr_n = intel_de_read64_2x32(display, TRANS_CMRR_N_LO(display, cpu_transcoder), TRANS_CMRR_N_HI(display, cpu_transcoder)); - crtc_state->cmrr.cmrr_m = + crtc_state->vrr.cmrr_m = intel_de_read64_2x32(display, TRANS_CMRR_M_LO(display, cpu_transcoder), TRANS_CMRR_M_HI(display, cpu_transcoder)); } else if (trans_vrr_ctl & VRR_CTL_VRR_ENABLE) { -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:38 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:38 +0530 Subject: [PATCH 09/13] drm/i915/display: Add vrr mode to crtc_state dump In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-10-ankit.k.nautiyal@intel.com> Print Vrr mode along with other vrr members in crtc_state dump. Signed-off-by: Ankit Nautiyal --- .../drm/i915/display/intel_crtc_state_dump.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 56a43f3fc7f6..9f4c88f05f4c 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -172,6 +172,20 @@ vlv_dump_csc(struct drm_printer *p, const char *name, csc->coeff[3 * i + 2]); } +static const char * const vrrtg_mode_str[] = { + [INTEL_VRRTG_MODE_NONE] = "none", + [INTEL_VRRTG_MODE_VRR] = "vrr", + [INTEL_VRRTG_MODE_CMRR] = "cmrr", +}; + +static const char *intel_vrrtg_mode_name(enum intel_vrrtg_mode mode) +{ + if (mode >= ARRAY_SIZE(vrrtg_mode_str)) + return "invalid"; + + return vrrtg_mode_str[mode]; +} + void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, struct intel_atomic_state *state, const char *context) @@ -292,8 +306,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", + drm_printf(&p, "vrr: %s, mode: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", str_yes_no(intel_vrr_is_enabled(pipe_config)), + intel_vrrtg_mode_name(pipe_config->vrr.mode), pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end); -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:39 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:39 +0530 Subject: [PATCH 10/13] drm/i915/vrr: Disable CMRR In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-11-ankit.k.nautiyal@intel.com> Switching between variable and fixed timings is possible as for that we just need to flip between VRR timings. However for CMRR along with the timings, few other bits also need to be changed on the fly, which might cause issues. So disable CMRR for now, till we have variable and fixed timings sorted out. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index dc4923d49c29..56830513c10d 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -182,7 +182,8 @@ is_cmrr_frac_required(struct intel_crtc_state *crtc_state) int calculated_refresh_k, actual_refresh_k, pixel_clock_per_line; struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!HAS_CMRR(display)) + /* Avoid CMRR for now till we have VRR with fixed timings working */ + if (!HAS_CMRR(display) || true) return false; actual_refresh_k = -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:40 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:40 +0530 Subject: [PATCH 11/13] drm/i915/display: Update intel_crtc_vrr_{enable/disable} In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-12-ankit.k.nautiyal@intel.com> With CMRR the vrr.enable was tracking the vrr timing generator, which made the helpers intel_crtc_vrr_{enable/disable} also track the vrr timing generator. Since we don not have CMRR now, the crtc_vrr_{enable/disable} should now track the vrr mode of operation of the vrr timing generator. Update the helpers intel_crtc_vrr_{enable/disable} to track the vrr mode of the vrr timing generator. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 24 +++++++++++++------- drivers/gpu/drm/i915/display/intel_vrr.c | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2013366a8374..5eef922b3172 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1121,14 +1121,18 @@ static bool intel_crtc_vrr_enabling(struct intel_atomic_state *state, intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + bool old_vrr_enabled = intel_vrr_is_enabled(old_crtc_state); + bool new_vrr_enabled = intel_vrr_is_enabled(new_crtc_state); + bool needs_modeset = intel_crtc_needs_modeset(new_crtc_state); + bool update_m_n = new_crtc_state->update_m_n; + bool update_lrr = new_crtc_state->update_lrr; + bool params_changed = vrr_params_changed(old_crtc_state, new_crtc_state); if (!new_crtc_state->hw.active) return false; - return is_enabling(vrr.mode, old_crtc_state, new_crtc_state) || - (intel_vrr_is_enabled(new_crtc_state) && - (new_crtc_state->update_m_n || new_crtc_state->update_lrr || - vrr_params_changed(old_crtc_state, new_crtc_state))); + return (new_vrr_enabled && (!old_vrr_enabled || needs_modeset)) || + (new_vrr_enabled && (update_m_n || update_lrr || params_changed)); } bool intel_crtc_vrr_disabling(struct intel_atomic_state *state, @@ -1138,14 +1142,18 @@ bool intel_crtc_vrr_disabling(struct intel_atomic_state *state, intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + bool old_vrr_enabled = intel_vrr_is_enabled(old_crtc_state); + bool new_vrr_enabled = intel_vrr_is_enabled(new_crtc_state); + bool needs_modeset = intel_crtc_needs_modeset(new_crtc_state); + bool update_m_n = new_crtc_state->update_m_n; + bool update_lrr = new_crtc_state->update_lrr; + bool params_changed = vrr_params_changed(old_crtc_state, new_crtc_state); if (!old_crtc_state->hw.active) return false; - return is_disabling(vrr.mode, old_crtc_state, new_crtc_state) || - (intel_vrr_is_enabled(old_crtc_state) && - (new_crtc_state->update_m_n || new_crtc_state->update_lrr || - vrr_params_changed(old_crtc_state, new_crtc_state))); + return (old_vrr_enabled && (!new_vrr_enabled || needs_modeset)) || + (old_vrr_enabled && (update_m_n || update_lrr || params_changed)); } static bool audio_enabling(const struct intel_crtc_state *old_crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 56830513c10d..160d1b965bf3 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -277,7 +277,7 @@ int intel_vrr_compute_vmax(struct intel_connector *connector, bool intel_vrr_is_enabled(const struct intel_crtc_state *crtc_state) { - return crtc_state->vrr.mode != INTEL_VRRTG_MODE_NONE; + return crtc_state->vrr.mode == INTEL_VRRTG_MODE_VRR; } void -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:41 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:41 +0530 Subject: [PATCH 12/13] drm/i915/vrr: Use crtc_vtotal for vmin In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-13-ankit.k.nautiyal@intel.com> To have fixed refresh rate with VRR timing generator the guardband/pipeline full cant be programmed on the fly. So we need to ensure that the values satisfy both the fixed and variable refresh rates. Since we compute these value based on vmin, lets set the vmin to crtc_vtotal for both fixed and variable timings instead of using the current refresh rate based approach. This way the guardband remains sufficient for both cases. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 34 +++++++++++++++++------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 160d1b965bf3..5874aa76d626 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -246,18 +246,34 @@ 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_compute_vmin(struct intel_connector *connector, - struct drm_display_mode *adjusted_mode) +int intel_vrr_fixed_rr_vtotal(const struct intel_crtc_state *crtc_state) { - int vmin; - const struct drm_display_info *info = &connector->base.display_info; + struct intel_display *display = to_intel_display(crtc_state); + int crtc_vtotal = crtc_state->hw.adjusted_mode.crtc_vtotal; - vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000, - adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq); - vmin = max_t(int, vmin, adjusted_mode->crtc_vtotal); + if (DISPLAY_VER(display) >= 13) + return crtc_vtotal; + else + return crtc_vtotal - + intel_vrr_real_vblank_delay(crtc_state); +} - return vmin; +static +int intel_vrr_compute_vmin(struct intel_crtc_state *crtc_state) +{ + /* + * To make fixed rr and vrr work seamless the guardband/pipeline full + * should be set such that it satisfies both the fixed and variable + * timings. + * For this set the vmin as crtc_vtotal. With this we never need to + * change anything to do with the guardband. + */ + return intel_vrr_fixed_rr_vtotal(crtc_state); } static @@ -310,7 +326,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, if (HAS_LRR(display)) crtc_state->update_lrr = true; - vmin = intel_vrr_compute_vmin(connector, adjusted_mode); + vmin = intel_vrr_compute_vmin(crtc_state); vmax = intel_vrr_compute_vmax(connector, adjusted_mode); if (vmin >= vmax) -- 2.45.2 From ankit.k.nautiyal at intel.com Sat Feb 1 09:31:42 2025 From: ankit.k.nautiyal at intel.com (Ankit Nautiyal) Date: Sat, 1 Feb 2025 15:01:42 +0530 Subject: [PATCH 13/13] drm/i915/vrr: Prepare for fixed refresh rate timings In-Reply-To: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> References: <20250201093142.3298281-1-ankit.k.nautiyal@intel.com> Message-ID: <20250201093142.3298281-14-ankit.k.nautiyal@intel.com> Currently we always compute the timings as if vrr is enabled. With this approach the state checker becomes complicated when we introduce fixed refresh rate mode with vrr timing generator. To avoid the complications, instead of always computing vrr timings, we compute vrr timings based on uapi.vrr_enable knob. So when the knob is disabled we always compute vmin=flipline=vmax. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 5874aa76d626..deac0dedcb27 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -263,6 +263,35 @@ int intel_vrr_fixed_rr_vtotal(const struct intel_crtc_state *crtc_state) 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_prepare_fixed_timings(struct intel_crtc_state *crtc_state) +{ + crtc_state->vrr.vmax = intel_vrr_fixed_rr_vmax(crtc_state); + crtc_state->vrr.vmin = intel_vrr_fixed_rr_vmin(crtc_state); + crtc_state->vrr.flipline = intel_vrr_fixed_rr_flipline(crtc_state); +} + static int intel_vrr_compute_vmin(struct intel_crtc_state *crtc_state) { @@ -348,6 +377,8 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, 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_prepare_fixed_timings(crtc_state); if (HAS_AS_SDP(display)) { crtc_state->vrr.vsync_start = @@ -485,6 +516,13 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) if (!intel_vrr_is_enabled(crtc_state)) 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); @@ -512,6 +550,13 @@ 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_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), + intel_vrr_fixed_rr_vmin(old_crtc_state) - 1); + intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), + intel_vrr_fixed_rr_vmax(old_crtc_state) - 1); + intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), + intel_vrr_fixed_rr_flipline(old_crtc_state) - 1); } void intel_vrr_get_config(struct intel_crtc_state *crtc_state) -- 2.45.2