Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77b1bad4 authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie
Browse files

drm/radeon: flush read cache for gtt with fence on r6xx and newer GPU V3

Cayman seems to be particularly sensitive to read cache returning
old data after bind/unbind to GTT. Flush read cache for GTT range
with each fences for all new hw. Should fix several rendering glitches.
Like

V2 flush whole address space
V3 also flush shader read cache

https://bugs.freedesktop.org/show_bug.cgi?id=40221
https://bugs.freedesktop.org/show_bug.cgi?id=38022
https://bugzilla.redhat.com/show_bug.cgi?id=738790



Signed-off-by: default avatarJerome Glisse <jglisse@redhat.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 8ab250d4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -625,9 +625,9 @@ int evergreen_blit_init(struct radeon_device *rdev)
	rdev->r600_blit.primitives.set_default_state = set_default_state;

	rdev->r600_blit.ring_size_common = 55; /* shaders + def state */
	rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
	rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
	rdev->r600_blit.ring_size_common += 5; /* done copy */
	rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
	rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */

	rdev->r600_blit.ring_size_per_loop = 74;
	if (rdev->family >= CHIP_CAYMAN)
+16 −0
Original line number Diff line number Diff line
@@ -2331,6 +2331,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
	if (rdev->wb.use_event) {
		u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET +
			(u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base);
		/* flush read cache over gart */
		radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
		radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
					PACKET3_VC_ACTION_ENA |
					PACKET3_SH_ACTION_ENA);
		radeon_ring_write(rdev, 0xFFFFFFFF);
		radeon_ring_write(rdev, 0);
		radeon_ring_write(rdev, 10); /* poll interval */
		/* EVENT_WRITE_EOP - flush caches, send int */
		radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
		radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
@@ -2339,6 +2347,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
		radeon_ring_write(rdev, fence->seq);
		radeon_ring_write(rdev, 0);
	} else {
		/* flush read cache over gart */
		radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
		radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
					PACKET3_VC_ACTION_ENA |
					PACKET3_SH_ACTION_ENA);
		radeon_ring_write(rdev, 0xFFFFFFFF);
		radeon_ring_write(rdev, 0);
		radeon_ring_write(rdev, 10); /* poll interval */
		radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
		radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0));
		/* wait for 3D idle clean */
+2 −2
Original line number Diff line number Diff line
@@ -503,9 +503,9 @@ int r600_blit_init(struct radeon_device *rdev)
	rdev->r600_blit.primitives.set_default_state = set_default_state;

	rdev->r600_blit.ring_size_common = 40; /* shaders + def state */
	rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
	rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
	rdev->r600_blit.ring_size_common += 5; /* done copy */
	rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
	rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */

	rdev->r600_blit.ring_size_per_loop = 76;
	/* set_render_target emits 2 extra dwords on rv6xx */