diff options
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 8a600153ef6c..c1b0aba4431a 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) | |||
2623 | /* | 2623 | /* |
2624 | * UVD | 2624 | * UVD |
2625 | */ | 2625 | */ |
2626 | uint32_t r600_uvd_get_rptr(struct radeon_device *rdev, | ||
2627 | struct radeon_ring *ring) | ||
2628 | { | ||
2629 | return RREG32(UVD_RBC_RB_RPTR); | ||
2630 | } | ||
2631 | |||
2632 | uint32_t r600_uvd_get_wptr(struct radeon_device *rdev, | ||
2633 | struct radeon_ring *ring) | ||
2634 | { | ||
2635 | return RREG32(UVD_RBC_RB_WPTR); | ||
2636 | } | ||
2637 | |||
2638 | void r600_uvd_set_wptr(struct radeon_device *rdev, | ||
2639 | struct radeon_ring *ring) | ||
2640 | { | ||
2641 | WREG32(UVD_RBC_RB_WPTR, ring->wptr); | ||
2642 | } | ||
2643 | |||
2626 | static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test) | 2644 | static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test) |
2627 | { | 2645 | { |
2628 | struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 2646 | struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
2629 | uint64_t rptr_addr; | ||
2630 | uint32_t rb_bufsz, tmp; | 2647 | uint32_t rb_bufsz, tmp; |
2631 | int r; | 2648 | int r; |
2632 | 2649 | ||
2633 | rptr_addr = rdev->wb.gpu_addr + R600_WB_UVD_RPTR_OFFSET; | ||
2634 | |||
2635 | if (upper_32_bits(rptr_addr) != upper_32_bits(ring->gpu_addr)) { | ||
2636 | DRM_ERROR("UVD ring and rptr not in the same 4GB segment!\n"); | ||
2637 | return -EINVAL; | ||
2638 | } | ||
2639 | |||
2640 | /* force RBC into idle state */ | 2650 | /* force RBC into idle state */ |
2641 | WREG32(UVD_RBC_RB_CNTL, 0x11010101); | 2651 | WREG32(UVD_RBC_RB_CNTL, 0x11010101); |
2642 | 2652 | ||
2643 | /* Set the write pointer delay */ | 2653 | /* Set the write pointer delay */ |
2644 | WREG32(UVD_RBC_RB_WPTR_CNTL, 0); | 2654 | WREG32(UVD_RBC_RB_WPTR_CNTL, 0); |
2645 | 2655 | ||
2646 | /* set the wb address */ | ||
2647 | WREG32(UVD_RBC_RB_RPTR_ADDR, rptr_addr >> 2); | ||
2648 | |||
2649 | /* programm the 4GB memory segment for rptr and ring buffer */ | 2656 | /* programm the 4GB memory segment for rptr and ring buffer */ |
2650 | WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(rptr_addr) | | 2657 | WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) | |
2651 | (0x7 << 16) | (0x1 << 31)); | 2658 | (0x7 << 16) | (0x1 << 31)); |
2652 | 2659 | ||
2653 | /* Initialize the ring buffer's read and write pointers */ | 2660 | /* 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) | |||
2662 | /* Set ring buffer size */ | 2669 | /* Set ring buffer size */ |
2663 | rb_bufsz = drm_order(ring->ring_size); | 2670 | rb_bufsz = drm_order(ring->ring_size); |
2664 | rb_bufsz = (0x1 << 8) | rb_bufsz; | 2671 | rb_bufsz = (0x1 << 8) | rb_bufsz; |
2665 | WREG32(UVD_RBC_RB_CNTL, rb_bufsz); | 2672 | WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f); |
2666 | 2673 | ||
2667 | if (ring_test) { | 2674 | if (ring_test) { |
2668 | ring->ready = true; | 2675 | ring->ready = true; |