From: jonggab.park Date: Fri, 28 Apr 2017 05:24:45 +0000 (+0900) Subject: drm/tbm: add get/put dma address interface. X-Git-Tag: accepted/tizen/4.0/unified/20170816.020004~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F69%2F136969%2F3;p=profile%2Fwearable%2Fplatform%2Fkernel%2Flinux-3.18-exynos7270.git drm/tbm: add get/put dma address interface. DMA address interface set for pp driver. This patch is from product kernel. Change-Id: I41ad97483fdd7f0e3c17fc216d04d47edca2f8b1 Signed-off-by: Jin-young Jeon Signed-off-by: Inki Dae --- diff --git a/drivers/gpu/drm/tgm/tbm.h b/drivers/gpu/drm/tgm/tbm.h index 94879cb..c17e9a2 100644 --- a/drivers/gpu/drm/tgm/tbm.h +++ b/drivers/gpu/drm/tgm/tbm.h @@ -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; diff --git a/drivers/gpu/drm/tgm/tbm_gem.c b/drivers/gpu/drm/tgm/tbm_gem.c index 0804821..f329a9b 100644 --- a/drivers/gpu/drm/tgm/tbm_gem.c +++ b/drivers/gpu/drm/tgm/tbm_gem.c @@ -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__); diff --git a/drivers/gpu/drm/tgm/tbm_gem.h b/drivers/gpu/drm/tgm/tbm_gem.h index aecaef9..db222b9 100644 --- a/drivers/gpu/drm/tgm/tbm_gem.h +++ b/drivers/gpu/drm/tgm/tbm_gem.h @@ -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); diff --git a/drivers/gpu/drm/tgm/tbm_gem_ion.c b/drivers/gpu/drm/tgm/tbm_gem_ion.c index 94b0561..3f71c15 100644 --- a/drivers/gpu/drm/tgm/tbm_gem_ion.c +++ b/drivers/gpu/drm/tgm/tbm_gem_ion.c @@ -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; } diff --git a/drivers/gpu/drm/tgm/tbm_gem_ion.h b/drivers/gpu/drm/tgm/tbm_gem_ion.h index 5d01354..d757acc 100644 --- a/drivers/gpu/drm/tgm/tbm_gem_ion.h +++ b/drivers/gpu/drm/tgm/tbm_gem_ion.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -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);