drm/radeon/kms/r7xx: add workaround for hw issue with HDP flush
Use of HDP_*_COHERENCY_FLUSH_CNTL can cause a hang in certain situations. Add workaround. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Cc: stable@kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
833ee5c4ab
commit
812d046915
4 changed files with 28 additions and 3 deletions
|
@ -884,7 +884,17 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
/* flush hdp cache so updates hit vram */
|
/* 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_LOW_ADDR, rdev->mc.gtt_start >> 12);
|
||||||
WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 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)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,6 +250,7 @@
|
||||||
#define HDP_NONSURFACE_SIZE 0x2C0C
|
#define HDP_NONSURFACE_SIZE 0x2C0C
|
||||||
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
|
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
|
||||||
#define HDP_TILING_CONFIG 0x2F3C
|
#define HDP_TILING_CONFIG 0x2F3C
|
||||||
|
#define HDP_DEBUG1 0x2F34
|
||||||
|
|
||||||
#define MC_VM_AGP_TOP 0x2184
|
#define MC_VM_AGP_TOP 0x2184
|
||||||
#define MC_VM_AGP_BOT 0x2188
|
#define MC_VM_AGP_BOT 0x2188
|
||||||
|
|
|
@ -204,7 +204,10 @@ static void rv770_mc_program(struct radeon_device *rdev)
|
||||||
WREG32((0x2c20 + j), 0x00000000);
|
WREG32((0x2c20 + j), 0x00000000);
|
||||||
WREG32((0x2c24 + 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);
|
rv515_mc_stop(rdev, &save);
|
||||||
if (r600_mc_wait_for_idle(rdev)) {
|
if (r600_mc_wait_for_idle(rdev)) {
|
||||||
|
|
|
@ -133,6 +133,7 @@
|
||||||
#define HDP_NONSURFACE_SIZE 0x2C0C
|
#define HDP_NONSURFACE_SIZE 0x2C0C
|
||||||
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
|
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
|
||||||
#define HDP_TILING_CONFIG 0x2F3C
|
#define HDP_TILING_CONFIG 0x2F3C
|
||||||
|
#define HDP_DEBUG1 0x2F34
|
||||||
|
|
||||||
#define MC_SHARED_CHMAP 0x2004
|
#define MC_SHARED_CHMAP 0x2004
|
||||||
#define NOOFCHAN_SHIFT 12
|
#define NOOFCHAN_SHIFT 12
|
||||||
|
|
Reference in a new issue