Commit bdc79f8e authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher

drm/amd/display: Unify loop for surface update and page flip.

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.
Signed-off-by: default avatarAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Reviewed-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1185da08
...@@ -2381,10 +2381,11 @@ static void amdgpu_dm_do_flip( ...@@ -2381,10 +2381,11 @@ static void amdgpu_dm_do_flip(
acrtc->crtc_id); 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 drm_device *dev,
struct amdgpu_display_manager *dm, struct amdgpu_display_manager *dm,
struct drm_crtc *pcrtc) struct drm_crtc *pcrtc,
bool *wait_for_vblank)
{ {
uint32_t i; uint32_t i;
struct drm_plane *plane; struct drm_plane *plane;
...@@ -2397,10 +2398,11 @@ void dc_commit_surfaces(struct drm_atomic_state *state, ...@@ -2397,10 +2398,11 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
for_each_plane_in_state(state, plane, old_plane_state, i) { for_each_plane_in_state(state, plane, old_plane_state, i) {
struct drm_plane_state *plane_state = plane->state; struct drm_plane_state *plane_state = plane->state;
struct drm_crtc *crtc = plane_state->crtc; 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_framebuffer *fb = plane_state->fb;
struct drm_connector *connector; struct drm_connector *connector;
struct dm_connector_state *dm_state = NULL; struct dm_connector_state *dm_state = NULL;
struct amdgpu_crtc *acrtc_attach;
enum dm_commit_action action; enum dm_commit_action action;
bool pflip_needed; bool pflip_needed;
...@@ -2409,13 +2411,13 @@ void dc_commit_surfaces(struct drm_atomic_state *state, ...@@ -2409,13 +2411,13 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
action = get_dm_commit_action(crtc->state); action = get_dm_commit_action(crtc->state);
/* Surfaces are created under two scenarios: /*
* 1. This commit is not a page flip. * TODO - TO decide if it's a flip or surface update
* 2. This commit is a page flip, and streams are created. * stop relying on allow_modeset flag and query DC
* using dc_check_update_surfaces_for_stream.
*/ */
pflip_needed = !state->allow_modeset; pflip_needed = !state->allow_modeset;
if (!pflip_needed || action == DM_COMMIT_ACTION_DPMS_ON if (!pflip_needed) {
|| action == DM_COMMIT_ACTION_SET) {
list_for_each_entry(connector, list_for_each_entry(connector,
&dev->mode_config.connector_list, &dev->mode_config.connector_list,
head) { head) {
...@@ -2445,11 +2447,23 @@ void dc_commit_surfaces(struct drm_atomic_state *state, ...@@ -2445,11 +2447,23 @@ void dc_commit_surfaces(struct drm_atomic_state *state,
if (crtc == pcrtc) { if (crtc == pcrtc) {
add_surface(dm->dc, crtc, plane, add_surface(dm->dc, crtc, plane,
&dc_surfaces_constructed[planes_count]); &dc_surfaces_constructed[planes_count]);
acrtc_attach = to_amdgpu_crtc(crtc);
dc_stream_attach = acrtc_attach->stream; dc_stream_attach = acrtc_attach->stream;
planes_count++; 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) { if (planes_count) {
...@@ -2471,8 +2485,6 @@ void amdgpu_dm_atomic_commit_tail( ...@@ -2471,8 +2485,6 @@ void amdgpu_dm_atomic_commit_tail(
struct drm_device *dev = state->dev; struct drm_device *dev = state->dev;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_display_manager *dm = &adev->dm; struct amdgpu_display_manager *dm = &adev->dm;
struct drm_plane *plane;
struct drm_plane_state *old_plane_state;
uint32_t i, j; uint32_t i, j;
uint32_t commit_streams_count = 0; uint32_t commit_streams_count = 0;
uint32_t new_crtcs_count = 0; uint32_t new_crtcs_count = 0;
...@@ -2637,7 +2649,7 @@ void amdgpu_dm_atomic_commit_tail( ...@@ -2637,7 +2649,7 @@ void amdgpu_dm_atomic_commit_tail(
/* update planes when needed per crtc*/ /* update planes when needed per crtc*/
for_each_crtc_in_state(state, pcrtc, old_crtc_state, j) 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++) { for (i = 0; i < new_crtcs_count; i++) {
/* /*
...@@ -2651,34 +2663,6 @@ void amdgpu_dm_atomic_commit_tail( ...@@ -2651,34 +2663,6 @@ void amdgpu_dm_atomic_commit_tail(
manage_dm_interrupts(adev, acrtc, true); manage_dm_interrupts(adev, acrtc, true);
dm_crtc_cursor_reset(&acrtc->base); 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;
}
} }
...@@ -2901,7 +2885,11 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -2901,7 +2885,11 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
struct dc *dc = adev->dm.dc; struct dc *dc = adev->dm.dc;
bool need_to_validate = false; bool need_to_validate = false;
struct validate_context *context; 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); ret = drm_atomic_helper_check(dev, state);
...@@ -2978,7 +2966,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -2978,7 +2966,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
new_stream_count++; new_stream_count++;
need_to_validate = true; need_to_validate = true;
wait_4_prev_commits = true; wait_for_prev_commits = true;
break; break;
} }
...@@ -3024,7 +3012,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -3024,7 +3012,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
new_stream_count++; new_stream_count++;
need_to_validate = true; need_to_validate = true;
wait_4_prev_commits = true; wait_for_prev_commits = true;
break; break;
} }
...@@ -3036,7 +3024,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -3036,7 +3024,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
set, set,
set_count, set_count,
acrtc->stream); acrtc->stream);
wait_4_prev_commits = true; wait_for_prev_commits = true;
} }
break; break;
} }
...@@ -3132,8 +3120,16 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -3132,8 +3120,16 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
if (need_to_validate == false || set_count == 0 || context) { if (need_to_validate == false || set_count == 0 || context) {
ret = 0; 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) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment