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 <tzimmerm...@suse.de>
Reviewed-by: Javier Martinez Canillas <javi...@redhat.com>
---
 drivers/gpu/drm/sysfb/drm_sysfb_helper.h  | 20 ++++++++-
 drivers/gpu/drm/sysfb/drm_sysfb_modeset.c | 51 ++++++++++++++++++++++-
 2 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h 
b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
index 89633e30ca62..875dd6594760 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
@@ -10,6 +10,7 @@
 
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
+#include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_modes.h>
 
 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 ddb4a7523ee6..e7c5f8b3b99c 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
@@ -11,7 +11,6 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_framebuffer.h>
-#include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_panic.h>
 #include <drm/drm_print.h>
@@ -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
  */
-- 
2.51.0

Reply via email to