diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c4d590a840a8..77c132a22608 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -14883,6 +14883,121 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state, return false; } +static int intel_atomic_check_async(struct intel_atomic_state *state) +{ + struct drm_i915_private *i915 = to_i915(state->base.dev); + const struct intel_crtc_state *old_crtc_state, *new_crtc_state; + const struct intel_plane_state *new_plane_state, *old_plane_state; + struct intel_crtc *crtc; + struct intel_plane *plane; + int i; + + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + if (needs_modeset(new_crtc_state)) { + drm_dbg_kms(&i915->drm, "Modeset Required. Async flip not supported\n"); + return -EINVAL; + } + + if (!new_crtc_state->hw.active) { + drm_dbg_kms(&i915->drm, "CRTC inactive\n"); + return -EINVAL; + } + if (old_crtc_state->active_planes != new_crtc_state->active_planes) { + drm_dbg_kms(&i915->drm, + "Active planes cannot be changed during async flip\n"); + return -EINVAL; + } + } + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + /* + * 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->id != PLANE_PRIMARY) + return -EINVAL; + + /* + * FIXME: This check is kept generic for all platforms. + * Need to verify this for all gen9 and gen10 platforms to enable + * this selectively if required. + */ + switch (new_plane_state->hw.fb->modifier) { + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + break; + default: + drm_dbg_kms(&i915->drm, + "Linear memory/CCS does not support async flips\n"); + return -EINVAL; + } + + if (old_plane_state->color_plane[0].stride != + new_plane_state->color_plane[0].stride) { + drm_dbg_kms(&i915->drm, "Stride cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.fb->modifier != + new_plane_state->hw.fb->modifier) { + drm_dbg_kms(&i915->drm, + "Framebuffer modifiers cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.fb->format != + new_plane_state->hw.fb->format) { + drm_dbg_kms(&i915->drm, + "Framebuffer format cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.rotation != + new_plane_state->hw.rotation) { + drm_dbg_kms(&i915->drm, "Rotation cannot be changed in async flip\n"); + return -EINVAL; + } + + if (!drm_rect_equals(&old_plane_state->uapi.src, &new_plane_state->uapi.src) || + !drm_rect_equals(&old_plane_state->uapi.dst, &new_plane_state->uapi.dst)) { + drm_dbg_kms(&i915->drm, + "Plane size/co-ordinates cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.alpha != new_plane_state->hw.alpha) { + drm_dbg_kms(&i915->drm, "Alpha value cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.pixel_blend_mode != + new_plane_state->hw.pixel_blend_mode) { + drm_dbg_kms(&i915->drm, + "Pixel blend mode cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.color_encoding != new_plane_state->hw.color_encoding) { + drm_dbg_kms(&i915->drm, + "Color encoding cannot be changed in async flip\n"); + return -EINVAL; + } + + if (old_plane_state->hw.color_range != new_plane_state->hw.color_range) { + drm_dbg_kms(&i915->drm, "Color range cannot be changed in async flip\n"); + return -EINVAL; + } + } + + return 0; +} + /** * intel_atomic_check - validate state object * @dev: drm device @@ -15051,6 +15166,12 @@ 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); + if (ret) + goto fail; + } + if (!needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe) continue; |