diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 8e1d07b9f1e3..528968ea5c4b 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -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) diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index cb672ce0e856..b58f6d532820 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -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);