--- /dev/null
+From e16e37efb4c9eb7bcb9dab756c975040c5257e98 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Mon, 10 Jun 2019 08:47:57 -0400
+Subject: drm/amd/display: Allow cursor async updates for framebuffer swaps
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit e16e37efb4c9eb7bcb9dab756c975040c5257e98 upstream.
+
+[Why]
+We previously allowed framebuffer swaps as async updates for cursor
+planes but had to disable them due to a bug in DRM with async update
+handling and incorrect ref counting. The check to block framebuffer
+swaps has been added to DRM for a while now, so this check is redundant.
+
+The real fix that allows this to properly in DRM has also finally been
+merged and is getting backported into stable branches, so dropping
+this now seems to be the right time to do so.
+
+[How]
+Drop the redundant check for old_fb != new_fb.
+
+With the proper fix in DRM, this should also fix some cursor stuttering
+issues with xf86-video-amdgpu since it double buffers the cursor.
+
+IGT tests that swap framebuffers (-varying-size for example) should
+also pass again.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: David Francis <david.francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -4209,20 +4209,10 @@ static int dm_plane_atomic_check(struct
+ static int dm_plane_atomic_async_check(struct drm_plane *plane,
+ struct drm_plane_state *new_plane_state)
+ {
+- struct drm_plane_state *old_plane_state =
+- drm_atomic_get_old_plane_state(new_plane_state->state, plane);
+-
+ /* Only support async updates on cursor planes. */
+ if (plane->type != DRM_PLANE_TYPE_CURSOR)
+ return -EINVAL;
+
+- /*
+- * DRM calls prepare_fb and cleanup_fb on new_plane_state for
+- * async commits so don't allow fb changes.
+- */
+- if (old_plane_state->fb != new_plane_state->fb)
+- return -EINVAL;
+-
+ return 0;
+ }
+
--- /dev/null
+From bd200d190f45b62c006d1ad0a63eeffd87db7a47 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Wed, 31 Jul 2019 10:33:54 -0400
+Subject: drm/amd/display: Don't replace the dc_state for fast updates
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit bd200d190f45b62c006d1ad0a63eeffd87db7a47 upstream.
+
+[Why]
+DRM private objects have no hw_done/flip_done fencing mechanism on their
+own and cannot be used to sequence commits accordingly.
+
+When issuing commits that don't touch the same set of hardware resources
+like page-flips on different CRTCs we can run into the issue below
+because of this:
+
+1. Client requests non-blocking Commit #1, has a new dc_state #1,
+state is swapped, commit tail is deferred to work queue
+
+2. Client requests non-blocking Commit #2, has a new dc_state #2,
+state is swapped, commit tail is deferred to work queue
+
+3. Commit #2 work starts, commit tail finishes,
+atomic state is cleared, dc_state #1 is freed
+
+4. Commit #1 work starts,
+commit tail encounters null pointer deref on dc_state #1
+
+In order to change the DC state as in the private object we need to
+ensure that we wait for all outstanding commits to finish and that
+any other pending commits must wait for the current one to finish as
+well.
+
+We do this for MEDIUM and FULL updates. But not for FAST updates, nor
+would we want to since it would cause stuttering from the delays.
+
+FAST updates that go through dm_determine_update_type_for_commit always
+create a new dc_state and lock the DRM private object if there are
+any changed planes.
+
+We need the old state to validate, but we don't actually need the new
+state here.
+
+[How]
+If the commit isn't a full update then the use after free can be
+resolved by simply discarding the new state entirely and retaining
+the existing one instead.
+
+With this change the sequence above can be reexamined. Commit #2 will
+still free Commit #1's reference, but before this happens we actually
+added an additional reference as part of Commit #2.
+
+If an update comes in during this that needs to change the dc_state
+it will need to wait on Commit #1 and Commit #2 to finish. Then it'll
+swap the state, finish the work in commit tail and drop the last
+reference on Commit #2's dc_state.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204181
+Fixes: 004b3938e637 ("drm/amd/display: Check scaling info when determing update type")
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: David Francis <david.francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -6860,6 +6860,29 @@ static int amdgpu_dm_atomic_check(struct
+ ret = -EINVAL;
+ goto fail;
+ }
++ } else {
++ /*
++ * The commit is a fast update. Fast updates shouldn't change
++ * the DC context, affect global validation, and can have their
++ * commit work done in parallel with other commits not touching
++ * the same resource. If we have a new DC context as part of
++ * the DM atomic state from validation we need to free it and
++ * retain the existing one instead.
++ */
++ struct dm_atomic_state *new_dm_state, *old_dm_state;
++
++ new_dm_state = dm_atomic_get_new_state(state);
++ old_dm_state = dm_atomic_get_old_state(state);
++
++ if (new_dm_state && old_dm_state) {
++ if (new_dm_state->context)
++ dc_release_state(new_dm_state->context);
++
++ new_dm_state->context = old_dm_state->context;
++
++ if (old_dm_state->context)
++ dc_retain_state(old_dm_state->context);
++ }
+ }
+
+ /* Must be success */
--- /dev/null
+From 43d10d30df156f7834fa91aecb69614fefc8bb0a Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Wed, 31 Jul 2019 09:45:16 -0400
+Subject: drm/amd/display: Skip determining update type for async updates
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit 43d10d30df156f7834fa91aecb69614fefc8bb0a upstream.
+
+[Why]
+By passing through the dm_determine_update_type_for_commit for atomic
+commits that can be done asynchronously we are incurring a
+performance penalty by locking access to the global private object
+and holding that access until the end of the programming sequence.
+
+This is also allocating a new large dc_state on every access in addition
+to retaining all the references on each stream and plane until the end
+of the programming sequence.
+
+[How]
+Shift the determination for async update before validation. Return early
+if it's going to be an async update.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: David Francis <david.francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 27 ++++++++++++++++------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -6788,6 +6788,26 @@ static int amdgpu_dm_atomic_check(struct
+ if (ret)
+ goto fail;
+
++ if (state->legacy_cursor_update) {
++ /*
++ * This is a fast cursor update coming from the plane update
++ * helper, check if it can be done asynchronously for better
++ * performance.
++ */
++ state->async_update =
++ !drm_atomic_helper_async_check(dev, state);
++
++ /*
++ * Skip the remaining global validation if this is an async
++ * update. Cursor updates can be done without affecting
++ * state or bandwidth calcs and this avoids the performance
++ * penalty of locking the private state object and
++ * allocating a new dc_state.
++ */
++ if (state->async_update)
++ return 0;
++ }
++
+ /* Check scaling and underscan changes*/
+ /* TODO Removed scaling changes validation due to inability to commit
+ * new stream into context w\o causing full reset. Need to
+@@ -6840,13 +6860,6 @@ static int amdgpu_dm_atomic_check(struct
+ ret = -EINVAL;
+ goto fail;
+ }
+- } else if (state->legacy_cursor_update) {
+- /*
+- * This is a fast cursor update coming from the plane update
+- * helper, check if it can be done asynchronously for better
+- * performance.
+- */
+- state->async_update = !drm_atomic_helper_async_check(dev, state);
+ }
+
+ /* Must be success */
phy-qcom-qmp-raise-qcom_qmp_phy_enable-polling-delay.patch
phy-qcom-qmp-correct-ready-status-again.patch
net-ibmvnic-free-reset-work-of-removed-device-from-q.patch
+drm-amd-display-allow-cursor-async-updates-for-framebuffer-swaps.patch
+drm-amd-display-skip-determining-update-type-for-async-updates.patch
+drm-amd-display-don-t-replace-the-dc_state-for-fast-updates.patch