[PATCH RFC v2 7/9] drm/atomic: Add drm_atomic_can_create_state() helper
From: Maxime Ripard
Date: Wed Aug 12 2026 - 09:11:27 EST
The atomic reset path will need to create pristine default states from
scratch for every plane, CRTC, and connector. This requires all of them
to implement the atomic_create_state hook.
Introduce a drm_atomic_can_create_state() helper that iterates over all
planes, CRTCs, and connectors and returns whether they all provide the
hook. Color operations are excluded since they always use
drm_atomic_helper_colorop_create_state() directly.
This will be used both as a precondition before filling a commit with
default states, and to report the device capability to userspace.
Signed-off-by: Maxime Ripard <mripard@xxxxxxxxxx>
---
drivers/gpu/drm/drm_atomic.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_atomic.h | 2 ++
2 files changed, 51 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index e78f7eb6bfd1..d8251447e44a 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1608,10 +1608,59 @@ drm_atomic_get_new_bridge_state(const struct drm_atomic_commit *state,
return drm_priv_to_bridge_state(obj_state);
}
EXPORT_SYMBOL(drm_atomic_get_new_bridge_state);
+/**
+ * drm_atomic_can_create_state - check if a device supports creating pristine states
+ * @dev: DRM device
+ *
+ * Check whether every plane, CRTC, and connector in @dev implements the
+ * &drm_plane_funcs.atomic_create_state, &drm_crtc_funcs.atomic_create_state,
+ * and &drm_connector_funcs.atomic_create_state hooks respectively. These hooks
+ * are required to create default states from scratch rather than duplicating
+ * the current state.
+ *
+ * Color operations are not checked because they always use
+ * drm_atomic_helper_colorop_create_state() and do not have a per-driver hook.
+ *
+ * Returns:
+ * True if all objects implement atomic_create_state, false otherwise.
+ */
+bool drm_atomic_can_create_state(struct drm_device *dev)
+{
+ struct drm_connector_list_iter conn_iter;
+ struct drm_connector *connector;
+ struct drm_plane *plane;
+ struct drm_crtc *crtc;
+
+ /*
+ * colorops don't have an atomic_create_state hook but
+ * drm_atomic_helper_colorop_create_state()
+ */
+
+ drm_for_each_plane(plane, dev)
+ if (!plane->funcs->atomic_create_state)
+ return false;
+
+ drm_for_each_crtc(crtc, dev)
+ if (!crtc->funcs->atomic_create_state)
+ return false;
+
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ if (!connector->funcs->atomic_create_state) {
+ drm_connector_list_iter_end(&conn_iter);
+ return false;
+ }
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return true;
+}
+EXPORT_SYMBOL(drm_atomic_can_create_state);
+
/**
* drm_atomic_add_encoder_bridges - add bridges attached to an encoder
* @state: atomic state
* @encoder: DRM encoder
*
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 00b3e9fc429a..7dc26e3da65c 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -700,10 +700,12 @@ int drm_crtc_commit_wait(struct drm_crtc_commit *commit);
struct drm_atomic_commit * __must_check
drm_atomic_commit_alloc(struct drm_device *dev);
void drm_atomic_commit_clear(struct drm_atomic_commit *state);
+bool drm_atomic_can_create_state(struct drm_device *dev);
+
/**
* drm_atomic_commit_get - acquire a reference to the atomic state
* @state: The atomic state
*
* Returns a new reference to the @state
--
2.55.0