diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1469-drm-amd-display-Use-vrr-friendly-pageflip-throttling.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1469-drm-amd-display-Use-vrr-friendly-pageflip-throttling.patch | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1469-drm-amd-display-Use-vrr-friendly-pageflip-throttling.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1469-drm-amd-display-Use-vrr-friendly-pageflip-throttling.patch new file mode 100644 index 00000000..635e0343 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1469-drm-amd-display-Use-vrr-friendly-pageflip-throttling.patch @@ -0,0 +1,146 @@ +From 7d0f56ae827a9ff9e1af371324d678cb11c80e8d Mon Sep 17 00:00:00 2001 +From: Mario Kleiner <mario.kleiner.de@gmail.com> +Date: Sat, 9 Feb 2019 07:52:55 +0100 +Subject: [PATCH 1469/2940] drm/amd/display: Use vrr friendly pageflip + throttling in DC. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In VRR mode, keep track of the vblank count of the last +completed pageflip in amdgpu_crtc->last_flip_vblank, as +recorded in the pageflip completion handler after each +completed flip. + +Use that count to prevent mmio programming a new pageflip +within the same vblank in which the last pageflip completed, +iow. to throttle pageflips to at most one flip per video +frame, while at the same time allowing to request a flip +not only before start of vblank, but also anywhere within +vblank. + +The old logic did the same, and made sense for regular fixed +refresh rate flipping, but in vrr mode it prevents requesting +a flip anywhere inside the possibly huge vblank, thereby +reducing framerate in vrr mode instead of improving it, by +delaying a slightly delayed flip requests up to a maximum +vblank duration + 1 scanout duration. This would limit VRR +usefulness to only help applications with a very high GPU +demand, which can submit the flip request before start of +vblank, but then have to wait long for fences to complete. + +With this method a flip can be both requested and - after +fences have completed - executed, ie. it doesn't matter if +the request (amdgpu_dm_do_flip()) gets delayed until deep +into the extended vblank due to cpu execution delays. This +also allows clients which want to regulate framerate within +the vrr range a much more fine-grained control of flip timing, +a feature that might be useful for video playback, and is +very useful for neuroscience/vision research applications. + +In regular non-VRR mode, retain the old flip submission +behavior. This to keep flip scheduling for fullscreen X11/GLX +OpenGL clients intact, if they use the GLX_OML_sync_control +extensions glXSwapBufferMscOML(, ..., target_msc,...) function +with a specific target_msc target vblank count. + +glXSwapBuffersMscOML() or DRI3/Present PresentPixmap() will +not flip at the proper target_msc for a non-zero target_msc +if VRR mode is active with this patch. They'd often flip one +frame too early. However, this limitation should not matter +much in VRR mode, as scheduling based on vblank counts is +pretty futile/unusable under variable refresh duration +anyway, so no real extra harm is done. + +According to some testing already done with this patch by +Nicholas on top of my tests, IGT tests didn't report any +problems. If fixes stuttering and flickering when flipping +at rates below the minimum vrr refresh rate. + +Fixes: bb47de736661 ("drm/amdgpu: Set FreeSync state using drm VRR +properties") +Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> +Cc: <stable@vger.kernel.org> +Cc: Harry Wentland <harry.wentland@amd.com> +Cc: Alex Deucher <alexander.deucher@amd.com> +Cc: Michel Dänzer <michel@daenzer.net> +Tested-by: Bruno Filipe <bmilreu@gmail.com> +Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> + +Change-Id: Id91fbd29b5749bd8538a6efd1b03362e4ceda40e +Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 ++++++++++++++++++- + 2 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +index 39db58809d9b..ec0ea57d0820 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +@@ -411,6 +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; + /* 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 e9e170c44e49..7fbba5d2df3a 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -302,6 +302,8 @@ static void dm_pflip_high_irq(void *interrupt_params) + return; + } + ++ /* Update to correct count(s) if racing with vblank irq */ ++ amdgpu_crtc->last_flip_vblank = drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); + + /* wake up usersapce */ + if (amdgpu_crtc->event) { +@@ -4791,6 +4793,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + uint64_t tiling_flags, dcc_address; + uint32_t target, target_vblank; + 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]; +@@ -4930,7 +4934,31 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + } + + if (pflip_present) { +- target = (uint32_t)drm_crtc_vblank_count(pcrtc) + wait_for_vblank; ++ if (!vrr_active) { ++ /* Use old throttling in non-vrr fixed refresh rate mode ++ * to keep flip scheduling based on target vblank counts ++ * working in a backwards compatible way, e.g., for ++ * clients using the GLX_OML_sync_control extension or ++ * DRI3/Present extension with defined target_msc. ++ */ ++ last_flip_vblank = drm_crtc_vblank_count(pcrtc); ++ } ++ else { ++ /* For variable refresh rate mode only: ++ * Get vblank of last completed flip to avoid > 1 vrr ++ * flips per video frame by use of throttling, but allow ++ * flip programming anywhere in the possibly large ++ * variable vrr vblank interval for fine-grained flip ++ * timing control and more opportunity to avoid stutter ++ * on late submission of flips. ++ */ ++ spin_lock_irqsave(&pcrtc->dev->event_lock, flags); ++ last_flip_vblank = acrtc_attach->last_flip_vblank; ++ 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); +-- +2.17.1 + |