diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 108 |
1 files changed, 104 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 147e92b3a959..b8002ac3e536 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include <linux/kernel.h> | ||
23 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
24 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
25 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
@@ -3952,10 +3953,10 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev) | |||
3952 | adev->gfx.rlc.reg_list_format_size_bytes >> 2, | 3953 | adev->gfx.rlc.reg_list_format_size_bytes >> 2, |
3953 | unique_indices, | 3954 | unique_indices, |
3954 | &indices_count, | 3955 | &indices_count, |
3955 | sizeof(unique_indices) / sizeof(int), | 3956 | ARRAY_SIZE(unique_indices), |
3956 | indirect_start_offsets, | 3957 | indirect_start_offsets, |
3957 | &offset_count, | 3958 | &offset_count, |
3958 | sizeof(indirect_start_offsets)/sizeof(int)); | 3959 | ARRAY_SIZE(indirect_start_offsets)); |
3959 | 3960 | ||
3960 | /* save and restore list */ | 3961 | /* save and restore list */ |
3961 | WREG32_FIELD(RLC_SRM_CNTL, AUTO_INCR_ADDR, 1); | 3962 | WREG32_FIELD(RLC_SRM_CNTL, AUTO_INCR_ADDR, 1); |
@@ -3977,14 +3978,14 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev) | |||
3977 | /* starting offsets starts */ | 3978 | /* starting offsets starts */ |
3978 | WREG32(mmRLC_GPM_SCRATCH_ADDR, | 3979 | WREG32(mmRLC_GPM_SCRATCH_ADDR, |
3979 | adev->gfx.rlc.starting_offsets_start); | 3980 | adev->gfx.rlc.starting_offsets_start); |
3980 | for (i = 0; i < sizeof(indirect_start_offsets)/sizeof(int); i++) | 3981 | for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++) |
3981 | WREG32(mmRLC_GPM_SCRATCH_DATA, | 3982 | WREG32(mmRLC_GPM_SCRATCH_DATA, |
3982 | indirect_start_offsets[i]); | 3983 | indirect_start_offsets[i]); |
3983 | 3984 | ||
3984 | /* unique indices */ | 3985 | /* unique indices */ |
3985 | temp = mmRLC_SRM_INDEX_CNTL_ADDR_0; | 3986 | temp = mmRLC_SRM_INDEX_CNTL_ADDR_0; |
3986 | data = mmRLC_SRM_INDEX_CNTL_DATA_0; | 3987 | data = mmRLC_SRM_INDEX_CNTL_DATA_0; |
3987 | for (i = 0; i < sizeof(unique_indices) / sizeof(int); i++) { | 3988 | for (i = 0; i < ARRAY_SIZE(unique_indices); i++) { |
3988 | if (unique_indices[i] != 0) { | 3989 | if (unique_indices[i] != 0) { |
3989 | WREG32(temp + i, unique_indices[i] & 0x3FFFF); | 3990 | WREG32(temp + i, unique_indices[i] & 0x3FFFF); |
3990 | WREG32(data + i, unique_indices[i] >> 20); | 3991 | WREG32(data + i, unique_indices[i] >> 20); |
@@ -6394,6 +6395,104 @@ static void gfx_v8_0_ring_set_wptr_compute(struct amdgpu_ring *ring) | |||
6394 | WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); | 6395 | WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); |
6395 | } | 6396 | } |
6396 | 6397 | ||
6398 | static void gfx_v8_0_ring_set_pipe_percent(struct amdgpu_ring *ring, | ||
6399 | bool acquire) | ||
6400 | { | ||
6401 | struct amdgpu_device *adev = ring->adev; | ||
6402 | int pipe_num, tmp, reg; | ||
6403 | int pipe_percent = acquire ? SPI_WCL_PIPE_PERCENT_GFX__VALUE_MASK : 0x1; | ||
6404 | |||
6405 | pipe_num = ring->me * adev->gfx.mec.num_pipe_per_mec + ring->pipe; | ||
6406 | |||
6407 | /* first me only has 2 entries, GFX and HP3D */ | ||
6408 | if (ring->me > 0) | ||
6409 | pipe_num -= 2; | ||
6410 | |||
6411 | reg = mmSPI_WCL_PIPE_PERCENT_GFX + pipe_num; | ||
6412 | tmp = RREG32(reg); | ||
6413 | tmp = REG_SET_FIELD(tmp, SPI_WCL_PIPE_PERCENT_GFX, VALUE, pipe_percent); | ||
6414 | WREG32(reg, tmp); | ||
6415 | } | ||
6416 | |||
6417 | static void gfx_v8_0_pipe_reserve_resources(struct amdgpu_device *adev, | ||
6418 | struct amdgpu_ring *ring, | ||
6419 | bool acquire) | ||
6420 | { | ||
6421 | int i, pipe; | ||
6422 | bool reserve; | ||
6423 | struct amdgpu_ring *iring; | ||
6424 | |||
6425 | mutex_lock(&adev->gfx.pipe_reserve_mutex); | ||
6426 | pipe = amdgpu_gfx_queue_to_bit(adev, ring->me, ring->pipe, 0); | ||
6427 | if (acquire) | ||
6428 | set_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6429 | else | ||
6430 | clear_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6431 | |||
6432 | if (!bitmap_weight(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES)) { | ||
6433 | /* Clear all reservations - everyone reacquires all resources */ | ||
6434 | for (i = 0; i < adev->gfx.num_gfx_rings; ++i) | ||
6435 | gfx_v8_0_ring_set_pipe_percent(&adev->gfx.gfx_ring[i], | ||
6436 | true); | ||
6437 | |||
6438 | for (i = 0; i < adev->gfx.num_compute_rings; ++i) | ||
6439 | gfx_v8_0_ring_set_pipe_percent(&adev->gfx.compute_ring[i], | ||
6440 | true); | ||
6441 | } else { | ||
6442 | /* Lower all pipes without a current reservation */ | ||
6443 | for (i = 0; i < adev->gfx.num_gfx_rings; ++i) { | ||
6444 | iring = &adev->gfx.gfx_ring[i]; | ||
6445 | pipe = amdgpu_gfx_queue_to_bit(adev, | ||
6446 | iring->me, | ||
6447 | iring->pipe, | ||
6448 | 0); | ||
6449 | reserve = test_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6450 | gfx_v8_0_ring_set_pipe_percent(iring, reserve); | ||
6451 | } | ||
6452 | |||
6453 | for (i = 0; i < adev->gfx.num_compute_rings; ++i) { | ||
6454 | iring = &adev->gfx.compute_ring[i]; | ||
6455 | pipe = amdgpu_gfx_queue_to_bit(adev, | ||
6456 | iring->me, | ||
6457 | iring->pipe, | ||
6458 | 0); | ||
6459 | reserve = test_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6460 | gfx_v8_0_ring_set_pipe_percent(iring, reserve); | ||
6461 | } | ||
6462 | } | ||
6463 | |||
6464 | mutex_unlock(&adev->gfx.pipe_reserve_mutex); | ||
6465 | } | ||
6466 | |||
6467 | static void gfx_v8_0_hqd_set_priority(struct amdgpu_device *adev, | ||
6468 | struct amdgpu_ring *ring, | ||
6469 | bool acquire) | ||
6470 | { | ||
6471 | uint32_t pipe_priority = acquire ? 0x2 : 0x0; | ||
6472 | uint32_t queue_priority = acquire ? 0xf : 0x0; | ||
6473 | |||
6474 | mutex_lock(&adev->srbm_mutex); | ||
6475 | vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); | ||
6476 | |||
6477 | WREG32(mmCP_HQD_PIPE_PRIORITY, pipe_priority); | ||
6478 | WREG32(mmCP_HQD_QUEUE_PRIORITY, queue_priority); | ||
6479 | |||
6480 | vi_srbm_select(adev, 0, 0, 0, 0); | ||
6481 | mutex_unlock(&adev->srbm_mutex); | ||
6482 | } | ||
6483 | static void gfx_v8_0_ring_set_priority_compute(struct amdgpu_ring *ring, | ||
6484 | enum amd_sched_priority priority) | ||
6485 | { | ||
6486 | struct amdgpu_device *adev = ring->adev; | ||
6487 | bool acquire = priority == AMD_SCHED_PRIORITY_HIGH_HW; | ||
6488 | |||
6489 | if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) | ||
6490 | return; | ||
6491 | |||
6492 | gfx_v8_0_hqd_set_priority(adev, ring, acquire); | ||
6493 | gfx_v8_0_pipe_reserve_resources(adev, ring, acquire); | ||
6494 | } | ||
6495 | |||
6397 | static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, | 6496 | static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, |
6398 | u64 addr, u64 seq, | 6497 | u64 addr, u64 seq, |
6399 | unsigned flags) | 6498 | unsigned flags) |
@@ -6839,6 +6938,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { | |||
6839 | .test_ib = gfx_v8_0_ring_test_ib, | 6938 | .test_ib = gfx_v8_0_ring_test_ib, |
6840 | .insert_nop = amdgpu_ring_insert_nop, | 6939 | .insert_nop = amdgpu_ring_insert_nop, |
6841 | .pad_ib = amdgpu_ring_generic_pad_ib, | 6940 | .pad_ib = amdgpu_ring_generic_pad_ib, |
6941 | .set_priority = gfx_v8_0_ring_set_priority_compute, | ||
6842 | }; | 6942 | }; |
6843 | 6943 | ||
6844 | static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { | 6944 | static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { |