[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