[RAMEN9610-12270] g2d: add missing IOMMU_CACHE to iommu mapping
authorCho KyongHo <pullip.cho@samsung.com>
Mon, 18 Feb 2019 02:24:59 +0000 (11:24 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:17 +0000 (20:23 +0300)
IOMMU_CACHE should be specified to iovmm_map() if G2D supports IO Cache
Coherency but it was missing because ION and IOMMU drivers adds
IOMMU_CACHE if their clients has DMA attributes of IO cache coherency.
But it is not correct to delegate configuration to IOMMU_CACHE to ION
and IOMMU drivers because G2D driver does not have any room to change
such configurations.

Change-Id: I6c20727c913af52781230669621bf8cf12faafdc
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/gpu/exynos/g2d/g2d_regs.c
drivers/gpu/exynos/g2d/g2d_task.c
drivers/gpu/exynos/g2d/g2d_uapi_process.c

index fd3ae69d0a7292cc1ba39653823b10a9a5bed5d1..ba20f8f9e4624cf3fe3df514e2a49408f0405751 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/property.h>
 
 #include <asm/cacheflush.h>
 
@@ -83,6 +84,10 @@ void g2d_hw_push_task(struct g2d_device *g2d_dev, struct g2d_task *task)
                               G2D_JOBn_LAYER_SECURE_REG(task->sec.job_id));
        }
 
+       if (device_get_dma_attr(g2d_dev->dev) != DEV_DMA_COHERENT)
+               __flush_dcache_area(page_address(task->cmd_page),
+                                   G2D_CMD_LIST_SIZE);
+
        writel_relaxed(G2D_JOB_HEADER_DATA(task->sec.priority,
                                           task->sec.job_id),
                        g2d_dev->reg + G2D_JOB_HEADER_REG);
index 83dfe6cd9d7ed4acd2d5887d7526d5507e74258b..5ce39bc027ea8ec7c7a83b247426ad66b94892c4 100644 (file)
@@ -43,16 +43,19 @@ static int g2d_map_cmd_data(struct g2d_task *task)
 {
        bool self_prot = task->g2d_dev->caps & G2D_DEVICE_CAPS_SELF_PROTECTION;
        struct scatterlist sgl;
+       int prot = IOMMU_READ;
 
        if (!self_prot && IS_ENABLED(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION))
                return 0;
 
+       if (device_get_dma_attr(task->g2d_dev->dev) == DEV_DMA_COHERENT)
+               prot |= IOMMU_CACHE;
+
        /* mapping the command data */
        sg_init_table(&sgl, 1);
        sg_set_page(&sgl, task->cmd_page, G2D_CMD_LIST_SIZE, 0);
        task->cmd_addr = iovmm_map(task->g2d_dev->dev, &sgl, 0,
-                                  G2D_CMD_LIST_SIZE, DMA_TO_DEVICE,
-                                  IOMMU_READ | IOMMU_CACHE);
+                                  G2D_CMD_LIST_SIZE, DMA_TO_DEVICE, prot);
 
        if (IS_ERR_VALUE(task->cmd_addr)) {
                dev_err(task->g2d_dev->dev,
index 3e49fa3213145095fb9c23357229a0ba03d3ef76..e853533d2d8fe5529d8408ecac44e5e54460cd16 100644 (file)
@@ -227,9 +227,6 @@ static int g2d_get_dmabuf(struct g2d_task *task,
                goto err;
        }
 
-       if (dir != DMA_TO_DEVICE)
-               prot |= IOMMU_WRITE;
-
        if (ion_cached_dmabuf(dmabuf)) {
                task->total_cached_len += buffer->payload;
 
@@ -252,6 +249,12 @@ static int g2d_get_dmabuf(struct g2d_task *task,
                goto err_map;
        }
 
+       if (dir != DMA_TO_DEVICE)
+               prot |= IOMMU_WRITE;
+
+       if (device_get_dma_attr(dev) == DEV_DMA_COHERENT)
+               prot |= IOMMU_CACHE;
+
        dma_addr = ion_iovmm_map(attachment, 0, buffer->payload, dir, prot);
        if (IS_ERR_VALUE(dma_addr)) {
                ret = (int)dma_addr;
@@ -374,6 +377,9 @@ static int g2d_get_userptr(struct g2d_task *task,
                        vma->vm_ops->open(vma);
        }
 
+       if (device_get_dma_attr(dev) == DEV_DMA_COHERENT)
+               prot |= IOMMU_CACHE;
+
        buffer->dma_addr = exynos_iovmm_map_userptr(dev, data->userptr,
                                                    data->length, prot);
        if (IS_ERR_VALUE(buffer->dma_addr)) {