aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0319-drm-amdgpu-stop-blocking-for-page-filp-fences.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0319-drm-amdgpu-stop-blocking-for-page-filp-fences.patch')
-rw-r--r--common/recipes-kernel/linux/files/0319-drm-amdgpu-stop-blocking-for-page-filp-fences.patch106
1 files changed, 106 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0319-drm-amdgpu-stop-blocking-for-page-filp-fences.patch b/common/recipes-kernel/linux/files/0319-drm-amdgpu-stop-blocking-for-page-filp-fences.patch
new file mode 100644
index 00000000..00bbecfd
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0319-drm-amdgpu-stop-blocking-for-page-filp-fences.patch
@@ -0,0 +1,106 @@
+From c13a496070571e8225a0574ff1d385e41dc9dfc8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 11 Feb 2016 15:48:30 +0100
+Subject: [PATCH 0319/1110] drm/amdgpu: stop blocking for page filp fences
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Just register an callback and reschedule the work item if necessary.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 43 ++++++++++++++++++-----------
+ 2 files changed, 28 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index d56dc9c..9a9673c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -721,6 +721,7 @@ struct amdgpu_flip_work {
+ struct fence *excl;
+ unsigned shared_count;
+ struct fence **shared;
++ struct fence_cb cb;
+ };
+
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+index da49396..35756ad 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+@@ -35,24 +35,32 @@
+ #include <drm/drm_crtc_helper.h>
+ #include <drm/drm_edid.h>
+
+-static void amdgpu_flip_wait_fence(struct amdgpu_device *adev,
+- struct fence **f)
++static void amdgpu_flip_callback(struct fence *f, struct fence_cb *cb)
+ {
+- long r;
++ struct amdgpu_flip_work *work =
++ container_of(cb, struct amdgpu_flip_work, cb);
++ struct amdgpu_device *adev = work->adev;
++ struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[work->crtc_id];
+
+- if (*f == NULL)
+- return;
++ fence_put(f);
++ queue_work(amdgpu_crtc->pflip_queue, &work->flip_work);
++}
+
+- r = fence_wait(*f, false);
+- if (r)
+- DRM_ERROR("failed to wait on page flip fence (%ld)!\n", r);
++static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
++ struct fence **f)
++{
++ struct fence *fence= *f;
++
++ if (fence == NULL)
++ return false;
+
+- /* We continue with the page flip even if we failed to wait on
+- * the fence, otherwise the DRM core and userspace will be
+- * confused about which BO the CRTC is scanning out
+- */
+- fence_put(*f);
+ *f = NULL;
++
++ if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback))
++ return true;
++
++ fence_put(*f);
++ return false;
+ }
+
+ static void amdgpu_flip_work_func(struct work_struct *__work)
+@@ -68,9 +76,12 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
+ int vpos, hpos, stat, min_udelay = 0;
+ struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
+
+- amdgpu_flip_wait_fence(adev, &work->excl);
++ if (amdgpu_flip_handle_fence(work, &work->excl))
++ return;
++
+ for (i = 0; i < work->shared_count; ++i)
+- amdgpu_flip_wait_fence(adev, &work->shared[i]);
++ if (amdgpu_flip_handle_fence(work, &work->shared[i]))
++ return;
+
+ /* We borrow the event spin lock for protecting flip_status */
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+@@ -246,7 +257,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
+ /* update crtc fb */
+ crtc->primary->fb = fb;
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+- queue_work(amdgpu_crtc->pflip_queue, &work->flip_work);
++ amdgpu_flip_work_func(&work->flip_work);
+ return 0;
+
+ vblank_cleanup:
+--
+2.7.4
+