aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4090-drm-amdkcl-4.17-fix-prime-bo-for-raven-A-A-issue.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4090-drm-amdkcl-4.17-fix-prime-bo-for-raven-A-A-issue.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4090-drm-amdkcl-4.17-fix-prime-bo-for-raven-A-A-issue.patch415
1 files changed, 415 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4090-drm-amdkcl-4.17-fix-prime-bo-for-raven-A-A-issue.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4090-drm-amdkcl-4.17-fix-prime-bo-for-raven-A-A-issue.patch
new file mode 100644
index 00000000..9e7aecfc
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4090-drm-amdkcl-4.17-fix-prime-bo-for-raven-A-A-issue.patch
@@ -0,0 +1,415 @@
+From d381e0d9128e27033f1a0515e4919b7bdecb2395 Mon Sep 17 00:00:00 2001
+From: Junwei Zhang <Jerry.Zhang@amd.com>
+Date: Tue, 22 May 2018 16:26:41 +0800
+Subject: [PATCH 4090/4131] drm/amdkcl: [4.17] fix prime bo for raven A+A issue
+
+For kernel < 4.17, drm prime functions are not exported.
+So retain the old path for prime bo sharing.
+
+Change-Id: I4436d0318710515076fcf87c5cf2a7127fb49cb3
+Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
+Reviewed-by: Le Ma <Le.Ma@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 ++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 151 +++++++++++++++++++++++++++++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 7 +-
+ drivers/gpu/drm/drm_prime.c | 32 ++++---
+ include/drm/drm_prime.h | 19 ++++
+ 6 files changed, 203 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index d455207..a866d5d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -392,6 +392,8 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
+ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *gobj,
+ int flags);
++struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
++ struct dma_buf *dma_buf);
+ struct drm_gem_object *
+ amdgpu_gem_prime_foreign_bo(struct amdgpu_device *adev, struct amdgpu_bo *bo);
+ int amdgpu_gem_prime_pin(struct drm_gem_object *obj);
+@@ -401,7 +403,7 @@ void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);
+ void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+ int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
+
+-//extern const struct dma_buf_ops amdgpu_dmabuf_ops;
++extern const struct dma_buf_ops amdgpu_dmabuf_ops;
+
+ /* sub-allocation manager, it has to be protected by another lock.
+ * By conception this is an helper for other part of the driver
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 4f97f7b..1397a47 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -901,7 +901,13 @@ static struct drm_driver kms_driver = {
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = amdgpu_gem_prime_export,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++ .gem_prime_import = amdgpu_gem_prime_import,
++#else
+ .gem_prime_import = drm_gem_prime_import,
++ .gem_prime_pin = amdgpu_gem_prime_pin,
++ .gem_prime_unpin = amdgpu_gem_prime_unpin,
++#endif
+ .gem_prime_res_obj = amdgpu_gem_prime_res_obj,
+ .gem_prime_get_sg_table = amdgpu_gem_prime_get_sg_table,
+ .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+index a6cac1f..716f880 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+@@ -115,6 +115,11 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
+ bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
+ bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++ if (attach->dmabuf->ops != &amdgpu_dmabuf_ops)
++#endif
++ bo->prime_shared_count = 1;
++
+ ww_mutex_unlock(&resv->lock);
+ return &bo->gem_base;
+
+@@ -123,6 +128,77 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
+ return ERR_PTR(ret);
+ }
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
++ struct device *target_dev,
++ struct dma_buf_attachment *attach)
++{
++ struct drm_gem_object *obj = dma_buf->priv;
++ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
++ struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
++ long r;
++
++ r = drm_gem_map_attach(dma_buf, target_dev, attach);
++ if (r)
++ return r;
++
++ r = amdgpu_bo_reserve(bo, false);
++ if (unlikely(r != 0))
++ goto error_detach;
++
++
++ if (attach->dev->driver != adev->dev->driver) {
++ /*
++ * Wait for all shared fences to complete before we switch to future
++ * use of exclusive fence on this prime shared bo.
++ */
++ r = reservation_object_wait_timeout_rcu(bo->tbo.resv,
++ true, false,
++ MAX_SCHEDULE_TIMEOUT);
++ if (unlikely(r < 0)) {
++ DRM_DEBUG_PRIME("Fence wait failed: %li\n", r);
++ goto error_unreserve;
++ }
++ }
++
++ /* pin buffer into GTT */
++ r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL);
++ if (r)
++ goto error_unreserve;
++
++ if (attach->dev->driver != adev->dev->driver)
++ bo->prime_shared_count++;
++
++error_unreserve:
++ amdgpu_bo_unreserve(bo);
++
++error_detach:
++ if (r)
++ drm_gem_map_detach(dma_buf, attach);
++ return r;
++}
++
++static void amdgpu_gem_map_detach(struct dma_buf *dma_buf,
++ struct dma_buf_attachment *attach)
++{
++ struct drm_gem_object *obj = dma_buf->priv;
++ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
++ struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
++ int ret = 0;
++
++ ret = amdgpu_bo_reserve(bo, true);
++ if (unlikely(ret != 0))
++ goto error;
++
++ amdgpu_bo_unpin(bo);
++ if (attach->dev->driver != adev->dev->driver && bo->prime_shared_count) bo->prime_shared_count--;
++ amdgpu_bo_unreserve(bo);
++
++error:
++ drm_gem_map_detach(dma_buf, attach);
++}
++#endif
++
+ struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *obj)
+ {
+ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+@@ -130,6 +206,52 @@ struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *obj)
+ return bo->tbo.resv;
+ }
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++static int amdgpu_gem_begin_cpu_access(struct dma_buf *dma_buf,
++ enum dma_data_direction direction)
++{
++ struct amdgpu_bo *bo = gem_to_amdgpu_bo(dma_buf->priv);
++ struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
++ struct ttm_operation_ctx ctx = { true, false };
++ u32 domain = amdgpu_display_framebuffer_domains(adev);
++ int ret;
++ bool reads = (direction == DMA_BIDIRECTIONAL ||
++ direction == DMA_FROM_DEVICE);
++
++ if (!reads || !(domain & AMDGPU_GEM_DOMAIN_GTT))
++ return 0;
++
++ /* move to gtt */
++ ret = amdgpu_bo_reserve(bo, false);
++ if (unlikely(ret != 0))
++ return ret;
++
++ if (!bo->pin_count && (bo->allowed_domains & AMDGPU_GEM_DOMAIN_GTT)) {
++ amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
++ ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
++ }
++
++ amdgpu_bo_unreserve(bo);
++ return ret;
++}
++
++const struct dma_buf_ops amdgpu_dmabuf_ops = {
++ .attach = amdgpu_gem_map_attach,
++ .detach = amdgpu_gem_map_detach,
++ .map_dma_buf = drm_gem_map_dma_buf,
++ .unmap_dma_buf = drm_gem_unmap_dma_buf,
++ .release = drm_gem_dmabuf_release,
++ .begin_cpu_access = amdgpu_gem_begin_cpu_access,
++ .map = drm_gem_dmabuf_kmap,
++ .map_atomic = drm_gem_dmabuf_kmap_atomic,
++ .unmap = drm_gem_dmabuf_kunmap,
++ .unmap_atomic = drm_gem_dmabuf_kunmap_atomic,
++ .mmap = drm_gem_dmabuf_mmap,
++ .vmap = drm_gem_dmabuf_vmap,
++ .vunmap = drm_gem_dmabuf_vunmap,
++};
++#endif
++
+ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *gobj,
+ int flags)
+@@ -142,12 +264,37 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
+ return ERR_PTR(-EPERM);
+
+ buf = drm_gem_prime_export(dev, gobj, flags);
+- if (!IS_ERR(buf))
++ if (!IS_ERR(buf)) {
+ buf->file->f_mapping = dev->anon_inode->i_mapping;
+-
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++ buf->ops = &amdgpu_dmabuf_ops;
++#endif
++ }
+ return buf;
+ }
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
++ struct dma_buf *dma_buf)
++{
++ struct drm_gem_object *obj;
++
++ if (dma_buf->ops == &amdgpu_dmabuf_ops) {
++ obj = dma_buf->priv;
++ if (obj->dev == dev) {
++ /*
++ * Importing dmabuf exported from out own gem increases
++ * refcount on gem itself instead of f_count of dmabuf.
++ */
++ drm_gem_object_get(obj);
++ return obj;
++ }
++ }
++
++ return drm_gem_prime_import(dev, dma_buf);
++}
++#endif
++
+ struct drm_gem_object *
+ amdgpu_gem_prime_foreign_bo(struct amdgpu_device *adev, struct amdgpu_bo *bo)
+ {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 1c3ef32..11ac7f2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -1047,8 +1047,11 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
+ return NULL;
+ }
+ gtt->ttm.ttm.func = &amdgpu_backend_func;
+- gtt->adev = adev;
+- if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS)
++ if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) {
++#else
++ if (ttm_dma_tt_init(&gtt->ttm, bo, page_flags)) {
++#endif
+ kfree(gtt);
+ return NULL;
+ }
+diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
+index 31363bd..0b5ec71 100644
+--- a/drivers/gpu/drm/drm_prime.c
++++ b/drivers/gpu/drm/drm_prime.c
+@@ -180,7 +180,7 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri
+ return -ENOENT;
+ }
+
+-static int drm_gem_map_attach(struct dma_buf *dma_buf,
++int drm_gem_map_attach(struct dma_buf *dma_buf,
+ struct device *target_dev,
+ struct dma_buf_attachment *attach)
+ {
+@@ -202,7 +202,7 @@ static int drm_gem_map_attach(struct dma_buf *dma_buf,
+ }
+ EXPORT_SYMBOL(drm_gem_map_attach);
+
+-static void drm_gem_map_detach(struct dma_buf *dma_buf,
++void drm_gem_map_detach(struct dma_buf *dma_buf,
+ struct dma_buf_attachment *attach)
+ {
+ struct drm_prime_attachment *prime_attach = attach->priv;
+@@ -255,7 +255,7 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
+ }
+ }
+
+-static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
++struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
+ enum dma_data_direction dir)
+ {
+ struct drm_prime_attachment *prime_attach = attach->priv;
+@@ -291,13 +291,15 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
+
+ return sgt;
+ }
++EXPORT_SYMBOL(drm_gem_map_dma_buf);
+
+-static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
++void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
+ struct sg_table *sgt,
+ enum dma_data_direction dir)
+ {
+ /* nothing to be done here */
+ }
++EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
+
+ /**
+ * drm_gem_dmabuf_export - dma_buf export implementation for GEM
+@@ -348,46 +350,53 @@ void drm_gem_dmabuf_release(struct dma_buf *dma_buf)
+ }
+ EXPORT_SYMBOL(drm_gem_dmabuf_release);
+
+-static void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
++void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
+ {
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct drm_device *dev = obj->dev;
+
+ return dev->driver->gem_prime_vmap(obj);
+ }
++EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
+
+-static void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
++void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
+ {
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct drm_device *dev = obj->dev;
+
+ dev->driver->gem_prime_vunmap(obj, vaddr);
+ }
++EXPORT_SYMBOL(drm_gem_dmabuf_vunmap);
+
+-static void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
++void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
+ unsigned long page_num)
+ {
+ return NULL;
+ }
++EXPORT_SYMBOL(drm_gem_dmabuf_kmap_atomic);
+
+-static void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf,
++void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf,
+ unsigned long page_num, void *addr)
+ {
+
+ }
+-static void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf,
++EXPORT_SYMBOL(drm_gem_dmabuf_kunmap_atomic);
++
++void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf,
+ unsigned long page_num)
+ {
+ return NULL;
+ }
++EXPORT_SYMBOL(drm_gem_dmabuf_kmap);
+
+-static void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf,
++void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf,
+ unsigned long page_num, void *addr)
+ {
+
+ }
++EXPORT_SYMBOL(drm_gem_dmabuf_kunmap);
+
+-static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
++int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
+ struct vm_area_struct *vma)
+ {
+ struct drm_gem_object *obj = dma_buf->priv;
+@@ -398,6 +407,7 @@ static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
+
+ return dev->driver->gem_prime_mmap(obj, vma);
+ }
++EXPORT_SYMBOL(drm_gem_dmabuf_mmap);
+
+ const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
+ .attach = drm_gem_map_attach,
+diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
+index 3ceecca..1c6e22f 100644
+--- a/include/drm/drm_prime.h
++++ b/include/drm/drm_prime.h
+@@ -81,6 +81,25 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
+ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
+ struct dma_buf_export_info *exp_info);
+ void drm_gem_dmabuf_release(struct dma_buf *dma_buf);
++int drm_gem_map_attach(struct dma_buf *dma_buf, struct device *target_dev,
++ struct dma_buf_attachment *attach);
++void drm_gem_map_detach(struct dma_buf *dma_buf,
++ struct dma_buf_attachment *attach);
++struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
++ enum dma_data_direction dir);
++void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
++ struct sg_table *sgt,
++ enum dma_data_direction dir);
++void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf);
++void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr);
++void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
++ unsigned long page_num);
++void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf,
++ unsigned long page_num, void *addr);
++void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num);
++void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num,
++ void *addr);
++int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma);
+ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
+ dma_addr_t *addrs, int max_pages);
+ struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages);
+--
+2.7.4
+