* [PATCH v3 00/20] drm/atomic: Rework initial state allocation
@ 2026-04-24 10:18 Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 01/20] drm/atomic: Document atomic state lifetime Maxime Ripard
` (19 more replies)
0 siblings, 20 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart, Laurent Pinchart
Hi,
This series started from my work on the hardware state readout[1], and
more specifically a discussion with Thomas[2].
This series expands the work that has been merged recently to make
drm_private_obj and drm_private_state allocation a bit more consistent
and ended up creating a new atomic_create_state callback to allocate a
new state with no side effect.
The first patches document the existing behaviour and fix a few
cleanups and typos.
Then, __drm_*_state_reset() helpers are renamed to
__drm_*_state_init() to clarify that they initialize rather than
reset state, and we add the new atomic_create_state callback to
every other DRM object (planes, CRTCs, connectors, colorops).
Next, we leverage those new callbacks to create a new helper,
drm_mode_config_create_initial_state(), to create the initial state
for all the objects of a driver, and update the driver skeleton to
recommend it.
Finally, we convert the tidss driver and the bridge_connector to the
new pattern.
This was tested on a TI SK-AM62, with the tidss driver.
Let me know what you think,
Maxime
1: https://lore.kernel.org/dri-devel/20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org/
2: https://lore.kernel.org/dri-devel/5920ffe5-b6b1-484b-b320-332b9eb9db82@suse.de/
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Changes in v3:
- Reintroduce state documentation that was dropped by accident
- Change name to drm_mode_config_create_initial_state()
- Don't call drm_mode_config_create_initial_state() in drm_dev_register
anymore
- Drop __drm_atomic_helper_*_create_state
- Improve documentation and commit messages where necessary
- Collected tags
- Link to v2: https://lore.kernel.org/r/20260320-drm-mode-config-init-v2-0-c63f1134e76c@kernel.org
Changes in v2:
- Change the _state_reset function names to _state_init
- Change the colorop too
- Various doc improvements
- Link to v1: https://lore.kernel.org/r/20260310-drm-mode-config-init-v1-0-de7397c8e1cf@kernel.org
---
Maxime Ripard (20):
drm/atomic: Document atomic state lifetime
drm/colorop: Fix typos in the doc
drm/atomic: Drop drm_private_obj.state assignment from create_state
drm/atomic: Expand atomic_create_state expectations for drm_private_obj
drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset()
drm/colorop: Rename __drm_colorop_state_reset()
drm/colorop: Create drm_atomic_helper_colorop_create_state()
drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo
drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset()
drm/plane: Add new atomic_create_state callback
drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset()
drm/crtc: Add new atomic_create_state callback
drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset()
drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset()
drm/connector: Add new atomic_create_state callback
drm/mode-config: Create drm_mode_config_create_initial_state()
drm/drv: Switch skeleton to drm_mode_config_create_initial_state()
drm/tidss: Switch to drm_mode_config_create_initial_state()
drm/tidss: Convert to atomic_create_state
drm/bridge_connector: Convert to atomic_create_state
Documentation/gpu/drm-kms.rst | 6 +
drivers/gpu/drm/display/drm_bridge_connector.c | 17 ++-
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 13 +-
drivers/gpu/drm/drm_atomic.c | 63 +++++++++
drivers/gpu/drm/drm_atomic_state_helper.c | 136 +++++++++++++++---
drivers/gpu/drm/drm_colorop.c | 41 ++++--
drivers/gpu/drm/drm_drv.c | 4 +-
drivers/gpu/drm/drm_mode_config.c | 154 ++++++++++++++++++++-
drivers/gpu/drm/i915/display/intel_crtc.c | 2 +-
drivers/gpu/drm/i915/display/intel_plane.c | 2 +-
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 2 +-
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 2 +-
drivers/gpu/drm/tidss/tidss_crtc.c | 17 +--
drivers/gpu/drm/tidss/tidss_drv.c | 6 +-
drivers/gpu/drm/tidss/tidss_plane.c | 2 +-
drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
include/drm/display/drm_hdmi_state_helper.h | 4 +-
include/drm/drm_atomic.h | 5 +-
include/drm/drm_atomic_state_helper.h | 14 +-
include/drm/drm_colorop.h | 2 +
include/drm/drm_connector.h | 16 +++
include/drm/drm_crtc.h | 16 +++
include/drm/drm_mode_config.h | 1 +
include/drm/drm_plane.h | 16 +++
24 files changed, 476 insertions(+), 67 deletions(-)
---
base-commit: ea61048876a7137897da26dac49ee234fb38a35a
change-id: 20260310-drm-mode-config-init-1e1f52b745d0
Best regards,
--
Maxime Ripard <mripard@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 01/20] drm/atomic: Document atomic state lifetime
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 02/20] drm/colorop: Fix typos in the doc Maxime Ripard
` (18 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
How drm_atomic_state structures and the various entity structures are
allocated and freed isn't really trivial. Document it.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Documentation/gpu/drm-kms.rst | 6 +++++
drivers/gpu/drm/drm_atomic.c | 55 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 2292e65f044c..017c7b196ed7 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -280,10 +280,16 @@ structure, ordering of committing state changes to hardware is sequenced using
:c:type:`struct drm_crtc_commit <drm_crtc_commit>`.
Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
coverage of specific topics.
+Atomic State Lifetime
+---------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
+ :doc: state lifetime
+
Handling Driver Private State
-----------------------------
.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
:doc: handling driver private state
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 41c57063f3b4..253a00f450b0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,10 +45,65 @@
#include <drm/drm_colorop.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
+/**
+ * DOC: state lifetime
+ *
+ * &struct drm_atomic_state represents an update to video pipeline
+ * state. Despite its confusing name, it's actually a transient object
+ * that holds a state update as a collection of pointers to individual
+ * objects' states. &struct drm_atomic_state has a much shorter lifetime
+ * than the objects' states, since it's only allocated while preparing,
+ * checking or committing the update, while object states are allocated
+ * when preparing the update and kept alive as long as they are active
+ * in the device.
+ *
+ * Their respective lifetimes are:
+ *
+ * - at reset time, the object reset implementation will allocate a new
+ * default state and will store it in the object state pointer.
+ *
+ * - whenever a new update is needed:
+ *
+ * + A new &struct drm_atomic_state is allocated using
+ * drm_atomic_state_alloc().
+ *
+ * + The current active state of affected entity is copied into this
+ * new &struct drm_atomic_state using drm_atomic_get_plane_state(),
+ * drm_atomic_get_crtc_state(), drm_atomic_get_connector_state(), or
+ * drm_atomic_get_private_obj_state(). This new state can then be
+ * modified.
+ *
+ * At that point, &struct drm_atomic_state stores three state
+ * pointers for any affected entity: the "old" and "new" states, and
+ * state_to_destroy. The old state is the state currently active in
+ * the hardware, which is either the one initialized by reset() or a
+ * newer one if a commit has been made. The new state is the state
+ * we just allocated and we might eventually commit to the hardware.
+ * The state_to_destroy points to the state we'll eventually have to
+ * free when the drm_atomic_state will be destroyed, and points to
+ * the new state for now since the old state is still the active
+ * state.
+ *
+ * + After the state is populated, it is checked. If the check is
+ * successful, the update is committed. Part of the commit is a call
+ * to drm_atomic_helper_swap_state() which will turn the new states
+ * into the active states. Doing so involves updating the object's
+ * state pointer (&drm_crtc.state or similar) to point to the new
+ * state, and state_to_destroy will now point to the old states,
+ * that used to be active but aren't anymore.
+ *
+ * + When the commit is done, and when all references to our &struct
+ * drm_atomic_state are put, drm_atomic_state_clear() runs and will
+ * free all state_to_destroy (ie. old states).
+ *
+ * + Now, we don't have any active &struct drm_atomic_state anymore,
+ * and only the entity active states remain allocated.
+ */
+
void __drm_crtc_commit_free(struct kref *kref)
{
struct drm_crtc_commit *commit =
container_of(kref, struct drm_crtc_commit, ref);
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 02/20] drm/colorop: Fix typos in the doc
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 01/20] drm/atomic: Document atomic state lifetime Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 03/20] drm/atomic: Drop drm_private_obj.state assignment from create_state Maxime Ripard
` (17 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
In the documentation of drm_colorop introduced by commit cfc27680ee20
("drm/colorop: Introduce new drm_colorop mode object"), the
documentation of __drm_colorop_state_reset() and __drm_colorop_reset()
were mentioning CRTC when they really meant colorop, probably due to
copy and paste.
Fixes: cfc27680ee20 ("drm/colorop: Introduce new drm_colorop mode object")
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_colorop.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 764d12060666..48d0b7ae3fc9 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -503,11 +503,11 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
* __drm_colorop_state_reset - resets colorop state to default values
* @colorop_state: atomic colorop state, must not be NULL
* @colorop: colorop object, must not be NULL
*
* Initializes the newly allocated @colorop_state with default
- * values. This is useful for drivers that subclass the CRTC state.
+ * values. This is useful for drivers that subclass the colorop state.
*/
static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
struct drm_colorop *colorop)
{
u64 val;
@@ -526,14 +526,14 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
/**
* __drm_colorop_reset - reset state on colorop
* @colorop: drm colorop
* @colorop_state: colorop state to assign
*
- * Initializes the newly allocated @colorop_state and assigns it to
- * the &drm_crtc->state pointer of @colorop, usually required when
- * initializing the drivers or when called from the &drm_colorop_funcs.reset
- * hook.
+ * Initializes the newly allocated @colorop_state and assigns it to the
+ * &drm_colorop->state pointer of @colorop, usually required when
+ * initializing the drivers or when called from the
+ * &drm_colorop_funcs.reset hook.
*
* This is useful for drivers that subclass the colorop state.
*/
static void __drm_colorop_reset(struct drm_colorop *colorop,
struct drm_colorop_state *colorop_state)
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 03/20] drm/atomic: Drop drm_private_obj.state assignment from create_state
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 01/20] drm/atomic: Document atomic state lifetime Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 02/20] drm/colorop: Fix typos in the doc Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 04/20] drm/atomic: Expand atomic_create_state expectations for drm_private_obj Maxime Ripard
` (16 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
The initial intent of the atomic_create_state hook was to simply
allocate a proper drm_private_state and return it, without any side
effect.
However, __drm_atomic_helper_private_obj_create_state(), which most
atomic_create_state implementations call, introduces a side effect by
setting drm_private_obj.state to the newly allocated state.
This assignment defeats the purpose, but is also redundant since
drm_atomic_private_obj_init(), the only call site for the
atomic_create_state hook, will also set this pointer to the newly
allocated state.
Drop the assignment in __drm_atomic_helper_private_obj_create_state().
Fixes: e7be39ed1716 ("drm/atomic-helper: Add private_obj atomic_create_state helper")
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 76746ad4a1bb..875149494b00 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -729,12 +729,10 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
void __drm_atomic_helper_private_obj_create_state(struct drm_private_obj *obj,
struct drm_private_state *state)
{
if (state)
state->obj = obj;
-
- obj->state = state;
}
EXPORT_SYMBOL(__drm_atomic_helper_private_obj_create_state);
/**
* __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 04/20] drm/atomic: Expand atomic_create_state expectations for drm_private_obj
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (2 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 03/20] drm/atomic: Drop drm_private_obj.state assignment from create_state Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 05/20] drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset() Maxime Ripard
` (15 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
The atomic_create_state callback documentation for planes, CRTCs, and
connectors explicitly states the expected behaviour: the returned
state must not be assigned to the object's state pointer, and hardware
must not be touched.
The drm_private_state_funcs.atomic_create_state documentation is
missing this clarification. Add it for consistency.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
include/drm/drm_atomic.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index f03cd199aee7..f7f9c6c85f3a 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -263,11 +263,14 @@ struct drm_private_state;
struct drm_private_state_funcs {
/**
* @atomic_create_state:
*
* Allocates a pristine, initialized, state for the private
- * object and returns it.
+ * object and returns it. This callback must have no side
+ * effects: in particular, the returned state must not be
+ * assigned to the object's state pointer and it must not affect
+ * the hardware state.
*
* RETURNS:
*
* A new, pristine, private state instance or an error pointer
* on failure.
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 05/20] drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (3 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 04/20] drm/atomic: Expand atomic_create_state expectations for drm_private_obj Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 06/20] drm/colorop: Rename __drm_colorop_state_reset() Maxime Ripard
` (14 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
drm_mode_config_reset() does not reset drm_private_states by design.
This is especially significant for the DP MST and tunneling code that
expect to be preserved across a suspend/resume cycle, where
drm_mode_config_reset() is also used.
Document this expectation.
Link: https://lore.kernel.org/dri-devel/aOaQLx-7EpsHRwkH@ideak-desk/
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_mode_config.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 66f7dc37b597..c33382a38191 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -187,10 +187,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
* @dev: drm device
*
* This functions calls all the crtc's, encoder's and connector's ->reset
* callback. Drivers can use this in e.g. their driver load or resume code to
* reset hardware and software state.
+ *
+ * Note that &drm_private_obj structures are expected to be stable across
+ * suspend/resume cycles, and drm_mode_config_reset() does not affect these
+ * structures.
*/
void drm_mode_config_reset(struct drm_device *dev)
{
struct drm_crtc *crtc;
struct drm_colorop *colorop;
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 06/20] drm/colorop: Rename __drm_colorop_state_reset()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (4 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 05/20] drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 07/20] drm/colorop: Create drm_atomic_helper_colorop_create_state() Maxime Ripard
` (13 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
__drm_colorop_state_reset() is used to initialize a newly allocated
drm_colorop_state, and is being typically called by drm_colorop_reset().
Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_colorop_state instance, we will need to call
__drm_colorop_state_reset() from both the reset and atomic_create paths.
To avoid any confusion, we can thus rename __drm_colorop_state_reset()
to __drm_colorop_state_init().
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_colorop.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 48d0b7ae3fc9..4c4d0a953e35 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -498,19 +498,19 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
__drm_atomic_helper_colorop_destroy_state(state);
kfree(state);
}
/**
- * __drm_colorop_state_reset - resets colorop state to default values
+ * __drm_colorop_state_init - Initializes colorop state to default values
* @colorop_state: atomic colorop state, must not be NULL
* @colorop: colorop object, must not be NULL
*
* Initializes the newly allocated @colorop_state with default
* values. This is useful for drivers that subclass the colorop state.
*/
-static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
- struct drm_colorop *colorop)
+static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
+ struct drm_colorop *colorop)
{
u64 val;
colorop_state->colorop = colorop;
colorop_state->bypass = true;
@@ -537,11 +537,11 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
*/
static void __drm_colorop_reset(struct drm_colorop *colorop,
struct drm_colorop_state *colorop_state)
{
if (colorop_state)
- __drm_colorop_state_reset(colorop_state, colorop);
+ __drm_colorop_state_init(colorop_state, colorop);
colorop->state = colorop_state;
}
void drm_colorop_reset(struct drm_colorop *colorop)
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 07/20] drm/colorop: Create drm_atomic_helper_colorop_create_state()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (5 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 06/20] drm/colorop: Rename __drm_colorop_state_reset() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 08/20] drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo Maxime Ripard
` (12 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
Commit 47b5ac7daa46 ("drm/atomic: Add new atomic_create_state callback
to drm_private_obj") introduced a new pattern for allocating drm object
states.
Instead of relying on the reset() callback, it created a new
atomic_create_state hook. This is helpful because reset is a bit
overloaded: it's used to create the initial software state, reset it,
but also reset the hardware.
It can also be used either at probe time, to create the initial state
and possibly reset the hardware to an expected default, but also during
suspend/resume.
Both these cases come with different expectations too: during the
initialization, we want to initialize all states, but during
suspend/resume, drm_private_states for example are expected to be kept
around.
reset() also isn't fallible, which makes it harder to handle
initialization errors properly. This is only really relevant for some
drivers though, since all the helpers for reset only create a new
state, and don't touch the hardware at all.
It was thus decided to create a new hook that would allocate and
initialize a pristine state without any side effect:
atomic_create_state to untangle a bit some of it, and to separate the
initialization with the actual reset one might need during a
suspend/resume.
Continue the transition to the new pattern with drm_colorop.
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_colorop.c | 23 +++++++++++++++++++++++
include/drm/drm_colorop.h | 2 ++
2 files changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 4c4d0a953e35..c0eecde8c176 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -521,10 +521,33 @@ static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
&val))
colorop_state->curve_1d_type = val;
}
}
+/**
+ * drm_atomic_helper_colorop_create_state - Allocates and initializes colorop atomic state
+ * @colorop: drm colorop
+ *
+ * Initializes a pristine @drm_colorop_state.
+ *
+ * RETURNS:
+ * Pointer to new colorop state, or ERR_PTR on failure.
+ */
+struct drm_colorop_state *
+drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop)
+{
+ struct drm_colorop_state *state;
+
+ state = kzalloc_obj(*state);
+ if (!state)
+ return ERR_PTR(-ENOMEM);
+
+ __drm_colorop_state_init(state, colorop);
+
+ return state;
+}
+
/**
* __drm_colorop_reset - reset state on colorop
* @colorop: drm colorop
* @colorop_state: colorop state to assign
*
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index bd082854ca74..874ed693329c 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -423,10 +423,12 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
uint32_t lut_size,
enum drm_colorop_lut3d_interpolation_type interpolation,
uint32_t flags);
+struct drm_colorop_state *
+drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop);
struct drm_colorop_state *
drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
struct drm_colorop_state *state);
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 08/20] drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (6 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 07/20] drm/colorop: Create drm_atomic_helper_colorop_create_state() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 09/20] drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset() Maxime Ripard
` (11 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
A typo has slipped through in the __drm_atomic_helper_plane_reset()
documentation, probably due to copy and paste. It will not assign
drm_crtc state pointer, but rather the drm_plane's.
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 875149494b00..e1f3d05ad347 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -303,11 +303,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
* __drm_atomic_helper_plane_reset - reset state on plane
* @plane: drm plane
* @plane_state: plane state to assign
*
* Initializes the newly allocated @plane_state and assigns it to
- * the &drm_crtc->state pointer of @plane, usually required when
+ * the &drm_plane->state pointer of @plane, usually required when
* initializing the drivers or when called from the &drm_plane_funcs.reset
* hook.
*
* This is useful for drivers that subclass the plane state.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 09/20] drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (7 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 08/20] drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 10/20] drm/plane: Add new atomic_create_state callback Maxime Ripard
` (10 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
__drm_atomic_helper_plane_state_reset() is used to initialize a newly
allocated drm_plane_state, and is being typically called by the
drm_plane_funcs.reset implementation.
Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_plane_state instance, we will need to call
__drm_atomic_helper_plane_state_reset() from both the reset and
atomic_create hooks.
To avoid any confusion, we can thus rename
__drm_atomic_helper_plane_state_reset() to
__drm_atomic_helper_plane_state_init().
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 12 ++++++------
drivers/gpu/drm/i915/display/intel_plane.c | 2 +-
include/drm/drm_atomic_state_helper.h | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index e1f3d05ad347..285efbf29520 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -235,19 +235,19 @@ void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
/**
- * __drm_atomic_helper_plane_state_reset - resets plane state to default values
+ * __drm_atomic_helper_plane_state_init - Initializes the plane state
* @plane_state: atomic plane state, must not be NULL
* @plane: plane object, must not be NULL
*
* Initializes the newly allocated @plane_state with default
- * values. This is useful for drivers that subclass the CRTC state.
+ * values. This is useful for drivers that subclass the plane state.
*/
-void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
- struct drm_plane *plane)
+void __drm_atomic_helper_plane_state_init(struct drm_plane_state *plane_state,
+ struct drm_plane *plane)
{
u64 val;
plane_state->plane = plane;
plane_state->rotation = DRM_MODE_ROTATE_0;
@@ -295,11 +295,11 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
plane->hotspot_y_property,
&val))
plane_state->hotspot_y = val;
}
}
-EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
+EXPORT_SYMBOL(__drm_atomic_helper_plane_state_init);
/**
* __drm_atomic_helper_plane_reset - reset state on plane
* @plane: drm plane
* @plane_state: plane state to assign
@@ -313,11 +313,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
*/
void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
struct drm_plane_state *plane_state)
{
if (plane_state)
- __drm_atomic_helper_plane_state_reset(plane_state, plane);
+ __drm_atomic_helper_plane_state_init(plane_state, plane);
plane->state = plane_state;
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index 5390ceb21ca4..d013d9228d0b 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -65,11 +65,11 @@
static void intel_plane_state_reset(struct intel_plane_state *plane_state,
struct intel_plane *plane)
{
memset(plane_state, 0, sizeof(*plane_state));
- __drm_atomic_helper_plane_state_reset(&plane_state->uapi, &plane->base);
+ __drm_atomic_helper_plane_state_init(&plane_state->uapi, &plane->base);
plane_state->scaler_id = -1;
}
struct intel_plane *intel_plane_alloc(void)
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 900672c6ea90..44e8850aae7f 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -51,11 +51,11 @@ struct drm_crtc_state *
drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state);
void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
-void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *state,
+void __drm_atomic_helper_plane_state_init(struct drm_plane_state *state,
struct drm_plane *plane);
void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
struct drm_plane_state *state);
void drm_atomic_helper_plane_reset(struct drm_plane *plane);
void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 10/20] drm/plane: Add new atomic_create_state callback
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (8 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 09/20] drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 11/20] drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset() Maxime Ripard
` (9 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
Commit 47b5ac7daa46 ("drm/atomic: Add new atomic_create_state callback
to drm_private_obj") introduced a new pattern for allocating drm object
states.
Instead of relying on the reset() callback, it created a new
atomic_create_state hook. This is helpful because reset is a bit
overloaded: it's used to create the initial software state, reset it,
but also reset the hardware.
It can also be used either at probe time, to create the initial state
and possibly reset the hardware to an expected default, but also during
suspend/resume.
Both these cases come with different expectations too: during the
initialization, we want to initialize all states, but during
suspend/resume, drm_private_states for example are expected to be kept
around.
reset() also isn't fallible, which makes it harder to handle
initialization errors properly. This is only really relevant for some
drivers though, since all the helpers for reset only create a new
state, and don't touch the hardware at all.
It was thus decided to create a new hook that would allocate and
initialize a pristine state without any side effect:
atomic_create_state to untangle a bit some of it, and to separate the
initialization with the actual reset one might need during a
suspend/resume.
Continue the transition to the new pattern with planes.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 25 +++++++++++++++++++++++++
drivers/gpu/drm/drm_mode_config.c | 21 ++++++++++++++++++++-
include/drm/drm_atomic_state_helper.h | 2 ++
include/drm/drm_plane.h | 16 ++++++++++++++++
4 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 285efbf29520..50fe4eec41a8 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -338,10 +338,35 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
if (plane->state)
__drm_atomic_helper_plane_reset(plane, plane->state);
}
EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
+/**
+ * drm_atomic_helper_plane_create_state - default &drm_plane_funcs.atomic_create_state hook for planes
+ * @plane: plane object
+ *
+ * Initializes a pristine @drm_plane_state.
+ *
+ * This is useful for drivers that don't subclass @drm_plane_state.
+ *
+ * RETURNS:
+ * Pointer to new plane state, or ERR_PTR on failure.
+ */
+struct drm_plane_state *drm_atomic_helper_plane_create_state(struct drm_plane *plane)
+{
+ struct drm_plane_state *state;
+
+ state = kzalloc_obj(*state);
+ if (!state)
+ return ERR_PTR(-ENOMEM);
+
+ __drm_atomic_helper_plane_state_init(state, plane);
+
+ return state;
+}
+EXPORT_SYMBOL(drm_atomic_helper_plane_create_state);
+
/**
* __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
* @plane: plane object
* @state: atomic plane state
*
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index c33382a38191..10b7815cbe48 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -180,10 +180,26 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
drm_connector_list_iter_end(&conn_iter);
return ret;
}
+static int drm_mode_config_plane_create_state(struct drm_plane *plane)
+{
+ struct drm_plane_state *plane_state;
+
+ if (!plane->funcs->atomic_create_state)
+ return 0;
+
+ plane_state = plane->funcs->atomic_create_state(plane);
+ if (IS_ERR(plane_state))
+ return PTR_ERR(plane_state);
+
+ plane->state = plane_state;
+
+ return 0;
+}
+
/**
* drm_mode_config_reset - call ->reset callbacks
* @dev: drm device
*
* This functions calls all the crtc's, encoder's and connector's ->reset
@@ -204,13 +220,16 @@ void drm_mode_config_reset(struct drm_device *dev)
struct drm_connector_list_iter conn_iter;
drm_for_each_colorop(colorop, dev)
drm_colorop_reset(colorop);
- drm_for_each_plane(plane, dev)
+ drm_for_each_plane(plane, dev) {
if (plane->funcs->reset)
plane->funcs->reset(plane);
+ else if (plane->funcs->atomic_create_state)
+ drm_mode_config_plane_create_state(plane);
+ }
drm_for_each_crtc(crtc, dev)
if (crtc->funcs->reset)
crtc->funcs->reset(crtc);
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 44e8850aae7f..df371b2eef3e 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -53,10 +53,12 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state);
void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void __drm_atomic_helper_plane_state_init(struct drm_plane_state *state,
struct drm_plane *plane);
+struct drm_plane_state *
+drm_atomic_helper_plane_create_state(struct drm_plane *plane);
void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
struct drm_plane_state *state);
void drm_atomic_helper_plane_reset(struct drm_plane *plane);
void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
struct drm_plane_state *state);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 703ef4d1bbbc..886e219c4609 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -386,10 +386,26 @@ struct drm_plane_funcs {
* 0 on success or a negative error code on failure.
*/
int (*set_property)(struct drm_plane *plane,
struct drm_property *property, uint64_t val);
+ /**
+ * @atomic_create_state:
+ *
+ * Allocates a pristine, initialized, state for the plane object
+ * and returns it. This callback must have no side effects: in
+ * particular, the returned state must not be assigned to the
+ * object's state pointer and it must not affect the hardware
+ * state.
+ *
+ * RETURNS:
+ *
+ * A new, pristine, plane state instance or an error pointer
+ * on failure.
+ */
+ struct drm_plane_state *(*atomic_create_state)(struct drm_plane *plane);
+
/**
* @atomic_duplicate_state:
*
* Duplicate the current atomic state for this plane and return it.
* The core and helpers guarantee that any atomic state duplicated with
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 11/20] drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (9 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 10/20] drm/plane: Add new atomic_create_state callback Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 12/20] drm/crtc: Add new atomic_create_state callback Maxime Ripard
` (8 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
__drm_atomic_helper_crtc_state_reset() is used to initialize a newly
allocated drm_crtc_state, and is being typically called by the
drm_crtc_funcs.reset implementation.
Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_crtc_state instance, we will need to call
__drm_atomic_helper_crtc_state_reset() from both the reset and
atomic_create hooks.
To avoid any confusion, we can thus rename
__drm_atomic_helper_crtc_state_reset() to
__drm_atomic_helper_crtc_state_init().
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 10 +++++-----
drivers/gpu/drm/i915/display/intel_crtc.c | 2 +-
include/drm/drm_atomic_state_helper.h | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 50fe4eec41a8..9cd8550cabb7 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -61,25 +61,25 @@
* For other drivers the building blocks are split out, see the documentation
* for these functions.
*/
/**
- * __drm_atomic_helper_crtc_state_reset - reset the CRTC state
+ * __drm_atomic_helper_crtc_state_init - Initializes the CRTC state
* @crtc_state: atomic CRTC state, must not be NULL
* @crtc: CRTC object, must not be NULL
*
* Initializes the newly allocated @crtc_state with default
* values. This is useful for drivers that subclass the CRTC state.
*/
void
-__drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
- struct drm_crtc *crtc)
+__drm_atomic_helper_crtc_state_init(struct drm_crtc_state *crtc_state,
+ struct drm_crtc *crtc)
{
crtc_state->crtc = crtc;
crtc_state->background_color = DRM_ARGB64_PREP(0xffff, 0, 0, 0);
}
-EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
+EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_init);
/**
* __drm_atomic_helper_crtc_reset - reset state on CRTC
* @crtc: drm CRTC
* @crtc_state: CRTC state to assign
@@ -94,11 +94,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
void
__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
struct drm_crtc_state *crtc_state)
{
if (crtc_state)
- __drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
+ __drm_atomic_helper_crtc_state_init(crtc_state, crtc);
if (drm_dev_has_vblank(crtc->dev))
drm_crtc_vblank_reset(crtc);
crtc->state = crtc_state;
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index b8189cd5d864..a2ed4a76e061 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -179,11 +179,11 @@ struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
struct intel_crtc *crtc)
{
memset(crtc_state, 0, sizeof(*crtc_state));
- __drm_atomic_helper_crtc_state_reset(&crtc_state->uapi, &crtc->base);
+ __drm_atomic_helper_crtc_state_init(&crtc_state->uapi, &crtc->base);
crtc_state->cpu_transcoder = INVALID_TRANSCODER;
crtc_state->master_transcoder = INVALID_TRANSCODER;
crtc_state->hsw_workaround_pipe = INVALID_PIPE;
crtc_state->scaler_state.scaler_id = -1;
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index df371b2eef3e..e7fbbfdc5d69 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -38,11 +38,11 @@ struct drm_connector_state;
struct drm_private_obj;
struct drm_private_state;
struct drm_modeset_acquire_ctx;
struct drm_device;
-void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *state,
+void __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *state,
struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 12/20] drm/crtc: Add new atomic_create_state callback
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (10 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 11/20] drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 13/20] drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset() Maxime Ripard
` (7 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
Commit 47b5ac7daa46 ("drm/atomic: Add new atomic_create_state callback
to drm_private_obj") introduced a new pattern for allocating drm object
states.
Instead of relying on the reset() callback, it created a new
atomic_create_state hook. This is helpful because reset is a bit
overloaded: it's used to create the initial software state, reset it,
but also reset the hardware.
It can also be used either at probe time, to create the initial state
and possibly reset the hardware to an expected default, but also during
suspend/resume.
Both these cases come with different expectations too: during the
initialization, we want to initialize all states, but during
suspend/resume, drm_private_states for example are expected to be kept
around.
reset() also isn't fallible, which makes it harder to handle
initialization errors properly. This is only really relevant for some
drivers though, since all the helpers for reset only create a new
state, and don't touch the hardware at all.
It was thus decided to create a new hook that would allocate and
initialize a pristine state without any side effect:
atomic_create_state to untangle a bit some of it, and to separate the
initialization with the actual reset one might need during a
suspend/resume.
Continue the transition to the new pattern with CRTCs.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 47 +++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_mode_config.c | 21 +++++++++++++-
include/drm/drm_atomic_state_helper.h | 4 +++
include/drm/drm_crtc.h | 16 +++++++++++
4 files changed, 87 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 9cd8550cabb7..b7da134c8c50 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -103,10 +103,32 @@ __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
crtc->state = crtc_state;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
+/**
+ * __drm_atomic_helper_crtc_create_state - initializes crtc state
+ * @crtc: crtc object
+ * @state: new state to initialize
+ *
+ * Initializes the newly allocated @state, usually required when
+ * initializing the drivers.
+ *
+ * @state is assumed to be zeroed.
+ *
+ * This is useful for drivers that subclass @drm_crtc_state.
+ */
+void __drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ __drm_atomic_helper_crtc_state_init(state, crtc);
+
+ if (drm_dev_has_vblank(crtc->dev))
+ drm_crtc_vblank_reset(crtc);
+}
+EXPORT_SYMBOL(__drm_atomic_helper_crtc_create_state);
+
/**
* drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
* @crtc: drm CRTC
*
* Resets the atomic state for @crtc by freeing the state pointer (which might
@@ -122,10 +144,35 @@ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
__drm_atomic_helper_crtc_reset(crtc, crtc_state);
}
EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
+/**
+ * drm_atomic_helper_crtc_create_state - default &drm_crtc_funcs.atomic_create_state hook for crtcs
+ * @crtc: crtc object
+ *
+ * Initializes a pristine @drm_crtc_state.
+ *
+ * This is useful for drivers that don't subclass @drm_crtc_state.
+ *
+ * RETURNS:
+ * Pointer to new crtc state, or ERR_PTR on failure.
+ */
+struct drm_crtc_state *drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc)
+{
+ struct drm_crtc_state *state;
+
+ state = kzalloc_obj(*state);
+ if (!state)
+ return ERR_PTR(-ENOMEM);
+
+ __drm_atomic_helper_crtc_create_state(crtc, state);
+
+ return state;
+}
+EXPORT_SYMBOL(drm_atomic_helper_crtc_create_state);
+
/**
* __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
* @crtc: CRTC object
* @state: atomic CRTC state
*
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 10b7815cbe48..182d9a8104e7 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -196,10 +196,26 @@ static int drm_mode_config_plane_create_state(struct drm_plane *plane)
plane->state = plane_state;
return 0;
}
+static int drm_mode_config_crtc_create_state(struct drm_crtc *crtc)
+{
+ struct drm_crtc_state *crtc_state;
+
+ if (!crtc->funcs->atomic_create_state)
+ return 0;
+
+ crtc_state = crtc->funcs->atomic_create_state(crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ crtc->state = crtc_state;
+
+ return 0;
+}
+
/**
* drm_mode_config_reset - call ->reset callbacks
* @dev: drm device
*
* This functions calls all the crtc's, encoder's and connector's ->reset
@@ -227,13 +243,16 @@ void drm_mode_config_reset(struct drm_device *dev)
plane->funcs->reset(plane);
else if (plane->funcs->atomic_create_state)
drm_mode_config_plane_create_state(plane);
}
- drm_for_each_crtc(crtc, dev)
+ drm_for_each_crtc(crtc, dev) {
if (crtc->funcs->reset)
crtc->funcs->reset(crtc);
+ else if (crtc->funcs->atomic_create_state)
+ drm_mode_config_crtc_create_state(crtc);
+ }
drm_for_each_encoder(encoder, dev)
if (encoder->funcs && encoder->funcs->reset)
encoder->funcs->reset(encoder);
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index e7fbbfdc5d69..129762b99de6 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -43,10 +43,14 @@ struct drm_device;
void __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *state,
struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
+void __drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state);
+struct drm_crtc_state *
+drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
struct drm_crtc_state *
drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 312fc1e745d2..41ea6eadf36f 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -636,10 +636,26 @@ struct drm_crtc_funcs {
* 0 on success or a negative error code on failure.
*/
int (*set_property)(struct drm_crtc *crtc,
struct drm_property *property, uint64_t val);
+ /**
+ * @atomic_create_state:
+ *
+ * Allocates a pristine, initialized, state for the CRTC object
+ * and returns it. This callback must have no side effects: in
+ * particular, the returned state must not be assigned to the
+ * object's state pointer and it must not affect the hardware
+ * state.
+ *
+ * RETURNS:
+ *
+ * A new, pristine, CRTC state instance or an error pointer
+ * on failure.
+ */
+ struct drm_crtc_state *(*atomic_create_state)(struct drm_crtc *crtc);
+
/**
* @atomic_duplicate_state:
*
* Duplicate the current atomic state for this CRTC and return it.
* The core and helpers guarantee that any atomic state duplicated with
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 13/20] drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (11 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 12/20] drm/crtc: Add new atomic_create_state callback Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 14/20] drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset() Maxime Ripard
` (6 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
__drm_atomic_helper_connector_state_reset() is used to initialize a
newly allocated drm_connector_state, and is being typically called by
the drm_connector_funcs.reset implementation.
Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_connector_state instance, we will need to call
__drm_atomic_helper_connector_state_reset() from both the reset and
atomic_create hooks.
To avoid any confusion, we can thus rename
__drm_atomic_helper_connector_state_reset() to
__drm_atomic_helper_connector_state_init().
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 12 ++++++------
include/drm/drm_atomic_state_helper.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index b7da134c8c50..f67aacaa3b6e 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -496,24 +496,24 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
/**
- * __drm_atomic_helper_connector_state_reset - reset the connector state
+ * __drm_atomic_helper_connector_state_init - Initializes the connector state
* @conn_state: atomic connector state, must not be NULL
- * @connector: connectotr object, must not be NULL
+ * @connector: connector object, must not be NULL
*
* Initializes the newly allocated @conn_state with default
* values. This is useful for drivers that subclass the connector state.
*/
void
-__drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
- struct drm_connector *connector)
+__drm_atomic_helper_connector_state_init(struct drm_connector_state *conn_state,
+ struct drm_connector *connector)
{
conn_state->connector = connector;
}
-EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
+EXPORT_SYMBOL(__drm_atomic_helper_connector_state_init);
/**
* __drm_atomic_helper_connector_reset - reset state on connector
* @connector: drm connector
* @conn_state: connector state to assign
@@ -528,11 +528,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
void
__drm_atomic_helper_connector_reset(struct drm_connector *connector,
struct drm_connector_state *conn_state)
{
if (conn_state)
- __drm_atomic_helper_connector_state_reset(conn_state, connector);
+ __drm_atomic_helper_connector_state_init(conn_state, connector);
connector->state = conn_state;
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 129762b99de6..e7c097e6dfe3 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -70,11 +70,11 @@ struct drm_plane_state *
drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane);
void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state);
void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
-void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
+void __drm_atomic_helper_connector_state_init(struct drm_connector_state *conn_state,
struct drm_connector *connector);
void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
struct drm_connector_state *conn_state);
void drm_atomic_helper_connector_reset(struct drm_connector *connector);
void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 14/20] drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (12 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 13/20] drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 15/20] drm/connector: Add new atomic_create_state callback Maxime Ripard
` (5 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
__drm_atomic_helper_connector_hdmi_reset() is typically used to
initialize a newly allocated drm_connector_state when the connector is
using the HDMI helpers, and is being called by the
drm_connector_funcs.reset implementation.
Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_connector_state instance, we will need to call
__drm_atomic_helper_connector_hdmi_reset() from both the reset and
atomic_create hooks.
To avoid any confusion, we can thus rename
__drm_atomic_helper_connector_hdmi_reset() to
__drm_atomic_helper_connector_hdmi_state_init().
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 4 ++--
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 13 +++++++------
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 2 +-
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 2 +-
drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
include/drm/display/drm_hdmi_state_helper.h | 4 ++--
6 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 39cc18f78eda..d72f29b73be3 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -270,12 +270,12 @@ static void drm_bridge_connector_reset(struct drm_connector *connector)
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
drm_atomic_helper_connector_reset(connector);
if (bridge_connector->bridge_hdmi)
- __drm_atomic_helper_connector_hdmi_reset(connector,
- connector->state);
+ __drm_atomic_helper_connector_hdmi_state_init(connector,
+ connector->state);
}
static const struct drm_connector_funcs drm_bridge_connector_funcs = {
.reset = drm_bridge_connector_reset,
.detect = drm_bridge_connector_detect,
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 9f3b696aceeb..8bf7ad3c99fb 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -304,29 +304,30 @@
* --kunitconfig=drivers/gpu/drm/tests \
* drm_atomic_helper_connector_hdmi_*
*/
/**
- * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources
+ * __drm_atomic_helper_connector_hdmi_state_init() - Initializes all HDMI @drm_connector_state resources
* @connector: DRM connector
* @new_conn_state: connector state to reset
*
* Initializes all HDMI resources from a @drm_connector_state without
* actually allocating it. This is useful for HDMI drivers, in
- * combination with __drm_atomic_helper_connector_reset() or
- * drm_atomic_helper_connector_reset().
+ * combination with __drm_atomic_helper_connector_state_init(),
+ * drm_atomic_helper_connector_reset(), or
+ * drm_atomic_helper_connector_create_state() .
*/
-void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
- struct drm_connector_state *new_conn_state)
+void __drm_atomic_helper_connector_hdmi_state_init(struct drm_connector *connector,
+ struct drm_connector_state *new_conn_state)
{
unsigned int max_bpc = connector->max_bpc;
new_conn_state->max_bpc = max_bpc;
new_conn_state->max_requested_bpc = max_bpc;
new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
}
-EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
+EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_state_init);
static enum hdmi_colorspace
output_color_format_to_hdmi_colorspace(const struct drm_connector *connector,
enum drm_output_color_format fmt)
{
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index dd2a78defdb4..29dfff4f0055 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -283,11 +283,11 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
static void sun4i_hdmi_connector_reset(struct drm_connector *connector)
{
drm_atomic_helper_connector_reset(connector);
- __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+ __drm_atomic_helper_connector_hdmi_state_init(connector, connector->state);
}
static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
.detect = sun4i_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
index a4357efaa983..5d671b281f28 100644
--- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
@@ -166,11 +166,11 @@ static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
};
static void dummy_hdmi_connector_reset(struct drm_connector *connector)
{
drm_atomic_helper_connector_reset(connector);
- __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+ __drm_atomic_helper_connector_hdmi_state_init(connector, connector->state);
}
static const struct drm_connector_funcs dummy_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index a99f53dadb28..14fcee05e133 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -506,11 +506,11 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
}
static void vc4_hdmi_connector_reset(struct drm_connector *connector)
{
drm_atomic_helper_connector_reset(connector);
- __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+ __drm_atomic_helper_connector_hdmi_state_init(connector, connector->state);
drm_atomic_helper_connector_tv_margins_reset(connector);
}
static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
.force = drm_atomic_helper_connector_hdmi_force,
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index 2349c0d0f00f..f7600aabdd5f 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -9,12 +9,12 @@ struct drm_connector_state;
struct drm_display_mode;
struct hdmi_audio_infoframe;
enum drm_connector_status;
-void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
- struct drm_connector_state *new_conn_state);
+void __drm_atomic_helper_connector_hdmi_state_init(struct drm_connector *connector,
+ struct drm_connector_state *new_conn_state);
int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
struct drm_atomic_state *state);
int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 15/20] drm/connector: Add new atomic_create_state callback
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (13 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 14/20] drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 16/20] drm/mode-config: Create drm_mode_config_create_initial_state() Maxime Ripard
` (4 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
Commit 47b5ac7daa46 ("drm/atomic: Add new atomic_create_state callback
to drm_private_obj") introduced a new pattern for allocating drm object
states.
Instead of relying on the reset() callback, it created a new
atomic_create_state hook. This is helpful because reset is a bit
overloaded: it's used to create the initial software state, reset it,
but also reset the hardware.
It can also be used either at probe time, to create the initial state
and possibly reset the hardware to an expected default, but also during
suspend/resume.
Both these cases come with different expectations too: during the
initialization, we want to initialize all states, but during
suspend/resume, drm_private_states for example are expected to be kept
around.
reset() also isn't fallible, which makes it harder to handle
initialization errors properly. This is only really relevant for some
drivers though, since all the helpers for reset only create a new
state, and don't touch the hardware at all.
It was thus decided to create a new hook that would allocate and
initialize a pristine state without any side effect:
atomic_create_state to untangle a bit some of it, and to separate the
initialization with the actual reset one might need during a
suspend/resume.
Continue the transition to the new pattern with connectors.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 26 ++++++++++++++++++++++++++
drivers/gpu/drm/drm_mode_config.c | 21 ++++++++++++++++++++-
include/drm/drm_atomic_state_helper.h | 2 ++
include/drm/drm_connector.h | 16 ++++++++++++++++
4 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index f67aacaa3b6e..6140926f4605 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -554,10 +554,36 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector)
kfree(connector->state);
__drm_atomic_helper_connector_reset(connector, conn_state);
}
EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
+/**
+ * drm_atomic_helper_connector_create_state - default &drm_connector_funcs.atomic_create_state hook for connectors
+ * @connector: connector object
+ *
+ * Initializes a pristine @drm_connector_state.
+ *
+ * This is useful for drivers that don't subclass @drm_connector_state.
+ *
+ * RETURNS:
+ * Pointer to new connector state, or ERR_PTR on failure.
+ */
+struct drm_connector_state *
+drm_atomic_helper_connector_create_state(struct drm_connector *connector)
+{
+ struct drm_connector_state *state;
+
+ state = kzalloc_obj(*state);
+ if (!state)
+ return ERR_PTR(-ENOMEM);
+
+ __drm_atomic_helper_connector_state_init(state, connector);
+
+ return state;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_create_state);
+
/**
* drm_atomic_helper_connector_tv_margins_reset - Resets TV connector properties
* @connector: DRM connector
*
* Resets the TV-related properties attached to a connector.
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 182d9a8104e7..92ff907f2485 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -212,10 +212,26 @@ static int drm_mode_config_crtc_create_state(struct drm_crtc *crtc)
crtc->state = crtc_state;
return 0;
}
+static int drm_mode_config_connector_create_state(struct drm_connector *connector)
+{
+ struct drm_connector_state *conn_state;
+
+ if (!connector->funcs->atomic_create_state)
+ return 0;
+
+ conn_state = connector->funcs->atomic_create_state(connector);
+ if (IS_ERR(conn_state))
+ return PTR_ERR(conn_state);
+
+ connector->state = conn_state;
+
+ return 0;
+}
+
/**
* drm_mode_config_reset - call ->reset callbacks
* @dev: drm device
*
* This functions calls all the crtc's, encoder's and connector's ->reset
@@ -255,13 +271,16 @@ void drm_mode_config_reset(struct drm_device *dev)
drm_for_each_encoder(encoder, dev)
if (encoder->funcs && encoder->funcs->reset)
encoder->funcs->reset(encoder);
drm_connector_list_iter_begin(dev, &conn_iter);
- drm_for_each_connector_iter(connector, &conn_iter)
+ drm_for_each_connector_iter(connector, &conn_iter) {
if (connector->funcs->reset)
connector->funcs->reset(connector);
+ else if (connector->funcs->atomic_create_state)
+ drm_mode_config_connector_create_state(connector);
+ }
drm_connector_list_iter_end(&conn_iter);
}
EXPORT_SYMBOL(drm_mode_config_reset);
/*
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index e7c097e6dfe3..8576cd256737 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -75,10 +75,12 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
void __drm_atomic_helper_connector_state_init(struct drm_connector_state *conn_state,
struct drm_connector *connector);
void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
struct drm_connector_state *conn_state);
void drm_atomic_helper_connector_reset(struct drm_connector *connector);
+struct drm_connector_state *
+drm_atomic_helper_connector_create_state(struct drm_connector *connector);
void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
struct drm_atomic_state *state);
void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
void
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 3e422a4f2e72..9fb794957d23 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1569,10 +1569,26 @@ struct drm_connector_funcs {
* when a connector is being hot-unplugged for drivers that support
* connector hotplugging (e.g. DisplayPort MST).
*/
void (*destroy)(struct drm_connector *connector);
+ /**
+ * @atomic_create_state:
+ *
+ * Allocates a pristine, initialized, state for the connector object
+ * and returns it. This callback must have no side effects: in
+ * particular, the returned state must not be assigned to the
+ * object's state pointer and it must not affect the hardware
+ * state.
+ *
+ * RETURNS:
+ *
+ * A new, pristine, connector state instance or an error pointer
+ * on failure.
+ */
+ struct drm_connector_state *(*atomic_create_state)(struct drm_connector *connector);
+
/**
* @atomic_duplicate_state:
*
* Duplicate the current atomic state for this connector and return it.
* The core and helpers guarantee that any atomic state duplicated with
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 16/20] drm/mode-config: Create drm_mode_config_create_initial_state()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (14 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 15/20] drm/connector: Add new atomic_create_state callback Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 17/20] drm/drv: Switch skeleton to drm_mode_config_create_initial_state() Maxime Ripard
` (3 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
drm_mode_config_reset() can be used to create the initial state, but
also to return to the initial state, when doing a suspend/resume cycle
for example.
It also affects both the software and the hardware, and drivers can
choose to reset the hardware as well. Most will just create an empty
state and the synchronisation between hardware and software states will
effectively be done when the first commit is done.
That dual role can be harmful, since some objects do need to be
initialized but also need to be preserved across a suspend/resume cycle.
drm_private_obj are such objects for example.
Thus, create another helper for drivers to call to initialize their
state when the driver is loaded, so we can make
drm_mode_config_reset() only about handling suspend/resume and similar.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic.c | 12 +++++-
drivers/gpu/drm/drm_mode_config.c | 87 +++++++++++++++++++++++++++++++++++++++
include/drm/drm_mode_config.h | 1 +
3 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 253a00f450b0..f31b6147e682 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -59,12 +59,20 @@
* when preparing the update and kept alive as long as they are active
* in the device.
*
* Their respective lifetimes are:
*
- * - at reset time, the object reset implementation will allocate a new
- * default state and will store it in the object state pointer.
+ * - at driver initialization time, the driver will allocate an initial,
+ * pristine, state and will store it using
+ * drm_mode_config_create_initial_state(). Historically, this was one
+ * of drm_mode_config_reset() job, so one might still encounter it in
+ * a driver.
+ *
+ * - at reset time, for example during suspend/resume,
+ * drm_mode_config_reset() will reset the software and hardware state
+ * to a known default and will store it in the object's state pointer.
+ * Not all objects are affected by drm_mode_config_reset() though.
*
* - whenever a new update is needed:
*
* + A new &struct drm_atomic_state is allocated using
* drm_atomic_state_alloc().
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 92ff907f2485..a43eb825671b 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -21,10 +21,11 @@
*/
#include <linux/export.h>
#include <linux/uaccess.h>
+#include <drm/drm_atomic.h>
#include <drm/drm_drv.h>
#include <drm/drm_encoder.h>
#include <drm/drm_file.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_managed.h>
@@ -281,10 +282,96 @@ void drm_mode_config_reset(struct drm_device *dev)
}
drm_connector_list_iter_end(&conn_iter);
}
EXPORT_SYMBOL(drm_mode_config_reset);
+/**
+ * drm_mode_config_create_initial_state - Allocates the initial state
+ * @dev: drm device
+ *
+ * This functions creates the initial state for all the objects. Drivers
+ * can use this in e.g. probe to initialize their software state.
+ *
+ * It has two main differences with drm_mode_config_reset(): the reset()
+ * hooks aren't called and thus the hardware will be left untouched, but
+ * also the &drm_private_obj structures will be initialized as opposed
+ * to drm_mode_config_reset() that skips them.
+ *
+ * Returns: 0 on success, negative error value on failure.
+ */
+int drm_mode_config_create_initial_state(struct drm_device *dev)
+{
+ struct drm_crtc *crtc;
+ struct drm_colorop *colorop;
+ struct drm_plane *plane;
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+ struct drm_private_obj *privobj;
+ int ret;
+
+ drm_for_each_privobj(privobj, dev) {
+ struct drm_private_state *privobj_state;
+
+ if (privobj->state)
+ continue;
+
+ if (!privobj->funcs->atomic_create_state)
+ continue;
+
+ privobj_state = privobj->funcs->atomic_create_state(privobj);
+ if (IS_ERR(privobj_state))
+ return PTR_ERR(privobj_state);
+
+ privobj->state = privobj_state;
+ }
+
+ drm_for_each_colorop(colorop, dev) {
+ struct drm_colorop_state *colorop_state;
+
+ if (colorop->state)
+ continue;
+
+ colorop_state = drm_atomic_helper_colorop_create_state(colorop);
+ if (IS_ERR(colorop_state))
+ return PTR_ERR(colorop_state);
+
+ colorop->state = colorop_state;
+ }
+
+ drm_for_each_plane(plane, dev) {
+ if (plane->state)
+ continue;
+
+ ret = drm_mode_config_plane_create_state(plane);
+ if (ret)
+ return ret;
+ }
+
+ drm_for_each_crtc(crtc, dev) {
+ if (crtc->state)
+ continue;
+
+ ret = drm_mode_config_crtc_create_state(crtc);
+ if (ret)
+ return ret;
+ }
+
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ if (connector->state)
+ continue;
+
+ ret = drm_mode_config_connector_create_state(connector);
+ if (ret)
+ return ret;
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_config_create_initial_state);
+
/*
* Global properties
*/
static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
{ DRM_PLANE_TYPE_OVERLAY, "Overlay" },
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 687c0ee163d2..00009250fde4 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -1005,9 +1005,10 @@ int __must_check drmm_mode_config_init(struct drm_device *dev);
static inline int drm_mode_config_init(struct drm_device *dev)
{
return drmm_mode_config_init(dev);
}
+int drm_mode_config_create_initial_state(struct drm_device *dev);
void drm_mode_config_reset(struct drm_device *dev);
void drm_mode_config_cleanup(struct drm_device *dev);
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 17/20] drm/drv: Switch skeleton to drm_mode_config_create_initial_state()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (15 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 16/20] drm/mode-config: Create drm_mode_config_create_initial_state() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 18/20] drm/tidss: Switch " Maxime Ripard
` (2 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
The driver skeleton currently recommends calling
drm_mode_config_reset() at probe time to create the initial state.
Now that drm_mode_config_create_initial_state() exists to handle
initial state allocation without hardware side effects, update the
skeleton to recommend it instead.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_drv.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 985c283cf59f..f537556b06a8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -340,11 +340,13 @@ void drm_minor_release(struct drm_minor *minor)
*
* // Further setup, display pipeline etc
*
* platform_set_drvdata(pdev, drm);
*
- * drm_mode_config_reset(drm);
+ * ret = drm_mode_config_create_initial_state(drm);
+ * if (ret)
+ * return ret;
*
* ret = drm_dev_register(drm);
* if (ret)
* return ret;
*
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 18/20] drm/tidss: Switch to drm_mode_config_create_initial_state()
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (16 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 17/20] drm/drv: Switch skeleton to drm_mode_config_create_initial_state() Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 19/20] drm/tidss: Convert to atomic_create_state Maxime Ripard
2026-04-24 10:19 ` [PATCH v3 20/20] drm/bridge_connector: " Maxime Ripard
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
Now that drm_mode_config_create_initial_state() exists to create the
initial state, use it instead of drm_mode_config_reset() during
driver probe.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/tidss/tidss_drv.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 1c8cc18bc53c..f5099d5d6e32 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -169,11 +169,15 @@ static int tidss_probe(struct platform_device *pdev)
goto err_runtime_suspend;
}
drm_kms_helper_poll_init(ddev);
- drm_mode_config_reset(ddev);
+ ret = drm_mode_config_create_initial_state(ddev);
+ if (ret) {
+ dev_err(dev, "failed to create initial state: %d\n", ret);
+ goto err_irq_uninstall;
+ }
ret = drm_dev_register(ddev, 0);
if (ret) {
dev_err(dev, "failed to register DRM device\n");
goto err_irq_uninstall;
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 19/20] drm/tidss: Convert to atomic_create_state
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (17 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 18/20] drm/tidss: Switch " Maxime Ripard
@ 2026-04-24 10:18 ` Maxime Ripard
2026-04-24 10:19 ` [PATCH v3 20/20] drm/bridge_connector: " Maxime Ripard
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
Our driver uses reset to create the various object states, but only
calls the helper that allocate a new state. They are thus strictly
equivalent to the new atomic_create_state helpers, so let's switch to
these.
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/tidss/tidss_crtc.c | 17 +++++++----------
drivers/gpu/drm/tidss/tidss_plane.c | 2 +-
2 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c
index a31c21c5f855..66e3d161c60b 100644
--- a/drivers/gpu/drm/tidss/tidss_crtc.c
+++ b/drivers/gpu/drm/tidss/tidss_crtc.c
@@ -355,24 +355,21 @@ static void tidss_crtc_destroy_state(struct drm_crtc *crtc,
__drm_atomic_helper_crtc_destroy_state(&tstate->base);
kfree(tstate);
}
-static void tidss_crtc_reset(struct drm_crtc *crtc)
+static struct drm_crtc_state *tidss_crtc_create_state(struct drm_crtc *crtc)
{
struct tidss_crtc_state *tstate;
- if (crtc->state)
- tidss_crtc_destroy_state(crtc, crtc->state);
-
tstate = kzalloc_obj(*tstate);
- if (!tstate) {
- crtc->state = NULL;
- return;
- }
+ if (!tstate)
+ return ERR_PTR(-ENOMEM);
- __drm_atomic_helper_crtc_reset(crtc, &tstate->base);
+ __drm_atomic_helper_crtc_create_state(crtc, &tstate->base);
+
+ return &tstate->base;
}
static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct tidss_crtc_state *state, *current_state;
@@ -403,14 +400,14 @@ static void tidss_crtc_destroy(struct drm_crtc *crtc)
drm_crtc_cleanup(crtc);
kfree(tcrtc);
}
static const struct drm_crtc_funcs tidss_crtc_funcs = {
- .reset = tidss_crtc_reset,
.destroy = tidss_crtc_destroy,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
+ .atomic_create_state = tidss_crtc_create_state,
.atomic_duplicate_state = tidss_crtc_duplicate_state,
.atomic_destroy_state = tidss_crtc_destroy_state,
.enable_vblank = tidss_crtc_enable_vblank,
.disable_vblank = tidss_crtc_disable_vblank,
};
diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c
index aaa02c851c59..518498d45765 100644
--- a/drivers/gpu/drm/tidss/tidss_plane.c
+++ b/drivers/gpu/drm/tidss/tidss_plane.c
@@ -176,12 +176,12 @@ static const struct drm_plane_helper_funcs tidss_primary_plane_helper_funcs = {
};
static const struct drm_plane_funcs tidss_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .reset = drm_atomic_helper_plane_reset,
.destroy = drm_plane_destroy,
+ .atomic_create_state = drm_atomic_helper_plane_create_state,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
};
struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 20/20] drm/bridge_connector: Convert to atomic_create_state
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
` (18 preceding siblings ...)
2026-04-24 10:18 ` [PATCH v3 19/20] drm/tidss: Convert to atomic_create_state Maxime Ripard
@ 2026-04-24 10:19 ` Maxime Ripard
19 siblings, 0 replies; 21+ messages in thread
From: Maxime Ripard @ 2026-04-24 10:19 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
The connector created by drm_bridge_connector only initializes a
pristine state in reset, which is equivalent to what
atomic_create_state would expect. Convert to it.
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index d72f29b73be3..4b310fe505b4 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -263,26 +263,33 @@ static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
if (bridge->funcs->debugfs_init)
bridge->funcs->debugfs_init(bridge, root);
}
}
-static void drm_bridge_connector_reset(struct drm_connector *connector)
+static struct drm_connector_state *
+drm_bridge_connector_create_state(struct drm_connector *connector)
{
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
+ struct drm_connector_state *conn_state;
+
+ conn_state = drm_atomic_helper_connector_create_state(connector);
+ if (IS_ERR(conn_state))
+ return conn_state;
- drm_atomic_helper_connector_reset(connector);
if (bridge_connector->bridge_hdmi)
__drm_atomic_helper_connector_hdmi_state_init(connector,
- connector->state);
+ conn_state);
+
+ return conn_state;
}
static const struct drm_connector_funcs drm_bridge_connector_funcs = {
- .reset = drm_bridge_connector_reset,
.detect = drm_bridge_connector_detect,
.force = drm_bridge_connector_force,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .atomic_create_state = drm_bridge_connector_create_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.debugfs_init = drm_bridge_connector_debugfs_init,
.oob_hotplug_event = drm_bridge_connector_oob_hotplug_event,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-04-24 10:20 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-24 10:18 [PATCH v3 00/20] drm/atomic: Rework initial state allocation Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 01/20] drm/atomic: Document atomic state lifetime Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 02/20] drm/colorop: Fix typos in the doc Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 03/20] drm/atomic: Drop drm_private_obj.state assignment from create_state Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 04/20] drm/atomic: Expand atomic_create_state expectations for drm_private_obj Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 05/20] drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 06/20] drm/colorop: Rename __drm_colorop_state_reset() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 07/20] drm/colorop: Create drm_atomic_helper_colorop_create_state() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 08/20] drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 09/20] drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 10/20] drm/plane: Add new atomic_create_state callback Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 11/20] drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 12/20] drm/crtc: Add new atomic_create_state callback Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 13/20] drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 14/20] drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 15/20] drm/connector: Add new atomic_create_state callback Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 16/20] drm/mode-config: Create drm_mode_config_create_initial_state() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 17/20] drm/drv: Switch skeleton to drm_mode_config_create_initial_state() Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 18/20] drm/tidss: Switch " Maxime Ripard
2026-04-24 10:18 ` [PATCH v3 19/20] drm/tidss: Convert to atomic_create_state Maxime Ripard
2026-04-24 10:19 ` [PATCH v3 20/20] drm/bridge_connector: " Maxime Ripard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox