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@xxxxxxx> > > 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 && > + !rdev->asic->ring[RADEON_RING_TYPE_GFX_INDEX]->hdp_flush && > radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM) > robj->rdev->asic->mmio_hdp_flush(rdev); > drm_gem_object_unreference_unlocked(gobj); > 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->mmio_hdp_flush) > rdev->asic->ring[ring->idx]->hdp_flush(rdev, ring); > /* We pad to match fetch size */ > while (ring->wptr & ring->align_mask) { > > > > -- > Earthling Michel Dänzer | http://www.amd.com > Libre software enthusiast | Mesa and X developer -- _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel