Add drm_atomic_helper_check_crtc_state(), which contains tests common to many CRTCs. The first added test verifies that an enabled CRTC has at least one enabled primary plane. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/drm_atomic_helper.c | 55 +++++++++++++++++++++++++++++ include/drm/drm_atomic_helper.h | 2 ++ 2 files changed, 57 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 987e4b212e9f..329d8a3c3d65 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -875,6 +875,61 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, } EXPORT_SYMBOL(drm_atomic_helper_check_plane_state); +/** + * drm_atomic_helper_check_crtc_state() - Check CRTC state for validity + * @crtc_state: CRTC state to check + * @can_disable_primary_planes: can the CRTC be enabled without a primary plane? + * + * Checks that a desired CRTC update is valid. Drivers that provide + * their own CRTC handling rather than helper-provided implementations may + * still wish to call this function to avoid duplication of error checking + * code. + * + * Note that @can_disable_primary_planes only tests if the CRTC can be + * enabled without a primary plane. To test if a primary plane can be updated + * without a CRTC, use drm_atomic_helper_check_plane_state() in the plane's + * atomic check. + * + * RETURNS: + * Zero if update appears valid, error code on failure + */ +int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state, + bool can_disable_primary_planes) +{ + struct drm_device *dev = crtc_state->crtc->dev; + struct drm_atomic_state *state = crtc_state->state; + + if (!crtc_state->enable) + return 0; + + /* needs at least one primary plane to be enabled */ + if (!can_disable_primary_planes) { + bool has_primary_plane = false; + struct drm_plane *plane; + + drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) { + struct drm_plane_state *plane_state; + + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + continue; + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + if (plane_state->fb && plane_state->crtc) { + has_primary_plane = true; + break; + } + } + if (!has_primary_plane) { + drm_dbg_kms(dev, "Cannot enable CRTC without a primary plane.\n"); + return -EINVAL; + } + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_check_crtc_state); + /** * drm_atomic_helper_check_planes - validate state object for planes changes * @dev: DRM device diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 4045e2507e11..2a0b17842402 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -46,6 +46,8 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, int max_scale, bool can_position, bool can_update_disabled); +int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state, + bool can_disable_primary_plane); int drm_atomic_helper_check_planes(struct drm_device *dev, struct drm_atomic_state *state); int drm_atomic_helper_check(struct drm_device *dev, -- 2.36.1