Very strictly speaking this is possible if you have special hw and genlocked CRTCs. In general switching a plane between two active CRTC just won't work so well and is probably not tested at all. Just forbid it. The exception is when both CRTC do a full modeset, then it should be no problem at all to move the planes around (presuming a correct implementation) so allow that case. I've put this into the core since I really couldn't come up with a case where we don't want to enforce that. But if that ever happens it would be easy to move this check into helpers. Cc: Thierry Reding <thierry.reding@xxxxxxxxx> Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxxx> --- drivers/gpu/drm/drm_atomic.c | 38 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_atomic_helper.c | 1 + 2 files changed, 39 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 434915448ea0..422183e7ee7d 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -663,6 +663,38 @@ drm_atomic_plane_get_property(struct drm_plane *plane, return 0; } +/* checks whether a plane has its CRTC switched while being in active use. */ +static bool +active_plane_switching(struct drm_atomic_state *state, + struct drm_plane *plane, + struct drm_plane_state *plane_state) +{ + struct drm_crtc_state *crtc_state, *curr_crtc_state; + + if (!plane->state->crtc || !plane_state->crtc) + return false; + + if (plane->state->crtc == plane_state->crtc) + return false; + + curr_crtc_state = plane->state->crtc->state; + if (!curr_crtc_state->active) + return false; + + crtc_state = drm_atomic_get_existing_crtc_state(state, + plane_state->crtc); + if (!crtc_state->active) + return false; + + /* plane switching CRTC and both CRTC are active. This is only ok if + * both CRTC do a full modeset. */ + if (drm_atomic_crtc_needs_modeset(curr_crtc_state) && + drm_atomic_crtc_needs_modeset(crtc_state)) + return false; + + return true; +} + /** * drm_atomic_plane_check - check plane state * @plane: plane to check @@ -734,6 +766,12 @@ static int drm_atomic_plane_check(struct drm_plane *plane, return -ENOSPC; } + if (active_plane_switching(state->state, plane, state)) { + DRM_DEBUG_ATOMIC("[PLANE:%d] switching active CRTC without modeset\n", + plane->base.id); + return -EINVAL; + } + return 0; } diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 6be0adb5a0e9..54c59ddc59a5 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -497,6 +497,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev, plane->base.id); return ret; } + } for_each_crtc_in_state(state, crtc, crtc_state, i) { -- 2.5.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx