Michel Dänzer writes:
On 30.08.2014 22:59, Mikael Pettersson wrote:
Since 3.17-rc1 my radeon card (RV370 / X1050 card) causes screen corruption after a while in X + firefox. This still occurs with yesterday's HEAD of Linus' repo. 3.16 and ealier kernels are fine.
I ran a bisect, which identified:
commit 72a9987edcedb89db988079a03c9b9c65b6ec9ac Author: Michel Dänzer michel.daenzer@amd.com Date: Thu Jul 31 18:43:49 2014 +0900
drm/radeon: Always flush the HDP cache before submitting a CS to the GPU
as the cause of my screen corruption. Reverting this from 3.17-rc2 (which requires manual intervention due to subsequent changes in radeon_ring_commit()) eliminates the screen corruption.
Does the patch below help?
Thanks for the patch, I'll test it on Friday evening when I'm back home and have access to the affected machine.
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 4c5ec44..3ff9c53 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1070,6 +1070,20 @@ void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring) radeon_ring_write(ring, rdev->config.r100.hdp_cntl); }
+/**
- r100_mmio_hdp_flush - flush Host Data Path via MMIO
- rdev: radeon device structure
- */
+void r100_mmio_hdp_flush(struct radeon_device *rdev) +{
- WREG32(RADEON_HOST_PATH_CNTL,
rdev->config.r100.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE);
- (void)RREG32(RADEON_HOST_PATH_CNTL);
- WREG32(RADEON_HOST_PATH_CNTL,
rdev->config.r100.hdp_cntl);
- (void)RREG32(RADEON_HOST_PATH_CNTL);
+}
static void r100_cp_load_microcode(struct radeon_device *rdev) { const __be32 *fw_data; diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index eeeeabe..c23a123 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -408,7 +408,7 @@ static struct radeon_asic r300_asic_pcie = { .resume = &r300_resume, .vga_set_state = &r100_vga_set_state, .asic_reset = &r300_asic_reset,
- .mmio_hdp_flush = NULL,
- .mmio_hdp_flush = r100_mmio_hdp_flush, .gui_idle = &r100_gui_idle, .mc_wait_for_idle = &r300_mc_wait_for_idle, .gart = {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 275a5dc..e9b1c35 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -150,6 +150,8 @@ void r100_gfx_set_wptr(struct radeon_device *rdev, struct radeon_ring *ring); void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring); +void r100_mmio_hdp_flush(struct radeon_device *rdev);
/*
- r200,rv250,rs300,rv280
*/ diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index bfd7e1b..3d0f564 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -368,6 +368,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, r = radeon_bo_wait(robj, &cur_placement, false); /* Flush HDP cache via MMIO if necessary */ if (rdev->asic->mmio_hdp_flush &&
robj->rdev->asic->mmio_hdp_flush(rdev); drm_gem_object_unreference_unlocked(gobj);!rdev->asic->ring[RADEON_RING_TYPE_GFX_INDEX]->hdp_flush && radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM)
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index d656079..b82843b 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -188,7 +188,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring, /* If we are emitting the HDP flush via the ring buffer, we need to * do it before padding. */
- if (hdp_flush && rdev->asic->ring[ring->idx]->hdp_flush)
- if (hdp_flush && rdev->asic->ring[ring->idx]->hdp_flush &&
rdev->asic->ring[ring->idx]->hdp_flush(rdev, ring); /* We pad to match fetch size */ while (ring->wptr & ring->align_mask) {!rdev->asic->mmio_hdp_flush)
-- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer
--