diff options
author | Christian König <christian.koenig@amd.com> | 2013-08-13 11:56:51 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-30 16:30:40 -0400 |
commit | 02c9f7fa4e7230fc4ae8bf26f64e45aa76011f9c (patch) | |
tree | 356f4dc89d3db10e332664c707de837fa8bc7e3e /drivers/gpu/drm/radeon/r600.c | |
parent | 76a0df859defc53e6cb61f698a48ac7da92c8d84 (diff) |
drm/radeon: rework UVD writeback & [rw]ptr handling
The hardware just doesn't support this correctly.
Disable it before we accidentally write anywhere we shouldn't.
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 8a600153ef6..c1b0aba4431 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2623,31 +2623,38 @@ void r600_dma_fini(struct radeon_device *rdev) /* * UVD */ +uint32_t r600_uvd_get_rptr(struct radeon_device *rdev, + struct radeon_ring *ring) +{ + return RREG32(UVD_RBC_RB_RPTR); +} + +uint32_t r600_uvd_get_wptr(struct radeon_device *rdev, + struct radeon_ring *ring) +{ + return RREG32(UVD_RBC_RB_WPTR); +} + +void r600_uvd_set_wptr(struct radeon_device *rdev, + struct radeon_ring *ring) +{ + WREG32(UVD_RBC_RB_WPTR, ring->wptr); +} + static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test) { struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - uint64_t rptr_addr; uint32_t rb_bufsz, tmp; int r; - rptr_addr = rdev->wb.gpu_addr + R600_WB_UVD_RPTR_OFFSET; - - if (upper_32_bits(rptr_addr) != upper_32_bits(ring->gpu_addr)) { - DRM_ERROR("UVD ring and rptr not in the same 4GB segment!\n"); - return -EINVAL; - } - /* force RBC into idle state */ WREG32(UVD_RBC_RB_CNTL, 0x11010101); /* Set the write pointer delay */ WREG32(UVD_RBC_RB_WPTR_CNTL, 0); - /* set the wb address */ - WREG32(UVD_RBC_RB_RPTR_ADDR, rptr_addr >> 2); - /* programm the 4GB memory segment for rptr and ring buffer */ - WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(rptr_addr) | + WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) | (0x7 << 16) | (0x1 << 31)); /* Initialize the ring buffer's read and write pointers */ @@ -2662,7 +2669,7 @@ static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test) /* Set ring buffer size */ rb_bufsz = drm_order(ring->ring_size); rb_bufsz = (0x1 << 8) | rb_bufsz; - WREG32(UVD_RBC_RB_CNTL, rb_bufsz); + WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f); if (ring_test) { ring->ready = true; |