aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2015-01-05 19:59:47 -0500
committerAlex Deucher <alexander.deucher@amd.com>2015-01-08 09:36:51 -0500
commit3a01fd367e09ebf05d75a000407364e7ebe2b678 (patch)
tree36e4e9a9e82b7e6cea9d146397b3788bdb91dce5 /drivers/gpu
parentd474ea7e52cbaaae22711d857949ba6018562c29 (diff)
drm/radeon: fix VM flush on CIK (v3)
We need to wait for the GPUVM flush to complete. There was some confusion as to how this mechanism was supposed to work. The operation is not atomic. For GPU initiated invalidations you need to read back a VM register to introduce enough latency for the update to complete. v2: drop gart changes v3: just read back rather than polling Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/cik.c11
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c10
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 6dcde3798b45..64fdae558d36 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -6033,6 +6033,17 @@ void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
6033 radeon_ring_write(ring, 0); 6033 radeon_ring_write(ring, 0);
6034 radeon_ring_write(ring, 1 << vm_id); 6034 radeon_ring_write(ring, 1 << vm_id);
6035 6035
6036 /* wait for the invalidate to complete */
6037 radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
6038 radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */
6039 WAIT_REG_MEM_FUNCTION(0) | /* always */
6040 WAIT_REG_MEM_ENGINE(0))); /* me */
6041 radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
6042 radeon_ring_write(ring, 0);
6043 radeon_ring_write(ring, 0); /* ref */
6044 radeon_ring_write(ring, 0); /* mask */
6045 radeon_ring_write(ring, 0x20); /* poll interval */
6046
6036 /* compute doesn't have PFP */ 6047 /* compute doesn't have PFP */
6037 if (usepfp) { 6048 if (usepfp) {
6038 /* sync PFP to ME, otherwise we might get invalid PFP reads */ 6049 /* sync PFP to ME, otherwise we might get invalid PFP reads */
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index dde5c7e29eb2..a0133c74f4cf 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -903,6 +903,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib)
903void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, 903void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
904 unsigned vm_id, uint64_t pd_addr) 904 unsigned vm_id, uint64_t pd_addr)
905{ 905{
906 u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) |
907 SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */
908
906 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 909 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
907 if (vm_id < 8) { 910 if (vm_id < 8) {
908 radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); 911 radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2);
@@ -943,5 +946,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
943 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 946 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
944 radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 947 radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
945 radeon_ring_write(ring, 1 << vm_id); 948 radeon_ring_write(ring, 1 << vm_id);
949
950 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
951 radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
952 radeon_ring_write(ring, 0);
953 radeon_ring_write(ring, 0); /* reference */
954 radeon_ring_write(ring, 0); /* mask */
955 radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */
946} 956}
947 957