The GEM CMA helper allocates GEM objects with dma_alloc_writecombine(),
so the objects are cache coherent, and the exporter methods for these
objects can skip cache sync.

To accomplish this a dma atrribute is added to drm_gem_object,
and is used with dma_map_sg_attrs/dma_unmap_sg_attrs in
drm_gem_map_dma_buf/drm_gem_map_detach. GEM CMA sets the attribute
to DMA_ATTR_SKIP_CPU_SYNC when the object is allocated in
drm_gem_cma_create().

Signed-off-by: Steve Longerbeam <steve_longerbeam at mentor.com>
---
 drivers/gpu/drm/drm_gem.c            | 1 +
 drivers/gpu/drm/drm_gem_cma_helper.c | 2 ++
 drivers/gpu/drm/drm_prime.c          | 7 ++++---
 include/drm/drm_gem.h                | 5 +++++
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 16a1647..f7f4531 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -169,6 +169,7 @@ void drm_gem_private_object_init(struct drm_device *dev,
        obj->handle_count = 0;
        obj->size = size;
        drm_vma_node_reset(&obj->vma_node);
+       init_dma_attrs(&obj->dma_attrs);
 }
 EXPORT_SYMBOL(drm_gem_private_object_init);

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index bd75f30..73c949a 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -75,6 +75,8 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size)
                goto error;
        }

+       dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &gem_obj->dma_attrs);
+
        return cma_obj;

 error:
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 9f935f5..9eaa8d3 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -153,8 +153,8 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf,
        sgt = prime_attach->sgt;
        if (sgt) {
                if (prime_attach->dir != DMA_NONE)
-                       dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
-                                       prime_attach->dir);
+                       dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents,
+                                          prime_attach->dir, &obj->dma_attrs);
                sg_free_table(sgt);
        }

@@ -201,7 +201,8 @@ static struct sg_table *drm_gem_map_dma_buf(struct 
dma_buf_attachment *attach,
        sgt = obj->dev->driver->gem_prime_get_sg_table(obj);

        if (!IS_ERR(sgt)) {
-               if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) {
+               if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents,
+                                     dir, &obj->dma_attrs)) {
                        sg_free_table(sgt);
                        kfree(sgt);
                        sgt = ERR_PTR(-ENOMEM);
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 7a592d7..f5546bf 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -104,6 +104,11 @@ struct drm_gem_object {
        struct dma_buf *dma_buf;

        /**
+        * dma_attrs - DMA attributes for this GEM object
+        */
+       struct dma_attrs dma_attrs;
+
+       /**
         * import_attach - dma buf attachment backing this object
         *
         * Any foreign dma_buf imported as a gem object has this set to the
-- 
1.9.1

Reply via email to