This should functionally be a no-op for us, since we are managing our
SMMU directly (dma_map_ops is NULL), but it populates the dma_len/
dma_address's so that we can use them for setting up pgtable mappings.

This inlines sync_for_device() and sync_for_cpu() into their only
callers to avoid doubling up on the dma-mapping calls.

Tested-by: Jianfeng Liu <[email protected]> # x1e78100 (Acer SFA14-11), 
v7.3-rc5 + this series, CONFIG_DMABUF_DEBUG=y
Signed-off-by: Rob Clark <[email protected]>
---
 drivers/gpu/drm/msm/msm_gem.c | 65 +++++++++++++++--------------------
 1 file changed, 28 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 181b9ad32672..bcdb57866cf6 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -116,34 +116,6 @@ void msm_gem_vma_put(struct drm_gem_object *obj)
 #endif
 }
 
-/*
- * Cache sync.. this is a bit over-complicated, to fit dma-mapping
- * API.  Really GPU cache is out of scope here (handled on cmdstream)
- * and all we need to do is invalidate newly allocated pages before
- * mapping to CPU as uncached/writecombine.
- *
- * On top of this, we have the added headache, that depending on
- * display generation, the display's iommu may be wired up to either
- * the toplevel drm device (mdss), or to the mdp sub-node, meaning
- * that here we either have dma-direct or iommu ops.
- *
- * Let this be a cautionary tail of abstraction gone wrong.
- */
-
-static void sync_for_device(struct msm_gem_object *msm_obj)
-{
-       struct device *dev = msm_obj->base.dev->dev;
-
-       dma_map_sgtable(dev, msm_obj->sgt, DMA_BIDIRECTIONAL, 0);
-}
-
-static void sync_for_cpu(struct msm_gem_object *msm_obj)
-{
-       struct device *dev = msm_obj->base.dev->dev;
-
-       dma_unmap_sgtable(dev, msm_obj->sgt, DMA_BIDIRECTIONAL, 0);
-}
-
 static void update_lru_active(struct drm_gem_object *obj)
 {
        struct msm_drm_private *priv = obj->dev->dev_private;
@@ -201,6 +173,7 @@ static struct page **get_pages(struct drm_gem_object *obj)
                struct drm_device *dev = obj->dev;
                struct page **p;
                size_t npages = obj->size >> PAGE_SHIFT;
+               unsigned map_attrs = DMA_ATTR_SKIP_CPU_SYNC;
 
                p = drm_gem_get_pages(obj);
 
@@ -219,13 +192,20 @@ static struct page **get_pages(struct drm_gem_object *obj)
                        goto error;
                }
 
-               update_device_mem(dev->dev_private, obj->size);
-
-               /* For non-cached buffers, ensure the new pages are clean
-                * because display controller, GPU, etc. are not coherent:
-                */
+               /* For non-cached buffers, ensure the new pages are clean. */
                if (msm_obj->flags & MSM_BO_WC)
-                       sync_for_device(msm_obj);
+                       map_attrs = 0;
+
+               ret = dma_map_sgtable(drm_dev_dma_dev(obj->dev),
+                                     msm_obj->sgt,
+                                     DMA_BIDIRECTIONAL,
+                                     map_attrs);
+               if (ret) {
+                       DRM_DEV_ERROR(dev->dev, "could not map sgtable: %d\n", 
ret);
+                       goto error;
+               }
+
+               update_device_mem(dev->dev_private, obj->size);
 
                update_lru(obj);
        }
@@ -233,6 +213,11 @@ static struct page **get_pages(struct drm_gem_object *obj)
        return msm_obj->pages;
 
 error:
+       if (!IS_ERR(msm_obj->sgt)) {
+               sg_free_table(msm_obj->sgt);
+               kfree(msm_obj->sgt);
+               msm_obj->sgt = NULL;
+       }
        msm_obj->sgt = NULL;
 
        drm_gem_put_pages(obj, msm_obj->pages, false, false);
@@ -253,12 +238,18 @@ static void put_pages(struct drm_gem_object *obj)
                drm_gpuvm_bo_gem_evict(obj, true);
 
        if (msm_obj->pages) {
+               unsigned unmap_attrs = DMA_ATTR_SKIP_CPU_SYNC;
+
                /* For non-cached buffers, ensure the new
-                * pages are clean because display controller,
-                * GPU, etc. are not coherent:
+                * pages are clean:
                 */
                if (msm_obj->flags & MSM_BO_WC)
-                       sync_for_cpu(msm_obj);
+                       unmap_attrs = 0;
+
+               dma_unmap_sgtable(drm_dev_dma_dev(obj->dev),
+                                 msm_obj->sgt,
+                                 DMA_BIDIRECTIONAL,
+                                 unmap_attrs);
 
                sg_free_table(msm_obj->sgt);
                kfree(msm_obj->sgt);
-- 
2.56.0

Reply via email to