diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0333-drm-amd-display-Fix-race-between-vblank-irq-and-page.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0333-drm-amd-display-Fix-race-between-vblank-irq-and-page.patch | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0333-drm-amd-display-Fix-race-between-vblank-irq-and-page.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0333-drm-amd-display-Fix-race-between-vblank-irq-and-page.patch deleted file mode 100644 index 5e7b4e77..00000000 --- a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0333-drm-amd-display-Fix-race-between-vblank-irq-and-page.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 87e40d9c82472f1aba4f9d52e51acc413b7efeba Mon Sep 17 00:00:00 2001 -From: Mario Kleiner <mario.kleiner.de@gmail.com> -Date: Mon, 24 Apr 2017 11:46:44 +0200 -Subject: [PATCH 0333/4131] drm/amd/display: Fix race between vblank irq and - pageflip irq. (v2) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since DC now uses CRTC_VERTICAL_INTERRUPT0 as VBLANK irq trigger -and vblank interrupts actually happen earliest at start of vblank, -instead of a bit before vblank, we no longer need some of the -fudging logic to deal with too early vblank irq handling (grep for -lb_vblank_lead_lines). This itself fixes a pageflip scheduling -bug in DC, caused by uninitialized use of lb_vblank_lead_lines, -with a wrong startup value of 0. Thanks to the new vblank irq -trigger this value of zero is now actually correct for DC :). - -A new problem is that vblank irq's race against pflip irq's, -and as both can fire at first line of vblank, it is no longer -guaranteed that vblank irq handling (therefore -> drm_handle_vblank() --> drm_update_vblank_count()) executes before pflip irq handling -for a given vblank interval when a pageflip completes. Therefore -the vblank count and timestamps emitted to user-space as part of -the pageflip completion event will be often stale and cause new -timestamping and swap scheduling errors in user-space. - -This was observed with large frequency on R9 380 Tonga Pro. - -Fix this by enforcing a vblank count+timestamp update right -before emitting the pageflip completion event from the pflip -irq handler. The logic in core drm_update_vblank_count() makes -sure that no redundant or conflicting updates happen, iow. the -call turns into a no-op if it wasn't needed for that vblank, -burning a few microseconds of cpu time though. - -Successfully tested on AMD R9 380 "Tonga Pro" (VI/DCE 10) -with DC enabled on the current DC staging branch. Independent -measurement of pageflip completion timing with special hardware -measurement equipment now confirms correct pageflip timestamps -and counts in the pageflip completion events. - -v2: Review comments by Michel, drop outdated paragraph - about problem already fixed in 2nd patch of the series. - Add acked/r-b by Harry and Michel. - -Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> -Acked-by: Harry Wentland <harry.wentland@amd.com> (v1) -Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> - -Cc: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> -Cc: Alex Deucher <alexander.deucher@amd.com> -Cc: Michel Dänzer <michel.daenzer@amd.com> -Signed-off-by: Alex Deucher <alexander.deucher@amd.com> -Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ - drivers/gpu/drm/drm_vblank.c | 31 +++++++++++++++++++++++ - include/drm/drm_vblank.h | 1 + - 3 files changed, 35 insertions(+) - -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 c51e181..7ede233 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -202,6 +202,9 @@ static void dm_pflip_high_irq(void *interrupt_params) - if (amdgpu_crtc->event - && amdgpu_crtc->event->event.base.type - == DRM_EVENT_FLIP_COMPLETE) { -+ /* Update to correct count/ts if racing with vblank irq */ -+ drm_accurate_vblank_count(&amdgpu_crtc->base); -+ - drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event); - /* page flip completed. clean up */ - amdgpu_crtc->event = NULL; -diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c -index 17e8ef9..1b82d73 100644 ---- a/drivers/gpu/drm/drm_vblank.c -+++ b/drivers/gpu/drm/drm_vblank.c -@@ -293,6 +293,37 @@ static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe) - return vblank->count; - } - -+ /** -+ * drm_accurate_vblank_count - retrieve the master vblank counter -+ * @crtc: which counter to retrieve -+ * -+ * This function is similar to @drm_crtc_vblank_count but this -+ * function interpolates to handle a race with vblank irq's. -+ * -+ * This is mostly useful for hardware that can obtain the scanout -+ * position, but doesn't have a frame counter. -+ */ -+u32 drm_accurate_vblank_count(struct drm_crtc *crtc) -+{ -+ struct drm_device *dev = crtc->dev; -+ unsigned int pipe = drm_crtc_index(crtc); -+ u32 vblank; -+ unsigned long flags; -+ -+ WARN(!dev->driver->get_vblank_timestamp, -+ "This function requires support for accurate vblank timestamps."); -+ -+ spin_lock_irqsave(&dev->vblank_time_lock, flags); -+ -+ drm_update_vblank_count(dev, pipe, false); -+ vblank = drm_vblank_count(dev, pipe); -+ -+ spin_unlock_irqrestore(&dev->vblank_time_lock, flags); -+ -+ return vblank; -+} -+EXPORT_SYMBOL(drm_accurate_vblank_count); -+ - /** - * drm_crtc_accurate_vblank_count - retrieve the master vblank counter - * @crtc: which counter to retrieve -diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h -index 7fba9ef..d0d1f2a 100644 ---- a/include/drm/drm_vblank.h -+++ b/include/drm/drm_vblank.h -@@ -169,6 +169,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc); - void drm_crtc_vblank_reset(struct drm_crtc *crtc); - void drm_crtc_vblank_on(struct drm_crtc *crtc); - u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); -+u32 drm_accurate_vblank_count(struct drm_crtc *crtc); - - bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, --- -2.7.4 - |