2011/9/13 Michel Dänzer <mic...@daenzer.net>: > From: Michel Dänzer <michel.daen...@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.daen...@amd.com>
Looks good to me. Reviewed-by: Alex Deucher <alexander.deuc...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel