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 | 62 ++++++++++++++--------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 181b9ad32672..c97395e4ea2b 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,8 @@ static struct page **get_pages(struct drm_gem_object *obj) return msm_obj->pages; error: + if (!IS_ERR(msm_obj->sgt)) + drm_prime_gem_destroy(obj, msm_obj->sgt); msm_obj->sgt = NULL; drm_gem_put_pages(obj, msm_obj->pages, false, false); @@ -253,12 +235,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
