diff options
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-.patch | 115 |
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 + |