drm/verisilicon: Add cache flush feature when dmabuf sync
authorHoegeun Kwon <hoegeun.kwon@samsung.com>
Mon, 17 Jul 2023 07:38:34 +0000 (16:38 +0900)
committerJaehoon Chung <jh80.chung@samsung.com>
Mon, 19 Feb 2024 00:13:59 +0000 (09:13 +0900)
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 <hoegeun.kwon@samsung.com>
(cherry picked from commit e318dd5d3e8f38910b4a61749c58d9992e717e97)
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
drivers/gpu/drm/verisilicon/vs_gem.c

index 3f96347..5b76bf6 100644 (file)
 #include "vs_drv.h"
 #include "vs_gem.h"
 
+#ifdef CONFIG_SIFIVE_FLUSH
+#include <soc/sifive/sifive_ccache.h>
+#endif
+
 static const struct drm_gem_object_funcs vs_gem_default_funcs;
 
 static int vs_gem_alloc_buf(struct vs_gem_object *vs_obj)
@@ -219,6 +223,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);
@@ -251,6 +292,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,
@@ -279,6 +321,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));
 }