Skip to content

Commit 71d1dea

Browse files
vsyrjalalutzbichler
authored andcommitted
drm/i915/vrr: Add extra vblank delay to estimates
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ä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Ankit Nautiyal <[email protected]>
1 parent dd4b2ff commit 71d1dea

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

drivers/gpu/drm/i915/display/intel_vrr.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,33 @@ intel_vrr_check_modeset(struct intel_atomic_state *state)
7575
}
7676
}
7777

78-
int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state)
78+
static int intel_vrr_real_vblank_delay(const struct intel_crtc_state *crtc_state)
7979
{
8080
return crtc_state->hw.adjusted_mode.crtc_vblank_start -
8181
crtc_state->hw.adjusted_mode.crtc_vdisplay;
8282
}
8383

84+
static int intel_vrr_extra_vblank_delay(struct intel_display *display)
85+
{
86+
/*
87+
* On ICL/TGL VRR hardware inserts one extra scanline
88+
* just after vactive, which pushes the vmin decision
89+
* boundary ahead accordingly. We'll include the extra
90+
* scanline in our vblank delay estimates to make sure
91+
* that we never underestimate how long we have until
92+
* the delayed vblank has passed.
93+
*/
94+
return DISPLAY_VER(display) < 13 ? 1 : 0;
95+
}
96+
97+
int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state)
98+
{
99+
struct intel_display *display = to_intel_display(crtc_state);
100+
101+
return intel_vrr_real_vblank_delay(crtc_state) +
102+
intel_vrr_extra_vblank_delay(display);
103+
}
104+
84105
static int intel_vrr_flipline_offset(struct intel_display *display)
85106
{
86107
/* ICL/TGL hardware imposes flipline>=vmin+1 */
@@ -130,7 +151,7 @@ int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state)
130151
return intel_vrr_vmin_flipline(crtc_state);
131152
else
132153
return intel_vrr_vmin_flipline(crtc_state) +
133-
intel_vrr_vblank_delay(crtc_state);
154+
intel_vrr_real_vblank_delay(crtc_state);
134155
}
135156

136157
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)
141162
return crtc_state->vrr.vmax;
142163
else
143164
return crtc_state->vrr.vmax +
144-
intel_vrr_vblank_delay(crtc_state);
165+
intel_vrr_real_vblank_delay(crtc_state);
145166
}
146167

147168
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)
309330
* vmin/vmax/flipline also need to be adjusted by
310331
* the vblank delay to maintain correct vtotals.
311332
*/
312-
crtc_state->vrr.vmin -= intel_vrr_vblank_delay(crtc_state);
313-
crtc_state->vrr.vmax -= intel_vrr_vblank_delay(crtc_state);
314-
crtc_state->vrr.flipline -= intel_vrr_vblank_delay(crtc_state);
333+
crtc_state->vrr.vmin -= intel_vrr_real_vblank_delay(crtc_state);
334+
crtc_state->vrr.vmax -= intel_vrr_real_vblank_delay(crtc_state);
335+
crtc_state->vrr.flipline -= intel_vrr_real_vblank_delay(crtc_state);
315336
}
316337
}
317338

0 commit comments

Comments
 (0)