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@xxxxxxxxx> Cc: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx> Cc: Harry Wentland <harry.wentland@xxxxxxx> Cc: Alex Deucher <alexander.deucher@xxxxxxx> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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); -- 2.17.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel