[PATCH] drm/radeon: Don't read from CP ring write pointer registers.
Alex Deucher
alexdeucher at gmail.com
Tue Sep 13 12:56:37 PDT 2011
2011/9/13 Michel Dänzer <michel at daenzer.net>:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> Apparently this doesn't always work reliably, e.g. at resume time.
>
> Just initialize to 0, so the ring is considered empty.
>
> Tested with hibernation on Sumo and Cayman cards.
>
> Should fix https://bugs.launchpad.net/ubuntu/+source/linux/+bug/820746/ .
>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
Looks good to me.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> drivers/gpu/drm/radeon/evergreen.c | 4 ++--
> drivers/gpu/drm/radeon/ni.c | 12 ++++++------
> drivers/gpu/drm/radeon/r100.c | 6 ++----
> drivers/gpu/drm/radeon/r600.c | 4 ++--
> 4 files changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index 15bd047..f2bd90a 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -1378,7 +1378,8 @@ int evergreen_cp_resume(struct radeon_device *rdev)
> /* Initialize the ring buffer's read and write pointers */
> WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
> WREG32(CP_RB_RPTR_WR, 0);
> - WREG32(CP_RB_WPTR, 0);
> + rdev->cp.wptr = 0;
> + WREG32(CP_RB_WPTR, rdev->cp.wptr);
>
> /* set the wb address wether it's enabled or not */
> WREG32(CP_RB_RPTR_ADDR,
> @@ -1403,7 +1404,6 @@ int evergreen_cp_resume(struct radeon_device *rdev)
> WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
>
> rdev->cp.rptr = RREG32(CP_RB_RPTR);
> - rdev->cp.wptr = RREG32(CP_RB_WPTR);
>
> evergreen_cp_start(rdev);
> rdev->cp.ready = true;
> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
> index 559dbd4..e3489ee 100644
> --- a/drivers/gpu/drm/radeon/ni.c
> +++ b/drivers/gpu/drm/radeon/ni.c
> @@ -1182,7 +1182,8 @@ int cayman_cp_resume(struct radeon_device *rdev)
>
> /* Initialize the ring buffer's read and write pointers */
> WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
> - WREG32(CP_RB0_WPTR, 0);
> + rdev->cp.wptr = 0;
> + WREG32(CP_RB0_WPTR, rdev->cp.wptr);
>
> /* set the wb address wether it's enabled or not */
> WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
> @@ -1202,7 +1203,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
> WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8);
>
> rdev->cp.rptr = RREG32(CP_RB0_RPTR);
> - rdev->cp.wptr = RREG32(CP_RB0_WPTR);
>
> /* ring1 - compute only */
> /* Set ring buffer size */
> @@ -1215,7 +1215,8 @@ int cayman_cp_resume(struct radeon_device *rdev)
>
> /* Initialize the ring buffer's read and write pointers */
> WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
> - WREG32(CP_RB1_WPTR, 0);
> + rdev->cp1.wptr = 0;
> + WREG32(CP_RB1_WPTR, rdev->cp1.wptr);
>
> /* set the wb address wether it's enabled or not */
> WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
> @@ -1227,7 +1228,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
> WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8);
>
> rdev->cp1.rptr = RREG32(CP_RB1_RPTR);
> - rdev->cp1.wptr = RREG32(CP_RB1_WPTR);
>
> /* ring2 - compute only */
> /* Set ring buffer size */
> @@ -1240,7 +1240,8 @@ int cayman_cp_resume(struct radeon_device *rdev)
>
> /* Initialize the ring buffer's read and write pointers */
> WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
> - WREG32(CP_RB2_WPTR, 0);
> + rdev->cp2.wptr = 0;
> + WREG32(CP_RB2_WPTR, rdev->cp2.wptr);
>
> /* set the wb address wether it's enabled or not */
> WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
> @@ -1252,7 +1253,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
> WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8);
>
> rdev->cp2.rptr = RREG32(CP_RB2_RPTR);
> - rdev->cp2.wptr = RREG32(CP_RB2_WPTR);
>
> /* start the rings */
> cayman_cp_start(rdev);
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index f2204cb..11e44a3 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -990,7 +990,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
> /* Force read & write ptr to 0 */
> WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE);
> WREG32(RADEON_CP_RB_RPTR_WR, 0);
> - WREG32(RADEON_CP_RB_WPTR, 0);
> + rdev->cp.wptr = 0;
> + WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
>
> /* set the wb address whether it's enabled or not */
> WREG32(R_00070C_CP_RB_RPTR_ADDR,
> @@ -1007,9 +1008,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
> WREG32(RADEON_CP_RB_CNTL, tmp);
> udelay(10);
> rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
> - rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
> - /* protect against crazy HW on resume */
> - rdev->cp.wptr &= rdev->cp.ptr_mask;
> /* Set cp mode to bus mastering & enable cp*/
> WREG32(RADEON_CP_CSQ_MODE,
> REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index bc54b26..8ca098d 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -2208,7 +2208,8 @@ int r600_cp_resume(struct radeon_device *rdev)
> /* Initialize the ring buffer's read and write pointers */
> WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
> WREG32(CP_RB_RPTR_WR, 0);
> - WREG32(CP_RB_WPTR, 0);
> + rdev->cp.wptr = 0;
> + WREG32(CP_RB_WPTR, rdev->cp.wptr);
>
> /* set the wb address whether it's enabled or not */
> WREG32(CP_RB_RPTR_ADDR,
> @@ -2233,7 +2234,6 @@ int r600_cp_resume(struct radeon_device *rdev)
> WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
>
> rdev->cp.rptr = RREG32(CP_RB_RPTR);
> - rdev->cp.wptr = RREG32(CP_RB_WPTR);
>
> r600_cp_start(rdev);
> rdev->cp.ready = true;
> --
> 1.7.5.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
More information about the dri-devel
mailing list