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