dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drm/ast: add dmabuf/prime buffer sharing support
@ 2022-08-26  1:31 oushixiong
  2022-08-26  7:29 ` Christian König
  0 siblings, 1 reply; 6+ messages in thread
From: oushixiong @ 2022-08-26  1:31 UTC (permalink / raw)
  To: Dave Airlie
  Cc: oushixiong, Thomas Zimmermann, David Airlie, linux-kernel,
	dri-devel, Sumit Semwal, linaro-mm-sig, Christian König,
	linux-media

This patch adds ast specific codes for DRM prime feature, this is to
allow for offloading of rending in one direction and outputs in other.

This patch is designed to solve the problem that the AST is not displayed
when the server plug in a discrete graphics graphics card at the same time.
We call the dirty callback function to copy the rendering results of the
discrete graphics card to the ast side by dma-buf.

v1->v2:
  - Fix the comment.
v2->v3:
  - we remove the attach function, add the drm_gem_pin() before dma_buf_vmap(),
    and add the drm_gem_unpin() after the dma_buf_vunmap().

Signed-off-by: oushixiong <oushixiong@kylinos.cn>
---
 drivers/gpu/drm/ast/ast_drv.c  |  27 +++++++
 drivers/gpu/drm/ast/ast_mode.c | 134 ++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/drm_gem.c      |   2 +
 include/drm/drm_gem.h          |   3 +
 4 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 7465c4f0156a..107383a56ca7 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/dma-buf.h>
 
 #include <drm/drm_aperture.h>
 #include <drm/drm_atomic_helper.h>
@@ -50,6 +51,29 @@ module_param_named(modeset, ast_modeset, int, 0400);
 
 DEFINE_DRM_GEM_FOPS(ast_fops);
 
+struct drm_gem_object *ast_gem_prime_import(struct drm_device *dev,
+						struct dma_buf *dma_buf)
+{
+	struct drm_gem_vram_object *gbo;
+
+	gbo = drm_gem_vram_of_gem(dma_buf->priv);
+	if (gbo->bo.base.dev == dev) {
+		/*
+		* Importing dmabuf exported from out own gem increases
+		* refcount on gem itself instead of f_count of dmabuf.
+		*/
+		drm_gem_object_get(&gbo->bo.base);
+		return &gbo->bo.base;
+	}
+
+	gbo = drm_gem_vram_create(dev, dma_buf->size, 0);
+	if (IS_ERR(gbo))
+		return NULL;
+
+	get_dma_buf(dma_buf);
+	return &gbo->bo.base;
+}
+
 static const struct drm_driver ast_driver = {
 	.driver_features = DRIVER_ATOMIC |
 			   DRIVER_GEM |
@@ -63,6 +87,9 @@ static const struct drm_driver ast_driver = {
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
 
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_import = ast_gem_prime_import,
+
 	DRM_GEM_VRAM_DRIVER
 };
 
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 45b56b39ad47..c81a6148b6df 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -48,6 +48,8 @@
 #include "ast_drv.h"
 #include "ast_tables.h"
 
+MODULE_IMPORT_NS(DMA_BUF);
+
 static inline void ast_load_palette_index(struct ast_private *ast,
 				     u8 index, u8 red, u8 green,
 				     u8 blue)
@@ -1535,8 +1537,138 @@ static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs =
 	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+static int ast_handle_damage(struct drm_framebuffer *fb, int x, int y,
+					int width, int height)
+{
+	struct drm_gem_vram_object *dst_bo = NULL;
+	void *dst = NULL;
+	int ret = 0, i;
+	unsigned long offset = 0;
+	bool unmap = false;
+	unsigned int bytesPerPixel;
+	struct iosys_map map;
+	struct iosys_map dmabuf_map;
+
+	bytesPerPixel = fb->format->cpp[0];
+
+	if (!fb->obj[0]->dma_buf)
+		return -EINVAL;
+
+	if (!fb->obj[0]->dma_buf->vmap_ptr.vaddr) {
+		ret = drm_gem_pin(fb->obj[0]->dma_buf->priv);
+		if (ret)
+			return ret;
+		ret = dma_buf_vmap(fb->obj[0]->dma_buf, &dmabuf_map);
+		if (ret)
+			goto err_vmap_dmabuf;
+	} else
+		dmabuf_map.vaddr = fb->obj[0]->dma_buf->vmap_ptr.vaddr;
+
+	dst_bo = drm_gem_vram_of_gem(fb->obj[0]);
+
+	ret = drm_gem_vram_pin(dst_bo, 0);
+	if (ret) {
+		DRM_ERROR("ast_bo_pin failed\n");
+		goto err_ast_pin;
+	}
+
+	if (!dst_bo->map.vaddr) {
+		ret = drm_gem_vram_vmap(dst_bo, &map);
+		if (ret) {
+			DRM_ERROR("failed to vmap fbcon\n");
+			goto err_vmap_ast_bo;
+		}
+		unmap = true;
+	}
+	dst = dst_bo->map.vaddr;
+
+	for (i = y; i < y + height; i++) {
+		offset = i * fb->pitches[0] + (x * bytesPerPixel);
+		memcpy_toio(dst + offset, dmabuf_map.vaddr + offset,
+			width * bytesPerPixel);
+	}
+
+	if (unmap)
+		drm_gem_vram_vunmap(dst_bo, &map);
+
+	drm_gem_vram_unpin(dst_bo);
+	return 0;
+
+err_vmap_ast_bo:
+	drm_gem_vram_unpin(dst_bo);
+err_ast_pin:
+err_vmap_dmabuf:
+	drm_gem_unpin(fb->obj[0]->dma_buf->priv);
+	return ret;
+}
+
+
+static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
+				struct drm_file *file,
+				unsigned int flags,
+				unsigned int color,
+				struct drm_clip_rect *clips,
+				unsigned int num_clips)
+{
+	int i, ret = 0;
+
+	drm_modeset_lock_all(fb->dev);
+	if (fb->obj[0]->dma_buf) {
+		ret = dma_buf_begin_cpu_access(fb->obj[0]->dma_buf,
+				DMA_FROM_DEVICE);
+		if (ret)
+			goto unlock;
+	}
+
+	for (i = 0; i < num_clips; i++) {
+		ret = ast_handle_damage(fb, clips[i].x1, clips[i].y1,
+				clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1);
+		if (ret)
+			break;
+	}
+
+	if (fb->obj[0]->dma_buf) {
+		dma_buf_end_cpu_access(fb->obj[0]->dma_buf,
+				DMA_FROM_DEVICE);
+	}
+
+unlock:
+	drm_modeset_unlock_all(fb->dev);
+
+	return ret;
+}
+
+static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+	struct iosys_map dmabuf_map;
+
+	if (fb->obj[0]->dma_buf) {
+		dmabuf_map.is_iomem = fb->obj[0]->dma_buf->vmap_ptr.is_iomem;
+		dmabuf_map.vaddr = fb->obj[0]->dma_buf->vmap_ptr.vaddr;
+		if (dmabuf_map.vaddr)
+			dma_buf_vunmap(fb->obj[0]->dma_buf, &dmabuf_map);
+		drm_gem_unpin(fb->obj[0]->dma_buf->priv);
+	}
+
+	drm_gem_fb_destroy(fb);
+}
+
+static const struct drm_framebuffer_funcs ast_gem_fb_funcs_dirtyfb = {
+	.destroy	= ast_user_framebuffer_destroy,
+	.create_handle	= drm_gem_fb_create_handle,
+	.dirty		= ast_user_framebuffer_dirty,
+};
+
+static struct drm_framebuffer *
+ast_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
+				const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
+					&ast_gem_fb_funcs_dirtyfb);
+}
+
 static const struct drm_mode_config_funcs ast_mode_config_funcs = {
-	.fb_create = drm_gem_fb_create,
+	.fb_create = ast_gem_fb_create_with_dirty,
 	.mode_valid = drm_vram_helper_mode_valid,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 56fb87885146..3a4f5137abc5 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1159,12 +1159,14 @@ int drm_gem_pin(struct drm_gem_object *obj)
 	else
 		return 0;
 }
+EXPORT_SYMBOL(drm_gem_pin);
 
 void drm_gem_unpin(struct drm_gem_object *obj)
 {
 	if (obj->funcs->unpin)
 		obj->funcs->unpin(obj);
 }
+EXPORT_SYMBOL(drm_gem_unpin);
 
 int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index e2941cee14b6..30c4366968bf 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -352,6 +352,9 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
 		     struct vm_area_struct *vma);
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 
+int drm_gem_pin(struct drm_gem_object *obj);
+void drm_gem_unpin(struct drm_gem_object *obj);
+
 /**
  * drm_gem_object_get - acquire a GEM buffer object reference
  * @obj: GEM buffer object
-- 
2.17.1


No virus found
		Checked by Hillstone Network AntiVirus

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] drm/ast: add dmabuf/prime buffer sharing support
  2022-08-26  1:31 [PATCH] drm/ast: add dmabuf/prime buffer sharing support oushixiong
@ 2022-08-26  7:29 ` Christian König
  0 siblings, 0 replies; 6+ messages in thread
From: Christian König @ 2022-08-26  7:29 UTC (permalink / raw)
  To: oushixiong, Dave Airlie
  Cc: Thomas Zimmermann, David Airlie, linux-kernel, dri-devel,
	linaro-mm-sig, Sumit Semwal, linux-media

Am 26.08.22 um 03:31 schrieb oushixiong:
> This patch adds ast specific codes for DRM prime feature, this is to
> allow for offloading of rending in one direction and outputs in other.
>
> This patch is designed to solve the problem that the AST is not displayed
> when the server plug in a discrete graphics graphics card at the same time.
> We call the dirty callback function to copy the rendering results of the
> discrete graphics card to the ast side by dma-buf.
>
> v1->v2:
>    - Fix the comment.
> v2->v3:
>    - we remove the attach function, add the drm_gem_pin() before dma_buf_vmap(),
>      and add the drm_gem_unpin() after the dma_buf_vunmap().
>
> Signed-off-by: oushixiong <oushixiong@kylinos.cn>
> ---
>   drivers/gpu/drm/ast/ast_drv.c  |  27 +++++++
>   drivers/gpu/drm/ast/ast_mode.c | 134 ++++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/drm_gem.c      |   2 +
>   include/drm/drm_gem.h          |   3 +
>   4 files changed, 165 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> index 7465c4f0156a..107383a56ca7 100644
> --- a/drivers/gpu/drm/ast/ast_drv.c
> +++ b/drivers/gpu/drm/ast/ast_drv.c
> @@ -28,6 +28,7 @@
>   
>   #include <linux/module.h>
>   #include <linux/pci.h>
> +#include <linux/dma-buf.h>
>   
>   #include <drm/drm_aperture.h>
>   #include <drm/drm_atomic_helper.h>
> @@ -50,6 +51,29 @@ module_param_named(modeset, ast_modeset, int, 0400);
>   
>   DEFINE_DRM_GEM_FOPS(ast_fops);
>   
> +struct drm_gem_object *ast_gem_prime_import(struct drm_device *dev,
> +						struct dma_buf *dma_buf)
> +{
> +	struct drm_gem_vram_object *gbo;
> +
> +	gbo = drm_gem_vram_of_gem(dma_buf->priv);
> +	if (gbo->bo.base.dev == dev) {
> +		/*
> +		* Importing dmabuf exported from out own gem increases
> +		* refcount on gem itself instead of f_count of dmabuf.
> +		*/
> +		drm_gem_object_get(&gbo->bo.base);
> +		return &gbo->bo.base;
> +	}
> +
> +	gbo = drm_gem_vram_create(dev, dma_buf->size, 0);
> +	if (IS_ERR(gbo))
> +		return NULL;
> +
> +	get_dma_buf(dma_buf);
> +	return &gbo->bo.base;
> +}
> +
>   static const struct drm_driver ast_driver = {
>   	.driver_features = DRIVER_ATOMIC |
>   			   DRIVER_GEM |
> @@ -63,6 +87,9 @@ static const struct drm_driver ast_driver = {
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   
> +	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
> +	.gem_prime_import = ast_gem_prime_import,
> +
>   	DRM_GEM_VRAM_DRIVER
>   };
>   
> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
> index 45b56b39ad47..c81a6148b6df 100644
> --- a/drivers/gpu/drm/ast/ast_mode.c
> +++ b/drivers/gpu/drm/ast/ast_mode.c
> @@ -48,6 +48,8 @@
>   #include "ast_drv.h"
>   #include "ast_tables.h"
>   
> +MODULE_IMPORT_NS(DMA_BUF);
> +
>   static inline void ast_load_palette_index(struct ast_private *ast,
>   				     u8 index, u8 red, u8 green,
>   				     u8 blue)
> @@ -1535,8 +1537,138 @@ static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs =
>   	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
>   };
>   
> +static int ast_handle_damage(struct drm_framebuffer *fb, int x, int y,
> +					int width, int height)
> +{
> +	struct drm_gem_vram_object *dst_bo = NULL;
> +	void *dst = NULL;
> +	int ret = 0, i;
> +	unsigned long offset = 0;
> +	bool unmap = false;
> +	unsigned int bytesPerPixel;
> +	struct iosys_map map;
> +	struct iosys_map dmabuf_map;
> +
> +	bytesPerPixel = fb->format->cpp[0];
> +
> +	if (!fb->obj[0]->dma_buf)
> +		return -EINVAL;
> +
> +	if (!fb->obj[0]->dma_buf->vmap_ptr.vaddr) {
> +		ret = drm_gem_pin(fb->obj[0]->dma_buf->priv);
> +		if (ret)
> +			return ret;

This is an full blown NAK to this!

By accessing dma_buf->priv you are assuming that this points to a GEM 
buffer.

Additional to that pinning the buffer shouldn't be necessary for a call 
to dma_buf_vmap().

Regards,
Christian.

> +		ret = dma_buf_vmap(fb->obj[0]->dma_buf, &dmabuf_map);
> +		if (ret)
> +			goto err_vmap_dmabuf;
> +	} else
> +		dmabuf_map.vaddr = fb->obj[0]->dma_buf->vmap_ptr.vaddr;
> +
> +	dst_bo = drm_gem_vram_of_gem(fb->obj[0]);
> +
> +	ret = drm_gem_vram_pin(dst_bo, 0);
> +	if (ret) {
> +		DRM_ERROR("ast_bo_pin failed\n");
> +		goto err_ast_pin;
> +	}
> +
> +	if (!dst_bo->map.vaddr) {
> +		ret = drm_gem_vram_vmap(dst_bo, &map);
> +		if (ret) {
> +			DRM_ERROR("failed to vmap fbcon\n");
> +			goto err_vmap_ast_bo;
> +		}
> +		unmap = true;
> +	}
> +	dst = dst_bo->map.vaddr;
> +
> +	for (i = y; i < y + height; i++) {
> +		offset = i * fb->pitches[0] + (x * bytesPerPixel);
> +		memcpy_toio(dst + offset, dmabuf_map.vaddr + offset,
> +			width * bytesPerPixel);
> +	}
> +
> +	if (unmap)
> +		drm_gem_vram_vunmap(dst_bo, &map);
> +
> +	drm_gem_vram_unpin(dst_bo);
> +	return 0;
> +
> +err_vmap_ast_bo:
> +	drm_gem_vram_unpin(dst_bo);
> +err_ast_pin:
> +err_vmap_dmabuf:
> +	drm_gem_unpin(fb->obj[0]->dma_buf->priv);
> +	return ret;
> +}
> +
> +
> +static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
> +				struct drm_file *file,
> +				unsigned int flags,
> +				unsigned int color,
> +				struct drm_clip_rect *clips,
> +				unsigned int num_clips)
> +{
> +	int i, ret = 0;
> +
> +	drm_modeset_lock_all(fb->dev);
> +	if (fb->obj[0]->dma_buf) {
> +		ret = dma_buf_begin_cpu_access(fb->obj[0]->dma_buf,
> +				DMA_FROM_DEVICE);
> +		if (ret)
> +			goto unlock;
> +	}
> +
> +	for (i = 0; i < num_clips; i++) {
> +		ret = ast_handle_damage(fb, clips[i].x1, clips[i].y1,
> +				clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1);
> +		if (ret)
> +			break;
> +	}
> +
> +	if (fb->obj[0]->dma_buf) {
> +		dma_buf_end_cpu_access(fb->obj[0]->dma_buf,
> +				DMA_FROM_DEVICE);
> +	}
> +
> +unlock:
> +	drm_modeset_unlock_all(fb->dev);
> +
> +	return ret;
> +}
> +
> +static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
> +{
> +	struct iosys_map dmabuf_map;
> +
> +	if (fb->obj[0]->dma_buf) {
> +		dmabuf_map.is_iomem = fb->obj[0]->dma_buf->vmap_ptr.is_iomem;
> +		dmabuf_map.vaddr = fb->obj[0]->dma_buf->vmap_ptr.vaddr;
> +		if (dmabuf_map.vaddr)
> +			dma_buf_vunmap(fb->obj[0]->dma_buf, &dmabuf_map);
> +		drm_gem_unpin(fb->obj[0]->dma_buf->priv);
> +	}
> +
> +	drm_gem_fb_destroy(fb);
> +}
> +
> +static const struct drm_framebuffer_funcs ast_gem_fb_funcs_dirtyfb = {
> +	.destroy	= ast_user_framebuffer_destroy,
> +	.create_handle	= drm_gem_fb_create_handle,
> +	.dirty		= ast_user_framebuffer_dirty,
> +};
> +
> +static struct drm_framebuffer *
> +ast_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
> +				const struct drm_mode_fb_cmd2 *mode_cmd)
> +{
> +	return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
> +					&ast_gem_fb_funcs_dirtyfb);
> +}
> +
>   static const struct drm_mode_config_funcs ast_mode_config_funcs = {
> -	.fb_create = drm_gem_fb_create,
> +	.fb_create = ast_gem_fb_create_with_dirty,
>   	.mode_valid = drm_vram_helper_mode_valid,
>   	.atomic_check = drm_atomic_helper_check,
>   	.atomic_commit = drm_atomic_helper_commit,
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 56fb87885146..3a4f5137abc5 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -1159,12 +1159,14 @@ int drm_gem_pin(struct drm_gem_object *obj)
>   	else
>   		return 0;
>   }
> +EXPORT_SYMBOL(drm_gem_pin);
>   
>   void drm_gem_unpin(struct drm_gem_object *obj)
>   {
>   	if (obj->funcs->unpin)
>   		obj->funcs->unpin(obj);
>   }
> +EXPORT_SYMBOL(drm_gem_unpin);
>   
>   int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
>   {
> diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> index e2941cee14b6..30c4366968bf 100644
> --- a/include/drm/drm_gem.h
> +++ b/include/drm/drm_gem.h
> @@ -352,6 +352,9 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
>   		     struct vm_area_struct *vma);
>   int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
>   
> +int drm_gem_pin(struct drm_gem_object *obj);
> +void drm_gem_unpin(struct drm_gem_object *obj);
> +
>   /**
>    * drm_gem_object_get - acquire a GEM buffer object reference
>    * @obj: GEM buffer object


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] drm/ast: add dmabuf/prime buffer sharing support
@ 2022-08-15  8:14 oushixiong
  0 siblings, 0 replies; 6+ messages in thread
From: oushixiong @ 2022-08-15  8:14 UTC (permalink / raw)
  To: Dave Airlie
  Cc: oushixiong, Thomas Zimmermann, David Airlie, dri-devel,
	Sumit Semwal, linaro-mm-sig, kernel test robot,
	Christian König, linux-media

This patch adds ast specific codes for DRM prime feature.
Add the prime function to solve the xorg conflict problem when AST
and AMD are in place at the same time, so that both can be displayed.

Signed-off-by: oushixiong <oushixiong@kylinos.cn>
Reported-by: kernel test robot <lkp@intel.com>
---
 drivers/gpu/drm/ast/ast_drv.c  |  22 ++++++
 drivers/gpu/drm/ast/ast_mode.c | 125 ++++++++++++++++++++++++++++++++-
 2 files changed, 146 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 7465c4f0156a..6c1f75174368 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/dma-buf.h>
 
 #include <drm/drm_aperture.h>
 #include <drm/drm_atomic_helper.h>
@@ -50,6 +51,23 @@ module_param_named(modeset, ast_modeset, int, 0400);
 
 DEFINE_DRM_GEM_FOPS(ast_fops);
 
+static struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
+					struct dma_buf_attachment *attach,
+					struct sg_table *sg)
+{
+	struct drm_gem_vram_object *gbo;
+	struct dma_resv *resv = attach->dmabuf->resv;
+
+	ww_mutex_lock(&resv->lock, NULL);
+	gbo = drm_gem_vram_create(dev, attach->dmabuf->size, 0);
+	ww_mutex_unlock(&resv->lock);
+
+	if (IS_ERR(gbo))
+		return NULL;
+
+	return &gbo->bo.base;
+}
+
 static const struct drm_driver ast_driver = {
 	.driver_features = DRIVER_ATOMIC |
 			   DRIVER_GEM |
@@ -63,6 +81,10 @@ static const struct drm_driver ast_driver = {
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
 
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_import_sg_table = ast_gem_prime_import_sg_table,
+
 	DRM_GEM_VRAM_DRIVER
 };
 
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 45b56b39ad47..ebe732705e34 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -48,6 +48,8 @@
 #include "ast_drv.h"
 #include "ast_tables.h"
 
+MODULE_IMPORT_NS(DMA_BUF);
+
 static inline void ast_load_palette_index(struct ast_private *ast,
 				     u8 index, u8 red, u8 green,
 				     u8 blue)
@@ -1535,8 +1537,129 @@ static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs =
 	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+static int ast_handle_damage(struct drm_framebuffer *fb, int x, int y,
+					int width, int height)
+{
+	struct drm_gem_vram_object *dst_bo = NULL;
+	void *dst = NULL;
+	int ret = 0, i;
+	unsigned long offset = 0;
+	bool unmap = false;
+	unsigned int bytesPerPixel;
+	struct iosys_map map;
+	struct iosys_map dmabuf_map;
+
+	bytesPerPixel = fb->format->cpp[0];
+
+	if (!fb->obj[0]->import_attach)
+		return -EINVAL;
+
+	if (!fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr) {
+		ret = dma_buf_vmap(fb->obj[0]->import_attach->dmabuf, &dmabuf_map);
+		if (ret)
+			return 0;
+	} else
+		dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr;
+
+	dst_bo = drm_gem_vram_of_gem(fb->obj[0]);
+
+	ret = drm_gem_vram_pin(dst_bo, 0);
+	if (ret) {
+		DRM_ERROR("ast_bo_pin failed\n");
+		goto error;
+	}
+
+	if (!dst_bo->map.vaddr) {
+		ret = drm_gem_vram_vmap(dst_bo, &map);
+		if (ret) {
+			DRM_ERROR("failed to vmap fbcon\n");
+			drm_gem_vram_unpin(dst_bo);
+			goto error;
+		}
+		unmap = true;
+	}
+	dst = dst_bo->map.vaddr;
+
+	for (i = y; i < y + height; i++) {
+		offset = i * fb->pitches[0] + (x * bytesPerPixel);
+		memcpy_toio(dst + offset, dmabuf_map.vaddr + offset,
+			width * bytesPerPixel);
+	}
+
+	if (unmap)
+		drm_gem_vram_vunmap(dst_bo, &map);
+
+	drm_gem_vram_unpin(dst_bo);
+error:
+	return 0;
+}
+
+
+static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
+				struct drm_file *file,
+				unsigned int flags,
+				unsigned int color,
+				struct drm_clip_rect *clips,
+				unsigned int num_clips)
+{
+	int i, ret = 0;
+
+	drm_modeset_lock_all(fb->dev);
+	if (fb->obj[0]->import_attach) {
+		ret = dma_buf_begin_cpu_access(fb->obj[0]->import_attach->dmabuf,
+				DMA_FROM_DEVICE);
+		if (ret)
+			goto unlock;
+	}
+
+	for (i = 0; i < num_clips; i++) {
+		ret = ast_handle_damage(fb, clips[i].x1, clips[i].y1,
+				clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1);
+		if (ret)
+			break;
+	}
+
+	if (fb->obj[0]->import_attach) {
+		dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,
+				DMA_FROM_DEVICE);
+	}
+
+unlock:
+	drm_modeset_unlock_all(fb->dev);
+
+	return ret;
+}
+
+static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+	struct iosys_map dmabuf_map;
+
+	if (fb->obj[0]->import_attach) {
+		dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr;
+		if (dmabuf_map.vaddr)
+			dma_buf_vunmap(fb->obj[0]->import_attach->dmabuf,
+					&dmabuf_map);
+	}
+
+	drm_gem_fb_destroy(fb);
+}
+
+static const struct drm_framebuffer_funcs ast_gem_fb_funcs_dirtyfb = {
+	.destroy	= ast_user_framebuffer_destroy,
+	.create_handle	= drm_gem_fb_create_handle,
+	.dirty		= ast_user_framebuffer_dirty,
+};
+
+static struct drm_framebuffer *
+ast_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
+				const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
+					&ast_gem_fb_funcs_dirtyfb);
+}
+
 static const struct drm_mode_config_funcs ast_mode_config_funcs = {
-	.fb_create = drm_gem_fb_create,
+	.fb_create = ast_gem_fb_create_with_dirty,
 	.mode_valid = drm_vram_helper_mode_valid,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
-- 
2.17.1


No virus found
		Checked by Hillstone Network AntiVirus

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] drm/ast: add dmabuf/prime buffer sharing support
@ 2022-08-10 12:41 oushixiong
  0 siblings, 0 replies; 6+ messages in thread
From: oushixiong @ 2022-08-10 12:41 UTC (permalink / raw)
  To: Dave Airlie; +Cc: David Airlie, oushixiong, dri-devel, Thomas Zimmermann

This patch adds ast specific codes for DRM prime feature.
Add the prime function to solve the xorg conflict problem when AST
and AMD are in place at the same time, so that both can be displayed.

Signed-off-by: oushixiong <oushixiong@kylinos.cn>
---
 drivers/gpu/drm/ast/ast_drv.c  |  22 +++++++
 drivers/gpu/drm/ast/ast_mode.c | 112 ++++++++++++++++++++++++++++++++-
 2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 7465c4f0156a..6f0c0992c2f0 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/dma-buf.h>
 
 #include <drm/drm_aperture.h>
 #include <drm/drm_atomic_helper.h>
@@ -50,6 +51,23 @@ module_param_named(modeset, ast_modeset, int, 0400);
 
 DEFINE_DRM_GEM_FOPS(ast_fops);
 
+struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
+					struct dma_buf_attachment *attach,
+					struct sg_table *sg)
+{
+	struct drm_gem_vram_object *gbo;
+	struct dma_resv *resv = attach->dmabuf->resv;
+
+	ww_mutex_lock(&resv->lock, NULL);
+	gbo = drm_gem_vram_create(dev, attach->dmabuf->size, 0);
+	ww_mutex_unlock(&resv->lock);
+
+	if (IS_ERR(gbo))
+		return NULL;
+
+	return &gbo->bo.base;
+}
+
 static const struct drm_driver ast_driver = {
 	.driver_features = DRIVER_ATOMIC |
 			   DRIVER_GEM |
@@ -63,6 +81,10 @@ static const struct drm_driver ast_driver = {
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
 
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_import_sg_table = ast_gem_prime_import_sg_table,
+
 	DRM_GEM_VRAM_DRIVER
 };
 
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 45b56b39ad47..213ab5df634c 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -48,6 +48,8 @@
 #include "ast_drv.h"
 #include "ast_tables.h"
 
+MODULE_IMPORT_NS(DMA_BUF);
+
 static inline void ast_load_palette_index(struct ast_private *ast,
 				     u8 index, u8 red, u8 green,
 				     u8 blue)
@@ -1535,8 +1537,116 @@ static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs =
 	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+int ast_handle_damage(struct drm_framebuffer *fb, int x, int y,
+					int width, int height)
+{
+	struct drm_gem_vram_object *dst_bo = NULL;
+	void *dst = NULL;
+	int ret = 0, i;
+	unsigned long offset = 0;
+	bool unmap = false;
+	unsigned int bytesPerPixel;
+	struct iosys_map map;
+	struct iosys_map dmabuf_map;
+
+	bytesPerPixel = fb->format->cpp[0];
+
+	if (!fb->obj[0]->import_attach)
+		return -EINVAL;
+
+	if (!fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr) {
+		ret = dma_buf_vmap(fb->obj[0]->import_attach->dmabuf, &dmabuf_map);
+		if (ret)
+			return 0;
+	} else {
+		dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr;
+	}
+
+	dst_bo = drm_gem_vram_of_gem(fb->obj[0]);
+
+	ret = drm_gem_vram_pin(dst_bo, 0);
+	if (ret) {
+		DRM_ERROR("ast_bo_pin failed\n");
+		goto error;
+	}
+
+	if (!dst_bo->map.vaddr) {
+		ret = drm_gem_vram_vmap(dst_bo, &map);
+		if (ret) {
+			DRM_ERROR("failed to vmap fbcon\n");
+			drm_gem_vram_unpin(dst_bo);
+			goto error;
+		}
+		unmap = true;
+	}
+	dst = dst_bo->map.vaddr;
+
+	for (i = y; i < y + height; i++) {
+		offset = i * fb->pitches[0] + (x * bytesPerPixel);
+		memcpy_toio(dst + offset, dmabuf_map.vaddr + offset,
+			width * bytesPerPixel);
+	}
+
+	if (unmap)
+		drm_gem_vram_vunmap(dst_bo, &map);
+
+	drm_gem_vram_unpin(dst_bo);
+error:
+	return 0;
+}
+
+
+int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
+				struct drm_file *file,
+				unsigned int flags,
+				unsigned int color,
+				struct drm_clip_rect *clips,
+				unsigned int num_clips)
+{
+	int i, ret = 0;
+
+	drm_modeset_lock_all(fb->dev);
+	if (fb->obj[0]->import_attach) {
+		ret = dma_buf_begin_cpu_access(fb->obj[0]->import_attach->dmabuf,
+				DMA_FROM_DEVICE);
+		if (ret)
+			goto unlock;
+	}
+
+	for (i = 0; i < num_clips; i++) {
+		ret = ast_handle_damage(fb, clips[i].x1, clips[i].y1,
+				clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1);
+		if (ret)
+			break;
+	}
+
+	if (fb->obj[0]->import_attach) {
+		dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,
+				DMA_FROM_DEVICE);
+	}
+
+unlock:
+	drm_modeset_unlock_all(fb->dev);
+
+	return ret;
+}
+
+static const struct drm_framebuffer_funcs ast_gem_fb_funcs_dirtyfb = {
+	.destroy	= drm_gem_fb_destroy,
+	.create_handle	= drm_gem_fb_create_handle,
+	.dirty		= ast_user_framebuffer_dirty,
+};
+
+struct drm_framebuffer *
+ast_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
+				const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
+					&ast_gem_fb_funcs_dirtyfb);
+}
+
 static const struct drm_mode_config_funcs ast_mode_config_funcs = {
-	.fb_create = drm_gem_fb_create,
+	.fb_create = ast_gem_fb_create_with_dirty,
 	.mode_valid = drm_vram_helper_mode_valid,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
-- 
2.17.1


No virus found
		Checked by Hillstone Network AntiVirus

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] drm/ast: add dmabuf/prime buffer sharing support
  2022-07-18  1:45 oushixiong
@ 2022-07-18  9:32 ` Thomas Zimmermann
  0 siblings, 0 replies; 6+ messages in thread
From: Thomas Zimmermann @ 2022-07-18  9:32 UTC (permalink / raw)
  To: oushixiong, Dave Airlie; +Cc: David Airlie, linux-kernel, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 13610 bytes --]

Hi

Am 18.07.22 um 03:45 schrieb oushixiong:
> This patch adds ast specific codes for DRM Prime feature.
> User application can get file descriptor from gem handle and also
> gem handle from file descriptor.this is to allow for offloading
> of rendering in one direction and outputs in the other.
> 
> Signed-off-by: oushixiong <oushixiong@kylinos.cn>
> ---
>   drivers/gpu/drm/ast/ast_drv.c  |  16 +++-
>   drivers/gpu/drm/ast/ast_drv.h  |  19 ++++-
>   drivers/gpu/drm/ast/ast_main.c | 115 ++++++++++++++++++++++++++++-
>   drivers/gpu/drm/ast/ast_ttm.c  | 130 ++++++++++++++++++++++++++++++++-

Your copy of the source code is way too old. Some of these files have 
been remove years ago. The most recent development tree is drm-tip at

   https://cgit.freedesktop.org/drm/drm-tip/

Best regards
Thomas

>   4 files changed, 273 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> index bf589c53b908..084d0c8b0f6b 100644
> --- a/drivers/gpu/drm/ast/ast_drv.c
> +++ b/drivers/gpu/drm/ast/ast_drv.c
> @@ -214,7 +214,7 @@ static const struct file_operations ast_fops = {
>   };
>   
>   static struct drm_driver driver = {
> -	.driver_features = DRIVER_MODESET | DRIVER_GEM,
> +	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
>   
>   	.load = ast_driver_load,
>   	.unload = ast_driver_unload,
> @@ -231,6 +231,20 @@ static struct drm_driver driver = {
>   	.dumb_create = ast_dumb_create,
>   	.dumb_map_offset = ast_dumb_mmap_offset,
>   
> +	.prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
> +	.prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
> +	.gem_prime_import       = drm_gem_prime_import,
> +	.gem_prime_export       = drm_gem_prime_export,
> +
> +	.gem_prime_get_sg_table = ast_gem_prime_get_sg_table,
> +	.gem_prime_import_sg_table = ast_gem_prime_import_sg_table,
> +	.gem_prime_vmap         = ast_gem_prime_vmap,
> +	.gem_prime_vunmap       = ast_gem_prime_vunmap,
> +	.gem_prime_pin          = ast_gem_prime_pin,
> +	.gem_prime_unpin        = ast_gem_prime_unpin,
> +
> +	.gem_prime_res_obj = ast_gem_prime_res_obj,
> +
>   };
>   
>   static int __init ast_init(void)
> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
> index e6c4cd3dc50e..b19b9aa5a517 100644
> --- a/drivers/gpu/drm/ast/ast_drv.h
> +++ b/drivers/gpu/drm/ast/ast_drv.h
> @@ -258,6 +258,7 @@ struct ast_encoder {
>   struct ast_framebuffer {
>   	struct drm_framebuffer base;
>   	struct drm_gem_object *obj;
> +	void *vmapping;
>   };
>   
>   struct ast_fbdev {
> @@ -330,6 +331,7 @@ struct ast_bo {
>   	struct drm_gem_object gem;
>   	struct ttm_place placements[3];
>   	int pin_count;
> +	struct ttm_bo_kmap_obj dma_buf_vmap;
>   };
>   #define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem)
>   
> @@ -361,7 +363,9 @@ int ast_mm_init(struct ast_private *ast);
>   void ast_mm_fini(struct ast_private *ast);
>   
>   int ast_bo_create(struct drm_device *dev, int size, int align,
> -		  uint32_t flags, struct ast_bo **pastbo);
> +		uint32_t flags, struct sg_table *sg,
> +		struct reservation_object *resv,
> +		struct ast_bo **pastbo);
>   
>   int ast_gem_create(struct drm_device *dev,
>   		   u32 size, bool iskernel,
> @@ -369,6 +373,19 @@ int ast_gem_create(struct drm_device *dev,
>   
>   int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr);
>   int ast_bo_unpin(struct ast_bo *bo);
> +struct sg_table *ast_gem_prime_get_sg_table(struct drm_gem_object *obj);
> +void *ast_gem_prime_vmap(struct drm_gem_object *obj);
> +void ast_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
> +
> +struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
> +			struct dma_buf_attachment *attach,
> +			struct sg_table *sg);
> +
> +int ast_gem_prime_pin(struct drm_gem_object *obj);
> +void ast_gem_prime_unpin(struct drm_gem_object *obj);
> +
> +struct reservation_object *ast_gem_prime_res_obj(struct drm_gem_object *obj);
> +
>   
>   static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
>   {
> diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
> index 224fa1ef87ff..6f8fc49b062c 100644
> --- a/drivers/gpu/drm/ast/ast_main.c
> +++ b/drivers/gpu/drm/ast/ast_main.c
> @@ -28,7 +28,7 @@
>   #include <drm/drmP.h>
>   #include "ast_drv.h"
>   
> -
> +#include <linux/dma-buf.h>
>   #include <drm/drm_fb_helper.h>
>   #include <drm/drm_crtc_helper.h>
>   
> @@ -383,17 +383,125 @@ static int ast_get_dram_info(struct drm_device *dev)
>   	return 0;
>   }
>   
> +int ast_handle_damage(struct ast_framebuffer *fb, int x, int y,
> +			int width, int height)
> +{
> +	struct ast_bo *dst_bo = NULL;
> +	void *dst = NULL;
> +	int ret = 0, i;
> +	unsigned long offset = 0;
> +	bool unmap = false;
> +	unsigned int bytesPerPixel;
> +
> +	bytesPerPixel = fb->base.format->cpp[0];
> +
> +	if (!fb->obj->import_attach)
> +		return -EINVAL;
> +
> +	if (!fb->vmapping) {
> +		fb->vmapping = dma_buf_vmap(fb->obj->import_attach->dmabuf);
> +		if (!fb->vmapping)
> +			return 0;
> +	}
> +	dst_bo = gem_to_ast_bo(fb->obj);
> +	ret = ast_bo_reserve(dst_bo, true);
> +	if (ret) {
> +		DRM_ERROR("ast_bo_reserve failed\n");
> +		ast_bo_unreserve(dst_bo);
> +		goto error;
> +	}
> +	if (!dst_bo->dma_buf_vmap.virtual) {
> +		ret = ttm_bo_kmap(&dst_bo->bo, 0,
> +			dst_bo->bo.num_pages, &dst_bo->dma_buf_vmap);
> +		if (ret) {
> +			DRM_ERROR("failed to kmap fbcon\n");
> +			goto error;
> +		}
> +		unmap = true;
> +	}
> +	dst = dst_bo->dma_buf_vmap.virtual;
> +
> +	for (i = y; i < y + height; i++) {
> +		offset = i * fb->base.pitches[0] + (x * bytesPerPixel);
> +		memcpy_toio(dst + offset, fb->vmapping + offset,
> +			width * bytesPerPixel);
> +	}
> +
> +	if (unmap)
> +		ttm_bo_kunmap(&dst_bo->dma_buf_vmap);
> +	ast_bo_unreserve(dst_bo);
> +
> +error:
> +	return 0;
> +}
> +
>   static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
>   {
>   	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
>   
> +	if (ast_fb->obj->import_attach) {
> +		if (ast_fb->vmapping)
> +			dma_buf_vunmap(ast_fb->obj->import_attach->dmabuf,
> +				ast_fb->vmapping);
> +	}
> +
>   	drm_gem_object_put_unlocked(ast_fb->obj);
>   	drm_framebuffer_cleanup(fb);
>   	kfree(ast_fb);
>   }
>   
> +static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
> +				struct drm_file *file,
> +				unsigned int flags,
> +				unsigned int color,
> +				struct drm_clip_rect *clips,
> +				unsigned int num_clips)
> +{
> +	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
> +	int i, ret = 0;
> +
> +	drm_modeset_lock_all(fb->dev);
> +
> +	if (ast_fb->obj->import_attach) {
> +		ret = dma_buf_begin_cpu_access(
> +				ast_fb->obj->import_attach->dmabuf,
> +				DMA_FROM_DEVICE);
> +		if (ret)
> +			goto unlock;
> +		}
> +
> +	for (i = 0; i < num_clips; i++) {
> +		ret = ast_handle_damage(ast_fb, clips[i].x1, clips[i].y1,
> +			clips[i].x2 - clips[i].x1,
> +			clips[i].y2 - clips[i].y1);
> +		if (ret)
> +			break;
> +	}
> +
> +	if (ast_fb->obj->import_attach) {
> +		dma_buf_end_cpu_access(ast_fb->obj->import_attach->dmabuf,
> +			DMA_FROM_DEVICE);
> +	}
> +
> +unlock:
> +	drm_modeset_unlock_all(fb->dev);
> +
> +	return ret;
> +}
> +
> +static int ast_user_framebuffer_create_handle(struct drm_framebuffer *fb,
> +			struct drm_file *file_priv,
> +			unsigned int *handle)
> +{
> +	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
> +
> +	return drm_gem_handle_create(file_priv, ast_fb->obj, handle);
> +}
> +
>   static const struct drm_framebuffer_funcs ast_fb_funcs = {
> +	.create_handle = ast_user_framebuffer_create_handle,
>   	.destroy = ast_user_framebuffer_destroy,
> +	.dirty = ast_user_framebuffer_dirty,
>   };
>   
>   
> @@ -605,7 +713,7 @@ int ast_gem_create(struct drm_device *dev,
>   	if (size == 0)
>   		return -EINVAL;
>   
> -	ret = ast_bo_create(dev, size, 0, 0, &astbo);
> +	ret = ast_bo_create(dev, size, 0, 0, NULL, NULL, &astbo);
>   	if (ret) {
>   		if (ret != -ERESTARTSYS)
>   			DRM_ERROR("failed to allocate GEM object\n");
> @@ -656,6 +764,9 @@ void ast_gem_free_object(struct drm_gem_object *obj)
>   {
>   	struct ast_bo *ast_bo = gem_to_ast_bo(obj);
>   
> +	if (ast_bo->gem.import_attach)
> +		drm_prime_gem_destroy(&ast_bo->gem, ast_bo->bo.sg);
> +
>   	ast_bo_unref(&ast_bo);
>   }
>   
> diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
> index fe354ebf374d..fea0429407e0 100644
> --- a/drivers/gpu/drm/ast/ast_ttm.c
> +++ b/drivers/gpu/drm/ast/ast_ttm.c
> @@ -27,6 +27,7 @@
>    */
>   #include <drm/drmP.h>
>   #include <drm/ttm/ttm_page_alloc.h>
> +#include <linux/dma-buf.h>
>   
>   #include "ast_drv.h"
>   
> @@ -215,8 +216,38 @@ static struct ttm_tt *ast_ttm_tt_create(struct ttm_buffer_object *bo,
>   	return tt;
>   }
>   
> +static int ast_ttm_tt_populate(struct ttm_tt *ttm,
> +			struct ttm_operation_ctx *ctx)
> +{
> +	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
> +
> +	if (ttm->state != tt_unpopulated)
> +		return 0;
> +
> +	if (slave && ttm->sg) {
> +		drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> +				NULL, ttm->num_pages);
> +		ttm->state = tt_unbound;
> +		return 0;
> +	}
> +
> +	return ttm_pool_populate(ttm, ctx);
> +}
> +
> +static void ast_ttm_tt_unpopulate(struct ttm_tt *ttm)
> +{
> +	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
> +
> +	if (slave)
> +		return;
> +
> +	ttm_pool_unpopulate(ttm);
> +}
> +
>   struct ttm_bo_driver ast_bo_driver = {
>   	.ttm_tt_create = ast_ttm_tt_create,
> +	.ttm_tt_populate = ast_ttm_tt_populate,
> +	.ttm_tt_unpopulate = ast_ttm_tt_unpopulate,
>   	.init_mem_type = ast_bo_init_mem_type,
>   	.eviction_valuable = ttm_bo_eviction_valuable,
>   	.evict_flags = ast_bo_evict_flags,
> @@ -297,13 +328,21 @@ void ast_ttm_placement(struct ast_bo *bo, int domain)
>   }
>   
>   int ast_bo_create(struct drm_device *dev, int size, int align,
> -		  uint32_t flags, struct ast_bo **pastbo)
> +		  uint32_t flags, struct sg_table *sg,
> +		  struct reservation_object *resv,
> +		  struct ast_bo **pastbo)
>   {
>   	struct ast_private *ast = dev->dev_private;
>   	struct ast_bo *astbo;
>   	size_t acc_size;
> +	enum ttm_bo_type type;
>   	int ret;
>   
> +	if (sg)
> +		type = ttm_bo_type_sg;
> +	else
> +		type = ttm_bo_type_device;
> +
>   	astbo = kzalloc(sizeof(struct ast_bo), GFP_KERNEL);
>   	if (!astbo)
>   		return -ENOMEM;
> @@ -320,9 +359,9 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
>   				       sizeof(struct ast_bo));
>   
>   	ret = ttm_bo_init(&ast->ttm.bdev, &astbo->bo, size,
> -			  ttm_bo_type_device, &astbo->placement,
> +			  type, &astbo->placement,
>   			  align >> PAGE_SHIFT, false, acc_size,
> -			  NULL, NULL, ast_bo_ttm_destroy);
> +			  sg, resv, ast_bo_ttm_destroy);
>   	if (ret)
>   		goto error;
>   
> @@ -418,3 +457,88 @@ int ast_mmap(struct file *filp, struct vm_area_struct *vma)
>   	ast = file_priv->minor->dev->dev_private;
>   	return ttm_bo_mmap(filp, vma, &ast->ttm.bdev);
>   }
> +
> +struct sg_table *ast_gem_prime_get_sg_table(struct drm_gem_object *obj)
> +{
> +	struct ast_bo *bo = gem_to_ast_bo(obj);
> +	int npages = bo->bo.num_pages;
> +
> +	return drm_prime_pages_to_sg(bo->bo.ttm->pages, npages);
> +}
> +
> +void *ast_gem_prime_vmap(struct drm_gem_object *obj)
> +{
> +	struct ast_bo *bo = gem_to_ast_bo(obj);
> +	int ret;
> +
> +	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
> +			&bo->dma_buf_vmap);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	return bo->dma_buf_vmap.virtual;
> +}
> +
> +void ast_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
> +{
> +	struct ast_bo *bo = gem_to_ast_bo(obj);
> +
> +	ttm_bo_kunmap(&bo->dma_buf_vmap);
> +}
> +
> +struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
> +				struct dma_buf_attachment *attach,
> +				struct sg_table *sg)
> +{
> +	struct ast_bo *bo;
> +	int ret;
> +
> +	struct reservation_object *resv = attach->dmabuf->resv;
> +
> +	ww_mutex_lock(&resv->lock, NULL);
> +	ret = ast_bo_create(dev, attach->dmabuf->size,
> +			PAGE_SIZE, 0, sg, resv, &bo);
> +	ww_mutex_unlock(&resv->lock);
> +
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	return &bo->gem;
> +}
> +
> +int ast_gem_prime_pin(struct drm_gem_object *obj)
> +{
> +	struct ast_bo *bo  = gem_to_ast_bo(obj);
> +	int ret = 0;
> +
> +	ret = ast_bo_reserve(bo, false);
> +	if (unlikely(ret != 0))
> +		return ret;
> +
> +	/* pin buffer into GTT */
> +	ret = ast_bo_pin(bo, TTM_PL_FLAG_SYSTEM, NULL);
> +	ast_bo_unreserve(bo);
> +
> +	return ret;
> +}
> +
> +void ast_gem_prime_unpin(struct drm_gem_object *obj)
> +{
> +	struct ast_bo *bo = gem_to_ast_bo(obj);
> +	int ret = 0;
> +
> +	ret = ast_bo_reserve(bo, false);
> +	if (unlikely(ret != 0))
> +		return;
> +
> +	ast_bo_unpin(bo);
> +	ast_bo_unreserve(bo);
> +}
> +
> +struct reservation_object *ast_gem_prime_res_obj(struct drm_gem_object *obj)
> +{
> +	struct ast_bo *bo = gem_to_ast_bo(obj);
> +
> +	return bo->bo.resv;
> +}
> +

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] drm/ast: add dmabuf/prime buffer sharing support
@ 2022-07-18  1:45 oushixiong
  2022-07-18  9:32 ` Thomas Zimmermann
  0 siblings, 1 reply; 6+ messages in thread
From: oushixiong @ 2022-07-18  1:45 UTC (permalink / raw)
  To: Dave Airlie; +Cc: David Airlie, oushixiong, linux-kernel, dri-devel

This patch adds ast specific codes for DRM Prime feature.
User application can get file descriptor from gem handle and also
gem handle from file descriptor.this is to allow for offloading
of rendering in one direction and outputs in the other.

Signed-off-by: oushixiong <oushixiong@kylinos.cn>
---
 drivers/gpu/drm/ast/ast_drv.c  |  16 +++-
 drivers/gpu/drm/ast/ast_drv.h  |  19 ++++-
 drivers/gpu/drm/ast/ast_main.c | 115 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/ast/ast_ttm.c  | 130 ++++++++++++++++++++++++++++++++-
 4 files changed, 273 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index bf589c53b908..084d0c8b0f6b 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -214,7 +214,7 @@ static const struct file_operations ast_fops = {
 };
 
 static struct drm_driver driver = {
-	.driver_features = DRIVER_MODESET | DRIVER_GEM,
+	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
 
 	.load = ast_driver_load,
 	.unload = ast_driver_unload,
@@ -231,6 +231,20 @@ static struct drm_driver driver = {
 	.dumb_create = ast_dumb_create,
 	.dumb_map_offset = ast_dumb_mmap_offset,
 
+	.prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
+	.gem_prime_import       = drm_gem_prime_import,
+	.gem_prime_export       = drm_gem_prime_export,
+
+	.gem_prime_get_sg_table = ast_gem_prime_get_sg_table,
+	.gem_prime_import_sg_table = ast_gem_prime_import_sg_table,
+	.gem_prime_vmap         = ast_gem_prime_vmap,
+	.gem_prime_vunmap       = ast_gem_prime_vunmap,
+	.gem_prime_pin          = ast_gem_prime_pin,
+	.gem_prime_unpin        = ast_gem_prime_unpin,
+
+	.gem_prime_res_obj = ast_gem_prime_res_obj,
+
 };
 
 static int __init ast_init(void)
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index e6c4cd3dc50e..b19b9aa5a517 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -258,6 +258,7 @@ struct ast_encoder {
 struct ast_framebuffer {
 	struct drm_framebuffer base;
 	struct drm_gem_object *obj;
+	void *vmapping;
 };
 
 struct ast_fbdev {
@@ -330,6 +331,7 @@ struct ast_bo {
 	struct drm_gem_object gem;
 	struct ttm_place placements[3];
 	int pin_count;
+	struct ttm_bo_kmap_obj dma_buf_vmap;
 };
 #define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem)
 
@@ -361,7 +363,9 @@ int ast_mm_init(struct ast_private *ast);
 void ast_mm_fini(struct ast_private *ast);
 
 int ast_bo_create(struct drm_device *dev, int size, int align,
-		  uint32_t flags, struct ast_bo **pastbo);
+		uint32_t flags, struct sg_table *sg,
+		struct reservation_object *resv,
+		struct ast_bo **pastbo);
 
 int ast_gem_create(struct drm_device *dev,
 		   u32 size, bool iskernel,
@@ -369,6 +373,19 @@ int ast_gem_create(struct drm_device *dev,
 
 int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr);
 int ast_bo_unpin(struct ast_bo *bo);
+struct sg_table *ast_gem_prime_get_sg_table(struct drm_gem_object *obj);
+void *ast_gem_prime_vmap(struct drm_gem_object *obj);
+void ast_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+
+struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
+			struct dma_buf_attachment *attach,
+			struct sg_table *sg);
+
+int ast_gem_prime_pin(struct drm_gem_object *obj);
+void ast_gem_prime_unpin(struct drm_gem_object *obj);
+
+struct reservation_object *ast_gem_prime_res_obj(struct drm_gem_object *obj);
+
 
 static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
 {
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 224fa1ef87ff..6f8fc49b062c 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -28,7 +28,7 @@
 #include <drm/drmP.h>
 #include "ast_drv.h"
 
-
+#include <linux/dma-buf.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 
@@ -383,17 +383,125 @@ static int ast_get_dram_info(struct drm_device *dev)
 	return 0;
 }
 
+int ast_handle_damage(struct ast_framebuffer *fb, int x, int y,
+			int width, int height)
+{
+	struct ast_bo *dst_bo = NULL;
+	void *dst = NULL;
+	int ret = 0, i;
+	unsigned long offset = 0;
+	bool unmap = false;
+	unsigned int bytesPerPixel;
+
+	bytesPerPixel = fb->base.format->cpp[0];
+
+	if (!fb->obj->import_attach)
+		return -EINVAL;
+
+	if (!fb->vmapping) {
+		fb->vmapping = dma_buf_vmap(fb->obj->import_attach->dmabuf);
+		if (!fb->vmapping)
+			return 0;
+	}
+	dst_bo = gem_to_ast_bo(fb->obj);
+	ret = ast_bo_reserve(dst_bo, true);
+	if (ret) {
+		DRM_ERROR("ast_bo_reserve failed\n");
+		ast_bo_unreserve(dst_bo);
+		goto error;
+	}
+	if (!dst_bo->dma_buf_vmap.virtual) {
+		ret = ttm_bo_kmap(&dst_bo->bo, 0,
+			dst_bo->bo.num_pages, &dst_bo->dma_buf_vmap);
+		if (ret) {
+			DRM_ERROR("failed to kmap fbcon\n");
+			goto error;
+		}
+		unmap = true;
+	}
+	dst = dst_bo->dma_buf_vmap.virtual;
+
+	for (i = y; i < y + height; i++) {
+		offset = i * fb->base.pitches[0] + (x * bytesPerPixel);
+		memcpy_toio(dst + offset, fb->vmapping + offset,
+			width * bytesPerPixel);
+	}
+
+	if (unmap)
+		ttm_bo_kunmap(&dst_bo->dma_buf_vmap);
+	ast_bo_unreserve(dst_bo);
+
+error:
+	return 0;
+}
+
 static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
 	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
 
+	if (ast_fb->obj->import_attach) {
+		if (ast_fb->vmapping)
+			dma_buf_vunmap(ast_fb->obj->import_attach->dmabuf,
+				ast_fb->vmapping);
+	}
+
 	drm_gem_object_put_unlocked(ast_fb->obj);
 	drm_framebuffer_cleanup(fb);
 	kfree(ast_fb);
 }
 
+static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
+				struct drm_file *file,
+				unsigned int flags,
+				unsigned int color,
+				struct drm_clip_rect *clips,
+				unsigned int num_clips)
+{
+	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
+	int i, ret = 0;
+
+	drm_modeset_lock_all(fb->dev);
+
+	if (ast_fb->obj->import_attach) {
+		ret = dma_buf_begin_cpu_access(
+				ast_fb->obj->import_attach->dmabuf,
+				DMA_FROM_DEVICE);
+		if (ret)
+			goto unlock;
+		}
+
+	for (i = 0; i < num_clips; i++) {
+		ret = ast_handle_damage(ast_fb, clips[i].x1, clips[i].y1,
+			clips[i].x2 - clips[i].x1,
+			clips[i].y2 - clips[i].y1);
+		if (ret)
+			break;
+	}
+
+	if (ast_fb->obj->import_attach) {
+		dma_buf_end_cpu_access(ast_fb->obj->import_attach->dmabuf,
+			DMA_FROM_DEVICE);
+	}
+
+unlock:
+	drm_modeset_unlock_all(fb->dev);
+
+	return ret;
+}
+
+static int ast_user_framebuffer_create_handle(struct drm_framebuffer *fb,
+			struct drm_file *file_priv,
+			unsigned int *handle)
+{
+	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
+
+	return drm_gem_handle_create(file_priv, ast_fb->obj, handle);
+}
+
 static const struct drm_framebuffer_funcs ast_fb_funcs = {
+	.create_handle = ast_user_framebuffer_create_handle,
 	.destroy = ast_user_framebuffer_destroy,
+	.dirty = ast_user_framebuffer_dirty,
 };
 
 
@@ -605,7 +713,7 @@ int ast_gem_create(struct drm_device *dev,
 	if (size == 0)
 		return -EINVAL;
 
-	ret = ast_bo_create(dev, size, 0, 0, &astbo);
+	ret = ast_bo_create(dev, size, 0, 0, NULL, NULL, &astbo);
 	if (ret) {
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("failed to allocate GEM object\n");
@@ -656,6 +764,9 @@ void ast_gem_free_object(struct drm_gem_object *obj)
 {
 	struct ast_bo *ast_bo = gem_to_ast_bo(obj);
 
+	if (ast_bo->gem.import_attach)
+		drm_prime_gem_destroy(&ast_bo->gem, ast_bo->bo.sg);
+
 	ast_bo_unref(&ast_bo);
 }
 
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index fe354ebf374d..fea0429407e0 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -27,6 +27,7 @@
  */
 #include <drm/drmP.h>
 #include <drm/ttm/ttm_page_alloc.h>
+#include <linux/dma-buf.h>
 
 #include "ast_drv.h"
 
@@ -215,8 +216,38 @@ static struct ttm_tt *ast_ttm_tt_create(struct ttm_buffer_object *bo,
 	return tt;
 }
 
+static int ast_ttm_tt_populate(struct ttm_tt *ttm,
+			struct ttm_operation_ctx *ctx)
+{
+	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+	if (ttm->state != tt_unpopulated)
+		return 0;
+
+	if (slave && ttm->sg) {
+		drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
+				NULL, ttm->num_pages);
+		ttm->state = tt_unbound;
+		return 0;
+	}
+
+	return ttm_pool_populate(ttm, ctx);
+}
+
+static void ast_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+	if (slave)
+		return;
+
+	ttm_pool_unpopulate(ttm);
+}
+
 struct ttm_bo_driver ast_bo_driver = {
 	.ttm_tt_create = ast_ttm_tt_create,
+	.ttm_tt_populate = ast_ttm_tt_populate,
+	.ttm_tt_unpopulate = ast_ttm_tt_unpopulate,
 	.init_mem_type = ast_bo_init_mem_type,
 	.eviction_valuable = ttm_bo_eviction_valuable,
 	.evict_flags = ast_bo_evict_flags,
@@ -297,13 +328,21 @@ void ast_ttm_placement(struct ast_bo *bo, int domain)
 }
 
 int ast_bo_create(struct drm_device *dev, int size, int align,
-		  uint32_t flags, struct ast_bo **pastbo)
+		  uint32_t flags, struct sg_table *sg,
+		  struct reservation_object *resv,
+		  struct ast_bo **pastbo)
 {
 	struct ast_private *ast = dev->dev_private;
 	struct ast_bo *astbo;
 	size_t acc_size;
+	enum ttm_bo_type type;
 	int ret;
 
+	if (sg)
+		type = ttm_bo_type_sg;
+	else
+		type = ttm_bo_type_device;
+
 	astbo = kzalloc(sizeof(struct ast_bo), GFP_KERNEL);
 	if (!astbo)
 		return -ENOMEM;
@@ -320,9 +359,9 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
 				       sizeof(struct ast_bo));
 
 	ret = ttm_bo_init(&ast->ttm.bdev, &astbo->bo, size,
-			  ttm_bo_type_device, &astbo->placement,
+			  type, &astbo->placement,
 			  align >> PAGE_SHIFT, false, acc_size,
-			  NULL, NULL, ast_bo_ttm_destroy);
+			  sg, resv, ast_bo_ttm_destroy);
 	if (ret)
 		goto error;
 
@@ -418,3 +457,88 @@ int ast_mmap(struct file *filp, struct vm_area_struct *vma)
 	ast = file_priv->minor->dev->dev_private;
 	return ttm_bo_mmap(filp, vma, &ast->ttm.bdev);
 }
+
+struct sg_table *ast_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+	struct ast_bo *bo = gem_to_ast_bo(obj);
+	int npages = bo->bo.num_pages;
+
+	return drm_prime_pages_to_sg(bo->bo.ttm->pages, npages);
+}
+
+void *ast_gem_prime_vmap(struct drm_gem_object *obj)
+{
+	struct ast_bo *bo = gem_to_ast_bo(obj);
+	int ret;
+
+	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
+			&bo->dma_buf_vmap);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return bo->dma_buf_vmap.virtual;
+}
+
+void ast_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+	struct ast_bo *bo = gem_to_ast_bo(obj);
+
+	ttm_bo_kunmap(&bo->dma_buf_vmap);
+}
+
+struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
+				struct dma_buf_attachment *attach,
+				struct sg_table *sg)
+{
+	struct ast_bo *bo;
+	int ret;
+
+	struct reservation_object *resv = attach->dmabuf->resv;
+
+	ww_mutex_lock(&resv->lock, NULL);
+	ret = ast_bo_create(dev, attach->dmabuf->size,
+			PAGE_SIZE, 0, sg, resv, &bo);
+	ww_mutex_unlock(&resv->lock);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &bo->gem;
+}
+
+int ast_gem_prime_pin(struct drm_gem_object *obj)
+{
+	struct ast_bo *bo  = gem_to_ast_bo(obj);
+	int ret = 0;
+
+	ret = ast_bo_reserve(bo, false);
+	if (unlikely(ret != 0))
+		return ret;
+
+	/* pin buffer into GTT */
+	ret = ast_bo_pin(bo, TTM_PL_FLAG_SYSTEM, NULL);
+	ast_bo_unreserve(bo);
+
+	return ret;
+}
+
+void ast_gem_prime_unpin(struct drm_gem_object *obj)
+{
+	struct ast_bo *bo = gem_to_ast_bo(obj);
+	int ret = 0;
+
+	ret = ast_bo_reserve(bo, false);
+	if (unlikely(ret != 0))
+		return;
+
+	ast_bo_unpin(bo);
+	ast_bo_unreserve(bo);
+}
+
+struct reservation_object *ast_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+	struct ast_bo *bo = gem_to_ast_bo(obj);
+
+	return bo->bo.resv;
+}
+
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-08-26  7:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-26  1:31 [PATCH] drm/ast: add dmabuf/prime buffer sharing support oushixiong
2022-08-26  7:29 ` Christian König
  -- strict thread matches above, loose matches on Subject: below --
2022-08-15  8:14 oushixiong
2022-08-10 12:41 oushixiong
2022-07-18  1:45 oushixiong
2022-07-18  9:32 ` Thomas Zimmermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).