[PATCH RFC 069/111] staging: etnaviv: move scatterlist map/unmap
Lucas Stach
l.stach at pengutronix.de
Thu Apr 2 08:30:11 PDT 2015
From: Russell King <rmk+kernel at arm.linux.org.uk>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
drivers/staging/etnaviv/etnaviv_gem.c | 89 ++++++++++++++++++++---------------
1 file changed, 52 insertions(+), 37 deletions(-)
diff --git a/drivers/staging/etnaviv/etnaviv_gem.c b/drivers/staging/etnaviv/etnaviv_gem.c
index 2f2bf5619ffd..8eeafcafb4e9 100644
--- a/drivers/staging/etnaviv/etnaviv_gem.c
+++ b/drivers/staging/etnaviv/etnaviv_gem.c
@@ -23,6 +23,55 @@
#include "etnaviv_gpu.h"
#include "etnaviv_mmu.h"
+static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
+{
+ struct drm_device *dev = etnaviv_obj->base.dev;
+
+ /*
+ * For non-cached buffers, ensure the new pages are clean
+ * because display controller, GPU, etc. are not coherent.
+ */
+ if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED)) {
+ dma_map_sg(dev->dev, etnaviv_obj->sgt->sgl,
+ etnaviv_obj->sgt->nents, DMA_BIDIRECTIONAL);
+ } else {
+ struct scatterlist *sg;
+ unsigned int i;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ sg_dma_address(sg) = sg_phys(sg);
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+ sg_dma_len(sg) = sg->length;
+#endif
+ }
+ }
+}
+
+static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
+{
+ struct drm_device *dev = etnaviv_obj->base.dev;
+
+ /*
+ * For non-cached buffers, ensure the new pages are clean
+ * because display controller, GPU, etc. are not coherent:
+ *
+ * WARNING: The DMA API does not support concurrent CPU
+ * and device access to the memory area. With BIDIRECTIONAL,
+ * we will clean the cache lines which overlap the region,
+ * and invalidate all cache lines (partially) contained in
+ * the region.
+ *
+ * If you have dirty data in the overlapping cache lines,
+ * that will corrupt the GPU-written data. If you have
+ * written into the remainder of the region, this can
+ * discard those writes.
+ */
+ if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED))
+ dma_unmap_sg(dev->dev, etnaviv_obj->sgt->sgl,
+ etnaviv_obj->sgt->nents,
+ DMA_BIDIRECTIONAL);
+}
+
/* called with dev->struct_mutex held */
static int etnaviv_gem_shmem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
{
@@ -42,27 +91,7 @@ static int etnaviv_gem_shmem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
static void put_pages(struct etnaviv_gem_object *etnaviv_obj)
{
if (etnaviv_obj->sgt) {
- struct drm_device *dev = etnaviv_obj->base.dev;
-
- /*
- * For non-cached buffers, ensure the new pages are clean
- * because display controller, GPU, etc. are not coherent:
- *
- * WARNING: The DMA API does not support concurrent CPU
- * and device access to the memory area. With BIDIRECTIONAL,
- * we will clean the cache lines which overlap the region,
- * and invalidate all cache lines (partially) contained in
- * the region.
- *
- * If you have dirty data in the overlapping cache lines,
- * that will corrupt the GPU-written data. If you have
- * written into the remainder of the region, this can
- * discard those writes.
- */
- if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED))
- dma_unmap_sg(dev->dev, etnaviv_obj->sgt->sgl,
- etnaviv_obj->sgt->nents,
- DMA_BIDIRECTIONAL);
+ etnaviv_gem_scatterlist_unmap(etnaviv_obj);
sg_free_table(etnaviv_obj->sgt);
kfree(etnaviv_obj->sgt);
etnaviv_obj->sgt = NULL;
@@ -99,13 +128,7 @@ struct page **etnaviv_gem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
etnaviv_obj->sgt = sgt;
- /*
- * For non-cached buffers, ensure the new pages are clean
- * because display controller, GPU, etc. are not coherent.
- */
- if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED))
- dma_map_sg(dev->dev, etnaviv_obj->sgt->sgl,
- etnaviv_obj->sgt->nents, DMA_BIDIRECTIONAL);
+ etnaviv_gem_scatter_map(etnaviv_obj);
}
return etnaviv_obj->pages;
@@ -836,15 +859,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
static void etnaviv_gem_userptr_release(struct etnaviv_gem_object *etnaviv_obj)
{
if (etnaviv_obj->sgt) {
- /*
- * For non-cached buffers, ensure the new pages are clean
- * because display controller, GPU, etc. are not coherent:
- */
- if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED))
- dma_unmap_sg(etnaviv_obj->base.dev->dev,
- etnaviv_obj->sgt->sgl,
- etnaviv_obj->sgt->nents,
- DMA_BIDIRECTIONAL);
+ etnaviv_gem_scatterlist_unmap(etnaviv_obj);
sg_free_table(etnaviv_obj->sgt);
kfree(etnaviv_obj->sgt);
}
--
2.1.4
More information about the dri-devel
mailing list