[PATCH 10/31] drm/amd/display: Unify loop for surface update and page flip.
Harry Wentland
harry.wentland at amd.com
Tue May 23 14:08:48 UTC 2017
From: Andrey Grodzovsky <Andrey.Grodzovsky at amd.com>
Remove extra loop we have for page flips and do flips in same loop we do
for surface create/update.
Add documentation for synchronization between commits on different crtcs.
Rename function to have DM prefix.
Change-Id: Ibb6644b15f75981eae7c65a891a9314fb5c23fe9
Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky at amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 88 +++++++++++-----------
1 file changed, 42 insertions(+), 46 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
index de5c63f42d65..6d8a1277d59e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
@@ -2562,10 +2562,11 @@ static void amdgpu_dm_do_flip(
acrtc->crtc_id);
}
-void dc_commit_surfaces(struct drm_atomic_state *state,
+static void amdgpu_dm_commit_surfaces(struct drm_atomic_state *state,
struct drm_device *dev,
struct amdgpu_display_manager *dm,
- struct drm_crtc *pcrtc)
+ struct drm_crtc *pcrtc,
+ bool *wait_for_vblank)
{
uint32_t i;
struct drm_plane *plane;
@@ -2578,10 +2579,11 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
for_each_plane_in_state(state, plane, old_plane_state, i) {
struct drm_plane_state *plane_state = plane->state;
struct drm_crtc *crtc = plane_state->crtc;
+ struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(crtc);
struct drm_framebuffer *fb = plane_state->fb;
struct drm_connector *connector;
struct dm_connector_state *dm_state = NULL;
- struct amdgpu_crtc *acrtc_attach;
+
enum dm_commit_action action;
bool pflip_needed;
@@ -2590,13 +2592,13 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
action = get_dm_commit_action(crtc->state);
- /* Surfaces are created under two scenarios:
- * 1. This commit is not a page flip.
- * 2. This commit is a page flip, and streams are created.
+ /*
+ * TODO - TO decide if it's a flip or surface update
+ * stop relying on allow_modeset flag and query DC
+ * using dc_check_update_surfaces_for_stream.
*/
pflip_needed = !state->allow_modeset;
- if (!pflip_needed || action == DM_COMMIT_ACTION_DPMS_ON
- || action == DM_COMMIT_ACTION_SET) {
+ if (!pflip_needed) {
list_for_each_entry(connector,
&dev->mode_config.connector_list,
head) {
@@ -2626,11 +2628,23 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
if (crtc == pcrtc) {
add_surface(dm->dc, crtc, plane,
&dc_surfaces_constructed[planes_count]);
- acrtc_attach = to_amdgpu_crtc(crtc);
dc_stream_attach = acrtc_attach->stream;
planes_count++;
}
+ } else if (crtc->state->planes_changed) {
+ *wait_for_vblank =
+ acrtc_attach->flip_flags & DRM_MODE_PAGE_FLIP_ASYNC ?
+ false : true;
+
+ amdgpu_dm_do_flip(
+ crtc,
+ fb,
+ drm_crtc_vblank_count(crtc) + *wait_for_vblank);
+
+ /*clean up the flags for next usage*/
+ acrtc_attach->flip_flags = 0;
}
+
}
if (planes_count) {
@@ -2652,8 +2666,6 @@ void amdgpu_dm_atomic_commit_tail(
struct drm_device *dev = state->dev;
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_display_manager *dm = &adev->dm;
- struct drm_plane *plane;
- struct drm_plane_state *old_plane_state;
uint32_t i, j;
uint32_t commit_streams_count = 0;
uint32_t new_crtcs_count = 0;
@@ -2818,7 +2830,7 @@ void amdgpu_dm_atomic_commit_tail(
/* update planes when needed per crtc*/
for_each_crtc_in_state(state, pcrtc, old_crtc_state, j)
- dc_commit_surfaces(state, dev, dm, pcrtc);
+ amdgpu_dm_commit_surfaces(state, dev, dm, pcrtc, &wait_for_vblank);
for (i = 0; i < new_crtcs_count; i++) {
/*
@@ -2832,34 +2844,6 @@ void amdgpu_dm_atomic_commit_tail(
manage_dm_interrupts(adev, acrtc, true);
dm_crtc_cursor_reset(&acrtc->base);
-
- }
-
- for_each_plane_in_state(state, plane, old_plane_state, i) {
- struct drm_plane_state *plane_state = plane->state;
- struct drm_crtc *crtc = plane_state->crtc;
- struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
- struct drm_framebuffer *fb = plane_state->fb;
- bool pflip_needed;
-
- if (!fb || !crtc || !crtc->state->planes_changed ||
- !crtc->state->active)
- continue;
- pflip_needed = !state->allow_modeset;
-
- if (pflip_needed) {
- wait_for_vblank =
- acrtc->flip_flags & DRM_MODE_PAGE_FLIP_ASYNC ?
- false : true;
-
- amdgpu_dm_do_flip(
- crtc,
- fb,
- drm_crtc_vblank_count(crtc) + wait_for_vblank);
-
- /*clean up the flags for next usage*/
- acrtc->flip_flags = 0;
- }
}
@@ -3082,7 +3066,11 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
struct dc *dc = adev->dm.dc;
bool need_to_validate = false;
struct validate_context *context;
- bool wait_4_prev_commits = false;
+ /*
+ * This bool will be set for true for any modeset/reset
+ * or surface update which implies non fast surfae update.
+ */
+ bool wait_for_prev_commits = false;
ret = drm_atomic_helper_check(dev, state);
@@ -3159,7 +3147,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
new_stream_count++;
need_to_validate = true;
- wait_4_prev_commits = true;
+ wait_for_prev_commits = true;
break;
}
@@ -3205,7 +3193,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
new_stream_count++;
need_to_validate = true;
- wait_4_prev_commits = true;
+ wait_for_prev_commits = true;
break;
}
@@ -3217,7 +3205,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
set,
set_count,
acrtc->stream);
- wait_4_prev_commits = true;
+ wait_for_prev_commits = true;
}
break;
}
@@ -3313,8 +3301,16 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
if (need_to_validate == false || set_count == 0 || context) {
ret = 0;
-
- if (wait_4_prev_commits) {
+ /*
+ * For full updates case when
+ * removing/adding/updateding streams on once CRTC while flipping
+ * on another CRTC,
+ * Adding all current active CRTC's states to the atomic commit in
+ * amdgpu_dm_atomic_check will guarantee that any such full update commit
+ * will wait for completion of any outstanding flip using DRMs
+ * synchronization events.
+ */
+ if (wait_for_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;
--
2.11.0
More information about the amd-gfx
mailing list