aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1711-drm-amd-display-Rework-vrr-flip-throttling-for-late-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1711-drm-amd-display-Rework-vrr-flip-throttling-for-late-.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1711-drm-amd-display-Rework-vrr-flip-throttling-for-late-.patch115
1 files changed, 115 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1711-drm-amd-display-Rework-vrr-flip-throttling-for-late-.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1711-drm-amd-display-Rework-vrr-flip-throttling-for-late-.patch
new file mode 100644
index 00000000..eeb57fca
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1711-drm-amd-display-Rework-vrr-flip-throttling-for-late-.patch
@@ -0,0 +1,115 @@
+From 26f412ed24f2eca47ad0c23e16d6ac2d1180b3ee Mon Sep 17 00:00:00 2001
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+Date: Fri, 29 Mar 2019 13:00:55 +0100
+Subject: [PATCH 1711/2940] drm/amd/display: Rework vrr flip throttling for
+ late vblank irq.
+
+For throttling to work correctly, we always need a baseline vblank
+count last_flip_vblank that increments at start of front-porch.
+
+This is the case for drm_crtc_vblank_count() in non-VRR mode, where
+the vblank irq fires at start of front-porch and triggers DRM core
+vblank handling, but it is no longer the case in VRR mode, where
+core vblank handling is done later, after end of front-porch.
+
+Therefore drm_crtc_vblank_count() is no longer useful for this.
+We also can't use drm_crtc_accurate_vblank_count(), as that would
+screw up vblank timestamps in VRR mode when called in front-porch.
+
+To solve this, use the cooked hardware vblank counter returned by
+amdgpu_get_vblank_counter_kms() instead, as that one is cooked to
+always increment at start of front-porch, independent of when
+vblank related irq's fire.
+
+This patch allows vblank irq handling to happen anywhere within
+vblank of even after it, without a negative impact on flip
+throttling, so followup patches can shift the vblank core
+handling trigger point wherever they need it.
+
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 +-
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++++++++++---------
+ 2 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+index ec0ea57d0820..7ce29c5700e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+@@ -411,7 +411,7 @@ struct amdgpu_crtc {
+ struct amdgpu_flip_work *pflip_works;
+ enum amdgpu_flip_status pflip_status;
+ int deferred_flip_completion;
+- u64 last_flip_vblank;
++ u32 last_flip_vblank;
+ /* pll sharing */
+ struct amdgpu_atom_ss ss;
+ bool ss_enabled;
+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 ed37a368d4fd..5190099fcdbd 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -287,7 +287,7 @@ 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);
++ drm_crtc_accurate_vblank_count(&amdgpu_crtc->base);
+
+ /* wake up usersapce */
+ if (amdgpu_crtc->event) {
+@@ -302,6 +302,14 @@ static void dm_pflip_high_irq(void *interrupt_params)
+ } else
+ WARN_ON(1);
+
++ /* 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
++ * of pageflip completion, so last_flip_vblank is the forbidden count
++ * for queueing new pageflips if vsync + VRR is enabled.
++ */
++ amdgpu_crtc->last_flip_vblank = amdgpu_get_vblank_counter_kms(adev->ddev,
++ amdgpu_crtc->crtc_id);
++
+ amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
+ spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
+
+@@ -4917,11 +4925,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ unsigned long flags;
+ struct amdgpu_bo *abo;
+ uint64_t tiling_flags;
+- uint32_t target, target_vblank;
++ uint32_t target_vblank, last_flip_vblank;
++ bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
+ bool pflip_present = false;
+- uint64_t last_flip_vblank;
+- bool vrr_active = acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE;
+-
+ struct {
+ struct dc_surface_update surface_updates[MAX_SURFACES];
+ struct dc_plane_info plane_infos[MAX_SURFACES];
+@@ -5063,7 +5069,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ * clients using the GLX_OML_sync_control extension or
+ * DRI3/Present extension with defined target_msc.
+ */
+- last_flip_vblank = drm_crtc_vblank_count(pcrtc);
++ last_flip_vblank = amdgpu_get_vblank_counter_kms(dm->ddev, acrtc_attach->crtc_id);
+ }
+ else {
+ /* For variable refresh rate mode only:
+@@ -5079,11 +5085,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
+ }
+
+- target = (uint32_t)last_flip_vblank + wait_for_vblank;
+-
+- /* Prepare wait for target vblank early - before the fence-waits */
+- target_vblank = target - (uint32_t)drm_crtc_vblank_count(pcrtc) +
+- amdgpu_get_vblank_counter_kms(pcrtc->dev, acrtc_attach->crtc_id);
++ target_vblank = last_flip_vblank + wait_for_vblank;
+
+ /*
+ * Wait until we're out of the vertical blank period before the one
+--
+2.17.1
+