diff options
author | Christian König <christian.koenig@amd.com> | 2013-08-13 05:56:51 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-30 16:30:40 -0400 |
commit | 02c9f7fa4e7230fc4ae8bf26f64e45aa76011f9c (patch) | |
tree | 356f4dc89d3db10e332664c707de837fa8bc7e3e /drivers/gpu/drm/radeon | |
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')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 3 |
10 files changed, 38 insertions, 31 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e661aec734b2..ce7036ae9f5a 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -7705,8 +7705,7 @@ static int cik_startup(struct radeon_device *rdev) | |||
7705 | 7705 | ||
7706 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 7706 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
7707 | if (ring->ring_size) { | 7707 | if (ring->ring_size) { |
7708 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 7708 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
7709 | R600_WB_UVD_RPTR_OFFSET, | ||
7710 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 7709 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
7711 | 0, 0xfffff, RADEON_CP_PACKET2); | 7710 | 0, 0xfffff, RADEON_CP_PACKET2); |
7712 | if (!r) | 7711 | if (!r) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 710c1d4ae5db..2139f6c64341 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -5291,8 +5291,7 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
5291 | 5291 | ||
5292 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 5292 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
5293 | if (ring->ring_size) { | 5293 | if (ring->ring_size) { |
5294 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 5294 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
5295 | R600_WB_UVD_RPTR_OFFSET, | ||
5296 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 5295 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
5297 | 0, 0xfffff, RADEON_CP_PACKET2); | 5296 | 0, 0xfffff, RADEON_CP_PACKET2); |
5298 | if (!r) | 5297 | if (!r) |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index bc298a3500a4..f543f4ca4dda 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -2225,8 +2225,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2225 | 2225 | ||
2226 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 2226 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
2227 | if (ring->ring_size) { | 2227 | if (ring->ring_size) { |
2228 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 2228 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
2229 | R600_WB_UVD_RPTR_OFFSET, | ||
2230 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 2229 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
2231 | 0, 0xfffff, RADEON_CP_PACKET2); | 2230 | 0, 0xfffff, RADEON_CP_PACKET2); |
2232 | if (!r) | 2231 | if (!r) |
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; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b26a20fe2859..2eab174bf22e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1027,7 +1027,6 @@ struct radeon_wb { | |||
1027 | #define R600_WB_DMA_RPTR_OFFSET 1792 | 1027 | #define R600_WB_DMA_RPTR_OFFSET 1792 |
1028 | #define R600_WB_IH_WPTR_OFFSET 2048 | 1028 | #define R600_WB_IH_WPTR_OFFSET 2048 |
1029 | #define CAYMAN_WB_DMA1_RPTR_OFFSET 2304 | 1029 | #define CAYMAN_WB_DMA1_RPTR_OFFSET 2304 |
1030 | #define R600_WB_UVD_RPTR_OFFSET 2560 | ||
1031 | #define R600_WB_EVENT_OFFSET 3072 | 1030 | #define R600_WB_EVENT_OFFSET 3072 |
1032 | #define CIK_WB_CP1_WPTR_OFFSET 3328 | 1031 | #define CIK_WB_CP1_WPTR_OFFSET 3328 |
1033 | #define CIK_WB_CP2_WPTR_OFFSET 3584 | 1032 | #define CIK_WB_CP2_WPTR_OFFSET 3584 |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 012fe7218c74..7432247a812a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1157,9 +1157,9 @@ static struct radeon_asic_ring rv770_uvd_ring = { | |||
1157 | .ring_test = &r600_uvd_ring_test, | 1157 | .ring_test = &r600_uvd_ring_test, |
1158 | .ib_test = &r600_uvd_ib_test, | 1158 | .ib_test = &r600_uvd_ib_test, |
1159 | .is_lockup = &radeon_ring_test_lockup, | 1159 | .is_lockup = &radeon_ring_test_lockup, |
1160 | .get_rptr = &radeon_ring_generic_get_rptr, | 1160 | .get_rptr = &r600_uvd_get_rptr, |
1161 | .get_wptr = &radeon_ring_generic_get_wptr, | 1161 | .get_wptr = &r600_uvd_get_wptr, |
1162 | .set_wptr = &radeon_ring_generic_set_wptr, | 1162 | .set_wptr = &r600_uvd_set_wptr, |
1163 | }; | 1163 | }; |
1164 | 1164 | ||
1165 | static struct radeon_asic rv770_asic = { | 1165 | static struct radeon_asic rv770_asic = { |
@@ -1593,9 +1593,9 @@ static struct radeon_asic_ring cayman_uvd_ring = { | |||
1593 | .ring_test = &r600_uvd_ring_test, | 1593 | .ring_test = &r600_uvd_ring_test, |
1594 | .ib_test = &r600_uvd_ib_test, | 1594 | .ib_test = &r600_uvd_ib_test, |
1595 | .is_lockup = &radeon_ring_test_lockup, | 1595 | .is_lockup = &radeon_ring_test_lockup, |
1596 | .get_rptr = &radeon_ring_generic_get_rptr, | 1596 | .get_rptr = &r600_uvd_get_rptr, |
1597 | .get_wptr = &radeon_ring_generic_get_wptr, | 1597 | .get_wptr = &r600_uvd_get_wptr, |
1598 | .set_wptr = &radeon_ring_generic_set_wptr, | 1598 | .set_wptr = &r600_uvd_set_wptr, |
1599 | }; | 1599 | }; |
1600 | 1600 | ||
1601 | static struct radeon_asic cayman_asic = { | 1601 | static struct radeon_asic cayman_asic = { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 5630291c4b06..37baf9c696f0 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -424,6 +424,12 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde | |||
424 | struct seq_file *m); | 424 | struct seq_file *m); |
425 | 425 | ||
426 | /* uvd */ | 426 | /* uvd */ |
427 | uint32_t r600_uvd_get_rptr(struct radeon_device *rdev, | ||
428 | struct radeon_ring *ring); | ||
429 | uint32_t r600_uvd_get_wptr(struct radeon_device *rdev, | ||
430 | struct radeon_ring *ring); | ||
431 | void r600_uvd_set_wptr(struct radeon_device *rdev, | ||
432 | struct radeon_ring *ring); | ||
427 | int r600_uvd_init(struct radeon_device *rdev, bool ring_test); | 433 | int r600_uvd_init(struct radeon_device *rdev, bool ring_test); |
428 | void r600_uvd_stop(struct radeon_device *rdev); | 434 | void r600_uvd_stop(struct radeon_device *rdev); |
429 | int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 435 | int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index fb5ea6208970..cb4b931d8d9f 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -363,7 +363,7 @@ u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev, | |||
363 | { | 363 | { |
364 | u32 rptr; | 364 | u32 rptr; |
365 | 365 | ||
366 | if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX]) | 366 | if (rdev->wb.enabled) |
367 | rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); | 367 | rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); |
368 | else | 368 | else |
369 | rptr = RREG32(ring->rptr_reg); | 369 | rptr = RREG32(ring->rptr_reg); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 52253b2ab0d5..1e8cf49d5871 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -1923,8 +1923,7 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1923 | 1923 | ||
1924 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 1924 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
1925 | if (ring->ring_size) { | 1925 | if (ring->ring_size) { |
1926 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 1926 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
1927 | R600_WB_UVD_RPTR_OFFSET, | ||
1928 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 1927 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
1929 | 0, 0xfffff, RADEON_CP_PACKET2); | 1928 | 0, 0xfffff, RADEON_CP_PACKET2); |
1930 | if (!r) | 1929 | if (!r) |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index da23ce8f4388..4ff59c8f508f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -6416,8 +6416,7 @@ static int si_startup(struct radeon_device *rdev) | |||
6416 | if (rdev->has_uvd) { | 6416 | if (rdev->has_uvd) { |
6417 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 6417 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
6418 | if (ring->ring_size) { | 6418 | if (ring->ring_size) { |
6419 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 6419 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
6420 | R600_WB_UVD_RPTR_OFFSET, | ||
6421 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 6420 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
6422 | 0, 0xfffff, RADEON_CP_PACKET2); | 6421 | 0, 0xfffff, RADEON_CP_PACKET2); |
6423 | if (!r) | 6422 | if (!r) |