From e318dd5d3e8f38910b4a61749c58d9992e717e97 Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Mon, 17 Jul 2023 16:38:34 +0900 Subject: [PATCH] drm/verisilicon: Add cache flush feature when dmabuf sync Add cache flush for gem memory. Cache flushing is done when the dmabuf sync ioctl is called. Change-Id: I8663a391b18bb10f69007bd631fec492c0e347b2 Signed-off-by: Hoegeun Kwon --- drivers/gpu/drm/verisilicon/vs_gem.c | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/verisilicon/vs_gem.c b/drivers/gpu/drm/verisilicon/vs_gem.c index a8d1556..1a3f018 100644 --- a/drivers/gpu/drm/verisilicon/vs_gem.c +++ b/drivers/gpu/drm/verisilicon/vs_gem.c @@ -10,6 +10,10 @@ #include "vs_drv.h" #include "vs_gem.h" +#ifdef CONFIG_SIFIVE_FLUSH +#include +#endif + static const struct drm_gem_object_funcs vs_gem_default_funcs; static int vs_gem_alloc_buf(struct vs_gem_object *vs_obj) @@ -220,6 +224,43 @@ static int vs_gem_mmap_obj(struct drm_gem_object *obj, return ret; } +static int vs_gem_prime_end_cpu_access(struct dma_buf *buf, + enum dma_data_direction direction) +{ +#ifdef CONFIG_SIFIVE_FLUSH + struct drm_gem_object *obj = buf->priv; + struct vs_gem_object *vs_obj = to_vs_gem_object(obj); + + starfive_flush_dcache(vs_obj->dma_addr, vs_obj->size); +#endif + + return 0; +} + +static struct dma_buf_ops vs_gem_prime_dmabuf_ops = { + .cache_sgt_mapping = true, + .attach = drm_gem_map_attach, + .detach = drm_gem_map_detach, + .map_dma_buf = drm_gem_map_dma_buf, + .unmap_dma_buf = drm_gem_unmap_dma_buf, + .release = drm_gem_dmabuf_release, + .mmap = drm_gem_dmabuf_mmap, + .vmap = drm_gem_dmabuf_vmap, + .vunmap = drm_gem_dmabuf_vunmap, + .end_cpu_access = vs_gem_prime_end_cpu_access, +}; + +static struct dma_buf *vs_gem_prime_export(struct drm_gem_object *obj, int flags) +{ + struct dma_buf *dmabuf; + + dmabuf = drm_gem_prime_export(obj, flags); + if (!IS_ERR(dmabuf)) + dmabuf->ops = &vs_gem_prime_dmabuf_ops; + + return dmabuf; +} + struct sg_table *vs_gem_prime_get_sg_table(struct drm_gem_object *obj) { struct vs_gem_object *vs_obj = to_vs_gem_object(obj); @@ -252,6 +293,7 @@ static const struct vm_operations_struct vs_vm_ops = { static const struct drm_gem_object_funcs vs_gem_default_funcs = { .free = vs_gem_free_object, + .export = vs_gem_prime_export, .get_sg_table = vs_gem_prime_get_sg_table, .vmap = vs_gem_prime_vmap, .vunmap = vs_gem_prime_vunmap, @@ -280,6 +322,16 @@ int vs_gem_dumb_create(struct drm_file *file, struct drm_gem_object *vs_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) { + struct drm_gem_object *obj; + + if (dma_buf->ops == &vs_gem_prime_dmabuf_ops) { + obj = dma_buf->priv; + if (obj->dev == dev) { + drm_gem_object_get(obj); + return obj; + } + } + return drm_gem_prime_import_dev(dev, dma_buf, to_dma_dev(dev)); } -- 2.7.4