diff options
author | Monk Liu <monk.liu@amd.com> | 2016-01-14 06:07:38 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-05-02 15:11:09 -0400 |
commit | 03ccf481980f8d3363263e73c64473d8f2779dc0 (patch) | |
tree | df0cad433591814429cc700ad4a013d51bdaec53 /drivers | |
parent | 128cff1af68689cf4d85d3ba948c86a194dee30f (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.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 25 |
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 | ||
455 | unsigned 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 | |||
467 | void 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 | * |