diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5501-drm-amd-display-Signal-hw_done-after-waiting-for-fli.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/5501-drm-amd-display-Signal-hw_done-after-waiting-for-fli.patch | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5501-drm-amd-display-Signal-hw_done-after-waiting-for-fli.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5501-drm-amd-display-Signal-hw_done-after-waiting-for-fli.patch new file mode 100644 index 00000000..11817c29 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5501-drm-amd-display-Signal-hw_done-after-waiting-for-fli.patch @@ -0,0 +1,113 @@ +From 6b4a08f22320f335167ff37f462a8125d440cffc Mon Sep 17 00:00:00 2001 +From: Shirish S <shirish.s@amd.com> +Date: Mon, 24 Sep 2018 19:01:47 +0530 +Subject: [PATCH 5501/5725] drm/amd/display: Signal hw_done() after waiting for + flip_done() + +In amdgpu_dm_commit_tail(), wait until flip_done() is signaled before +we signal hw_done(). + +[Why] + +This is to temporarily address a paging error that occurs when a +nonblocking commit contends with another commit, particularly in a +mirrored display configuration where at least 2 CRTCs are updated. +The error occurs in drm_atomic_helper_wait_for_flip_done(), when we +attempt to access the contents of new_crtc_state->commit. + +Here's the sequence for a mirrored 2 display setup (irrelevant steps +left out for clarity): + +**THREAD 1** | **THREAD 2** + | +Initialize atomic state for flip | + | +Queue worker | + ... + + | Do work for flip + | + | Signal hw_done() on CRTC 1 + | Signal hw_done() on CRTC 2 + | + | Wait for flip_done() on CRTC 1 + + <---- **PREEMPTED BY THREAD 1** + +Initialize atomic state for cursor | +update (1) | + | +Do cursor update work on both CRTCs | + | +Clear atomic state (2) | +**DONE** | + ... + | + | Wait for flip_done() on CRTC 2 + | *ERROR* + | + +The issue starts with (1). When the atomic state is initialized, the +current CRTC states are duplicated to be the new_crtc_states, and +referenced to be the old_crtc_states. (The new_crtc_states are to be +filled with update data.) + +Some things to note: + +* Due to the mirrored configuration, the cursor updates on both CRTCs. + +* At this point, the pflip IRQ has already been handled, and flip_done + signaled on all CRTCs. The cursor commit can therefore continue. + +* The old_crtc_states used by the cursor update are the **same states** + as the new_crtc_states used by the flip worker. + +At (2), the old_crtc_state is freed (*), and the cursor commit +completes. We then context switch back to the flip worker, where we +attempt to access the new_crtc_state->commit object. This is +problematic, as this state has already been freed. + +(*) Technically, 'state->crtcs[i].state' is freed, which was made to + reference old_crtc_state in drm_atomic_helper_swap_state() + +[How] + +By moving hw_done() after wait_for_flip_done(), we're guaranteed that +the new_crtc_state (from the flip worker's perspective) still exists. +This is because any other commit will be blocked, waiting for the +hw_done() signal. + +Note that both the i915 and imx drivers have this sequence flipped +already, masking this problem. + +Change-Id: Ib064b1009936c5048baf041d6809c92283cba08d +Signed-off-by: Shirish S <shirish.s@amd.com> +Signed-off-by: Leo Li <sunpeng.li@amd.com> +Reviewed-by: Harry Wentland <harry.wentland@amd.com> +Signed-off-by: Raveendra Talabattula <raveendra.talabattula@amd.com> +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++++++ + 1 file changed, 8 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 9363ca5..a488601 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -4893,6 +4893,14 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) + if (wait_for_vblank) + drm_atomic_helper_wait_for_flip_done(dev, state); + ++ /* ++ * FIXME: ++ * Delay hw_done() until flip_done() is signaled. This is to block ++ * another commit from freeing the CRTC state while we're still ++ * waiting on flip_done. ++ */ ++ drm_atomic_helper_commit_hw_done(state); ++ + drm_atomic_helper_cleanup_planes(dev, state); + + /* +-- +2.7.4 + |