summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-07-09 10:52:39 +0200
committerChristian König <deathsimple@vodafone.de>2012-07-17 10:32:15 +0200
commitbf66625e02ac8e4535627394bcfb237bbf8a157f (patch)
treee1d10c50e0a3c803a3e00af4c7f99d8ed454a80a
parentdrm/radeon: fix ring commit padding (diff)
downloadlinux-bf66625e02ac8e4535627394bcfb237bbf8a157f.tar.xz
linux-bf66625e02ac8e4535627394bcfb237bbf8a157f.zip
drm/radeon: fix fence value access
It is possible that radeon_fence_process is called after writeback is disabled for suspend, leading to an invalid read of register 0x0. This fixes a problem for me where the fence value is temporary incremented by 0x100000000 on suspend/resume. Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index be4e4f390e89..a194a142f898 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -42,21 +42,23 @@
static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
{
- if (rdev->wb.enabled) {
- *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq);
+ struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
+ if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+ *drv->cpu_addr = cpu_to_le32(seq);
} else {
- WREG32(rdev->fence_drv[ring].scratch_reg, seq);
+ WREG32(drv->scratch_reg, seq);
}
}
static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
{
+ struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
u32 seq = 0;
- if (rdev->wb.enabled) {
- seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr);
+ if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+ seq = le32_to_cpu(*drv->cpu_addr);
} else {
- seq = RREG32(rdev->fence_drv[ring].scratch_reg);
+ seq = RREG32(drv->scratch_reg);
}
return seq;
}