summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2014-01-09 16:51:56 -0500
committerAlex Deucher <alexander.deucher@amd.com>2014-01-16 10:03:57 -0500
commit78664783f3604cd67eef459fd847b476e6c43f6b (patch)
treeb10e983cea000b2b6a291e4b37f5467e3427e605
parentbde0926d11eb0ad2acefa90ab8f0a3864ce0744f (diff)
drm/radeon/cik: use WAIT_REG_MEM special op for CP HDP flush
This is the preferred flushing method on CIK. Note, this only works on the PFP so the engine bit must be set. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/cik.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index ee8b65280dc0..9f860c8b7b9d 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -3496,16 +3496,37 @@ static void cik_hdp_flush_cp_ring_emit(struct radeon_device *rdev,
int ridx)
{
struct radeon_ring *ring = &rdev->ring[ridx];
+ u32 ref_and_mask;
- /* We should be using the new WAIT_REG_MEM special op packet here
- * but it causes the CP to hang
- */
- radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
- radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
- WRITE_DATA_DST_SEL(0)));
- radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
- radeon_ring_write(ring, 0);
- radeon_ring_write(ring, 0);
+ switch (ring->idx) {
+ case CAYMAN_RING_TYPE_CP1_INDEX:
+ case CAYMAN_RING_TYPE_CP2_INDEX:
+ default:
+ switch (ring->me) {
+ case 0:
+ ref_and_mask = CP2 << ring->pipe;
+ break;
+ case 1:
+ ref_and_mask = CP6 << ring->pipe;
+ break;
+ default:
+ return;
+ }
+ break;
+ case RADEON_RING_TYPE_GFX_INDEX:
+ ref_and_mask = CP0;
+ break;
+ }
+
+ radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
+ radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(1) | /* write, wait, write */
+ WAIT_REG_MEM_FUNCTION(3) | /* == */
+ WAIT_REG_MEM_ENGINE(1))); /* pfp */
+ radeon_ring_write(ring, GPU_HDP_FLUSH_REQ >> 2);
+ radeon_ring_write(ring, GPU_HDP_FLUSH_DONE >> 2);
+ radeon_ring_write(ring, ref_and_mask);
+ radeon_ring_write(ring, ref_and_mask);
+ radeon_ring_write(ring, 0x20); /* poll interval */
}
/**