drm/tbm: add get/put dma address interface. 69/136969/3
authorjonggab.park <jonggab.park@samsung.com>
Fri, 28 Apr 2017 05:24:45 +0000 (14:24 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 4 Jul 2017 02:25:41 +0000 (02:25 +0000)
DMA address interface set for pp driver.
This patch is from product kernel.

Change-Id: I41ad97483fdd7f0e3c17fc216d04d47edca2f8b1
Signed-off-by: Jin-young Jeon <jy0.jeon@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/tgm/tbm.h
drivers/gpu/drm/tgm/tbm_gem.c
drivers/gpu/drm/tgm/tbm_gem.h
drivers/gpu/drm/tgm/tbm_gem_ion.c
drivers/gpu/drm/tgm/tbm_gem_ion.h

index 94879cb..c17e9a2 100644 (file)
@@ -29,6 +29,12 @@ struct tbm_private {
                        uint32_t flags, int *prime_fd);
        int (*gem_prime_fd_to_handle) (struct drm_device *dev,
                        struct drm_file *file_priv, int prime_fd, uint32_t *handle);
+       void * (*gem_get_dma_addr)(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp);
+       void (*gem_put_dma_addr)(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp);
 #ifdef CONFIG_DRM_DMA_SYNC
        unsigned gem_fence_context;
        atomic_t gem_fence_seqno;
index 0804821..f329a9b 100644 (file)
@@ -625,6 +625,33 @@ int tbm_gem_object_unreference(struct drm_gem_object *obj)
        return 0;
 }
 
+dma_addr_t *tbm_gem_get_dma_addr(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp)
+{
+       struct tgm_drv_private *dev_priv = drm_dev->dev_private;
+       struct tbm_private *tbm_priv = dev_priv->tbm_priv;
+       dma_addr_t *addr = NULL;
+
+       if (tbm_priv->gem_get_dma_addr)
+               addr = tbm_priv->gem_get_dma_addr(drm_dev, dev,
+                       gem_handle, filp);
+
+       return addr;
+}
+
+void tbm_gem_put_dma_addr(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp)
+{
+       struct tgm_drv_private *dev_priv = drm_dev->dev_private;
+       struct tbm_private *tbm_priv = dev_priv->tbm_priv;
+
+       if (tbm_priv->gem_put_dma_addr)
+               tbm_priv->gem_put_dma_addr(drm_dev, dev,
+                       gem_handle, filp);
+}
+
 static int tbm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        DRM_INFO("%s\n", __func__);
index aecaef9..db222b9 100644 (file)
@@ -56,6 +56,12 @@ int tbm_gem_mmap_ioctl(struct drm_device *dev, void *data,
 int tbm_gem_get_ioctl(struct drm_device *dev, void *data,
                                      struct drm_file *file_priv);
 int tbm_gem_info(struct seq_file *m, void *data);
+dma_addr_t *tbm_gem_get_dma_addr(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp);
+void tbm_gem_put_dma_addr(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp);
 int tbm_gem_init(struct drm_device *drm_dev);
 int tbm_gem_prime_fd_to_handle(struct drm_device *dev,
                struct drm_file *file_priv, int prime_fd, uint32_t *handle);
index 94b0561..3f71c15 100644 (file)
@@ -126,6 +126,61 @@ err:
        buf->sgt = NULL;
 }
 
+void *tbm_gem_ion_get_dma_addr(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp)
+{
+       struct tbm_gem_object *tbm_gem_obj;
+       struct drm_gem_object *obj;
+       struct tbm_gem_buf      *buffer;
+
+       obj = drm_gem_object_lookup(drm_dev, filp, gem_handle);
+       if (!obj) {
+               DRM_ERROR("failed to lookup gem object.\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       tbm_gem_obj = to_tbm_gem_obj(obj);
+       buffer = tbm_gem_obj->buffer;
+       buffer->iova =  iovmm_map(dev, buffer->sgt->sgl, 0, buffer->size,
+               DMA_TO_DEVICE, 0);
+
+       DRM_DEBUG("%s:h[%d]obj[%p]a[0x%x]\n", __func__, gem_handle,
+               obj, (int)buffer->iova);
+
+       return &buffer->iova;
+}
+
+void tbm_gem_ion_put_dma_addr(struct drm_device *drm_dev,
+               struct device *dev, unsigned int gem_handle,
+               struct drm_file *filp)
+{
+       struct tbm_gem_object *tbm_gem_obj;
+       struct drm_gem_object *obj;
+       struct tbm_gem_buf      *buffer;
+
+       obj = drm_gem_object_lookup(drm_dev, filp, gem_handle);
+       if (!obj) {
+               DRM_ERROR("failed to lookup gem object.\n");
+               return;
+       }
+
+       tbm_gem_obj = to_tbm_gem_obj(obj);
+       buffer = tbm_gem_obj->buffer;
+
+       DRM_DEBUG("%s:h[%d]obj[%p]a[0x%x]\n", __func__, gem_handle,
+               obj, (int)buffer->iova);
+
+       iovmm_unmap(dev, buffer->iova);
+       drm_gem_object_unreference_unlocked(obj);
+
+       /*
+        * decrease obj->refcount one more time because we has already
+        * increased it at exynos_drm_gem_get_dma_addr().
+        */
+       drm_gem_object_unreference_unlocked(obj);
+}
+
 struct dma_buf *tbm_gem_ion_prime_export(struct drm_device *dev,
                                  struct drm_gem_object *obj, int flags)
 {
@@ -316,6 +371,8 @@ err:
        tbm_priv->gem_priv = gem_priv;
        tbm_priv->gem_bufer_alloc = tbm_gem_ion_buffer_alloc;
        tbm_priv->gem_bufer_dealloc = tbm_gem_ion_buffer_dealloc;
+       tbm_priv->gem_get_dma_addr = tbm_gem_ion_get_dma_addr;
+       tbm_priv->gem_put_dma_addr = tbm_gem_ion_put_dma_addr;
 
        return 0;
 }
index 5d01354..d757acc 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/dma-buf.h>
 #include <linux/exynos_ion.h>
+#include <linux/exynos_iovmm.h>
 #include <linux/ion.h>
 #include <drm/drmP.h>
 #include <tgm_drv.h>
@@ -35,6 +36,7 @@ struct tbm_gem_buf {
        bool                    pfnmap;
        unsigned int            bufcount;
        struct drm_gem_object *obj;
+       dma_addr_t              iova;
 };
 
  int tbm_gem_ion_init(struct drm_device *drm_dev);