diff mbox series

[3/3] drm/amd/display: Provide more accurate pageflip timestamps in vrr mode.

Message ID 20190211032225.9488-4-mario.kleiner.de@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/3] drm/amdgpu: Fix get_crtc_scanoutpos behavior in vrr when vpos >= vtotal. | expand

Commit Message

Mario Kleiner Feb. 11, 2019, 3:22 a.m. UTC
This implements more accurate pageflip completion timestamps
for crtc's running in variable refresh rate mode.

In vrr mode, the pageflip completion interrupt handler takes
a ktime_get() timestamp of pageflip completion as a at least
roughly correct lower estimate of when the vblank of flip
completion will end and thereby display of the new scanout
buffer will start.

It submits this proposed timestamp via the new helper function
drm_crtc_set_vrr_pageflip_timestamp(). The DRM core will decide
when sending out pageflip events, if the regular vblank timestamp
gets sent out, or this alternate later timestamp, following the
rule that a post-flip buffer can't start displaying earlier than
the vblank timestamp, which corresponds to the end of the shortest
possible vblank interval under vrr mode.

This is a crude first implementation, but it should reduce
pageflip timestamp errors from potentially dozens of milliseconds
to probably less than 2 msecs in the common case, given the fixed
and short back-porch duration and the usually low interrupt dispatch
delay from pageflip interrupt.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d4da331aa349..49c5a044297f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -280,7 +280,9 @@  static void dm_pflip_high_irq(void *interrupt_params)
 	struct amdgpu_crtc *amdgpu_crtc;
 	struct common_irq_params *irq_params = interrupt_params;
 	struct amdgpu_device *adev = irq_params->adev;
+	struct dm_crtc_state *acrtc_state;
 	unsigned long flags;
+	ktime_t t_onset = ktime_get();
 
 	amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP);
 
@@ -306,6 +308,24 @@  static void dm_pflip_high_irq(void *interrupt_params)
 	/* Update to correct count(s) if racing with vblank irq */
 	amdgpu_crtc->last_flip_vblank = drm_crtc_accurate_vblank_count(&amdgpu_crtc->base);
 
+	/* VRR pageflip timestamp handling: In VRR mode, compute alternate flip
+	 * timestamp for flip completion in extended front porch, ie. estimating
+	 * the time of the end of a longer than minimum vblank interval. DRM
+	 * will decide to use this alternate timestamp, or the standard vblank
+	 * timestamp for minimum duration vblank. The later timestamp is the one
+	 * chosen for the pageflip event.
+	 */
+	acrtc_state = to_dm_crtc_state(amdgpu_crtc->base.state);
+	if (acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) {
+		/* FIXME: t_onset is just a pflip irq timestamp taken above.
+		 * Add the fixed back-porch duration? Or even better use some
+		 * hardware trickery to get a more precise estimate of true
+		 * end of vblank?
+		 */
+		/* Propose "late" vblank end timestamp for consideration. */
+		drm_crtc_set_vrr_pageflip_timestamp(&amdgpu_crtc->base, t_onset);
+	}
+
 	/* wake up userspace */
 	if (amdgpu_crtc->event) {
 		drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event);