* [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset
@ 2026-09-08 14:46 Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 05/41] drm/amdgpu: Convert to atomic_create_state Maxime Ripard
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Maxime Ripard @ 2026-09-08 14:46 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, Maxime Ripard, hamohammed.sa, louis.chauvet,
melissa.srw, alexander.deucher, amd-gfx, christian.koenig,
alison.wang, stefan, John Stultz, sumit.semwal, xinliang.liu,
yongqin.liu, Frank.Li, Sascha Hauer, festevam, imx, kernel,
victor.liu, anitha.chrisanthus, paulk, chenhuacai, jeffbai,
lvjianmin, wuqianhai, xry111, zhengxingda, marex, airlied, kraxel,
spice-devel, virtualization, andy.yan, heiko, hjc, linux-rockchip,
Baolin Wang, orsonzhai, zhang.lyra, alain.volmat, rgallaispou,
alexandre.torgue, mcoquelin.stm32, philippe.cornu,
raphael.gallais-pou, yannick.fertre, jyri.sarha, tomi.valkeinen,
hansg, dmitry.osipenko, gurchetansingh, olvaffe, michal.simek,
harry.wentland, siqueira, sunpeng.li, linux,
Dharma Balasubiramani, Ludovic Desroches, Manikandan Muralidharan,
alexandre.belloni, claudiu.beznea, nicolas.ferre, alim.akhtar,
inki.dae, krzk, kyungmin.park, linux-samsung-soc, sw0312.kim,
p.zabel, angelogioacchino.delregno, chunkuang.hu, matthias.bgg,
Lyude Paul, dakr, nouveau, geert+renesas, kieran.bingham+renesas,
laurent.pinchart+renesas, linux-renesas-soc, magnus.damm,
tomi.valkeinen+renesas, Biju Das, linux-sunxi, samuel, wens,
Zack Rusin, bcm-kernel-feedback-list
This is a follow-up to the bridge reset removal series, and part of a
larger effort to remove the reset hook from all KMS objects.
The plane reset hook is overloaded: it is called both at probe time
to create the initial software state and during suspend/resume to
reset hardware and software state. These two roles have different
requirements, and the reset hook is not fallible, making error
handling difficult for the initial state allocation path.
While reset has the semantics to reset both the software and hardware
state, the vast majority of implementations and all the helpers only
reset the software state, making them equivalent to
atomic_create_state in practice. The atomic_create_state hook makes
this explicit: it only allocates and initializes a pristine state
without any side effect, and returns the state pointer or an ERR_PTR
on failure.
This series first adds the necessary infrastructure in the simple-kms
and GEM atomic helpers, then converts all 51 plane drivers tree-wide
from the reset hook to atomic_create_state. The conversions were done
using a combination of Coccinelle semantic patches and manual
adjustments. Once all drivers are converted, the old helpers and the
reset hook itself are removed from struct drm_plane_funcs.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Changes in v4:
- Fix a NULL pointer dereference with vkms
- Rebase on drm-misc-next-2026-09-03
- Link to v3: https://lore.kernel.org/r/20260831-drm-no-more-plane-reset-v3-0-1877c7aa57b3@kernel.org
Changes in v3:
- Drop leftover state destruction in sun4i
- Rebase on current drm-misc-next
- Link to v2: https://lore.kernel.org/r/20260814-drm-no-more-plane-reset-v2-0-82d2963dd134@kernel.org
Changes in v2:
- Rebase on latest drm-misc-next tag
- Fix sashiko reviews
- Fix atmel-hlcdc breakage
- Link to v1: https://lore.kernel.org/r/20260709-drm-no-more-plane-reset-v1-0-302d986fe5f0@kernel.org
---
Maxime Ripard (41):
drm/simple-kms: Remove unused reset_plane hook
drm/vkms: Move frame_info into vkms_plane_state
drm/vkms: Convert to atomic_create_state
drm/gem-atomic-helper: Remove __drm_gem_reset_shadow_plane()
drm/amdgpu: Convert to atomic_create_state
drm/fsl-dcu: Convert to atomic_create_state
drm/hisilicon/kirin: Convert to atomic_create_state
drm/imx/dc: Convert to atomic_create_state
drm/kmb: Convert to atomic_create_state
drm/logicvc: Convert to atomic_create_state
drm/loongson: Convert to atomic_create_state
drm/lcdif: Convert to atomic_create_state
drm/mxsfb: Convert to atomic_create_state
drm/qxl: Convert to atomic_create_state
drm/rockchip: Convert to atomic_create_state
drm/sprd: Convert to atomic_create_state
drm/sti: Convert to atomic_create_state
drm/stm: Convert to atomic_create_state
drm/tests: kunit: Convert to atomic_create_state
drm/tilcdc: Convert to atomic_create_state
drm/vboxvideo: Convert to atomic_create_state
drm/verisilicon: Convert to atomic_create_state
drm/virtio: Convert to atomic_create_state
drm/xlnx: Convert to atomic_create_state
drm/atomic-state-helper: Remove drm_atomic_helper_plane_reset()
drm/amdgpu_dm: Convert to atomic_create_state
drm/armada: Convert to atomic_create_state
drm/atmel-hlcdc: Drop spurious csc_init call from reset
drm/atmel-hlcdc: Convert to atomic_create_state
drm/exynos: Convert to atomic_create_state
drm/imx/ipuv3: Convert to atomic_create_state
drm/mediatek: Convert to atomic_create_state
drm/nouveau: Convert to atomic_create_state
drm/omap: Convert to atomic_create_state
drm/rcar-du: Convert to atomic_create_state
drm/rz-du: Convert to atomic_create_state
drm/shmobile: Convert to atomic_create_state
drm/sun4i: layer: Convert to atomic_create_state
drm/vmwgfx: Convert to atomic_create_state
drm/atomic-state-helper: Remove __drm_atomic_helper_plane_reset()
drm/plane: Remove reset
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 2 +-
.../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 28 ++++++++-----
.../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 2 +-
.../display/amdgpu_dm/tests/amdgpu_dm_plane_test.c | 30 +++++---------
drivers/gpu/drm/armada/armada_overlay.c | 39 ++++++++----------
drivers/gpu/drm/armada/armada_plane.c | 15 +++----
drivers/gpu/drm/armada/armada_plane.h | 2 +-
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 33 +++++++--------
drivers/gpu/drm/drm_atomic_state_helper.c | 41 ------------------
drivers/gpu/drm/drm_gem_atomic_helper.c | 20 ---------
drivers/gpu/drm/drm_mode_config.c | 4 +-
drivers/gpu/drm/exynos/exynos_drm_plane.c | 22 ++++------
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +-
drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +-
drivers/gpu/drm/imx/dc/dc-plane.c | 2 +-
drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c | 19 ++++-----
drivers/gpu/drm/kmb/kmb_plane.c | 2 +-
drivers/gpu/drm/logicvc/logicvc_layer.c | 2 +-
drivers/gpu/drm/loongson/lsdc_plane.c | 2 +-
drivers/gpu/drm/mediatek/mtk_plane.c | 22 ++++------
drivers/gpu/drm/mxsfb/lcdif_kms.c | 2 +-
drivers/gpu/drm/mxsfb/mxsfb_kms.c | 2 +-
drivers/gpu/drm/nouveau/dispnv50/wndw.c | 15 ++++---
drivers/gpu/drm/omapdrm/omap_plane.c | 13 +++---
drivers/gpu/drm/qxl/qxl_display.c | 4 +-
drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c | 15 +++----
drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c | 15 +++----
drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c | 15 +++----
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 15 +++----
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
drivers/gpu/drm/sprd/sprd_dpu.c | 2 +-
drivers/gpu/drm/sti/sti_cursor.c | 2 +-
drivers/gpu/drm/sti/sti_gdp.c | 2 +-
drivers/gpu/drm/sti/sti_hqvdp.c | 2 +-
drivers/gpu/drm/stm/ltdc.c | 2 +-
drivers/gpu/drm/sun4i/sun4i_layer.c | 21 ++++------
drivers/gpu/drm/tests/drm_kunit_helpers.c | 2 +-
drivers/gpu/drm/tilcdc/tilcdc_plane.c | 2 +-
drivers/gpu/drm/vboxvideo/vbox_mode.c | 2 +-
drivers/gpu/drm/verisilicon/vs_cursor_plane.c | 2 +-
drivers/gpu/drm/verisilicon/vs_plane.c | 14 +++----
drivers/gpu/drm/verisilicon/vs_plane.h | 2 +-
drivers/gpu/drm/verisilicon/vs_primary_plane.c | 2 +-
drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +-
drivers/gpu/drm/vkms/vkms_composer.c | 30 +++++++-------
drivers/gpu/drm/vkms/vkms_drv.h | 2 +-
drivers/gpu/drm/vkms/vkms_formats.c | 48 +++++++++++-----------
drivers/gpu/drm/vkms/vkms_plane.c | 36 +++++-----------
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 17 ++++----
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 2 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 +-
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 +-
drivers/gpu/drm/xlnx/zynqmp_kms.c | 2 +-
include/drm/drm_atomic_state_helper.h | 3 --
include/drm/drm_gem_atomic_helper.h | 2 -
include/drm/drm_plane.h | 12 ------
include/drm/drm_simple_kms_helper.h | 1 -
59 files changed, 236 insertions(+), 381 deletions(-)
---
base-commit: 17c6b88e85ffe5de5720004ae8c2176d52944aca
change-id: 20260629-drm-no-more-plane-reset-04950f42e07f
Best regards,
--
Maxime Ripard <mripard@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 05/41] drm/amdgpu: Convert to atomic_create_state
2026-09-08 14:46 [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Maxime Ripard
@ 2026-09-08 14:46 ` Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 26/41] drm/amdgpu_dm: " Maxime Ripard
2026-09-10 7:03 ` [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Thomas Zimmermann
2 siblings, 0 replies; 5+ messages in thread
From: Maxime Ripard @ 2026-09-08 14:46 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, Maxime Ripard, alexander.deucher, amd-gfx,
christian.koenig
The plane only initializes a pristine state in its reset hook
using drm_atomic_helper_plane_reset(), which is equivalent to what
atomic_create_state expects. Convert to it.
The conversion was done using the following Coccinelle semantic patch:
@@
identifier funcs;
symbol drm_atomic_helper_plane_reset;
symbol drm_atomic_helper_plane_create_state;
@@
struct drm_plane_funcs funcs = {
...,
- .reset = drm_atomic_helper_plane_reset,
+ .atomic_create_state = drm_atomic_helper_plane_create_state,
...,
};
@match_struct_reset@
identifier funcs, reset_func;
@@
struct drm_plane_funcs funcs = {
...,
.reset = reset_func,
...,
};
@reset_uses_helpers depends on match_struct_reset@
identifier match_struct_reset.reset_func;
@@
void reset_func(...)
{
<+...
(
__drm_atomic_helper_plane_reset(...);
|
__drm_gem_reset_shadow_plane(...);
)
...+>
}
@match_struct_destroy@
identifier funcs, destroy_func;
@@
struct drm_plane_funcs funcs = {
...,
.atomic_destroy_state = destroy_func,
...,
};
@script:python renamed_func@
old_name << match_struct_reset.reset_func;
new_name;
@@
if old_name.endswith("_reset"):
coccinelle.new_name = old_name.replace("_reset", "_create_state")
else:
coccinelle.new_name = old_name
@update_struct depends on match_struct_reset && reset_uses_helpers@
identifier match_struct_reset.funcs, match_struct_reset.reset_func;
identifier renamed_func.new_name;
@@
struct drm_plane_funcs funcs = {
...,
- .reset = reset_func,
+ .atomic_create_state = new_name,
...,
};
@drop_destroy depends on update_struct && match_struct_destroy@
identifier match_struct_reset.reset_func;
identifier match_struct_destroy.destroy_func;
identifier container_func;
identifier P;
symbol drm_atomic_helper_plane_destroy_state;
symbol __drm_atomic_helper_plane_destroy_state;
@@
void reset_func(struct drm_plane *P)
{
...
(
- if (P->state) {
- <+...
(
- drm_atomic_helper_plane_destroy_state(P, P->state);
|
- __drm_atomic_helper_plane_destroy_state(P->state);
|
- P->funcs->atomic_destroy_state(P, P->state);
|
- destroy_func(P, P->state);
)
- ...+>
- }
|
- drm_WARN_ON_ONCE(P->dev, P->state);
|
- WARN_ON(P->state);
)
...
(
- kfree(P->state);
|
- kfree(container_func(P->state));
|
// kfree is optional
)
(
- P->state = NULL;
|
// plane->state clearing is optional
)
...
}
@drop_destroy_mtk depends on update_struct@
identifier P;
symbol __drm_atomic_helper_plane_destroy_state;
symbol to_mtk_plane_state;
@@
void mtk_plane_reset(struct drm_plane *P)
{
...
- if (P->state) {
- __drm_atomic_helper_plane_destroy_state(P->state);
- ...
- } else {
...
- }
...
}
@transform_nv50_wndw depends on update_struct@
identifier S;
@@
void nv50_wndw_reset(...)
{
...
- if (WARN_ON(!(S = kzalloc_obj(*S))))
+ S = kzalloc_obj(*S);
+ if (WARN_ON(!S))
return;
...
}
@transform_kzalloc depends on update_struct@
identifier match_struct_reset.reset_func;
identifier P, S;
statement ST;
statement list STL;
@@
void reset_func(struct drm_plane *P)
{
<...
S = kzalloc_obj(*S);
(
- if (S)
- {
- STL
- }
+ if (!S) return;
+
+ STL
|
- if (S) ST
+ if (!S) return;
+
+ ST
)
...>
}
@transform_body depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier S, P;
expression PS;
@@
- void reset_func(struct drm_plane *P)
+ struct drm_plane_state *new_name(struct drm_plane *P)
{
...
S = kzalloc_obj(*S);
...
(
if (!S) {
...
- return;
+ return ERR_PTR(-ENOMEM);
}
|
if (WARN_ON(!S)) {
...
- return;
+ return ERR_PTR(-ENOMEM);
}
|
if (S == NULL) {
...
- return;
+ return ERR_PTR(-ENOMEM);
}
)
...
(
- __drm_atomic_helper_plane_reset(P, PS);
+ __drm_atomic_helper_plane_state_init(PS, P);
|
- __drm_gem_reset_shadow_plane(P, PS);
+ __drm_gem_shadow_plane_state_init(P, PS);
)
...
}
@update_early_return depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
struct drm_plane_state *new_name(struct drm_plane *P)
{
<+...
- return;
+ return ERR_PTR(-EINVAL);
...+>
}
@update_return_plane depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
struct drm_plane_state *new_name(struct drm_plane *P)
{
...
__drm_atomic_helper_plane_state_init(PS, P);
...
+
+ return PS;
}
@update_return_shadow depends on update_struct@
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
struct drm_plane_state *new_name(struct drm_plane *P)
{
...
__drm_gem_shadow_plane_state_init(P, PS);
...
+
+ return &PS->base;
}
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Cc: alexander.deucher@amd.com
Cc: amd-gfx@lists.freedesktop.org
Cc: christian.koenig@amd.com
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
index c835504fdf2b..8a6275eec3eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -142,11 +142,11 @@ static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .reset = drm_atomic_helper_plane_reset,
+ .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,
};
static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 26/41] drm/amdgpu_dm: Convert to atomic_create_state
2026-09-08 14:46 [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 05/41] drm/amdgpu: Convert to atomic_create_state Maxime Ripard
@ 2026-09-08 14:46 ` Maxime Ripard
2026-09-10 16:31 ` Leo Li
2026-09-10 7:03 ` [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Thomas Zimmermann
2 siblings, 1 reply; 5+ messages in thread
From: Maxime Ripard @ 2026-09-08 14:46 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, Maxime Ripard, alexander.deucher, amd-gfx,
christian.koenig, harry.wentland, siqueira, sunpeng.li
The plane reset implementation creates a custom state
subclass, but only initializes a pristine state without resetting any
hardware. This is equivalent to what atomic_create_state expects.
Convert to it.
The conversion was done using the following Coccinelle semantic patch:
@@
identifier funcs;
symbol drm_atomic_helper_plane_reset;
symbol drm_atomic_helper_plane_create_state;
@@
struct drm_plane_funcs funcs = {
...,
- .reset = drm_atomic_helper_plane_reset,
+ .atomic_create_state = drm_atomic_helper_plane_create_state,
...,
};
@match_struct_reset@
identifier funcs, reset_func;
@@
struct drm_plane_funcs funcs = {
...,
.reset = reset_func,
...,
};
@reset_uses_helpers depends on match_struct_reset@
identifier match_struct_reset.reset_func;
@@
void reset_func(...)
{
<+...
(
__drm_atomic_helper_plane_reset(...);
|
__drm_gem_reset_shadow_plane(...);
)
...+>
}
@match_struct_destroy@
identifier funcs, destroy_func;
@@
struct drm_plane_funcs funcs = {
...,
.atomic_destroy_state = destroy_func,
...,
};
@script:python renamed_func@
old_name << match_struct_reset.reset_func;
new_name;
@@
if old_name.endswith("_reset"):
coccinelle.new_name = old_name.replace("_reset", "_create_state")
else:
coccinelle.new_name = old_name
@update_struct depends on match_struct_reset && reset_uses_helpers@
identifier match_struct_reset.funcs, match_struct_reset.reset_func;
identifier renamed_func.new_name;
@@
struct drm_plane_funcs funcs = {
...,
- .reset = reset_func,
+ .atomic_create_state = new_name,
...,
};
@drop_destroy depends on update_struct && match_struct_destroy@
identifier match_struct_reset.reset_func;
identifier match_struct_destroy.destroy_func;
identifier container_func;
identifier P;
symbol drm_atomic_helper_plane_destroy_state;
symbol __drm_atomic_helper_plane_destroy_state;
@@
void reset_func(struct drm_plane *P)
{
...
(
- if (P->state) {
- <+...
(
- drm_atomic_helper_plane_destroy_state(P, P->state);
|
- __drm_atomic_helper_plane_destroy_state(P->state);
|
- P->funcs->atomic_destroy_state(P, P->state);
|
- destroy_func(P, P->state);
)
- ...+>
- }
|
- drm_WARN_ON_ONCE(P->dev, P->state);
|
- WARN_ON(P->state);
)
...
(
- kfree(P->state);
|
- kfree(container_func(P->state));
|
// kfree is optional
)
(
- P->state = NULL;
|
// plane->state clearing is optional
)
...
}
@drop_destroy_mtk depends on update_struct@
identifier P;
symbol __drm_atomic_helper_plane_destroy_state;
symbol to_mtk_plane_state;
@@
void mtk_plane_reset(struct drm_plane *P)
{
...
- if (P->state) {
- __drm_atomic_helper_plane_destroy_state(P->state);
- ...
- } else {
...
- }
...
}
@transform_nv50_wndw depends on update_struct@
identifier S;
@@
void nv50_wndw_reset(...)
{
...
- if (WARN_ON(!(S = kzalloc_obj(*S))))
+ S = kzalloc_obj(*S);
+ if (WARN_ON(!S))
return;
...
}
@transform_kzalloc depends on update_struct@
identifier match_struct_reset.reset_func;
identifier P, S;
statement ST;
statement list STL;
@@
void reset_func(struct drm_plane *P)
{
<...
S = kzalloc_obj(*S);
(
- if (S)
- {
- STL
- }
+ if (!S) return;
+
+ STL
|
- if (S) ST
+ if (!S) return;
+
+ ST
)
...>
}
@transform_body depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier S, P;
expression PS;
@@
- void reset_func(struct drm_plane *P)
+ struct drm_plane_state *new_name(struct drm_plane *P)
{
...
S = kzalloc_obj(*S);
...
(
if (!S) {
...
- return;
+ return ERR_PTR(-ENOMEM);
}
|
if (WARN_ON(!S)) {
...
- return;
+ return ERR_PTR(-ENOMEM);
}
|
if (S == NULL) {
...
- return;
+ return ERR_PTR(-ENOMEM);
}
)
...
(
- __drm_atomic_helper_plane_reset(P, PS);
+ __drm_atomic_helper_plane_state_init(PS, P);
|
- __drm_gem_reset_shadow_plane(P, PS);
+ __drm_gem_shadow_plane_state_init(P, PS);
)
...
}
@update_early_return depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
struct drm_plane_state *new_name(struct drm_plane *P)
{
<+...
- return;
+ return ERR_PTR(-EINVAL);
...+>
}
@update_return_plane depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
struct drm_plane_state *new_name(struct drm_plane *P)
{
...
__drm_atomic_helper_plane_state_init(PS, P);
...
+
+ return PS;
}
@update_return_shadow depends on update_struct@
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
struct drm_plane_state *new_name(struct drm_plane *P)
{
...
__drm_gem_shadow_plane_state_init(P, PS);
...
+
+ return &PS->base;
}
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Cc: alexander.deucher@amd.com
Cc: amd-gfx@lists.freedesktop.org
Cc: christian.koenig@amd.com
Cc: harry.wentland@amd.com
Cc: siqueira@igalia.com
Cc: sunpeng.li@amd.com
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 28 ++++++++++++--------
.../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 2 +-
.../display/amdgpu_dm/tests/amdgpu_dm_plane_test.c | 30 ++++++++--------------
3 files changed, 29 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 824ef3ce5de0..f9655f534d3b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1786,28 +1786,27 @@ static const struct drm_plane_helper_funcs dm_primary_plane_helper_funcs = {
.atomic_async_update = amdgpu_dm_plane_atomic_async_update,
.get_scanout_buffer = amdgpu_display_get_scanout_buffer,
.panic_flush = amdgpu_dm_plane_panic_flush,
};
-STATIC_IFN_KUNIT void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane)
+STATIC_IFN_KUNIT struct drm_plane_state *amdgpu_dm_plane_drm_plane_create_state(struct drm_plane *plane)
{
struct dm_plane_state *amdgpu_state;
amdgpu_state = kzalloc_obj(*amdgpu_state);
if (!amdgpu_state)
- return;
+ return ERR_PTR(-ENOMEM);
- if (plane->state)
- plane->funcs->atomic_destroy_state(plane, plane->state);
-
- __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
+ __drm_atomic_helper_plane_state_init(&amdgpu_state->base, plane);
amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->blend_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
+
+ return &amdgpu_state->base;
}
-EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_reset);
+EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_create_state);
STATIC_IFN_KUNIT struct drm_plane_state *
amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane)
{
struct dm_plane_state *dm_plane_state, *old_dm_plane_state;
@@ -2166,11 +2165,11 @@ dm_plane_init_colorops(struct drm_plane *plane)
static const struct drm_plane_funcs dm_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_helper_destroy,
- .reset = amdgpu_dm_plane_drm_plane_reset,
+ .atomic_create_state = amdgpu_dm_plane_drm_plane_create_state,
.atomic_duplicate_state = amdgpu_dm_plane_drm_plane_duplicate_state,
.atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state,
.format_mod_supported = amdgpu_dm_plane_format_mod_supported,
.format_mod_supported_async = amdgpu_dm_plane_format_mod_supported,
#ifdef AMD_PRIVATE_COLOR
@@ -2276,13 +2275,20 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
res = dm_plane_init_colorops(plane);
if (res)
return res;
#endif
- /* Create (reset) the plane state */
- if (plane->funcs->reset)
- plane->funcs->reset(plane);
+ /* Create the plane state */
+ if (plane->funcs->atomic_create_state) {
+ struct drm_plane_state *plane_state;
+
+ plane_state = plane->funcs->atomic_create_state(plane);
+ if (IS_ERR(plane_state))
+ return PTR_ERR(plane_state);
+
+ plane->state = plane_state;
+ }
return 0;
}
bool amdgpu_dm_plane_is_video_format(uint32_t format)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index 092ade738ce9..6aaea290206d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -115,11 +115,11 @@ void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev,
int amdgpu_dm_plane_atomic_async_check(struct drm_plane *plane,
struct drm_atomic_commit *state, bool flip);
int amdgpu_dm_plane_atomic_check(struct drm_plane *plane,
struct drm_atomic_commit *state);
void amdgpu_dm_plane_panic_flush(struct drm_plane *plane);
-void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane);
+struct drm_plane_state *amdgpu_dm_plane_drm_plane_create_state(struct drm_plane *plane);
struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane);
void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
void amdgpu_dm_plane_add_modifier_dedup(uint64_t **mods, uint64_t *size,
uint64_t *cap, uint64_t mod);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
index ba97092c7bb8..ab425ee14f30 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
@@ -2922,40 +2922,32 @@ static void dm_test_panic_flush_no_dc_state(struct kunit *test)
static const struct drm_plane_funcs dm_test_plane_reset_funcs = {
.atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state,
};
/**
- * dm_test_plane_reset_initializes_state() - Verify reset installs default state.
+ * dm_test_plane_create_state_initializes_state() - Verify create_state allocates default state.
* @test: KUnit test context.
*
- * Verify amdgpu_dm_plane_drm_plane_reset() destroys the existing plane state,
- * allocates a fresh dm_plane_state, and initializes the AMD-specific transfer
- * function and HDR multiplier defaults.
+ * Verify amdgpu_dm_plane_drm_plane_create_state() allocates a fresh
+ * dm_plane_state, and initializes the AMD-specific transfer function and HDR
+ * multiplier defaults.
*/
-static void dm_test_plane_reset_initializes_state(struct kunit *test)
+static void dm_test_plane_create_state_initializes_state(struct kunit *test)
{
- struct dm_plane_state *old_state;
+ struct drm_plane_state *plane_state;
struct dm_plane_state *new_state;
struct drm_plane *plane;
plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, plane);
- /*
- * Provide an existing state plus a funcs table so reset exercises the
- * destroy-existing-state path. The destroy hook frees this state, so it
- * must be a plain (non-KUnit-managed) allocation.
- */
- old_state = kzalloc(sizeof(*old_state), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, old_state);
plane->funcs = &dm_test_plane_reset_funcs;
- plane->state = &old_state->base;
- amdgpu_dm_plane_drm_plane_reset(plane);
+ plane_state = amdgpu_dm_plane_drm_plane_create_state(plane);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_state);
- KUNIT_ASSERT_NOT_NULL(test, plane->state);
- new_state = to_dm_plane_state(plane->state);
+ new_state = to_dm_plane_state(plane_state);
KUNIT_EXPECT_EQ(test, new_state->degamma_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT);
KUNIT_EXPECT_EQ(test, new_state->hdr_mult, AMDGPU_HDR_MULT_DEFAULT);
KUNIT_EXPECT_EQ(test, new_state->shaper_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT);
KUNIT_EXPECT_EQ(test, new_state->blend_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT);
@@ -3096,12 +3088,12 @@ static struct kunit_case amdgpu_dm_plane_test_cases[] = {
KUNIT_CASE(dm_test_atomic_check_helper_failure),
KUNIT_CASE(dm_test_atomic_check_color_pipeline_conflict),
KUNIT_CASE(dm_test_atomic_check_scaling_failure),
/* amdgpu_dm_plane_panic_flush() */
KUNIT_CASE(dm_test_panic_flush_no_dc_state),
- /* amdgpu_dm_plane_drm_plane_reset() */
- KUNIT_CASE(dm_test_plane_reset_initializes_state),
+ /* amdgpu_dm_plane_drm_plane_create_state() */
+ KUNIT_CASE(dm_test_plane_create_state_initializes_state),
/* amdgpu_dm_plane_drm_plane_duplicate_state() */
KUNIT_CASE(dm_test_plane_duplicate_state_copies_fields),
/* amdgpu_dm_plane_drm_plane_destroy_state() */
KUNIT_CASE(dm_test_plane_destroy_state_minimal),
/* amdgpu_dm_plane_add_modifier() */
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset
2026-09-08 14:46 [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 05/41] drm/amdgpu: Convert to atomic_create_state Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 26/41] drm/amdgpu_dm: " Maxime Ripard
@ 2026-09-10 7:03 ` Thomas Zimmermann
2 siblings, 0 replies; 5+ messages in thread
From: Thomas Zimmermann @ 2026-09-10 7:03 UTC (permalink / raw)
To: Maxime Ripard, Maarten Lankhorst, David Airlie, Simona Vetter
Cc: dri-devel, hamohammed.sa, louis.chauvet, melissa.srw,
alexander.deucher, amd-gfx, christian.koenig, alison.wang, stefan,
John Stultz, sumit.semwal, xinliang.liu, yongqin.liu, Frank.Li,
Sascha Hauer, festevam, imx, kernel, victor.liu,
anitha.chrisanthus, paulk, chenhuacai, jeffbai, lvjianmin,
wuqianhai, xry111, zhengxingda, marex, airlied, kraxel,
spice-devel, virtualization, andy.yan, heiko, hjc, linux-rockchip,
Baolin Wang, orsonzhai, zhang.lyra, alain.volmat, rgallaispou,
alexandre.torgue, mcoquelin.stm32, philippe.cornu,
raphael.gallais-pou, yannick.fertre, jyri.sarha, tomi.valkeinen,
hansg, dmitry.osipenko, gurchetansingh, olvaffe, michal.simek,
harry.wentland, siqueira, sunpeng.li, linux,
Dharma Balasubiramani, Ludovic Desroches, Manikandan Muralidharan,
alexandre.belloni, claudiu.beznea, nicolas.ferre, alim.akhtar,
inki.dae, krzk, kyungmin.park, linux-samsung-soc, sw0312.kim,
p.zabel, angelogioacchino.delregno, chunkuang.hu, matthias.bgg,
Lyude Paul, dakr, nouveau, geert+renesas, kieran.bingham+renesas,
laurent.pinchart+renesas, linux-renesas-soc, magnus.damm,
tomi.valkeinen+renesas, Biju Das, linux-sunxi, samuel, wens,
Zack Rusin, bcm-kernel-feedback-list
Hi Maxime,
nice series. I looked through all the patches. For those patches where
I did not respond specifically, you can add
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Best regards
Thomas
Am 08.09.26 um 16:46 schrieb Maxime Ripard:
> This is a follow-up to the bridge reset removal series, and part of a
> larger effort to remove the reset hook from all KMS objects.
>
> The plane reset hook is overloaded: it is called both at probe time
> to create the initial software state and during suspend/resume to
> reset hardware and software state. These two roles have different
> requirements, and the reset hook is not fallible, making error
> handling difficult for the initial state allocation path.
>
> While reset has the semantics to reset both the software and hardware
> state, the vast majority of implementations and all the helpers only
> reset the software state, making them equivalent to
> atomic_create_state in practice. The atomic_create_state hook makes
> this explicit: it only allocates and initializes a pristine state
> without any side effect, and returns the state pointer or an ERR_PTR
> on failure.
>
> This series first adds the necessary infrastructure in the simple-kms
> and GEM atomic helpers, then converts all 51 plane drivers tree-wide
> from the reset hook to atomic_create_state. The conversions were done
> using a combination of Coccinelle semantic patches and manual
> adjustments. Once all drivers are converted, the old helpers and the
> reset hook itself are removed from struct drm_plane_funcs.
>
> Signed-off-by: Maxime Ripard <mripard@kernel.org>
> ---
> Changes in v4:
> - Fix a NULL pointer dereference with vkms
> - Rebase on drm-misc-next-2026-09-03
> - Link to v3: https://lore.kernel.org/r/20260831-drm-no-more-plane-reset-v3-0-1877c7aa57b3@kernel.org
>
> Changes in v3:
> - Drop leftover state destruction in sun4i
> - Rebase on current drm-misc-next
> - Link to v2: https://lore.kernel.org/r/20260814-drm-no-more-plane-reset-v2-0-82d2963dd134@kernel.org
>
> Changes in v2:
> - Rebase on latest drm-misc-next tag
> - Fix sashiko reviews
> - Fix atmel-hlcdc breakage
> - Link to v1: https://lore.kernel.org/r/20260709-drm-no-more-plane-reset-v1-0-302d986fe5f0@kernel.org
>
> ---
> Maxime Ripard (41):
> drm/simple-kms: Remove unused reset_plane hook
> drm/vkms: Move frame_info into vkms_plane_state
> drm/vkms: Convert to atomic_create_state
> drm/gem-atomic-helper: Remove __drm_gem_reset_shadow_plane()
> drm/amdgpu: Convert to atomic_create_state
> drm/fsl-dcu: Convert to atomic_create_state
> drm/hisilicon/kirin: Convert to atomic_create_state
> drm/imx/dc: Convert to atomic_create_state
> drm/kmb: Convert to atomic_create_state
> drm/logicvc: Convert to atomic_create_state
> drm/loongson: Convert to atomic_create_state
> drm/lcdif: Convert to atomic_create_state
> drm/mxsfb: Convert to atomic_create_state
> drm/qxl: Convert to atomic_create_state
> drm/rockchip: Convert to atomic_create_state
> drm/sprd: Convert to atomic_create_state
> drm/sti: Convert to atomic_create_state
> drm/stm: Convert to atomic_create_state
> drm/tests: kunit: Convert to atomic_create_state
> drm/tilcdc: Convert to atomic_create_state
> drm/vboxvideo: Convert to atomic_create_state
> drm/verisilicon: Convert to atomic_create_state
> drm/virtio: Convert to atomic_create_state
> drm/xlnx: Convert to atomic_create_state
> drm/atomic-state-helper: Remove drm_atomic_helper_plane_reset()
> drm/amdgpu_dm: Convert to atomic_create_state
> drm/armada: Convert to atomic_create_state
> drm/atmel-hlcdc: Drop spurious csc_init call from reset
> drm/atmel-hlcdc: Convert to atomic_create_state
> drm/exynos: Convert to atomic_create_state
> drm/imx/ipuv3: Convert to atomic_create_state
> drm/mediatek: Convert to atomic_create_state
> drm/nouveau: Convert to atomic_create_state
> drm/omap: Convert to atomic_create_state
> drm/rcar-du: Convert to atomic_create_state
> drm/rz-du: Convert to atomic_create_state
> drm/shmobile: Convert to atomic_create_state
> drm/sun4i: layer: Convert to atomic_create_state
> drm/vmwgfx: Convert to atomic_create_state
> drm/atomic-state-helper: Remove __drm_atomic_helper_plane_reset()
> drm/plane: Remove reset
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 2 +-
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 28 ++++++++-----
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 2 +-
> .../display/amdgpu_dm/tests/amdgpu_dm_plane_test.c | 30 +++++---------
> drivers/gpu/drm/armada/armada_overlay.c | 39 ++++++++----------
> drivers/gpu/drm/armada/armada_plane.c | 15 +++----
> drivers/gpu/drm/armada/armada_plane.h | 2 +-
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 33 +++++++--------
> drivers/gpu/drm/drm_atomic_state_helper.c | 41 ------------------
> drivers/gpu/drm/drm_gem_atomic_helper.c | 20 ---------
> drivers/gpu/drm/drm_mode_config.c | 4 +-
> drivers/gpu/drm/exynos/exynos_drm_plane.c | 22 ++++------
> drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +-
> drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +-
> drivers/gpu/drm/imx/dc/dc-plane.c | 2 +-
> drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c | 19 ++++-----
> drivers/gpu/drm/kmb/kmb_plane.c | 2 +-
> drivers/gpu/drm/logicvc/logicvc_layer.c | 2 +-
> drivers/gpu/drm/loongson/lsdc_plane.c | 2 +-
> drivers/gpu/drm/mediatek/mtk_plane.c | 22 ++++------
> drivers/gpu/drm/mxsfb/lcdif_kms.c | 2 +-
> drivers/gpu/drm/mxsfb/mxsfb_kms.c | 2 +-
> drivers/gpu/drm/nouveau/dispnv50/wndw.c | 15 ++++---
> drivers/gpu/drm/omapdrm/omap_plane.c | 13 +++---
> drivers/gpu/drm/qxl/qxl_display.c | 4 +-
> drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c | 15 +++----
> drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c | 15 +++----
> drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c | 15 +++----
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 15 +++----
> drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
> drivers/gpu/drm/sprd/sprd_dpu.c | 2 +-
> drivers/gpu/drm/sti/sti_cursor.c | 2 +-
> drivers/gpu/drm/sti/sti_gdp.c | 2 +-
> drivers/gpu/drm/sti/sti_hqvdp.c | 2 +-
> drivers/gpu/drm/stm/ltdc.c | 2 +-
> drivers/gpu/drm/sun4i/sun4i_layer.c | 21 ++++------
> drivers/gpu/drm/tests/drm_kunit_helpers.c | 2 +-
> drivers/gpu/drm/tilcdc/tilcdc_plane.c | 2 +-
> drivers/gpu/drm/vboxvideo/vbox_mode.c | 2 +-
> drivers/gpu/drm/verisilicon/vs_cursor_plane.c | 2 +-
> drivers/gpu/drm/verisilicon/vs_plane.c | 14 +++----
> drivers/gpu/drm/verisilicon/vs_plane.h | 2 +-
> drivers/gpu/drm/verisilicon/vs_primary_plane.c | 2 +-
> drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +-
> drivers/gpu/drm/vkms/vkms_composer.c | 30 +++++++-------
> drivers/gpu/drm/vkms/vkms_drv.h | 2 +-
> drivers/gpu/drm/vkms/vkms_formats.c | 48 +++++++++++-----------
> drivers/gpu/drm/vkms/vkms_plane.c | 36 +++++-----------
> drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 17 ++++----
> drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 2 +-
> drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-
> drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 +-
> drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 +-
> drivers/gpu/drm/xlnx/zynqmp_kms.c | 2 +-
> include/drm/drm_atomic_state_helper.h | 3 --
> include/drm/drm_gem_atomic_helper.h | 2 -
> include/drm/drm_plane.h | 12 ------
> include/drm/drm_simple_kms_helper.h | 1 -
> 59 files changed, 236 insertions(+), 381 deletions(-)
> ---
> base-commit: 17c6b88e85ffe5de5720004ae8c2176d52944aca
> change-id: 20260629-drm-no-more-plane-reset-04950f42e07f
>
> Best regards,
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 26/41] drm/amdgpu_dm: Convert to atomic_create_state
2026-09-08 14:46 ` [PATCH v4 26/41] drm/amdgpu_dm: " Maxime Ripard
@ 2026-09-10 16:31 ` Leo Li
0 siblings, 0 replies; 5+ messages in thread
From: Leo Li @ 2026-09-10 16:31 UTC (permalink / raw)
To: Maxime Ripard, Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Simona Vetter
Cc: dri-devel, alexander.deucher, amd-gfx, christian.koenig,
harry.wentland, siqueira
On 2026-09-08 10:46, Maxime Ripard wrote:
> The plane reset implementation creates a custom state
> subclass, but only initializes a pristine state without resetting any
> hardware. This is equivalent to what atomic_create_state expects.
> Convert to it.
>
> The conversion was done using the following Coccinelle semantic patch:
>
> @@
> identifier funcs;
> symbol drm_atomic_helper_plane_reset;
> symbol drm_atomic_helper_plane_create_state;
> @@
>
> struct drm_plane_funcs funcs = {
> ...,
> - .reset = drm_atomic_helper_plane_reset,
> + .atomic_create_state = drm_atomic_helper_plane_create_state,
> ...,
> };
>
> @match_struct_reset@
> identifier funcs, reset_func;
> @@
> struct drm_plane_funcs funcs = {
> ...,
> .reset = reset_func,
> ...,
> };
>
> @reset_uses_helpers depends on match_struct_reset@
> identifier match_struct_reset.reset_func;
> @@
>
> void reset_func(...)
> {
> <+...
> (
> __drm_atomic_helper_plane_reset(...);
> |
> __drm_gem_reset_shadow_plane(...);
> )
> ...+>
> }
>
> @match_struct_destroy@
> identifier funcs, destroy_func;
> @@
> struct drm_plane_funcs funcs = {
> ...,
> .atomic_destroy_state = destroy_func,
> ...,
> };
>
> @script:python renamed_func@
> old_name << match_struct_reset.reset_func;
> new_name;
> @@
> if old_name.endswith("_reset"):
> coccinelle.new_name = old_name.replace("_reset", "_create_state")
> else:
> coccinelle.new_name = old_name
>
> @update_struct depends on match_struct_reset && reset_uses_helpers@
> identifier match_struct_reset.funcs, match_struct_reset.reset_func;
> identifier renamed_func.new_name;
> @@
> struct drm_plane_funcs funcs = {
> ...,
> - .reset = reset_func,
> + .atomic_create_state = new_name,
> ...,
> };
>
> @drop_destroy depends on update_struct && match_struct_destroy@
> identifier match_struct_reset.reset_func;
> identifier match_struct_destroy.destroy_func;
> identifier container_func;
> identifier P;
> symbol drm_atomic_helper_plane_destroy_state;
> symbol __drm_atomic_helper_plane_destroy_state;
> @@
>
> void reset_func(struct drm_plane *P)
> {
> ...
> (
> - if (P->state) {
> - <+...
> (
> - drm_atomic_helper_plane_destroy_state(P, P->state);
> |
> - __drm_atomic_helper_plane_destroy_state(P->state);
> |
> - P->funcs->atomic_destroy_state(P, P->state);
> |
> - destroy_func(P, P->state);
> )
> - ...+>
> - }
> |
> - drm_WARN_ON_ONCE(P->dev, P->state);
> |
> - WARN_ON(P->state);
> )
> ...
> (
> - kfree(P->state);
> |
> - kfree(container_func(P->state));
> |
> // kfree is optional
> )
> (
> - P->state = NULL;
> |
> // plane->state clearing is optional
> )
> ...
> }
>
> @drop_destroy_mtk depends on update_struct@
> identifier P;
> symbol __drm_atomic_helper_plane_destroy_state;
> symbol to_mtk_plane_state;
> @@
>
> void mtk_plane_reset(struct drm_plane *P)
> {
> ...
> - if (P->state) {
> - __drm_atomic_helper_plane_destroy_state(P->state);
> - ...
> - } else {
> ...
> - }
> ...
> }
>
> @transform_nv50_wndw depends on update_struct@
> identifier S;
> @@
>
> void nv50_wndw_reset(...)
> {
> ...
> - if (WARN_ON(!(S = kzalloc_obj(*S))))
> + S = kzalloc_obj(*S);
> + if (WARN_ON(!S))
> return;
> ...
> }
>
> @transform_kzalloc depends on update_struct@
> identifier match_struct_reset.reset_func;
> identifier P, S;
> statement ST;
> statement list STL;
> @@
>
> void reset_func(struct drm_plane *P)
> {
> <...
> S = kzalloc_obj(*S);
> (
> - if (S)
> - {
> - STL
> - }
> + if (!S) return;
> +
> + STL
> |
> - if (S) ST
> + if (!S) return;
> +
> + ST
> )
> ...>
> }
>
> @transform_body depends on update_struct@
> identifier match_struct_reset.reset_func;
> identifier renamed_func.new_name;
> identifier S, P;
> expression PS;
> @@
> - void reset_func(struct drm_plane *P)
> + struct drm_plane_state *new_name(struct drm_plane *P)
> {
> ...
> S = kzalloc_obj(*S);
> ...
> (
> if (!S) {
> ...
> - return;
> + return ERR_PTR(-ENOMEM);
> }
> |
> if (WARN_ON(!S)) {
> ...
> - return;
> + return ERR_PTR(-ENOMEM);
> }
> |
> if (S == NULL) {
> ...
> - return;
> + return ERR_PTR(-ENOMEM);
> }
> )
> ...
> (
> - __drm_atomic_helper_plane_reset(P, PS);
> + __drm_atomic_helper_plane_state_init(PS, P);
> |
> - __drm_gem_reset_shadow_plane(P, PS);
> + __drm_gem_shadow_plane_state_init(P, PS);
> )
> ...
> }
>
> @update_early_return depends on update_struct@
> identifier match_struct_reset.reset_func;
> identifier renamed_func.new_name;
> identifier P;
> expression PS;
> @@
> struct drm_plane_state *new_name(struct drm_plane *P)
> {
> <+...
> - return;
> + return ERR_PTR(-EINVAL);
> ...+>
> }
>
> @update_return_plane depends on update_struct@
> identifier match_struct_reset.reset_func;
> identifier renamed_func.new_name;
> identifier P;
> expression PS;
> @@
> struct drm_plane_state *new_name(struct drm_plane *P)
> {
> ...
> __drm_atomic_helper_plane_state_init(PS, P);
> ...
> +
> + return PS;
> }
>
> @update_return_shadow depends on update_struct@
> identifier renamed_func.new_name;
> identifier P;
> expression PS;
> @@
> struct drm_plane_state *new_name(struct drm_plane *P)
> {
> ...
> __drm_gem_shadow_plane_state_init(P, PS);
> ...
> +
> + return &PS->base;
> }
>
> Signed-off-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Thanks!
Leo
> ---
> Cc: alexander.deucher@amd.com
> Cc: amd-gfx@lists.freedesktop.org
> Cc: christian.koenig@amd.com
> Cc: harry.wentland@amd.com
> Cc: siqueira@igalia.com
> Cc: sunpeng.li@amd.com
> ---
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 28 ++++++++++++--------
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 2 +-
> .../display/amdgpu_dm/tests/amdgpu_dm_plane_test.c | 30 ++++++++--------------
> 3 files changed, 29 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> index 824ef3ce5de0..f9655f534d3b 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> @@ -1786,28 +1786,27 @@ static const struct drm_plane_helper_funcs dm_primary_plane_helper_funcs = {
> .atomic_async_update = amdgpu_dm_plane_atomic_async_update,
> .get_scanout_buffer = amdgpu_display_get_scanout_buffer,
> .panic_flush = amdgpu_dm_plane_panic_flush,
> };
>
> -STATIC_IFN_KUNIT void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane)
> +STATIC_IFN_KUNIT struct drm_plane_state *amdgpu_dm_plane_drm_plane_create_state(struct drm_plane *plane)
> {
> struct dm_plane_state *amdgpu_state;
>
> amdgpu_state = kzalloc_obj(*amdgpu_state);
> if (!amdgpu_state)
> - return;
> + return ERR_PTR(-ENOMEM);
>
> - if (plane->state)
> - plane->funcs->atomic_destroy_state(plane, plane->state);
> -
> - __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> + __drm_atomic_helper_plane_state_init(&amdgpu_state->base, plane);
> amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
> amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
> amdgpu_state->blend_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
> +
> + return &amdgpu_state->base;
> }
> -EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_reset);
> +EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_create_state);
>
> STATIC_IFN_KUNIT struct drm_plane_state *
> amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane)
> {
> struct dm_plane_state *dm_plane_state, *old_dm_plane_state;
> @@ -2166,11 +2165,11 @@ dm_plane_init_colorops(struct drm_plane *plane)
>
> static const struct drm_plane_funcs dm_plane_funcs = {
> .update_plane = drm_atomic_helper_update_plane,
> .disable_plane = drm_atomic_helper_disable_plane,
> .destroy = drm_plane_helper_destroy,
> - .reset = amdgpu_dm_plane_drm_plane_reset,
> + .atomic_create_state = amdgpu_dm_plane_drm_plane_create_state,
> .atomic_duplicate_state = amdgpu_dm_plane_drm_plane_duplicate_state,
> .atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state,
> .format_mod_supported = amdgpu_dm_plane_format_mod_supported,
> .format_mod_supported_async = amdgpu_dm_plane_format_mod_supported,
> #ifdef AMD_PRIVATE_COLOR
> @@ -2276,13 +2275,20 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
> res = dm_plane_init_colorops(plane);
> if (res)
> return res;
> #endif
>
> - /* Create (reset) the plane state */
> - if (plane->funcs->reset)
> - plane->funcs->reset(plane);
> + /* Create the plane state */
> + if (plane->funcs->atomic_create_state) {
> + struct drm_plane_state *plane_state;
> +
> + plane_state = plane->funcs->atomic_create_state(plane);
> + if (IS_ERR(plane_state))
> + return PTR_ERR(plane_state);
> +
> + plane->state = plane_state;
> + }
>
> return 0;
> }
>
> bool amdgpu_dm_plane_is_video_format(uint32_t format)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> index 092ade738ce9..6aaea290206d 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> @@ -115,11 +115,11 @@ void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev,
> int amdgpu_dm_plane_atomic_async_check(struct drm_plane *plane,
> struct drm_atomic_commit *state, bool flip);
> int amdgpu_dm_plane_atomic_check(struct drm_plane *plane,
> struct drm_atomic_commit *state);
> void amdgpu_dm_plane_panic_flush(struct drm_plane *plane);
> -void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane);
> +struct drm_plane_state *amdgpu_dm_plane_drm_plane_create_state(struct drm_plane *plane);
> struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane);
> void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane,
> struct drm_plane_state *state);
> void amdgpu_dm_plane_add_modifier_dedup(uint64_t **mods, uint64_t *size,
> uint64_t *cap, uint64_t mod);
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
> index ba97092c7bb8..ab425ee14f30 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
> @@ -2922,40 +2922,32 @@ static void dm_test_panic_flush_no_dc_state(struct kunit *test)
> static const struct drm_plane_funcs dm_test_plane_reset_funcs = {
> .atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state,
> };
>
> /**
> - * dm_test_plane_reset_initializes_state() - Verify reset installs default state.
> + * dm_test_plane_create_state_initializes_state() - Verify create_state allocates default state.
> * @test: KUnit test context.
> *
> - * Verify amdgpu_dm_plane_drm_plane_reset() destroys the existing plane state,
> - * allocates a fresh dm_plane_state, and initializes the AMD-specific transfer
> - * function and HDR multiplier defaults.
> + * Verify amdgpu_dm_plane_drm_plane_create_state() allocates a fresh
> + * dm_plane_state, and initializes the AMD-specific transfer function and HDR
> + * multiplier defaults.
> */
> -static void dm_test_plane_reset_initializes_state(struct kunit *test)
> +static void dm_test_plane_create_state_initializes_state(struct kunit *test)
> {
> - struct dm_plane_state *old_state;
> + struct drm_plane_state *plane_state;
> struct dm_plane_state *new_state;
> struct drm_plane *plane;
>
> plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
> KUNIT_ASSERT_NOT_NULL(test, plane);
>
> - /*
> - * Provide an existing state plus a funcs table so reset exercises the
> - * destroy-existing-state path. The destroy hook frees this state, so it
> - * must be a plain (non-KUnit-managed) allocation.
> - */
> - old_state = kzalloc(sizeof(*old_state), GFP_KERNEL);
> - KUNIT_ASSERT_NOT_NULL(test, old_state);
> plane->funcs = &dm_test_plane_reset_funcs;
> - plane->state = &old_state->base;
>
> - amdgpu_dm_plane_drm_plane_reset(plane);
> + plane_state = amdgpu_dm_plane_drm_plane_create_state(plane);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_state);
>
> - KUNIT_ASSERT_NOT_NULL(test, plane->state);
> - new_state = to_dm_plane_state(plane->state);
> + new_state = to_dm_plane_state(plane_state);
> KUNIT_EXPECT_EQ(test, new_state->degamma_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT);
> KUNIT_EXPECT_EQ(test, new_state->hdr_mult, AMDGPU_HDR_MULT_DEFAULT);
> KUNIT_EXPECT_EQ(test, new_state->shaper_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT);
> KUNIT_EXPECT_EQ(test, new_state->blend_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT);
>
> @@ -3096,12 +3088,12 @@ static struct kunit_case amdgpu_dm_plane_test_cases[] = {
> KUNIT_CASE(dm_test_atomic_check_helper_failure),
> KUNIT_CASE(dm_test_atomic_check_color_pipeline_conflict),
> KUNIT_CASE(dm_test_atomic_check_scaling_failure),
> /* amdgpu_dm_plane_panic_flush() */
> KUNIT_CASE(dm_test_panic_flush_no_dc_state),
> - /* amdgpu_dm_plane_drm_plane_reset() */
> - KUNIT_CASE(dm_test_plane_reset_initializes_state),
> + /* amdgpu_dm_plane_drm_plane_create_state() */
> + KUNIT_CASE(dm_test_plane_create_state_initializes_state),
> /* amdgpu_dm_plane_drm_plane_duplicate_state() */
> KUNIT_CASE(dm_test_plane_duplicate_state_copies_fields),
> /* amdgpu_dm_plane_drm_plane_destroy_state() */
> KUNIT_CASE(dm_test_plane_destroy_state_minimal),
> /* amdgpu_dm_plane_add_modifier() */
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-10 16:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-08 14:46 [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 05/41] drm/amdgpu: Convert to atomic_create_state Maxime Ripard
2026-09-08 14:46 ` [PATCH v4 26/41] drm/amdgpu_dm: " Maxime Ripard
2026-09-10 16:31 ` Leo Li
2026-09-10 7:03 ` [PATCH v4 00/41] drm/plane: Convert all drivers to atomic_create_state and remove reset Thomas Zimmermann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox