@@ -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;
}
@@ -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) {
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@gmail.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/drm_atomic.c | 38 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_atomic_helper.c | 1 + 2 files changed, 39 insertions(+)