drm/simple-kms: Add create_plane_state hook

The simple-kms helper provides a reset_plane hook to let drivers
override the default plane reset. However, the reset hook is
overloaded: it is used to create the initial software state at probe
time, but also to reset both the hardware and software state during
suspend/resume. These two roles have different expectations, and
reset is not fallible which makes error handling difficult.

The atomic_create_state pattern was introduced to untangle this by
providing a hook that only allocates and initializes a pristine state
without any side effect.

Add a create_plane_state hook to struct
drm_simple_display_pipe_funcs. When provided,
drm_simple_kms_plane_reset() will use it to allocate a fresh state,
falling back to reset_plane and then to the default
drm_atomic_helper_plane_reset().

This will allow simple-kms drivers to be converted to the
atomic_create_state pattern.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-1-82d2963dd134@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
This commit is contained in:
Maxime Ripard 2026-08-14 16:56:50 +02:00
parent e3eca845ef
commit a8a198cefe
No known key found for this signature in database
GPG Key ID: 275FCE19A23DBE76
2 changed files with 25 additions and 2 deletions

View File

@ -281,15 +281,37 @@ static const struct drm_plane_helper_funcs drm_simple_kms_plane_helper_funcs = {
.atomic_update = drm_simple_kms_plane_atomic_update,
};
static void drm_simple_kms_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
static void drm_simple_kms_plane_reset(struct drm_plane *plane)
{
struct drm_simple_display_pipe *pipe;
pipe = container_of(plane, struct drm_simple_display_pipe, plane);
if (!pipe->funcs || !pipe->funcs->reset_plane)
if (!pipe->funcs)
return drm_atomic_helper_plane_reset(plane);
return pipe->funcs->reset_plane(pipe);
if (pipe->funcs->create_plane_state) {
struct drm_plane_state *state;
if (plane->state) {
drm_simple_kms_plane_destroy_state(plane, plane->state);
plane->state = NULL;
}
state = pipe->funcs->create_plane_state(pipe);
if (WARN_ON(IS_ERR(state)))
return;
plane->state = state;
return;
}
if (pipe->funcs->reset_plane)
return pipe->funcs->reset_plane(pipe);
return drm_atomic_helper_plane_reset(plane);
}
static struct drm_plane_state *drm_simple_kms_plane_duplicate_state(struct drm_plane *plane)

View File

@ -44,6 +44,7 @@ struct drm_simple_display_pipe_funcs {
void (*destroy_crtc_state)(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state);
void (*reset_plane)(struct drm_simple_display_pipe *pipe);
struct drm_plane_state * (*create_plane_state)(struct drm_simple_display_pipe *pipe);
struct drm_plane_state * (*duplicate_plane_state)(struct drm_simple_display_pipe *pipe);
void (*destroy_plane_state)(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);