From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?windows-1252?Q?Michel_D=E4nzer?= Subject: Re: [BISECTED] 3.17-rc1 radeon screen corruption due to "Always flush the HDP cache before submitting a CS to the GPU" Date: Tue, 02 Sep 2014 16:34:04 +0900 Message-ID: <540572EC.4070909@daenzer.net> References: <21505.55482.547592.906934@gargle.gargle.HOWL> Mime-Version: 1.0 Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mail.gna.ch (darkcity.gna.ch [195.226.6.51]) by gabe.freedesktop.org (Postfix) with ESMTP id ECC546E41B for ; Tue, 2 Sep 2014 00:34:10 -0700 (PDT) In-Reply-To: <21505.55482.547592.906934@gargle.gargle.HOWL> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Mikael Pettersson Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org On 30.08.2014 22:59, Mikael Pettersson wrote: > Since 3.17-rc1 my radeon card (RV370 / X1050 card) causes screen corrupti= on > 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=C3=A4nzer > 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? 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 =3D { .resume =3D &r300_resume, .vga_set_state =3D &r100_vga_set_state, .asic_reset =3D &r300_asic_reset, - .mmio_hdp_flush =3D NULL, + .mmio_hdp_flush =3D r100_mmio_hdp_flush, .gui_idle =3D &r100_gui_idle, .mc_wait_for_idle =3D &r300_mc_wait_for_idle, .gart =3D { 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/r= adeon_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 =3D 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) =3D=3D RADEON_GEM_DOMAIN_VRA= M) 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, str= uct 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=E4nzer | http://www.amd.com Libre software enthusiast | Mesa and X developer