From f1b398a2e5594e63b7a02644363749aad34890c9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 24 Oct 2011 11:45:27 -0400 Subject: [PATCH] drm/radeon/kms/cayman: use WAIT_REG_MEM for surface_sync in blit code The SURFACE_SYNC packet only works properly in an IB. May fix: https://bugs.freedesktop.org/show_bug.cgi?id=40221 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 33 ++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 9ebbdc5..60e35a0 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -94,11 +94,32 @@ cp_set_surface_sync(struct radeon_device *rdev, else cp_coher_size = ((size + 255) >> 8); - radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(rdev, sync_type); - radeon_ring_write(rdev, cp_coher_size); - radeon_ring_write(rdev, mc_addr >> 8); - radeon_ring_write(rdev, 10); /* poll interval */ + if (rdev->family >= CHIP_CAYMAN) { + /* SURFACE_SYNC packets may only work in IBs on cayman */ + radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 3)); + radeon_ring_write(rdev, (0x85f0 - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(rdev, sync_type); /* CP_COHER_CNTL */ + radeon_ring_write(rdev, cp_coher_size); /* CP_COHER_SIZE */ + radeon_ring_write(rdev, mc_addr >> 8); /* CP_COHER_BASE */ + + radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(rdev, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(rdev, 0); /* CP_COHER_CNTL2 */ + + radeon_ring_write(rdev, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(rdev, (0 << 4) | (3 << 0)); + radeon_ring_write(rdev, 0x85fc >> 2); /* CP_COHER_STATUS */ + radeon_ring_write(rdev, 0); + radeon_ring_write(rdev, 0); /* ref */ + radeon_ring_write(rdev, (1 << 31)); /* mask */ + radeon_ring_write(rdev, 10); /* poll interval */ + } else { + radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(rdev, sync_type); + radeon_ring_write(rdev, cp_coher_size); + radeon_ring_write(rdev, mc_addr >> 8); + radeon_ring_write(rdev, 10); /* poll interval */ + } } /* emits 11dw + 1 surface sync = 16dw */ @@ -626,6 +647,8 @@ int evergreen_blit_init(struct radeon_device *rdev) rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */ rdev->r600_blit.ring_size_per_loop = 74; + if (rdev->family >= CHIP_CAYMAN) + rdev->r600_blit.ring_size_per_loop += 30; /* additional DWs for surface sync */ rdev->r600_blit.max_dim = 16384; -- 1.7.1.1