From: Thomas Zimmermann Date: Thu, 18 Sep 2025 15:39:49 +0000 (+0200) Subject: drm/sysfb: Add custom plane state X-Git-Tag: v6.19-rc1~157^2~24^2~80 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e45f72b6782f88ed50932033ad206df5dd3d7103;p=thirdparty%2Flinux.git drm/sysfb: Add custom plane state The plane-state type struct drm_sysfb_plane_state will store the helper for blitting to the scanout buffer. v2: - add variable for duplicated shadow-plane state (Javier) - fix build error Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20250918154207.84714-2-tzimmermann@suse.de --- diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h index 89633e30ca625..875dd65947607 100644 --- a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h +++ b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h @@ -10,6 +10,7 @@ #include #include +#include #include struct drm_format_info; @@ -93,6 +94,16 @@ static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *de * Plane */ +struct drm_sysfb_plane_state { + struct drm_shadow_plane_state base; +}; + +static inline struct drm_sysfb_plane_state * +to_drm_sysfb_plane_state(struct drm_plane_state *base) +{ + return container_of(to_drm_shadow_plane_state(base), struct drm_sysfb_plane_state, base); +} + size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, const u32 *native_fourccs, size_t native_nfourccs, u32 *fourccs_out, size_t nfourccs_out); @@ -120,10 +131,17 @@ int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane, .atomic_disable = drm_sysfb_plane_helper_atomic_disable, \ .get_scanout_buffer = drm_sysfb_plane_helper_get_scanout_buffer +void drm_sysfb_plane_reset(struct drm_plane *plane); +struct drm_plane_state *drm_sysfb_plane_atomic_duplicate_state(struct drm_plane *plane); +void drm_sysfb_plane_atomic_destroy_state(struct drm_plane *plane, + struct drm_plane_state *plane_state); + #define DRM_SYSFB_PLANE_FUNCS \ + .reset = drm_sysfb_plane_reset, \ .update_plane = drm_atomic_helper_update_plane, \ .disable_plane = drm_atomic_helper_disable_plane, \ - DRM_GEM_SHADOW_PLANE_FUNCS + .atomic_duplicate_state = drm_sysfb_plane_atomic_duplicate_state, \ + .atomic_destroy_state = drm_sysfb_plane_atomic_destroy_state /* * CRTC diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c index ddb4a7523ee61..e7c5f8b3b99c6 100644 --- a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c +++ b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -185,6 +184,13 @@ size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, } EXPORT_SYMBOL(drm_sysfb_build_fourcc_list); +static void drm_sysfb_plane_state_destroy(struct drm_sysfb_plane_state *sysfb_plane_state) +{ + __drm_gem_destroy_shadow_plane_state(&sysfb_plane_state->base); + + kfree(sysfb_plane_state); +} + int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane, struct drm_atomic_state *new_state) { @@ -321,6 +327,49 @@ int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane, } EXPORT_SYMBOL(drm_sysfb_plane_helper_get_scanout_buffer); +void drm_sysfb_plane_reset(struct drm_plane *plane) +{ + struct drm_sysfb_plane_state *sysfb_plane_state; + + if (plane->state) + drm_sysfb_plane_state_destroy(to_drm_sysfb_plane_state(plane->state)); + + sysfb_plane_state = kzalloc(sizeof(*sysfb_plane_state), GFP_KERNEL); + if (sysfb_plane_state) + __drm_gem_reset_shadow_plane(plane, &sysfb_plane_state->base); + else + __drm_gem_reset_shadow_plane(plane, NULL); +} +EXPORT_SYMBOL(drm_sysfb_plane_reset); + +struct drm_plane_state *drm_sysfb_plane_atomic_duplicate_state(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct drm_plane_state *plane_state = plane->state; + struct drm_sysfb_plane_state *new_sysfb_plane_state; + struct drm_shadow_plane_state *new_shadow_plane_state; + + if (drm_WARN_ON(dev, !plane_state)) + return NULL; + + new_sysfb_plane_state = kzalloc(sizeof(*new_sysfb_plane_state), GFP_KERNEL); + if (!new_sysfb_plane_state) + return NULL; + new_shadow_plane_state = &new_sysfb_plane_state->base; + + __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state); + + return &new_shadow_plane_state->base; +} +EXPORT_SYMBOL(drm_sysfb_plane_atomic_duplicate_state); + +void drm_sysfb_plane_atomic_destroy_state(struct drm_plane *plane, + struct drm_plane_state *plane_state) +{ + drm_sysfb_plane_state_destroy(to_drm_sysfb_plane_state(plane_state)); +} +EXPORT_SYMBOL(drm_sysfb_plane_atomic_destroy_state); + /* * CRTC */