diff mbox series

[2/5] drm/vram-helpers: Add helpers for struct drm_plane_helper_funcs

Message ID 20191022102520.13181-3-tzimmermann@suse.de (mailing list archive)
State New, archived
Headers show
Series drm/vram: Provide helpers for prepare_fb() and cleanup_fb() | expand

Commit Message

Thomas Zimmermann Oct. 22, 2019, 10:25 a.m. UTC
The new helpers pin and unpin a framebuffer's GEM VRAM objects during
plane updates. This should be sufficient for most drivers prepare_fb and
cleanup_fb implementations.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_gem_vram_helper.c | 81 +++++++++++++++++++++++++++
 include/drm/drm_gem_vram_helper.h     | 12 ++++
 2 files changed, 93 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c
index dc7942981f4a..3ddb90475178 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -3,9 +3,11 @@ 
 #include <drm/drm_debugfs.h>
 #include <drm/drm_device.h>
 #include <drm/drm_file.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_gem_ttm_helper.h>
 #include <drm/drm_gem_vram_helper.h>
 #include <drm/drm_mode.h>
+#include <drm/drm_plane.h>
 #include <drm/drm_prime.h>
 #include <drm/ttm/ttm_page_alloc.h>
 
@@ -653,6 +655,85 @@  int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
 }
 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);
 
+/*
+ * Helpers for struct drm_plane_helper_funcs
+ */
+
+/**
+ * drm_gem_vram_plane_helper_funcs_prepare_fb() - \
+ *	Implements &struct drm_plane_helper_funcs.prepare_fb
+ * @plane:	a DRM plane.
+ * @new_state:	the plane's new state
+ *
+ * During plane updates, this function pins the GEM VRAM
+ * objects of the plane's new framebuffer to VRAM. Call
+ * drm_gem_vram_plane_helper_funcs_cleanup_fb() to unpin them.
+ *
+ * Returns:
+ *	0 on success, or
+ *	a negative errno code otherwise.
+ */
+int
+drm_gem_vram_plane_helper_funcs_prepare_fb(struct drm_plane *plane,
+					   struct drm_plane_state *new_state)
+{
+	size_t i;
+	struct drm_gem_vram_object *gbo;
+	int ret;
+
+	if (!new_state->fb)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(new_state->fb->obj); ++i) {
+		if (!new_state->fb->obj[i])
+			continue;
+		gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]);
+		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
+		if (ret)
+			goto err_drm_gem_vram_unpin;
+	}
+
+	return 0;
+
+err_drm_gem_vram_unpin:
+	while (i) {
+		--i;
+		gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]);
+		drm_gem_vram_unpin(gbo);
+	}
+	return ret;
+}
+EXPORT_SYMBOL(drm_gem_vram_plane_helper_funcs_prepare_fb);
+
+/**
+ * drm_gem_vram_plane_helper_funcs_cleanup_fb() - \
+ *	Implements &struct drm_plane_helper_funcs.cleanup_fb
+ * @plane:	a DRM plane.
+ * @old_state:	the plane's old state
+ *
+ * During plane updates, this function unpins the GEM VRAM
+ * objects of the plane's old framebuffer from VRAM. Complements
+ * drm_gem_vram_plane_helper_funcs_prepare_fb().
+ */
+void
+drm_gem_vram_plane_helper_funcs_cleanup_fb(struct drm_plane *plane,
+					   struct drm_plane_state *old_state)
+{
+	size_t i;
+	struct drm_gem_vram_object *gbo;
+
+	if (!old_state->fb)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(old_state->fb->obj); ++i) {
+		if (!old_state->fb->obj[i])
+			continue;
+		gbo = drm_gem_vram_of_gem(old_state->fb->obj[i]);
+		drm_gem_vram_unpin(gbo);
+	}
+}
+EXPORT_SYMBOL(drm_gem_vram_plane_helper_funcs_cleanup_fb);
+
 /*
  * PRIME helpers
  */
diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h
index 354a9cd358a3..19ba5c0a1fd0 100644
--- a/include/drm/drm_gem_vram_helper.h
+++ b/include/drm/drm_gem_vram_helper.h
@@ -13,6 +13,8 @@ 
 #include <linux/kernel.h> /* for container_of() */
 
 struct drm_mode_create_dumb;
+struct drm_plane;
+struct drm_plane_state;
 struct drm_vram_mm_funcs;
 struct filp;
 struct vm_area_struct;
@@ -124,6 +126,16 @@  int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
 					 struct drm_device *dev,
 					 uint32_t handle, uint64_t *offset);
 
+/*
+ * Helpers for struct drm_plane_helper_funcs
+ */
+int
+drm_gem_vram_plane_helper_funcs_prepare_fb(struct drm_plane *plane,
+					   struct drm_plane_state *new_state);
+void
+drm_gem_vram_plane_helper_funcs_cleanup_fb(struct drm_plane *plane,
+					   struct drm_plane_state *old_state);
+
 /**
  * define DRM_GEM_VRAM_DRIVER - default callback functions for \
 	&struct drm_driver