From e3c3cf28220b6755b16ee3600a7d18d545ee4f6e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 28 Dec 2011 21:34:35 +0000 Subject: [PATCH] drm/radeon: flush read cache for gtt with fence on r6xx and newer GPU svn path=/dists/sid/linux-2.6/; revision=18428 --- debian/changelog | 2 + ...-read-cache-for-gtt-with-fence-on-r6.patch | 96 +++++++++++++++++++ debian/patches/series/base | 1 + 3 files changed, 99 insertions(+) create mode 100644 debian/patches/bugfix/all/drm-radeon-flush-read-cache-for-gtt-with-fence-on-r6.patch diff --git a/debian/changelog b/debian/changelog index f322f6c0d..511b73faf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,8 @@ linux-2.6 (3.1.6-2) UNRELEASED; urgency=low [ Ben Hutchings ] * snapshot: Implement compat_ioctl (Closes: #502816) * iwlwifi: allow to switch to HT40 if not associated (Closes: #653423) + * drm/radeon: flush read cache for gtt with fence on r6xx and newer GPU + (Closes: #646376) [ Jonathan Nieder ] * prerm: Print an error message when aborting removal of the running diff --git a/debian/patches/bugfix/all/drm-radeon-flush-read-cache-for-gtt-with-fence-on-r6.patch b/debian/patches/bugfix/all/drm-radeon-flush-read-cache-for-gtt-with-fence-on-r6.patch new file mode 100644 index 000000000..3fd2bc671 --- /dev/null +++ b/debian/patches/bugfix/all/drm-radeon-flush-read-cache-for-gtt-with-fence-on-r6.patch @@ -0,0 +1,96 @@ +From: Jerome Glisse +Date: Wed, 26 Oct 2011 11:41:22 -0400 +Subject: [PATCH] drm/radeon: flush read cache for gtt with fence on r6xx and + newer GPU V3 + +commit 77b1bad423599c9841ea282a82172f039bb2ff92 upstream. + +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: Jerome Glisse +Reviewed-by: Alex Deucher +Signed-off-by: Dave Airlie +[bwh: For 3.1, patch ring size numbers in {r600,evergreen}_blit_prepare_copy() + instead of {r600,evergreen}_blit_init().] +--- + drivers/gpu/drm/radeon/evergreen_blit_kms.c | 4 ++-- + drivers/gpu/drm/radeon/r600.c | 16 ++++++++++++++++ + drivers/gpu/drm/radeon/r600_blit_kms.c | 4 ++-- + 3 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c +index 551e76f..914e5af 100644 +--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c ++++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c +@@ -779,9 +779,9 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, + ring_size = num_loops * dwords_per_loop; + /* set default + shaders */ + ring_size += 55; /* shaders + def state */ +- ring_size += 10; /* fence emit for VB IB */ ++ ring_size += 16; /* fence emit for VB IB */ + ring_size += 5; /* done copy */ +- ring_size += 10; /* fence emit for done copy */ ++ ring_size += 16; /* fence emit for done copy */ + r = radeon_ring_lock(rdev, ring_size); + if (r) + return r; +diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c +index 12470b0..1f007ad 100644 +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -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 */ +diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c +index ff36532..e09d281 100644 +--- a/drivers/gpu/drm/radeon/r600_blit_kms.c ++++ b/drivers/gpu/drm/radeon/r600_blit_kms.c +@@ -632,9 +632,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, + ring_size = num_loops * dwords_per_loop; + /* set default + shaders */ + ring_size += 40; /* shaders + def state */ +- ring_size += 10; /* fence emit for VB IB */ ++ ring_size += 16; /* fence emit for VB IB */ + ring_size += 5; /* done copy */ +- ring_size += 10; /* fence emit for done copy */ ++ ring_size += 16; /* fence emit for done copy */ + r = radeon_ring_lock(rdev, ring_size); + if (r) + return r; diff --git a/debian/patches/series/base b/debian/patches/series/base index 5994ded56..b4772be1e 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -88,3 +88,4 @@ + bugfix/all/cciss-Add-IRQF_SHARED-back-in-for-the-non-MSI-X-inte.patch + bugfix/all/snapshot-Implement-compat_ioctl.patch + bugfix/all/iwlwifi-allow-to-switch-to-ht40-if-not-associated.patch ++ bugfix/all/drm-radeon-flush-read-cache-for-gtt-with-fence-on-r6.patch