aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-amd/0043-drm-radeon-fix-CP-semaphores-on-CIK.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-amd/0043-drm-radeon-fix-CP-semaphores-on-CIK.patch')
-rw-r--r--common/recipes-kernel/linux/linux-amd/0043-drm-radeon-fix-CP-semaphores-on-CIK.patch117
1 files changed, 117 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-amd/0043-drm-radeon-fix-CP-semaphores-on-CIK.patch b/common/recipes-kernel/linux/linux-amd/0043-drm-radeon-fix-CP-semaphores-on-CIK.patch
new file mode 100644
index 00000000..0e94f860
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-amd/0043-drm-radeon-fix-CP-semaphores-on-CIK.patch
@@ -0,0 +1,117 @@
+From 6aa3711a4b7e021f834b4b5aaa8e15e8a0fdc808 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig at amd.com>
+Date: Wed, 19 Feb 2014 13:21:35 -0500
+Subject: [PATCH 43/60] drm/radeon: fix CP semaphores on CIK
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig at amd.com>
+---
+ drivers/gpu/drm/radeon/radeon.h | 4 +++-
+ drivers/gpu/drm/radeon/radeon_ring.c | 2 +-
+ drivers/gpu/drm/radeon/radeon_semaphore.c | 19 ++++++++++++++++---
+ 3 files changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
+index d3f1389..e98da4b 100644
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -137,6 +137,9 @@ extern int radeon_aspm;
+ /* max number of rings */
+ #define RADEON_NUM_RINGS 8
+
++/* number of hw syncs before falling back on blocking */
++#define RADEON_NUM_SYNCS 4
++
+ /* hardcode those limit for now */
+ #define RADEON_VA_IB_OFFSET (1 << 20)
+ #define RADEON_VA_RESERVED_SIZE (8 << 20)
+@@ -553,7 +556,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp,
+ /*
+ * Semaphores.
+ */
+-/* everything here is constant */
+ struct radeon_semaphore {
+ struct radeon_sa_bo *sa_bo;
+ signed waiters;
+diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
+index 91457f8..529893fc 100644
+--- a/drivers/gpu/drm/radeon/radeon_ring.c
++++ b/drivers/gpu/drm/radeon/radeon_ring.c
+@@ -139,7 +139,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
+ }
+
+ /* 64 dwords should be enough for fence too */
+- r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8);
++ r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8);
+ if (r) {
+ dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
+ return r;
+diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
+index 2b42aa1..9006b32 100644
+--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
++++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
+@@ -34,14 +34,15 @@
+ int radeon_semaphore_create(struct radeon_device *rdev,
+ struct radeon_semaphore **semaphore)
+ {
++ uint32_t *cpu_addr;
+ int i, r;
+
+ *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL);
+ if (*semaphore == NULL) {
+ return -ENOMEM;
+ }
+- r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo,
+- &(*semaphore)->sa_bo, 8, 8, true);
++ r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo,
++ 8 * RADEON_NUM_SYNCS, 8, true);
+ if (r) {
+ kfree(*semaphore);
+ *semaphore = NULL;
+@@ -49,7 +50,10 @@ int radeon_semaphore_create(struct radeon_device *rdev,
+ }
+ (*semaphore)->waiters = 0;
+ (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
+- *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
++
++ cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo);
++ for (i = 0; i < RADEON_NUM_SYNCS; ++i)
++ cpu_addr[i] = 0;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i)
+ (*semaphore)->sync_to[i] = NULL;
+@@ -125,6 +129,7 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+ struct radeon_semaphore *semaphore,
+ int ring)
+ {
++ unsigned count = 0;
+ int i, r;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+@@ -140,6 +145,12 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+ return -EINVAL;
+ }
+
++ if (++count > RADEON_NUM_SYNCS) {
++ /* not enough room, wait manually */
++ radeon_fence_wait_locked(fence);
++ continue;
++ }
++
+ /* allocate enough space for sync command */
+ r = radeon_ring_alloc(rdev, &rdev->ring[i], 16);
+ if (r) {
+@@ -164,6 +175,8 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+
+ radeon_ring_commit(rdev, &rdev->ring[i]);
+ radeon_fence_note_sync(fence, ring);
++
++ semaphore->gpu_addr += 8;
+ }
+
+ return 0;
+--
+1.9.1
+