aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch423
1 files changed, 423 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch
new file mode 100644
index 00000000..3dcf1e5b
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch
@@ -0,0 +1,423 @@
+From ada9566114097cebd9471fdee421e7e3f2931041 Mon Sep 17 00:00:00 2001
+From: "Hongbo.He" <Hongbo.He@amd.com>
+Date: Tue, 6 Dec 2016 16:23:39 +0800
+Subject: [PATCH 0783/4131] Revert "drm/amdgpu: "revert fix exclusive mode game
+ texture blank(v2)""
+
+This reverts commit 3bf3029fd2416d63d5439fde2412e76ac77d081f.
+
+Change-Id: I10ce2f9a2d3716d3b0e0eced8e7c9a6b32411ba8
+
+ Conflicts:
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 8 ++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 7 ++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c | 192 ++++++++++++++++++++++----------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h | 10 +-
+ 5 files changed, 164 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 6cf1620..9db84c8 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -59,6 +59,7 @@
+ #include "amdgpu_sync.h"
+ #include "amdgpu_ring.h"
+ #include "amdgpu_vm.h"
++#include "amdgpu_sem.h"
+ #include "amd_powerplay.h"
+ #include "amdgpu_dpm.h"
+ #include "amdgpu_acp.h"
+@@ -757,6 +758,8 @@ struct amdgpu_fpriv {
+ struct mutex bo_list_lock;
+ struct idr bo_list_handles;
+ struct amdgpu_ctx_mgr ctx_mgr;
++ spinlock_t sem_handles_lock;
++ struct idr sem_handles;
+ u32 vram_lost_counter;
+ };
+
+@@ -1327,6 +1330,8 @@ int amdgpu_sem_ioctl(struct drm_device *dev, void *data,
+ int amdgpu_sem_add_cs(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring,
+ struct amdgpu_sync *sync);
+
++void amdgpu_sem_destroy(struct amdgpu_fpriv *fpriv, u32 handle);
++
+ int amdgpu_gem_dgma_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+index cd84bd0..b502338 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+@@ -131,6 +131,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ unsigned i;
+ int r = 0;
+ bool need_pipe_sync = false;
++ unsigned extra_nop = 0;
+
+ if (num_ibs == 0)
+ return -EINVAL;
+@@ -157,6 +158,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ alloc_size = ring->funcs->emit_frame_size + num_ibs *
+ ring->funcs->emit_ib_size;
+
++ if (job && !job->vm_needs_flush && ring->funcs->type == AMDGPU_RING_TYPE_GFX) {
++ extra_nop = 128;
++ alloc_size += extra_nop;
++ }
++
+ r = amdgpu_ring_alloc(ring, alloc_size);
+ if (r) {
+ dev_err(adev->dev, "scheduling IB failed (%d).\n", r);
+@@ -174,6 +180,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ ring->funcs->insert_start(ring);
+
+ if (job) {
++ amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */
++
+ r = amdgpu_vm_flush(ring, job, need_pipe_sync);
+ if (r) {
+ amdgpu_ring_undo(ring);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index a5507b5..2e32262 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -877,6 +877,8 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
+
+ mutex_init(&fpriv->bo_list_lock);
+ idr_init(&fpriv->bo_list_handles);
++ spin_lock_init(&fpriv->sem_handles_lock);
++ idr_init(&fpriv->sem_handles);
+
+ amdgpu_ctx_mgr_init(&fpriv->ctx_mgr);
+
+@@ -904,6 +906,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
+ struct amdgpu_device *adev = dev->dev_private;
+ struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
+ struct amdgpu_bo_list *list;
++ struct amdgpu_sem *sem;
+ int handle;
+
+ if (!fpriv)
+@@ -936,6 +939,10 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
+ idr_destroy(&fpriv->bo_list_handles);
+ mutex_destroy(&fpriv->bo_list_lock);
+
++ idr_for_each_entry(&fpriv->sem_handles, sem, handle)
++ amdgpu_sem_destroy(fpriv, handle);
++ idr_destroy(&fpriv->sem_handles);
++
+ kfree(fpriv);
+ file_priv->driver_priv = NULL;
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c
+index 9fae1ef..d26b23f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c
+@@ -40,31 +40,17 @@ static int amdgpu_sem_cring_add(struct amdgpu_fpriv *fpriv,
+ struct drm_amdgpu_sem_in *in,
+ struct amdgpu_sem *sem);
+
+-static const struct file_operations amdgpu_sem_fops;
+-
+-static struct amdgpu_sem *amdgpu_sem_alloc(struct dma_fence *fence)
++static void amdgpu_sem_core_free(struct kref *kref)
+ {
+- struct amdgpu_sem *sem;
+-
+- sem = kzalloc(sizeof(struct amdgpu_sem), GFP_KERNEL);
+- if (!sem)
+- return NULL;
++ struct amdgpu_sem_core *core = container_of(
++ kref, struct amdgpu_sem_core, kref);
+
+- sem->file = anon_inode_getfile("sem_file",
+- &amdgpu_sem_fops,
+- sem, 0);
+- if (IS_ERR(sem->file))
+- goto err;
++ if (core->file)
++ fput(core->file);
+
+- kref_init(&sem->kref);
+- INIT_LIST_HEAD(&sem->list);
+- /* fence should be get before passing here */
+- sem->fence = fence;
+-
+- return sem;
+-err:
+- kfree(sem);
+- return NULL;
++ dma_fence_put(core->fence);
++ mutex_destroy(&core->lock);
++ kfree(core);
+ }
+
+ static void amdgpu_sem_free(struct kref *kref)
+@@ -72,15 +58,28 @@ static void amdgpu_sem_free(struct kref *kref)
+ struct amdgpu_sem *sem = container_of(
+ kref, struct amdgpu_sem, kref);
+
+- dma_fence_put(sem->fence);
++ list_del(&sem->list);
++ kref_put(&sem->base->kref, amdgpu_sem_core_free);
+ kfree(sem);
+ }
+
++static inline void amdgpu_sem_get(struct amdgpu_sem *sem)
++{
++ if (sem)
++ kref_get(&sem->kref);
++}
++
++static inline void amdgpu_sem_put(struct amdgpu_sem *sem)
++{
++ if (sem)
++ kref_put(&sem->kref, amdgpu_sem_free);
++}
++
+ static int amdgpu_sem_release(struct inode *inode, struct file *file)
+ {
+ struct amdgpu_sem *sem = file->private_data;
+
+- kref_put(&sem->kref, amdgpu_sem_free);
++ amdgpu_sem_put(sem);
+ return 0;
+ }
+
+@@ -102,49 +101,128 @@ static const struct file_operations amdgpu_sem_fops = {
+ .compat_ioctl = amdgpu_sem_file_ioctl,
+ };
+
+-static int amdgpu_sem_create(void)
++
++static inline struct amdgpu_sem *amdgpu_sem_lookup(struct amdgpu_fpriv *fpriv, u32 handle)
+ {
+- return get_unused_fd_flags(O_CLOEXEC);
++ struct amdgpu_sem *sem;
++
++ spin_lock(&fpriv->sem_handles_lock);
++
++ /* Check if we currently have a reference on the object */
++ sem = idr_find(&fpriv->sem_handles, handle);
++ amdgpu_sem_get(sem);
++
++ spin_unlock(&fpriv->sem_handles_lock);
++
++ return sem;
+ }
+
+-static int amdgpu_sem_signal(int fd, struct dma_fence *fence)
++static struct amdgpu_sem_core *amdgpu_sem_core_alloc(void)
++{
++ struct amdgpu_sem_core *core;
++
++ core = kzalloc(sizeof(*core), GFP_KERNEL);
++ if (!core)
++ return NULL;
++
++ kref_init(&core->kref);
++ mutex_init(&core->lock);
++ return core;
++}
++
++static struct amdgpu_sem *amdgpu_sem_alloc(void)
+ {
+ struct amdgpu_sem *sem;
+
+- sem = amdgpu_sem_alloc(fence);
++ sem = kzalloc(sizeof(*sem), GFP_KERNEL);
+ if (!sem)
++ return NULL;
++
++ kref_init(&sem->kref);
++ INIT_LIST_HEAD(&sem->list);
++
++ return sem;
++}
++
++static int amdgpu_sem_create(struct amdgpu_fpriv *fpriv, u32 *handle)
++{
++ struct amdgpu_sem *sem;
++ struct amdgpu_sem_core *core;
++ int ret;
++
++ sem = amdgpu_sem_alloc();
++ core = amdgpu_sem_core_alloc();
++ if (!sem || !core) {
++ kfree(sem);
++ kfree(core);
+ return -ENOMEM;
+- fd_install(fd, sem->file);
++ }
++
++ sem->base = core;
++
++ idr_preload(GFP_KERNEL);
++ spin_lock(&fpriv->sem_handles_lock);
++
++ ret = idr_alloc(&fpriv->sem_handles, sem, 1, 0, GFP_NOWAIT);
++
++ spin_unlock(&fpriv->sem_handles_lock);
++ idr_preload_end();
++
++ if (ret < 0)
++ return ret;
++
++ *handle = ret;
++ return 0;
++}
++
++static int amdgpu_sem_signal(struct amdgpu_fpriv *fpriv,
++ u32 handle, struct dma_fence *fence)
++{
++ struct amdgpu_sem *sem;
++ struct amdgpu_sem_core *core;
++
++ sem = amdgpu_sem_lookup(fpriv, handle);
++ if (!sem)
++ return -EINVAL;
++
++ core = sem->base;
++ mutex_lock(&core->lock);
++ dma_fence_put(core->fence);
++ core->fence = dma_fence_get(fence);
++ mutex_unlock(&core->lock);
+
++ amdgpu_sem_put(sem);
+ return 0;
+ }
+
+-static int amdgpu_sem_wait(int fd, struct amdgpu_fpriv *fpriv,
++static int amdgpu_sem_wait(struct amdgpu_fpriv *fpriv,
+ struct drm_amdgpu_sem_in *in)
+ {
+- struct file *file = fget(fd);
+ struct amdgpu_sem *sem;
+- int r;
++ int ret;
+
+- if (!file)
++ sem = amdgpu_sem_lookup(fpriv, in->handle);
++ if (!sem)
+ return -EINVAL;
+
+- sem = file->private_data;
+- if (!sem) {
+- r = -EINVAL;
+- goto err;
+- }
+- r = amdgpu_sem_cring_add(fpriv, in, sem);
+-err:
+- fput(file);
+- return r;
++ ret = amdgpu_sem_cring_add(fpriv, in, sem);
++ amdgpu_sem_put(sem);
++
++ return ret;
+ }
+
+-static void amdgpu_sem_destroy(void)
++void amdgpu_sem_destroy(struct amdgpu_fpriv *fpriv, u32 handle)
+ {
+- /* userspace should close fd when they try to destroy sem,
+- * closing fd will free semaphore object.
+- */
++ struct amdgpu_sem *sem = amdgpu_sem_lookup(fpriv, handle);
++ if (!sem)
++ return;
++
++ spin_lock(&fpriv->sem_handles_lock);
++ idr_remove(&fpriv->sem_handles, handle);
++ spin_unlock(&fpriv->sem_handles_lock);
++
++ kref_put(&sem->kref, amdgpu_sem_free);
++ kref_put(&sem->kref, amdgpu_sem_free);
+ }
+
+ static struct dma_fence *amdgpu_sem_get_fence(struct amdgpu_fpriv *fpriv,
+@@ -219,12 +297,14 @@ int amdgpu_sem_add_cs(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring,
+ mutex_lock(&ctx->rings[ring->idx].sem_lock);
+ list_for_each_entry_safe(sem, tmp, &ctx->rings[ring->idx].sem_list,
+ list) {
+- r = amdgpu_sync_fence(ctx->adev, sync, sem->fence);
+- dma_fence_put(sem->fence);
++ r = amdgpu_sync_fence(ctx->adev, sync, sem->base->fence);
+ if (r)
+ goto err;
+- list_del(&sem->list);
+- kfree(sem);
++ mutex_lock(&sem->base->lock);
++ dma_fence_put(sem->base->fence);
++ sem->base->fence = NULL;
++ mutex_unlock(&sem->base->lock);
++ list_del_init(&sem->list);
+ }
+ err:
+ mutex_unlock(&ctx->rings[ring->idx].sem_lock);
+@@ -238,14 +318,13 @@ int amdgpu_sem_ioctl(struct drm_device *dev, void *data,
+ struct amdgpu_fpriv *fpriv = filp->driver_priv;
+ struct dma_fence *fence;
+ int r = 0;
+- int fd = args->in.fd;
+
+ switch (args->in.op) {
+ case AMDGPU_SEM_OP_CREATE_SEM:
+- args->out.fd = amdgpu_sem_create();
++ r = amdgpu_sem_create(fpriv, &args->out.handle);
+ break;
+ case AMDGPU_SEM_OP_WAIT_SEM:
+- r = amdgpu_sem_wait(fd, fpriv, &args->in);
++ r = amdgpu_sem_wait(fpriv, &args->in);
+ break;
+ case AMDGPU_SEM_OP_SIGNAL_SEM:
+ fence = amdgpu_sem_get_fence(fpriv, &args->in);
+@@ -253,14 +332,15 @@ int amdgpu_sem_ioctl(struct drm_device *dev, void *data,
+ r = PTR_ERR(fence);
+ return r;
+ }
+- r = amdgpu_sem_signal(fd, fence);
++ r = amdgpu_sem_signal(fpriv, args->in.handle, fence);
+ dma_fence_put(fence);
+ break;
+ case AMDGPU_SEM_OP_DESTROY_SEM:
+- amdgpu_sem_destroy();
++ amdgpu_sem_destroy(fpriv, args->in.handle);
+ break;
+ default:
+- return -EINVAL;
++ r = -EINVAL;
++ break;
+ }
+
+ return r;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h
+index 10ec58e..40854ff 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h
+@@ -34,10 +34,16 @@
+ #include <linux/spinlock.h>
+ #include <linux/dma-fence.h>
+
+-struct amdgpu_sem {
++struct amdgpu_sem_core {
+ struct file *file;
+ struct kref kref;
+- struct dam_fence *fence;
++ struct dma_fence *fence;
++ struct mutex lock;
++};
++
++struct amdgpu_sem {
++ struct amdgpu_sem_core *base;
++ struct kref kref;
+ struct list_head list;
+ };
+
+--
+2.7.4
+