diff options
Diffstat (limited to 'meta-baldeagle/recipes-kernel/linux/linux-yocto/0004-yocto-poky-dora-10.0.0-amd-drm-radeon-allow-semaphore-emission-to-fail.patch')
-rw-r--r-- | meta-baldeagle/recipes-kernel/linux/linux-yocto/0004-yocto-poky-dora-10.0.0-amd-drm-radeon-allow-semaphore-emission-to-fail.patch | 754 |
1 files changed, 0 insertions, 754 deletions
diff --git a/meta-baldeagle/recipes-kernel/linux/linux-yocto/0004-yocto-poky-dora-10.0.0-amd-drm-radeon-allow-semaphore-emission-to-fail.patch b/meta-baldeagle/recipes-kernel/linux/linux-yocto/0004-yocto-poky-dora-10.0.0-amd-drm-radeon-allow-semaphore-emission-to-fail.patch deleted file mode 100644 index f8d0e106..00000000 --- a/meta-baldeagle/recipes-kernel/linux/linux-yocto/0004-yocto-poky-dora-10.0.0-amd-drm-radeon-allow-semaphore-emission-to-fail.patch +++ /dev/null @@ -1,754 +0,0 @@ -From 26046527719672da3148501129151ccbceaf8339 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> -Date: Mon, 8 Jul 2013 05:11:52 -0600 -Subject: [PATCH 04/44] drm/radeon: allow semaphore emission to fail -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some rings can only use semaphore in certain states, take that into account -and fall back to waiting for a fence when a ring currently can't emit a -semaphore. - -Signed-off-by: Christian König <christian.koenig@amd.com> ---- - drivers/gpu/drm/radeon/cik.c | 4 +- - drivers/gpu/drm/radeon/cik_sdma.c | 13 ++- - drivers/gpu/drm/radeon/evergreen_dma.c | 9 +-- - drivers/gpu/drm/radeon/r100.c | 3 +- - drivers/gpu/drm/radeon/r600.c | 13 ++- - drivers/gpu/drm/radeon/r600_dma.c | 13 ++- - drivers/gpu/drm/radeon/radeon.h | 14 ++-- - drivers/gpu/drm/radeon/radeon_asic.h | 18 ++--- - drivers/gpu/drm/radeon/radeon_cs.c | 9 ++- - drivers/gpu/drm/radeon/radeon_fence.c | 26 ++++++ - drivers/gpu/drm/radeon/radeon_gart.c | 2 +- - drivers/gpu/drm/radeon/radeon_ring.c | 46 +++-------- - drivers/gpu/drm/radeon/radeon_semaphore.c | 123 ++++++++++++++++++++++------- - drivers/gpu/drm/radeon/rv770_dma.c | 9 +-- - drivers/gpu/drm/radeon/si_dma.c | 9 +-- - drivers/gpu/drm/radeon/uvd_v1_0.c | 4 +- - drivers/gpu/drm/radeon/uvd_v3_1.c | 4 +- - 17 files changed, 182 insertions(+), 137 deletions(-) - -diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c -index 2277a59..0608446 100644 ---- a/drivers/gpu/drm/radeon/cik.c -+++ b/drivers/gpu/drm/radeon/cik.c -@@ -3082,7 +3082,7 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev, - cik_cp_hdp_flush(rdev, ring); - } - --void cik_semaphore_ring_emit(struct radeon_device *rdev, -+bool cik_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -@@ -3093,6 +3093,8 @@ void cik_semaphore_ring_emit(struct radeon_device *rdev, - radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - radeon_ring_write(ring, addr & 0xffffffff); - radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); -+ -+ return true; - } - - /* -diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c -index 56ede52..ace0bc6 100644 ---- a/drivers/gpu/drm/radeon/cik_sdma.c -+++ b/drivers/gpu/drm/radeon/cik_sdma.c -@@ -133,7 +133,7 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, - * Add a DMA semaphore packet to the ring wait on or signal - * other rings (CIK). - */ --void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, -+bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -@@ -144,6 +144,8 @@ void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SEMAPHORE, 0, extra_bits)); - radeon_ring_write(ring, addr & 0xfffffff8); - radeon_ring_write(ring, upper_32_bits(addr) & 0xffffffff); -+ -+ return true; - } - - /** -@@ -446,13 +448,8 @@ int cik_copy_dma(struct radeon_device *rdev, - return r; - } - -- if (radeon_fence_need_sync(*fence, ring->idx)) { -- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, -- ring->idx); -- radeon_fence_note_sync(*fence, ring->idx); -- } else { -- radeon_semaphore_free(rdev, &sem, NULL); -- } -+ radeon_semaphore_sync_to(sem, *fence); -+ radeon_semaphore_sync_rings(rdev, sem, ring->idx); - - for (i = 0; i < num_loops; i++) { - cur_size_in_bytes = size_in_bytes; -diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c -index 6a0656d..a37b544 100644 ---- a/drivers/gpu/drm/radeon/evergreen_dma.c -+++ b/drivers/gpu/drm/radeon/evergreen_dma.c -@@ -131,13 +131,8 @@ int evergreen_copy_dma(struct radeon_device *rdev, - return r; - } - -- if (radeon_fence_need_sync(*fence, ring->idx)) { -- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, -- ring->idx); -- radeon_fence_note_sync(*fence, ring->idx); -- } else { -- radeon_semaphore_free(rdev, &sem, NULL); -- } -+ radeon_semaphore_sync_to(sem, *fence); -+ radeon_semaphore_sync_rings(rdev, sem, ring->idx); - - for (i = 0; i < num_loops; i++) { - cur_size_in_dw = size_in_dw; -diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c -index d713330..aa015a5 100644 ---- a/drivers/gpu/drm/radeon/r100.c -+++ b/drivers/gpu/drm/radeon/r100.c -@@ -869,13 +869,14 @@ void r100_fence_ring_emit(struct radeon_device *rdev, - radeon_ring_write(ring, RADEON_SW_INT_FIRE); - } - --void r100_semaphore_ring_emit(struct radeon_device *rdev, -+bool r100_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) - { - /* Unused on older asics, since we don't have semaphores or multiple rings */ - BUG(); -+ return false; - } - - int r100_copy_blit(struct radeon_device *rdev, -diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c -index f9be220..a5de2cf 100644 ---- a/drivers/gpu/drm/radeon/r600.c -+++ b/drivers/gpu/drm/radeon/r600.c -@@ -2597,7 +2597,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev, - } - } - --void r600_semaphore_ring_emit(struct radeon_device *rdev, -+bool r600_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -@@ -2611,6 +2611,8 @@ void r600_semaphore_ring_emit(struct radeon_device *rdev, - radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - radeon_ring_write(ring, addr & 0xffffffff); - radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); -+ -+ return true; - } - - /** -@@ -2653,13 +2655,8 @@ int r600_copy_cpdma(struct radeon_device *rdev, - return r; - } - -- if (radeon_fence_need_sync(*fence, ring->idx)) { -- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, -- ring->idx); -- radeon_fence_note_sync(*fence, ring->idx); -- } else { -- radeon_semaphore_free(rdev, &sem, NULL); -- } -+ radeon_semaphore_sync_to(sem, *fence); -+ radeon_semaphore_sync_rings(rdev, sem, ring->idx); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); -diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c -index 3b31745..7844d15 100644 ---- a/drivers/gpu/drm/radeon/r600_dma.c -+++ b/drivers/gpu/drm/radeon/r600_dma.c -@@ -311,7 +311,7 @@ void r600_dma_fence_ring_emit(struct radeon_device *rdev, - * Add a DMA semaphore packet to the ring wait on or signal - * other rings (r6xx-SI). - */ --void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, -+bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -@@ -322,6 +322,8 @@ void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, - radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SEMAPHORE, 0, s, 0)); - radeon_ring_write(ring, addr & 0xfffffffc); - radeon_ring_write(ring, upper_32_bits(addr) & 0xff); -+ -+ return true; - } - - /** -@@ -462,13 +464,8 @@ int r600_copy_dma(struct radeon_device *rdev, - return r; - } - -- if (radeon_fence_need_sync(*fence, ring->idx)) { -- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, -- ring->idx); -- radeon_fence_note_sync(*fence, ring->idx); -- } else { -- radeon_semaphore_free(rdev, &sem, NULL); -- } -+ radeon_semaphore_sync_to(sem, *fence); -+ radeon_semaphore_sync_rings(rdev, sem, ring->idx); - - for (i = 0; i < num_loops; i++) { - cur_size_in_dw = size_in_dw; -diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h -index f44ca58..c0d4230 100644 ---- a/drivers/gpu/drm/radeon/radeon.h -+++ b/drivers/gpu/drm/radeon/radeon.h -@@ -348,6 +348,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, i - void radeon_fence_process(struct radeon_device *rdev, int ring); - bool radeon_fence_signaled(struct radeon_fence *fence); - int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); -+int radeon_fence_wait_locked(struct radeon_fence *fence); - int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); - int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); - int radeon_fence_wait_any(struct radeon_device *rdev, -@@ -548,17 +549,20 @@ struct radeon_semaphore { - struct radeon_sa_bo *sa_bo; - signed waiters; - uint64_t gpu_addr; -+ struct radeon_fence *sync_to[RADEON_NUM_RINGS]; - }; - - int radeon_semaphore_create(struct radeon_device *rdev, - struct radeon_semaphore **semaphore); --void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, -+bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore); --void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, -+bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore); -+void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, -+ struct radeon_fence *fence); - int radeon_semaphore_sync_rings(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, -- int signaler, int waiter); -+ int waiting_ring); - void radeon_semaphore_free(struct radeon_device *rdev, - struct radeon_semaphore **semaphore, - struct radeon_fence *fence); -@@ -765,7 +769,6 @@ struct radeon_ib { - struct radeon_fence *fence; - struct radeon_vm *vm; - bool is_const_ib; -- struct radeon_fence *sync_to[RADEON_NUM_RINGS]; - struct radeon_semaphore *semaphore; - }; - -@@ -915,7 +918,6 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, - struct radeon_ib *ib, struct radeon_vm *vm, - unsigned size); - void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); --void radeon_ib_sync_to(struct radeon_ib *ib, struct radeon_fence *fence); - int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, - struct radeon_ib *const_ib); - int radeon_ib_pool_init(struct radeon_device *rdev); -@@ -1629,7 +1631,7 @@ struct radeon_asic_ring { - /* command emmit functions */ - void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); - void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence); -- void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, -+ bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, - struct radeon_semaphore *semaphore, bool emit_wait); - void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); - -diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h -index 70c29d5..8588670 100644 ---- a/drivers/gpu/drm/radeon/radeon_asic.h -+++ b/drivers/gpu/drm/radeon/radeon_asic.h -@@ -80,7 +80,7 @@ int r100_irq_set(struct radeon_device *rdev); - int r100_irq_process(struct radeon_device *rdev); - void r100_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); --void r100_semaphore_ring_emit(struct radeon_device *rdev, -+bool r100_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *cp, - struct radeon_semaphore *semaphore, - bool emit_wait); -@@ -313,13 +313,13 @@ int r600_cs_parse(struct radeon_cs_parser *p); - int r600_dma_cs_parse(struct radeon_cs_parser *p); - void r600_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); --void r600_semaphore_ring_emit(struct radeon_device *rdev, -+bool r600_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *cp, - struct radeon_semaphore *semaphore, - bool emit_wait); - void r600_dma_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); --void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, -+bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait); -@@ -566,10 +566,6 @@ int sumo_dpm_force_performance_level(struct radeon_device *rdev, - */ - void cayman_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); --void cayman_uvd_semaphore_emit(struct radeon_device *rdev, -- struct radeon_ring *ring, -- struct radeon_semaphore *semaphore, -- bool emit_wait); - void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev); - int cayman_init(struct radeon_device *rdev); - void cayman_fini(struct radeon_device *rdev); -@@ -696,7 +692,7 @@ void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); - int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); - void cik_sdma_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); --void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, -+bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait); -@@ -712,7 +708,7 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); - void cik_fence_compute_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); --void cik_semaphore_ring_emit(struct radeon_device *rdev, -+bool cik_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *cp, - struct radeon_semaphore *semaphore, - bool emit_wait); -@@ -802,7 +798,7 @@ void uvd_v1_0_stop(struct radeon_device *rdev); - - int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); - int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); --void uvd_v1_0_semaphore_emit(struct radeon_device *rdev, -+bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait); -@@ -814,7 +810,7 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev, - struct radeon_fence *fence); - - /* uvd v3.1 */ --void uvd_v3_1_semaphore_emit(struct radeon_device *rdev, -+bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait); -diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c -index 80285e3..eb5cd94 100644 ---- a/drivers/gpu/drm/radeon/radeon_cs.c -+++ b/drivers/gpu/drm/radeon/radeon_cs.c -@@ -159,7 +159,8 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p) - if (!p->relocs[i].robj) - continue; - -- radeon_ib_sync_to(&p->ib, p->relocs[i].robj->tbo.sync_obj); -+ radeon_semaphore_sync_to(p->ib.semaphore, -+ p->relocs[i].robj->tbo.sync_obj); - } - } - -@@ -495,9 +496,9 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, - goto out; - } - radeon_cs_sync_rings(parser); -- radeon_ib_sync_to(&parser->ib, vm->fence); -- radeon_ib_sync_to(&parser->ib, radeon_vm_grab_id( -- rdev, vm, parser->ring)); -+ radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence); -+ radeon_semaphore_sync_to(parser->ib.semaphore, -+ radeon_vm_grab_id(rdev, vm, parser->ring)); - - if ((rdev->family >= CHIP_TAHITI) && - (parser->chunk_const_ib_idx != -1)) { -diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c -index ddb8f8e..8aea16e 100644 ---- a/drivers/gpu/drm/radeon/radeon_fence.c -+++ b/drivers/gpu/drm/radeon/radeon_fence.c -@@ -404,6 +404,32 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) - return 0; - } - -+/** -+ * radeon_fence_wait_locked - wait for a fence to signal -+ * -+ * @fence: radeon fence object -+ * -+ * Wait for the requested fence to signal (all asics). -+ * Returns 0 if the fence has passed, error for all other cases. -+ */ -+int radeon_fence_wait_locked(struct radeon_fence *fence) -+{ -+ int r; -+ -+ if (fence == NULL) { -+ WARN(1, "Querying an invalid fence : %p !\n", fence); -+ return -EINVAL; -+ } -+ -+ r = radeon_fence_wait_seq(fence->rdev, fence->seq, -+ fence->ring, false, false); -+ if (r) { -+ return r; -+ } -+ fence->seq = RADEON_FENCE_SIGNALED_SEQ; -+ return 0; -+} -+ - static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) - { - unsigned i; -diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c -index 3b1de72..f8d7b16 100644 ---- a/drivers/gpu/drm/radeon/radeon_gart.c -+++ b/drivers/gpu/drm/radeon/radeon_gart.c -@@ -1169,7 +1169,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, - radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset, - addr, bo_va->flags); - -- radeon_ib_sync_to(&ib, vm->fence); -+ radeon_semaphore_sync_to(ib.semaphore, vm->fence); - r = radeon_ib_schedule(rdev, &ib, NULL); - if (r) { - radeon_ib_free(rdev, &ib); -diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c -index 18254e1..9214403 100644 ---- a/drivers/gpu/drm/radeon/radeon_ring.c -+++ b/drivers/gpu/drm/radeon/radeon_ring.c -@@ -61,7 +61,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, - struct radeon_ib *ib, struct radeon_vm *vm, - unsigned size) - { -- int i, r; -+ int r; - - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true); - if (r) { -@@ -87,8 +87,6 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, - ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); - } - ib->is_const_ib = false; -- for (i = 0; i < RADEON_NUM_RINGS; ++i) -- ib->sync_to[i] = NULL; - - return 0; - } -@@ -109,25 +107,6 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) - } - - /** -- * radeon_ib_sync_to - sync to fence before executing the IB -- * -- * @ib: IB object to add fence to -- * @fence: fence to sync to -- * -- * Sync to the fence before executing the IB -- */ --void radeon_ib_sync_to(struct radeon_ib *ib, struct radeon_fence *fence) --{ -- struct radeon_fence *other; -- -- if (!fence) -- return; -- -- other = ib->sync_to[fence->ring]; -- ib->sync_to[fence->ring] = radeon_fence_later(fence, other); --} -- --/** - * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring - * - * @rdev: radeon_device pointer -@@ -151,8 +130,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, - struct radeon_ib *const_ib) - { - struct radeon_ring *ring = &rdev->ring[ib->ring]; -- bool need_sync = false; -- int i, r = 0; -+ int r = 0; - - if (!ib->length_dw || !ring->ready) { - /* TODO: Nothings in the ib we should report. */ -@@ -166,19 +144,15 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, - dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); - return r; - } -- for (i = 0; i < RADEON_NUM_RINGS; ++i) { -- struct radeon_fence *fence = ib->sync_to[i]; -- if (radeon_fence_need_sync(fence, ib->ring)) { -- need_sync = true; -- radeon_semaphore_sync_rings(rdev, ib->semaphore, -- fence->ring, ib->ring); -- radeon_fence_note_sync(fence, ib->ring); -- } -- } -- /* immediately free semaphore when we don't need to sync */ -- if (!need_sync) { -- radeon_semaphore_free(rdev, &ib->semaphore, NULL); -+ -+ /* sync with other rings */ -+ r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); -+ if (r) { -+ dev_err(rdev->dev, "failed to sync rings (%d)\n", r); -+ radeon_ring_unlock_undo(rdev, ring); -+ return r; - } -+ - /* if we can't remember our last VM flush then flush now! */ - /* XXX figure out why we have to flush for every IB */ - if (ib->vm /*&& !ib->vm->last_flush*/) { -diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c -index 8dcc20f..34ea889 100644 ---- a/drivers/gpu/drm/radeon/radeon_semaphore.c -+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c -@@ -34,7 +34,7 @@ - int radeon_semaphore_create(struct radeon_device *rdev, - struct radeon_semaphore **semaphore) - { -- int r; -+ int i, r; - - *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); - if (*semaphore == NULL) { -@@ -50,54 +50,117 @@ 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; -+ -+ for (i = 0; i < RADEON_NUM_RINGS; ++i) -+ (*semaphore)->sync_to[i] = NULL; -+ - return 0; - } - --void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, -+bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ridx, - struct radeon_semaphore *semaphore) - { -- --semaphore->waiters; -- radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); -+ struct radeon_ring *ring = &rdev->ring[ridx]; -+ -+ if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, false)) { -+ --semaphore->waiters; -+ -+ /* for debugging lockup only, used by sysfs debug files */ -+ ring->last_semaphore_signal_addr = semaphore->gpu_addr; -+ return true; -+ } -+ return false; - } - --void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, -+bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, - struct radeon_semaphore *semaphore) - { -- ++semaphore->waiters; -- radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); -+ struct radeon_ring *ring = &rdev->ring[ridx]; -+ -+ if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, true)) { -+ ++semaphore->waiters; -+ -+ /* for debugging lockup only, used by sysfs debug files */ -+ ring->last_semaphore_wait_addr = semaphore->gpu_addr; -+ return true; -+ } -+ return false; - } - --/* caller must hold ring lock */ -+/** -+ * radeon_semaphore_sync_to - use the semaphore to sync to a fence -+ * -+ * @semaphore: semaphore object to add fence to -+ * @fence: fence to sync to -+ * -+ * Sync to the fence using this semaphore object -+ */ -+void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, -+ struct radeon_fence *fence) -+{ -+ struct radeon_fence *other; -+ -+ if (!fence) -+ return; -+ -+ other = semaphore->sync_to[fence->ring]; -+ semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other); -+} -+ -+/** -+ * radeon_semaphore_sync_rings - sync ring to all registered fences -+ * -+ * @rdev: radeon_device pointer -+ * @semaphore: semaphore object to use for sync -+ * @ring: ring that needs sync -+ * -+ * Ensure that all registered fences are signaled before letting -+ * the ring continue. The caller must hold the ring lock. -+ */ - int radeon_semaphore_sync_rings(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, -- int signaler, int waiter) -+ int ring) - { -- int r; -+ int i, r; - -- /* no need to signal and wait on the same ring */ -- if (signaler == waiter) { -- return 0; -- } -+ for (i = 0; i < RADEON_NUM_RINGS; ++i) { -+ struct radeon_fence *fence = semaphore->sync_to[i]; - -- /* prevent GPU deadlocks */ -- if (!rdev->ring[signaler].ready) { -- dev_err(rdev->dev, "Trying to sync to a disabled ring!"); -- return -EINVAL; -- } -+ /* check if we really need to sync */ -+ if (!radeon_fence_need_sync(fence, ring)) -+ continue; - -- r = radeon_ring_alloc(rdev, &rdev->ring[signaler], 8); -- if (r) { -- return r; -- } -- radeon_semaphore_emit_signal(rdev, signaler, semaphore); -- radeon_ring_commit(rdev, &rdev->ring[signaler]); -+ /* prevent GPU deadlocks */ -+ if (!rdev->ring[i].ready) { -+ dev_err(rdev->dev, "Syncing to a disabled ring!"); -+ return -EINVAL; -+ } - -- /* we assume caller has already allocated space on waiters ring */ -- radeon_semaphore_emit_wait(rdev, waiter, semaphore); -+ /* allocate enough space for sync command */ -+ r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); -+ if (r) { -+ return r; -+ } - -- /* for debugging lockup only, used by sysfs debug files */ -- rdev->ring[signaler].last_semaphore_signal_addr = semaphore->gpu_addr; -- rdev->ring[waiter].last_semaphore_wait_addr = semaphore->gpu_addr; -+ /* emit the signal semaphore */ -+ if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { -+ /* signaling wasn't successful wait manually */ -+ radeon_ring_undo(&rdev->ring[i]); -+ radeon_fence_wait_locked(fence); -+ continue; -+ } -+ -+ /* we assume caller has already allocated space on waiters ring */ -+ if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { -+ /* waiting wasn't successful wait manually */ -+ radeon_ring_undo(&rdev->ring[i]); -+ radeon_fence_wait_locked(fence); -+ continue; -+ } -+ -+ radeon_ring_commit(rdev, &rdev->ring[i]); -+ radeon_fence_note_sync(fence, ring); -+ } - - return 0; - } -diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c -index f9b02e3..aca8cbe 100644 ---- a/drivers/gpu/drm/radeon/rv770_dma.c -+++ b/drivers/gpu/drm/radeon/rv770_dma.c -@@ -66,13 +66,8 @@ int rv770_copy_dma(struct radeon_device *rdev, - return r; - } - -- if (radeon_fence_need_sync(*fence, ring->idx)) { -- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, -- ring->idx); -- radeon_fence_note_sync(*fence, ring->idx); -- } else { -- radeon_semaphore_free(rdev, &sem, NULL); -- } -+ radeon_semaphore_sync_to(sem, *fence); -+ radeon_semaphore_sync_rings(rdev, sem, ring->idx); - - for (i = 0; i < num_loops; i++) { - cur_size_in_dw = size_in_dw; -diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c -index 17205fd..97af34c 100644 ---- a/drivers/gpu/drm/radeon/si_dma.c -+++ b/drivers/gpu/drm/radeon/si_dma.c -@@ -202,13 +202,8 @@ int si_copy_dma(struct radeon_device *rdev, - return r; - } - -- if (radeon_fence_need_sync(*fence, ring->idx)) { -- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, -- ring->idx); -- radeon_fence_note_sync(*fence, ring->idx); -- } else { -- radeon_semaphore_free(rdev, &sem, NULL); -- } -+ radeon_semaphore_sync_to(sem, *fence); -+ radeon_semaphore_sync_rings(rdev, sem, ring->idx); - - for (i = 0; i < num_loops; i++) { - cur_size_in_bytes = size_in_bytes; -diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c -index 7266805..d4a68af 100644 ---- a/drivers/gpu/drm/radeon/uvd_v1_0.c -+++ b/drivers/gpu/drm/radeon/uvd_v1_0.c -@@ -357,7 +357,7 @@ int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) - * - * Emit a semaphore command (either wait or signal) to the UVD ring. - */ --void uvd_v1_0_semaphore_emit(struct radeon_device *rdev, -+bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -@@ -372,6 +372,8 @@ void uvd_v1_0_semaphore_emit(struct radeon_device *rdev, - - radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); - radeon_ring_write(ring, emit_wait ? 1 : 0); -+ -+ return true; - } - - /** -diff --git a/drivers/gpu/drm/radeon/uvd_v3_1.c b/drivers/gpu/drm/radeon/uvd_v3_1.c -index 5b6fa1f..d722db2 100644 ---- a/drivers/gpu/drm/radeon/uvd_v3_1.c -+++ b/drivers/gpu/drm/radeon/uvd_v3_1.c -@@ -37,7 +37,7 @@ - * - * Emit a semaphore command (either wait or signal) to the UVD ring. - */ --void uvd_v3_1_semaphore_emit(struct radeon_device *rdev, -+bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -@@ -52,4 +52,6 @@ void uvd_v3_1_semaphore_emit(struct radeon_device *rdev, - - radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); - radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); -+ -+ return true; - } --- -1.7.9.5 - |