diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1713-drm-amd-display-Make-pageflip-event-delivery-compati.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1713-drm-amd-display-Make-pageflip-event-delivery-compati.patch | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1713-drm-amd-display-Make-pageflip-event-delivery-compati.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1713-drm-amd-display-Make-pageflip-event-delivery-compati.patch new file mode 100644 index 00000000..271a2a6a --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1713-drm-amd-display-Make-pageflip-event-delivery-compati.patch @@ -0,0 +1,157 @@ +From 944cd0c0316cf21d88a738e1540a8d7331dd22f3 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner <mario.kleiner.de@gmail.com> +Date: Fri, 29 Mar 2019 13:00:57 +0100 +Subject: [PATCH 1713/2940] drm/amd/display: Make pageflip event delivery + compatible with VRR. + +We want vblank counts and timestamps of flip completion as sent +in pageflip completion events to be consistent with the vblank +count and timestamp of the vblank of flip completion, like in non +VRR mode. + +In VRR mode, drm_update_vblank_count() - and thereby vblank +count and timestamp updates - must be delayed until after the +end of front-porch of each vblank, as it is only safe to +calculate vblank timestamps outside of the front-porch, when +we actually know when the vblank will end or has ended. + +The function drm_update_vblank_count() which updates timestamps +and counts gets called by drm_crtc_accurate_vblank_count() or by +drm_crtc_handle_vblank(). + +Therefore we must make sure that pageflip events for a completed +flip are only sent out after drm_crtc_accurate_vblank_count() or +drm_crtc_handle_vblank() is executed, after end of front-porch +for the vblank of flip completion. + +Two cases: + +a) Pageflip irq handler executes inside front-porch: + In this case we must defer sending pageflip events until + drm_crtc_handle_vblank() executes after end of front-porch, + and thereby calculates proper vblank count and timestamp. + Iow. the pflip irq handler must just arm a pageflip event + to be sent out by drm_crtc_handle_vblank() later on. + +b) Pageflip irq handler executes after end of front-porch, e.g., + after flip completion in back-porch or due to a massively + delayed handler invocation into the active scanout of the new + frame. In this case we can call drm_crtc_accurate_vblank_count() + to safely force calculation of a proper vblank count and + timestamp, and must send the pageflip completion event + ourselves from the pageflip irq handler. + + This is the same behaviour as needed for standard fixed refresh + rate mode. + +To decide from within pageflip handler if we are in case a) or b), +we check the current scanout position against the boundary of +front-porch. In non-VRR mode we just do what we did in the past. + +Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> +Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> +Signed-off-by: Chaudhary Amit Kumar <Chaudharyamit.Kumar@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 68 +++++++++++++++---- + 1 file changed, 53 insertions(+), 15 deletions(-) + +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 4a0415961e92..82f5d1449efc 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -264,6 +264,10 @@ static void dm_pflip_high_irq(void *interrupt_params) + struct common_irq_params *irq_params = interrupt_params; + struct amdgpu_device *adev = irq_params->adev; + unsigned long flags; ++ struct drm_pending_vblank_event *e; ++ struct dm_crtc_state *acrtc_state; ++ uint32_t vpos, hpos, v_blank_start, v_blank_end; ++ bool vrr_active; + + amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP); + +@@ -286,21 +290,56 @@ static void dm_pflip_high_irq(void *interrupt_params) + return; + } + +- /* Update to correct count(s) if racing with vblank irq */ +- drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); ++ /* page flip completed. */ ++ e = amdgpu_crtc->event; ++ amdgpu_crtc->event = NULL; + +- /* wake up usersapce */ +- if (amdgpu_crtc->event) { +- /* Update to correct count(s) if racing with vblank irq */ +- drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); ++ if (!e) ++ WARN_ON(1); + +- drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event); ++ acrtc_state = to_dm_crtc_state(amdgpu_crtc->base.state); ++ vrr_active = amdgpu_dm_vrr_active(acrtc_state); + +- /* page flip completed. clean up */ +- amdgpu_crtc->event = NULL; ++ /* Fixed refresh rate, or VRR scanout position outside front-porch? */ ++ if (!vrr_active || ++ !dc_stream_get_scanoutpos(acrtc_state->stream, &v_blank_start, ++ &v_blank_end, &hpos, &vpos) || ++ (vpos < v_blank_start)) { ++ /* Update to correct count and vblank timestamp if racing with ++ * vblank irq. This also updates to the correct vblank timestamp ++ * even in VRR mode, as scanout is past the front-porch atm. ++ */ ++ drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); ++ /* Wake up userspace by sending the pageflip event with proper ++ * count and timestamp of vblank of flip completion. ++ */ ++ if (e) { ++ drm_crtc_send_vblank_event(&amdgpu_crtc->base, e); + +- } else +- WARN_ON(1); ++ /* Event sent, so done with vblank for this flip */ ++ drm_crtc_vblank_put(&amdgpu_crtc->base); ++ } ++ } else if (e) { ++ /* VRR active and inside front-porch: vblank count and ++ * timestamp for pageflip event will only be up to date after ++ * drm_crtc_handle_vblank() has been executed from late vblank ++ * irq handler after start of back-porch (vline 0). We queue the ++ * pageflip event for send-out by drm_crtc_handle_vblank() with ++ * updated timestamp and count, once it runs after us. ++ * ++ * We need to open-code this instead of using the helper ++ * drm_crtc_arm_vblank_event(), as that helper would ++ * call drm_crtc_accurate_vblank_count(), which we must ++ * not call in VRR mode while we are in front-porch! ++ */ ++ ++ /* sequence will be replaced by real count during send-out. */ ++ e->sequence = drm_crtc_vblank_count(&amdgpu_crtc->base); ++ e->pipe = amdgpu_crtc->crtc_id; ++ ++ list_add_tail(&e->base.link, &adev->ddev->vblank_event_list); ++ e = NULL; ++ } + + /* Keep track of vblank of this flip for flip throttling. We use the + * cooked hw counter, as that one incremented at start of this vblank +@@ -313,10 +352,9 @@ static void dm_pflip_high_irq(void *interrupt_params) + amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; + spin_unlock_irqrestore(&adev->ddev->event_lock, flags); + +- DRM_DEBUG_DRIVER("%s - crtc :%d[%p], pflip_stat:AMDGPU_FLIP_NONE\n", +- __func__, amdgpu_crtc->crtc_id, amdgpu_crtc); +- +- drm_crtc_vblank_put(&amdgpu_crtc->base); ++ DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_NONE, vrr[%d]-fp %d\n", ++ amdgpu_crtc->crtc_id, amdgpu_crtc, ++ vrr_active, (int) !e); + } + + static void dm_vupdate_high_irq(void *interrupt_params) +-- +2.17.1 + |