aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1713-drm-amd-display-Make-pageflip-event-delivery-compati.patch
diff options
context:
space:
mode:
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.patch157
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
+