aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/si_dma.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2015-01-05 19:54:50 -0500
committerAlex Deucher <alexander.deucher@amd.com>2015-01-08 09:36:50 -0500
commitd474ea7e52cbaaae22711d857949ba6018562c29 (patch)
tree3a83f3fa0f79f230e16869b16f35cb8c469beb91 /drivers/gpu/drm/radeon/si_dma.c
parentdrm/radeon: fix VM flush on cayman/aruba (v3) (diff)
downloadlinux-dev-d474ea7e52cbaaae22711d857949ba6018562c29.tar.xz
linux-dev-d474ea7e52cbaaae22711d857949ba6018562c29.zip
drm/radeon: fix VM flush on SI (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/drm/radeon/si_dma.c')
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index f5cc777e1c5f..aa7b872b2c43 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -206,6 +206,14 @@ void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
radeon_ring_write(ring, 1 << vm_id);
+
+ /* wait for invalidate to complete */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0));
+ radeon_ring_write(ring, VM_INVALIDATE_REQUEST);
+ radeon_ring_write(ring, 0xff << 16); /* retry */
+ radeon_ring_write(ring, 1 << vm_id); /* mask */
+ radeon_ring_write(ring, 0); /* value */
+ radeon_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */
}
/**