Skip to content

Commit

Permalink
drm/i915: Check async flip capability early on
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ville Syrjälä authored and Joonas Lahtinen committed Mar 8, 2022
1 parent 117f5bb commit 176c0b5
Showing 1 changed file with 72 additions and 7 deletions.
79 changes: 72 additions & 7 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -7401,7 +7401,7 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
* Correspondingly, support is currently added for primary plane only.
*
* Async flip can only change the plane surface address, so anything else
* changing is rejected from the intel_atomic_check_async() function.
* changing is rejected from the intel_async_flip_check_hw() function.
* Once this check is cleared, flip done interrupt is enabled using
* the intel_crtc_enable_flip_done() function.
*
Expand All @@ -7411,7 +7411,65 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
* correspond to the last vblank and have no relation to the actual time when
* the flip done event was sent.
*/
static int intel_atomic_check_async(struct intel_atomic_state *state, struct intel_crtc *crtc)
static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_plane_state *old_plane_state;
struct intel_plane_state *new_plane_state;
struct intel_plane *plane;
int i;

if (!new_crtc_state->uapi.async_flip)
return 0;

if (!new_crtc_state->uapi.active) {
drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s] not active\n",
crtc->base.base.id, crtc->base.name);
return -EINVAL;
}

if (intel_crtc_needs_modeset(new_crtc_state)) {
drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s] modeset required\n",
crtc->base.base.id, crtc->base.name);
return -EINVAL;
}

for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
new_plane_state, i) {
if (plane->pipe != crtc->pipe)
continue;

/*
* TODO: Async flip is only supported through the page flip IOCTL
* as of now. So support currently added for primary plane only.
* Support for other planes on platforms on which supports
* this(vlv/chv and icl+) should be added when async flip is
* enabled in the atomic IOCTL path.
*/
if (!plane->async_flip) {
drm_dbg_kms(&i915->drm,
"[PLANE:%d:%s] async flip not supported\n",
plane->base.base.id, plane->base.name);
return -EINVAL;
}

if (!old_plane_state->uapi.fb || !new_plane_state->uapi.fb) {
drm_dbg_kms(&i915->drm,
"[PLANE:%d:%s] no old or new framebuffer\n",
plane->base.base.id, plane->base.name);
return -EINVAL;
}
}

return 0;
}

static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state, *new_crtc_state;
Expand All @@ -7422,6 +7480,9 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);

if (!new_crtc_state->uapi.async_flip)
return 0;

if (intel_crtc_needs_modeset(new_crtc_state)) {
drm_dbg_kms(&i915->drm, "Modeset Required. Async flip not supported\n");
return -EINVAL;
Expand Down Expand Up @@ -7616,6 +7677,12 @@ static int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;

for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
ret = intel_async_flip_check_uapi(state, crtc);
if (ret)
return ret;
}

ret = intel_bigjoiner_add_affected_crtcs(state);
if (ret)
goto fail;
Expand Down Expand Up @@ -7772,11 +7839,9 @@ static int intel_atomic_check(struct drm_device *dev,

for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
if (new_crtc_state->uapi.async_flip) {
ret = intel_atomic_check_async(state, crtc);
if (ret)
goto fail;
}
ret = intel_async_flip_check_hw(state, crtc);
if (ret)
goto fail;

if (!intel_crtc_needs_modeset(new_crtc_state) &&
!new_crtc_state->update_pipe)
Expand Down

0 comments on commit 176c0b5

Please sign in to comment.