Blob Blame History Raw
From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Date: Mon, 15 May 2017 13:59:31 -0400
Subject: drm/amd/display: Use dc_update_surfaces_for_stream for flip.
Git-commit: 3379da831b4032e3d7cac2cb199293e59f0c9e9f
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Today we use special interface for flip because of fear of cuncurency issues
over dc->current_ctx. This should be no longer an issue when flipping on
multiple CRTCs concurently since for fast update (as flip is) no new context
is created and the exsisitng is not destroyed. For full updates case when
removing or adding streams on once CRTC while flipping on another
Adding all current active CRTC's states to the atomic commit in
amdgpu_dm_atomic_check will garntee that any such full update commit
will wait for completion of any outstanding flip.

Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Reviewed-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c       |    9 ++++--
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c |   23 +++++++++++++++-
 2 files changed, 28 insertions(+), 4 deletions(-)

--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1349,6 +1349,7 @@ static void dm_page_flip(struct amdgpu_d
 	struct amdgpu_crtc *acrtc;
 	const struct dc_stream *stream;
 	struct dc_flip_addrs addr = { {0} };
+	struct dc_surface_update surface_updates[1] = { {0} };
 
 	/*
 	 * TODO risk of concurrency issues
@@ -1411,9 +1412,11 @@ static void dm_page_flip(struct amdgpu_d
 		acrtc->base.state->event = NULL;
 	}
 
-	dc_flip_surface_addrs(adev->dm.dc,
-			      dc_stream_get_status(stream)->surfaces,
-			      &addr, 1);
+	surface_updates->surface = dc_stream_get_status(stream)->surfaces[0];
+	surface_updates->flip_addr = &addr;
+
+
+	dc_update_surfaces_for_stream(adev->dm.dc, surface_updates, 1, stream);
 
 	DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
 			 __func__,
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
@@ -2901,6 +2901,7 @@ int amdgpu_dm_atomic_check(struct drm_de
 	struct dc *dc = adev->dm.dc;
 	bool need_to_validate = false;
 	struct validate_context *context;
+	bool wait_4_prev_commits = false;
 
 	ret = drm_atomic_helper_check(dev, state);
 
@@ -2977,6 +2978,7 @@ int amdgpu_dm_atomic_check(struct drm_de
 
 			new_stream_count++;
 			need_to_validate = true;
+			wait_4_prev_commits = true;
 			break;
 		}
 
@@ -3022,6 +3024,7 @@ int amdgpu_dm_atomic_check(struct drm_de
 
 			new_stream_count++;
 			need_to_validate = true;
+			wait_4_prev_commits = true;
 
 			break;
 		}
@@ -3033,6 +3036,7 @@ int amdgpu_dm_atomic_check(struct drm_de
 						set,
 						set_count,
 						acrtc->stream);
+				wait_4_prev_commits = true;
 			}
 			break;
 		}
@@ -3125,9 +3129,26 @@ int amdgpu_dm_atomic_check(struct drm_de
 
 	context = dc_get_validate_context(dc, set, set_count);
 
-	if (need_to_validate == false || set_count == 0 || context)
+	if (need_to_validate == false || set_count == 0 || context) {
+
 		ret = 0;
 
+		if (wait_4_prev_commits) {
+			list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+				struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+				struct drm_crtc_state *crtc_state;
+
+				if (acrtc->stream) {
+					crtc_state = drm_atomic_get_crtc_state(state, crtc);
+					if (IS_ERR(crtc_state)) {
+						ret = PTR_ERR(crtc_state);
+						break;
+					}
+				}
+			}
+		}
+	}
+
 	if (context) {
 		dc_resource_validate_ctx_destruct(context);
 		dm_free(context);