aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMonk Liu <monk.liu@amd.com>2016-01-14 06:07:38 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-05-02 15:11:09 -0400
commit03ccf481980f8d3363263e73c64473d8f2779dc0 (patch)
treedf0cad433591814429cc700ad4a013d51bdaec53 /drivers
parent128cff1af68689cf4d85d3ba948c86a194dee30f (diff)
drm/amdgpu: patch cond exec for SDMA
More ground work for conditional execution on SDMA necessary for preemption. Signed-off-by: Monk Liu <monk.liu@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c25
3 files changed, 37 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 49adb451c3bc..412fc2f39fa5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -302,6 +302,8 @@ struct amdgpu_ring_funcs {
302 void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count); 302 void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count);
303 /* pad the indirect buffer to the necessary number of dw */ 303 /* pad the indirect buffer to the necessary number of dw */
304 void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib); 304 void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
305 unsigned (*init_cond_exec)(struct amdgpu_ring *ring);
306 void (*patch_cond_exec)(struct amdgpu_ring *ring, unsigned offset);
305}; 307};
306 308
307/* 309/*
@@ -2182,6 +2184,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
2182#define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r)) 2184#define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r))
2183#define amdgpu_ring_emit_hdp_invalidate(r) (r)->funcs->emit_hdp_invalidate((r)) 2185#define amdgpu_ring_emit_hdp_invalidate(r) (r)->funcs->emit_hdp_invalidate((r))
2184#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib))) 2186#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
2187#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
2188#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
2185#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) 2189#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
2186#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) 2190#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
2187#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) 2191#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index a15d690d9089..644336d76aca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -124,7 +124,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
124 struct amdgpu_ctx *ctx, *old_ctx; 124 struct amdgpu_ctx *ctx, *old_ctx;
125 struct amdgpu_vm *vm; 125 struct amdgpu_vm *vm;
126 struct fence *hwf; 126 struct fence *hwf;
127 unsigned i; 127 unsigned i, patch_offset = ~0;
128
128 int r = 0; 129 int r = 0;
129 130
130 if (num_ibs == 0) 131 if (num_ibs == 0)
@@ -149,6 +150,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
149 return r; 150 return r;
150 } 151 }
151 152
153 if (ring->type == AMDGPU_RING_TYPE_SDMA && ring->funcs->init_cond_exec)
154 patch_offset = amdgpu_ring_init_cond_exec(ring);
155
152 if (vm) { 156 if (vm) {
153 /* do context switch */ 157 /* do context switch */
154 amdgpu_vm_flush(ring, ib->vm_id, ib->vm_pd_addr, 158 amdgpu_vm_flush(ring, ib->vm_id, ib->vm_pd_addr,
@@ -204,6 +208,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
204 if (f) 208 if (f)
205 *f = fence_get(hwf); 209 *f = fence_get(hwf);
206 210
211 if (patch_offset != ~0 && ring->funcs->patch_cond_exec)
212 amdgpu_ring_patch_cond_exec(ring, patch_offset);
213
207 amdgpu_ring_commit(ring); 214 amdgpu_ring_commit(ring);
208 return 0; 215 return 0;
209} 216}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 8c8ca98dd129..833d2658428f 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -452,6 +452,31 @@ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
452 amdgpu_ring_write(ring, SDMA_PKT_TRAP_INT_CONTEXT_INT_CONTEXT(0)); 452 amdgpu_ring_write(ring, SDMA_PKT_TRAP_INT_CONTEXT_INT_CONTEXT(0));
453} 453}
454 454
455unsigned init_cond_exec(struct amdgpu_ring *ring)
456{
457 unsigned ret;
458 amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_COND_EXE));
459 amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
460 amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
461 amdgpu_ring_write(ring, 1);
462 ret = ring->wptr;/* this is the offset we need patch later */
463 amdgpu_ring_write(ring, 0x55aa55aa);/* insert dummy here and patch it later */
464 return ret;
465}
466
467void patch_cond_exec(struct amdgpu_ring *ring, unsigned offset)
468{
469 unsigned cur;
470 BUG_ON(ring->ring[offset] != 0x55aa55aa);
471
472 cur = ring->wptr - 1;
473 if (likely(cur > offset))
474 ring->ring[offset] = cur - offset;
475 else
476 ring->ring[offset] = (ring->ring_size>>2) - offset + cur;
477}
478
479
455/** 480/**
456 * sdma_v3_0_gfx_stop - stop the gfx async dma engines 481 * sdma_v3_0_gfx_stop - stop the gfx async dma engines
457 * 482 *