Skip to content

Commit 176c0b5

Browse files
vsyrjalajlahtine-intel
authored andcommitted
drm/i915: Check async flip capability early on
Since the async flip state check is done very late and thus it can see potentially all the planes in the state (due to the wm/ddb optimization) we need to move the "can the requested plane do async flips at all?" check much earlier. For this purpose we introduce intel_async_flip_check_uapi() that gets called early during the atomic check. And for good measure we'll throw in a couple of basic checks: - is the crtc active? - was a modeset flagged? - is+was the plane enabled? Though atm all of those should be guaranteed by the fact that the async flip can only be requested through the legacy page flip ioctl. Cc: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> Fixes: c3639f3 ("drm/i915: Use wm0 only during async flips for DG2") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220214105532.13049-3-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> (cherry picked from commit b0b2bed) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
1 parent 117f5bb commit 176c0b5

1 file changed

Lines changed: 72 additions & 7 deletions

File tree

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7401,7 +7401,7 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
74017401
* Correspondingly, support is currently added for primary plane only.
74027402
*
74037403
* Async flip can only change the plane surface address, so anything else
7404-
* changing is rejected from the intel_atomic_check_async() function.
7404+
* changing is rejected from the intel_async_flip_check_hw() function.
74057405
* Once this check is cleared, flip done interrupt is enabled using
74067406
* the intel_crtc_enable_flip_done() function.
74077407
*
@@ -7411,7 +7411,65 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
74117411
* correspond to the last vblank and have no relation to the actual time when
74127412
* the flip done event was sent.
74137413
*/
7414-
static int intel_atomic_check_async(struct intel_atomic_state *state, struct intel_crtc *crtc)
7414+
static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
7415+
struct intel_crtc *crtc)
7416+
{
7417+
struct drm_i915_private *i915 = to_i915(state->base.dev);
7418+
const struct intel_crtc_state *new_crtc_state =
7419+
intel_atomic_get_new_crtc_state(state, crtc);
7420+
const struct intel_plane_state *old_plane_state;
7421+
struct intel_plane_state *new_plane_state;
7422+
struct intel_plane *plane;
7423+
int i;
7424+
7425+
if (!new_crtc_state->uapi.async_flip)
7426+
return 0;
7427+
7428+
if (!new_crtc_state->uapi.active) {
7429+
drm_dbg_kms(&i915->drm,
7430+
"[CRTC:%d:%s] not active\n",
7431+
crtc->base.base.id, crtc->base.name);
7432+
return -EINVAL;
7433+
}
7434+
7435+
if (intel_crtc_needs_modeset(new_crtc_state)) {
7436+
drm_dbg_kms(&i915->drm,
7437+
"[CRTC:%d:%s] modeset required\n",
7438+
crtc->base.base.id, crtc->base.name);
7439+
return -EINVAL;
7440+
}
7441+
7442+
for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
7443+
new_plane_state, i) {
7444+
if (plane->pipe != crtc->pipe)
7445+
continue;
7446+
7447+
/*
7448+
* TODO: Async flip is only supported through the page flip IOCTL
7449+
* as of now. So support currently added for primary plane only.
7450+
* Support for other planes on platforms on which supports
7451+
* this(vlv/chv and icl+) should be added when async flip is
7452+
* enabled in the atomic IOCTL path.
7453+
*/
7454+
if (!plane->async_flip) {
7455+
drm_dbg_kms(&i915->drm,
7456+
"[PLANE:%d:%s] async flip not supported\n",
7457+
plane->base.base.id, plane->base.name);
7458+
return -EINVAL;
7459+
}
7460+
7461+
if (!old_plane_state->uapi.fb || !new_plane_state->uapi.fb) {
7462+
drm_dbg_kms(&i915->drm,
7463+
"[PLANE:%d:%s] no old or new framebuffer\n",
7464+
plane->base.base.id, plane->base.name);
7465+
return -EINVAL;
7466+
}
7467+
}
7468+
7469+
return 0;
7470+
}
7471+
7472+
static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct intel_crtc *crtc)
74157473
{
74167474
struct drm_i915_private *i915 = to_i915(state->base.dev);
74177475
const struct intel_crtc_state *old_crtc_state, *new_crtc_state;
@@ -7422,6 +7480,9 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
74227480
old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
74237481
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
74247482

7483+
if (!new_crtc_state->uapi.async_flip)
7484+
return 0;
7485+
74257486
if (intel_crtc_needs_modeset(new_crtc_state)) {
74267487
drm_dbg_kms(&i915->drm, "Modeset Required. Async flip not supported\n");
74277488
return -EINVAL;
@@ -7616,6 +7677,12 @@ static int intel_atomic_check(struct drm_device *dev,
76167677
if (ret)
76177678
goto fail;
76187679

7680+
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
7681+
ret = intel_async_flip_check_uapi(state, crtc);
7682+
if (ret)
7683+
return ret;
7684+
}
7685+
76197686
ret = intel_bigjoiner_add_affected_crtcs(state);
76207687
if (ret)
76217688
goto fail;
@@ -7772,11 +7839,9 @@ static int intel_atomic_check(struct drm_device *dev,
77727839

77737840
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
77747841
new_crtc_state, i) {
7775-
if (new_crtc_state->uapi.async_flip) {
7776-
ret = intel_atomic_check_async(state, crtc);
7777-
if (ret)
7778-
goto fail;
7779-
}
7842+
ret = intel_async_flip_check_hw(state, crtc);
7843+
if (ret)
7844+
goto fail;
77807845

77817846
if (!intel_crtc_needs_modeset(new_crtc_state) &&
77827847
!new_crtc_state->update_pipe)

0 commit comments

Comments
 (0)