diff options
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.patch | 415 |
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(>t->ttm, bo, page_flags)) { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || !defined(BUILD_AS_DKMS) ++ if (ttm_sg_tt_init(>t->ttm, bo, page_flags)) { ++#else ++ if (ttm_dma_tt_init(>t->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 + |