aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c108
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
6398static 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
6417static 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
6467static 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}
6483static 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
6397static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, 6496static 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
6844static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { 6944static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = {