diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2015-01-06 03:42:25 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-01-08 17:36:50 +0300 |
commit | cbfc35b90f3b4853d1eb9fcb82e99531d6a1c629 (patch) | |
tree | 91a7356e4aa8a6b5cf006ae1b49d00324e804d2e /drivers/gpu/drm/radeon/ni.c | |
parent | 79305ec6e60d320832505e95c1a028d309fcd2b6 (diff) | |
download | linux-cbfc35b90f3b4853d1eb9fcb82e99531d6a1c629.tar.xz |
drm/radeon: fix VM flush on cayman/aruba (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/ni.c')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 360de9f1f491..aea48c89b241 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2516,6 +2516,16 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); |