ion: add invalid cache function [1/1]
authorYao.Liu <yao.liu@amlogic.com>
Fri, 28 Dec 2018 12:38:21 +0000 (07:38 -0500)
committerLuan Yuan <luan.yuan@amlogic.com>
Sat, 29 Dec 2018 11:20:49 +0000 (19:20 +0800)
PD#SWPL-3736

Problem:
H265 encoder use ge2d to do format convert, ge2d dst
buffer is allocated from ion heap and is cached buffer.
The cache consistency problem caused encoded stream error.

Solution:
ION add invalid cache function, invalid cache before
CPU access cache buffer

Verify:
U212

Change-Id: Ib14f2a9ee5b536c3546c5957fd0505cacae45f80
Signed-off-by: Yao.Liu <yao.liu@amlogic.com>
drivers/staging/android/ion/compat_ion.c
drivers/staging/android/ion/ion-ioctl.c
drivers/staging/android/ion/ion.c
drivers/staging/android/ion/ion_priv.h
drivers/staging/android/uapi/ion.h

index 9a978d2..86d6ad5 100644 (file)
@@ -189,6 +189,11 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case ION_IOC_SYNC:
                return filp->f_op->unlocked_ioctl(filp, cmd,
                                                (unsigned long)compat_ptr(arg));
+#ifdef CONFIG_AMLOGIC_MODIFY
+       case ION_IOC_INVALID_CACHE:
+               return filp->f_op->unlocked_ioctl(filp, cmd,
+                                               (unsigned long)compat_ptr(arg));
+#endif
        default:
                return -ENOIOCTLCMD;
        }
index 2b700e8..0ae2f10 100644 (file)
@@ -55,6 +55,10 @@ static unsigned int ion_ioctl_dir(unsigned int cmd)
        case ION_IOC_FREE:
        case ION_IOC_CUSTOM:
                return _IOC_WRITE;
+#ifdef CONFIG_AMLOGIC_MODIFY
+       case ION_IOC_INVALID_CACHE:
+               return _IOC_WRITE;
+#endif
        default:
                return _IOC_DIR(cmd);
        }
@@ -153,6 +157,13 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                ret = ion_sync_for_device(client, data.fd.fd);
                break;
        }
+#ifdef CONFIG_AMLOGIC_MODIFY
+       case ION_IOC_INVALID_CACHE:
+       {
+               ret = ion_sync_for_cpu(client, data.fd.fd);
+               break;
+       }
+#endif
        case ION_IOC_CUSTOM:
        {
                if (!dev->custom_ioctl)
index e015d84..e19f66e 100644 (file)
@@ -40,6 +40,9 @@
 #include "ion.h"
 #include "ion_priv.h"
 #include "compat_ion.h"
+#ifdef CONFIG_AMLOGIC_MODIFY
+#include <linux/of_device.h>
+#endif
 
 bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
 {
@@ -1155,6 +1158,38 @@ int ion_sync_for_device(struct ion_client *client, int fd)
        return 0;
 }
 
+#ifdef CONFIG_AMLOGIC_MODIFY
+int ion_sync_for_cpu(struct ion_client *client, int fd)
+{
+       struct dma_buf *dmabuf;
+       struct ion_buffer *buffer;
+       struct miscdevice *mdev;
+
+       dmabuf = dma_buf_get(fd);
+       if (IS_ERR(dmabuf))
+               return PTR_ERR(dmabuf);
+
+       /* if this memory came from ion */
+       if (dmabuf->ops != &dma_buf_ops) {
+               pr_err("%s: can not sync dmabuf from another exporter\n",
+                      __func__);
+               dma_buf_put(dmabuf);
+               return -EINVAL;
+       }
+       buffer = dmabuf->priv;
+       mdev = &client->dev->dev;
+
+       dma_sync_sg_for_cpu(mdev->this_device,
+                           buffer->sg_table->sgl,
+                           buffer->sg_table->nents,
+                           DMA_FROM_DEVICE);
+
+       dma_buf_put(dmabuf);
+
+       return 0;
+}
+#endif
+
 int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query)
 {
        struct ion_device *dev = client->dev;
@@ -1426,7 +1461,9 @@ struct ion_device *ion_device_create(long (*custom_ioctl)
 {
        struct ion_device *idev;
        int ret;
-
+#ifdef CONFIG_AMLOGIC_MODIFY
+       struct miscdevice *mdev;
+#endif
        idev = kzalloc(sizeof(*idev), GFP_KERNEL);
        if (!idev)
                return ERR_PTR(-ENOMEM);
@@ -1441,7 +1478,10 @@ struct ion_device *ion_device_create(long (*custom_ioctl)
                kfree(idev);
                return ERR_PTR(ret);
        }
-
+#ifdef CONFIG_AMLOGIC_MODIFY
+       mdev = &idev->dev;
+       of_dma_configure(mdev->this_device, mdev->this_device->of_node);
+#endif
        idev->debug_root = debugfs_create_dir("ion", NULL);
        if (!idev->debug_root) {
                pr_err("ion: failed to create debugfs root directory.\n");
index 0dd8781..57a52d9 100644 (file)
@@ -469,6 +469,10 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 
 int ion_sync_for_device(struct ion_client *client, int fd);
 
+#ifdef CONFIG_AMLOGIC_MODIFY
+int ion_sync_for_cpu(struct ion_client *client, int fd);
+#endif
+
 struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
                                                int id);
 
index 14cd873..a989023 100644 (file)
@@ -233,4 +233,13 @@ struct ion_heap_query {
 #define ION_IOC_HEAP_QUERY     _IOWR(ION_IOC_MAGIC, 8, \
                                        struct ion_heap_query)
 
+#ifdef CONFIG_AMLOGIC_MODIFY
+/**
+ * DOC: ION_IOC_INVALID_CACHE - invalid cache before
+ * cpu read the memory and after device write the memory.
+ * this will make the buffer in memory coherent.
+ */
+#define ION_IOC_INVALID_CACHE  _IOWR(ION_IOC_MAGIC, 9, struct ion_fd_data)
+#endif
+
 #endif /* _UAPI_LINUX_ION_H */