Commit caff0e66 authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher

drm/amd/display: Block immediate flips for non-fast updates

[Why]
Underflow can occur in the case where we change buffer pitch, DCC state,
rotation or mirroring for a plane while also performing an immediate
flip. It can also generate a p-state warning stack trace on DCN1 which
is typically observed during the cursor handler pipe locking because of
how frequent cursor updates can occur.

[How]
Store the update type on each CRTC - every plane will have access to
the CRTC state if it's flipping. If the update type is not
UPDATE_TYPE_FAST then the immediate flip should be disallowed.

No changes to the target vblank sequencing need to be done, we just
need to ensure that the surface registers do a double buffered update.
Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: default avatarDavid Francis <david.francis@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2cc450ce
...@@ -5723,8 +5723,14 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, ...@@ -5723,8 +5723,14 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
bundle->surface_updates[planes_count].plane_info = bundle->surface_updates[planes_count].plane_info =
&bundle->plane_infos[planes_count]; &bundle->plane_infos[planes_count];
/*
* Only allow immediate flips for fast updates that don't
* change FB pitch, DCC state, rotation or mirroing.
*/
bundle->flip_addrs[planes_count].flip_immediate = bundle->flip_addrs[planes_count].flip_immediate =
(crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0; (crtc->state->pageflip_flags &
DRM_MODE_PAGE_FLIP_ASYNC) != 0 &&
acrtc_state->update_type == UPDATE_TYPE_FAST;
timestamp_ns = ktime_get_ns(); timestamp_ns = ktime_get_ns();
bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000); bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
...@@ -7400,6 +7406,14 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -7400,6 +7406,14 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
} }
} }
/* Store the overall update type for use later in atomic check. */
for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
struct dm_crtc_state *dm_new_crtc_state =
to_dm_crtc_state(new_crtc_state);
dm_new_crtc_state->update_type = (int)overall_update_type;
}
/* Must be success */ /* Must be success */
WARN_ON(ret); WARN_ON(ret);
return ret; return ret;
......
...@@ -310,6 +310,7 @@ struct dm_crtc_state { ...@@ -310,6 +310,7 @@ struct dm_crtc_state {
bool cm_has_degamma; bool cm_has_degamma;
bool cm_is_degamma_srgb; bool cm_is_degamma_srgb;
int update_type;
int active_planes; int active_planes;
bool interrupts_enabled; bool interrupts_enabled;
......
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