Use of HDP_*_COHERENCY_FLUSH_CNTL can cause a hang in certain
situations.  Add workaround.

Signed-off-by: Alex Deucher <alexdeuc...@gmail.com>
Cc: sta...@kernel.org
---
 drivers/gpu/drm/radeon/r600.c   |   24 ++++++++++++++++++++++--
 drivers/gpu/drm/radeon/r600d.h  |    1 +
 drivers/gpu/drm/radeon/rv770.c  |    5 ++++-
 drivers/gpu/drm/radeon/rv770d.h |    1 +
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index ad38ca8..e25b8ac 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -884,7 +884,17 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
        u32 tmp;
 
        /* flush hdp cache so updates hit vram */
-       WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+               void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+               u32 tmp;
+
+               /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
+                * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+                */
+               WREG32(HDP_DEBUG1, 0);
+               tmp = readl((void __iomem *)ptr);
+       } else
+               WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
 
        WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
        WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 
12);
@@ -3527,5 +3537,15 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
  */
 void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
 {
-       WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+       /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
+        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+        */
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+               void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+               u32 tmp;
+
+               WREG32(HDP_DEBUG1, 0);
+               tmp = readl((void __iomem *)ptr);
+       } else
+               WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
 }
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index b7318ac..858a192 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -250,6 +250,7 @@
 #define        HDP_NONSURFACE_SIZE                             0x2C0C
 #define HDP_REG_COHERENCY_FLUSH_CNTL                   0x54A0
 #define        HDP_TILING_CONFIG                               0x2F3C
+#define HDP_DEBUG1                                      0x2F34
 
 #define MC_VM_AGP_TOP                                  0x2184
 #define MC_VM_AGP_BOT                                  0x2188
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 4183d6f..d14cb5d 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -204,7 +204,10 @@ static void rv770_mc_program(struct radeon_device *rdev)
                WREG32((0x2c20 + j), 0x00000000);
                WREG32((0x2c24 + j), 0x00000000);
        }
-       WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
+       /* r7xx hw bug.  Read from HDP_DEBUG1 rather
+        * than writing to HDP_REG_COHERENCY_FLUSH_CNTL
+        */
+       tmp = RREG32(HDP_DEBUG1);
 
        rv515_mc_stop(rdev, &save);
        if (r600_mc_wait_for_idle(rdev)) {
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
index fd733f2..b7a5a20 100644
--- a/drivers/gpu/drm/radeon/rv770d.h
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -133,6 +133,7 @@
 #define        HDP_NONSURFACE_SIZE                             0x2C0C
 #define HDP_REG_COHERENCY_FLUSH_CNTL                   0x54A0
 #define        HDP_TILING_CONFIG                               0x2F3C
+#define HDP_DEBUG1                                      0x2F34
 
 #define MC_SHARED_CHMAP                                                0x2004
 #define                NOOFCHAN_SHIFT                                  12
-- 
1.7.1.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to