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(
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;
......@@ -2397,10 +2398,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;
......@@ -2409,13 +2411,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) {
......@@ -2445,11 +2447,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) {
......@@ -2471,8 +2485,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;
......@@ -2637,7 +2649,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++) {
/*
......@@ -2651,34 +2663,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;
}
}
......@@ -2901,7 +2885,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);
......@@ -2978,7 +2966,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;
}
......@@ -3024,7 +3012,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;
}
......@@ -3036,7 +3024,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;
}
......@@ -3132,8 +3120,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;
......
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