From 51e7f44027a184f5f9048caa0d7e29eebdd9a5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:52 +0200 Subject: drm/i915: Fix include order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include the headers in the correct alphabetical order. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-4-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 70088e355055..66f9ce2b4486 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -7,9 +7,9 @@ #include "i915_reg.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_dp.h" #include "intel_vrr.h" #include "intel_vrr_regs.h" -#include "intel_dp.h" #define FIXED_POINT_PRECISION 100 #define CMRR_PRECISION_TOLERANCE 10 -- cgit v1.2.3 From b7eeed399b2851b140119e4866cabaaf1cba182d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:09:53 +0200 Subject: drm/i915: Introduce intel_vrr_{vmin,vmax}_vtotal() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ICL/TGL vmin/vmax/flipline won't actually match the vtotal values (currently they do, but that is wrong and needs to be fixed). Add a few helpers that will compute the actual vtotal values for us. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-5-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 66f9ce2b4486..2e9c286bb079 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -102,6 +102,17 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat return crtc_state->vrr.pipeline_full + crtc_state->framestart_delay + 1; } +int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) +{ + /* Min vblank actually determined by flipline that is always >=vmin+1 */ + return crtc_state->vrr.vmin + 1; +} + +int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->vrr.vmax; +} + int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) { /* Min vblank actually determined by flipline that is always >=vmin+1 */ -- cgit v1.2.3 From 67badd015cba8d25fc88bf13cc49d8f7c377d547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:01 +0200 Subject: drm/i915/vrr: Introduce intel_vrr_vblank_delay() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a VRR specific function for determining the current vblank delay. Currently thus will give the same answer as intel_mode_vblank_delay() but that will change later. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-13-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 2e9c286bb079..05da10919ba8 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -75,6 +75,12 @@ intel_vrr_check_modeset(struct intel_atomic_state *state) } } +int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->hw.adjusted_mode.crtc_vblank_start - + crtc_state->hw.adjusted_mode.crtc_vdisplay; +} + /* * Without VRR registers get latched at: * vblank_start -- cgit v1.2.3 From 758736b0df3a55915014e54065d87e35cbfae7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:02 +0200 Subject: drm/i915/vrr: Drop the extra vmin adjustment for ADL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently only ICL/TGL need the annoying vmin adjustment. On ADL+ we can program flipline==vmin and the hardware actually respects that properly. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-14-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 05da10919ba8..0f0c50265fc1 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -81,6 +81,19 @@ int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) crtc_state->hw.adjusted_mode.crtc_vdisplay; } +static int intel_vrr_flipline_offset(struct intel_display *display) +{ + /* ICL/TGL hardware imposes flipline>=vmin+1 */ + return DISPLAY_VER(display) < 13 ? 1 : 0; +} + +static int intel_vrr_vmin_flipline(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + return crtc_state->vrr.vmin + intel_vrr_flipline_offset(display); +} + /* * Without VRR registers get latched at: * vblank_start @@ -110,8 +123,8 @@ 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) { - /* Min vblank actually determined by flipline that is always >=vmin+1 */ - return crtc_state->vrr.vmin + 1; + /* Min vblank actually determined by flipline */ + return intel_vrr_vmin_flipline(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) @@ -121,8 +134,8 @@ int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) { - /* Min vblank actually determined by flipline that is always >=vmin+1 */ - return crtc_state->vrr.vmin + 1 - intel_vrr_vblank_exit_length(crtc_state); + /* Min vblank actually determined by flipline */ + return intel_vrr_vmin_flipline(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); } int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state) @@ -219,15 +232,17 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, if (vmin >= vmax) return; + crtc_state->vrr.vmin = vmin; + crtc_state->vrr.vmax = vmax; + + crtc_state->vrr.flipline = crtc_state->vrr.vmin; + /* * 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. + * generate, and on ICL/TGL 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.vmin -= intel_vrr_flipline_offset(display); /* * When panel is VRR capable and userspace has @@ -272,7 +287,7 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) if (DISPLAY_VER(display) >= 13) { crtc_state->vrr.guardband = - crtc_state->vrr.vmin + 1 - adjusted_mode->crtc_vblank_start; + crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start; } else { crtc_state->vrr.pipeline_full = min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start - -- cgit v1.2.3 From b6e4f92a21e35ca8bd7b21b4b5866da59dd51c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:03 +0200 Subject: drm/i915/vrr: Fix vmin/vmax/flipline on TGL when using vblank delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out that TGL needs its vmin/vmax/flipline adjusted based on the vblank delay, otherwise the hardware pushes the vtotals further out. Make it so. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-15-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 0f0c50265fc1..1110f0e65e88 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -117,30 +117,41 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat if (DISPLAY_VER(display) >= 13) return crtc_state->vrr.guardband; else - /* The hw imposes the extra scanline before frame start */ + /* hardware imposes one extra scanline somewhere */ return crtc_state->vrr.pipeline_full + crtc_state->framestart_delay + 1; } 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 */ - return intel_vrr_vmin_flipline(crtc_state); + if (DISPLAY_VER(display) >= 13) + return intel_vrr_vmin_flipline(crtc_state); + else + return intel_vrr_vmin_flipline(crtc_state) + + intel_vrr_vblank_delay(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) { - return crtc_state->vrr.vmax; + 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_vblank_delay(crtc_state); } int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) { - /* Min vblank actually determined by flipline */ - return intel_vrr_vmin_flipline(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); + return intel_vrr_vmin_vtotal(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); } int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state) { - return crtc_state->vrr.vmax - intel_vrr_vblank_exit_length(crtc_state); + return intel_vrr_vmax_vtotal(crtc_state) - intel_vrr_vblank_exit_length(crtc_state); } static bool @@ -289,9 +300,18 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) crtc_state->vrr.guardband = crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start; } else { + /* hardware imposes one extra scanline somewhere */ crtc_state->vrr.pipeline_full = min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start - crtc_state->framestart_delay - 1); + + /* + * vmin/vmax/flipline also need to be adjusted by + * the vblank delay to maintain correct vtotals. + */ + crtc_state->vrr.vmin -= intel_vrr_vblank_delay(crtc_state); + crtc_state->vrr.vmax -= intel_vrr_vblank_delay(crtc_state); + crtc_state->vrr.flipline -= intel_vrr_vblank_delay(crtc_state); } } -- cgit v1.2.3 From 8b85eadabd0902bde4562c493f4e1068a0c80c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:04 +0200 Subject: drm/i915/vrr: Add extra vblank delay to estimates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ICL/TGL the VRR hardware injects an extra scanline just after vactive. This essentically behaves the same as an extra line of vblank delay, except it only appears in this one specific spot. Consider our DSB interrupt signalling scheme: 1. arm the update 2. wait for undelayed vblank (or rather safe window with VRR) 3. wait for enough usecs to get past the delayed vblank 4. signal interrupt to indicate that arming has latched If step 2 waits for end of vactive step 3 needs to account for the extra one scanline, or else we risk signalling the interrupt before the delayed vblank has actually elapsed. So include the extra scanline in our vblank delay estimates. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-16-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 33 ++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 1110f0e65e88..b5e30bfe1791 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -75,12 +75,33 @@ intel_vrr_check_modeset(struct intel_atomic_state *state) } } -int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) +static int intel_vrr_real_vblank_delay(const struct intel_crtc_state *crtc_state) { return crtc_state->hw.adjusted_mode.crtc_vblank_start - crtc_state->hw.adjusted_mode.crtc_vdisplay; } +static int intel_vrr_extra_vblank_delay(struct intel_display *display) +{ + /* + * On ICL/TGL VRR hardware inserts one extra scanline + * just after vactive, which pushes the vmin decision + * boundary ahead accordingly. We'll include the extra + * scanline in our vblank delay estimates to make sure + * that we never underestimate how long we have until + * the delayed vblank has passed. + */ + return DISPLAY_VER(display) < 13 ? 1 : 0; +} + +int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + return intel_vrr_real_vblank_delay(crtc_state) + + intel_vrr_extra_vblank_delay(display); +} + static int intel_vrr_flipline_offset(struct intel_display *display) { /* ICL/TGL hardware imposes flipline>=vmin+1 */ @@ -130,7 +151,7 @@ int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state) return intel_vrr_vmin_flipline(crtc_state); else return intel_vrr_vmin_flipline(crtc_state) + - intel_vrr_vblank_delay(crtc_state); + intel_vrr_real_vblank_delay(crtc_state); } int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) @@ -141,7 +162,7 @@ int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state) return crtc_state->vrr.vmax; else return crtc_state->vrr.vmax + - intel_vrr_vblank_delay(crtc_state); + intel_vrr_real_vblank_delay(crtc_state); } int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state) @@ -309,9 +330,9 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state) * vmin/vmax/flipline also need to be adjusted by * the vblank delay to maintain correct vtotals. */ - crtc_state->vrr.vmin -= intel_vrr_vblank_delay(crtc_state); - crtc_state->vrr.vmax -= intel_vrr_vblank_delay(crtc_state); - crtc_state->vrr.flipline -= intel_vrr_vblank_delay(crtc_state); + 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); } } -- cgit v1.2.3 From fd95e73debdffd77febc0f0b4b304378856a5e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 10 Dec 2024 23:10:05 +0200 Subject: drm/i915/vrr: Plumb the DSB into intel_vrr_send_push() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plumb the DSB down into intel_vrr_send_push() so that we can perform the opration on the DSB. TRANS_PUSH, being a transcoder register, needs non-posted writes to make it through. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241210211007.5976-17-ville.syrjala@linux.intel.com Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_vrr.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index b5e30bfe1791..b268a0a01cd1 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -390,7 +390,8 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) crtc_state->vrr.flipline - 1); } -void intel_vrr_send_push(const struct intel_crtc_state *crtc_state) +void intel_vrr_send_push(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; @@ -398,8 +399,15 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state) if (!crtc_state->vrr.enable) return; - intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), - TRANS_PUSH_EN | TRANS_PUSH_SEND); + if (dsb) + intel_dsb_nonpost_start(dsb); + + intel_de_write_dsb(display, dsb, + TRANS_PUSH(display, cpu_transcoder), + TRANS_PUSH_EN | TRANS_PUSH_SEND); + + if (dsb) + intel_dsb_nonpost_end(dsb); } bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state) -- cgit v1.2.3 From 387f269e56eafa461a314a30b4e7f85625b2cba6 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 30 Jan 2025 10:46:05 +0530 Subject: drm/i915/vrr: Compute vrr.vsync_{start, end} during full modeset vrr.vsync_{start,end} computation should not depend on crtc_state->vrr.enable. --v1: - Explain commit message more clearly [Jani] - Instead of tweaking to fastset use vrr.flipline while computing AS_SDP. --v2: - Correct computation of vrr.vsync_start/end should not depend on vrr.enable.[ville] - vrr enable disable requirement should not obstruct by SDP enable disable requirements. [Ville] --v3: - Create separate patch for crtc_state_dump [Ankit]. --v4: - Update commit message and header [Ankit]. Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250130051609.1796524-3-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index b268a0a01cd1..adb51609d0a3 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -299,7 +299,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } - if (intel_dp->as_sdp_supported && crtc_state->vrr.enable) { + if (HAS_AS_SDP(display)) { crtc_state->vrr.vsync_start = (crtc_state->hw.adjusted_mode.crtc_vtotal - crtc_state->hw.adjusted_mode.vsync_start); @@ -388,6 +388,12 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) trans_vrr_ctl(crtc_state)); intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), crtc_state->vrr.flipline - 1); + + if (HAS_AS_SDP(display)) + intel_de_write(display, + TRANS_VRR_VSYNC(display, cpu_transcoder), + VRR_VSYNC_END(crtc_state->vrr.vsync_end) | + VRR_VSYNC_START(crtc_state->vrr.vsync_start)); } void intel_vrr_send_push(struct intel_dsb *dsb, @@ -432,12 +438,6 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), TRANS_PUSH_EN); - if (HAS_AS_SDP(display)) - intel_de_write(display, - TRANS_VRR_VSYNC(display, cpu_transcoder), - VRR_VSYNC_END(crtc_state->vrr.vsync_end) | - VRR_VSYNC_START(crtc_state->vrr.vsync_start)); - if (crtc_state->cmrr.enable) { intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE | @@ -462,10 +462,6 @@ 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); - - if (HAS_AS_SDP(display)) - intel_de_write(display, - TRANS_VRR_VSYNC(display, cpu_transcoder), 0); } void intel_vrr_get_config(struct intel_crtc_state *crtc_state) @@ -505,10 +501,6 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) TRANS_VRR_VMAX(display, cpu_transcoder)) + 1; crtc_state->vrr.vmin = intel_de_read(display, TRANS_VRR_VMIN(display, cpu_transcoder)) + 1; - } - - if (crtc_state->vrr.enable) { - crtc_state->mode_flags |= I915_MODE_FLAG_VRR; if (HAS_AS_SDP(display)) { trans_vrr_vsync = @@ -520,4 +512,7 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) REG_FIELD_GET(VRR_VSYNC_END_MASK, trans_vrr_vsync); } } + + if (crtc_state->vrr.enable) + crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } -- cgit v1.2.3 From c3571a239e108fe92adedd49ca3905d435093157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 10 Feb 2025 18:07:11 +0200 Subject: drm/i915/vrr: Check that the push send bit is clear after delayed vblank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we don't do mailbox updates the push send bit should alwyas clear by the time the delay vblank fires and the flip completes. Check for that to make sure we haven't screwed up the sequencing/vblank evasion/etc. On the DSB path we should be able to guarantee this since we don't have to deal with any scheduler latencies and whatnot. I suppose unexpected DMA/memory latencies might be the only thing that might trip us up here. For the MMIO path we do always have a non-zero chance that vblank evasion fails (since we can't really guarantee anything about the scheduling behaviour). That could trip up this check, but that seems fine since we already print errors for other types of vblank evasion failures. Should the CPU vblank evasion actually fail, then the push send bit can still be set when the next commit happens. But both the DSB and MMIO paths should handle that situation gracefully. v2: Only check once instead of polling for two scanlines since we should now be guaranteed to be past the delayed vblank. Also check in the MMIO path for good measure v3: Skip the push send check when VRR is disabled. With joiner the secondary pipe's DSBs doen't have access to the transcoder registers, and so doing this check there triggers a reponse timeout error on the DSB. VRR is not currently allowed when using joiner, so this will prevent the bogus register access. Reviewed-by: Ankit Nautiyal Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250210160711.24010-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_vrr.c') diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index adb51609d0a3..cac49319026d 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -416,6 +416,40 @@ void intel_vrr_send_push(struct intel_dsb *dsb, intel_dsb_nonpost_end(dsb); } +void intel_vrr_check_push_sent(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (!crtc_state->vrr.enable) + return; + + /* + * Make sure the push send bit has cleared. This should + * already be the case as long as the caller makes sure + * this is called after the delayed vblank has occurred. + */ + if (dsb) { + int wait_us, count; + + wait_us = 2; + count = 1; + + /* + * If the bit hasn't cleared the DSB will + * raise the poll error interrupt. + */ + intel_dsb_poll(dsb, TRANS_PUSH(display, cpu_transcoder), + TRANS_PUSH_SEND, 0, wait_us, count); + } else { + if (intel_vrr_is_push_sent(crtc_state)) + drm_err(display->drm, "[CRTC:%d:%s] VRR push send still pending\n", + crtc->base.base.id, crtc->base.name); + } +} + bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); -- cgit v1.2.3