aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2013-08-13 05:56:51 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-08-30 16:30:40 -0400
commit02c9f7fa4e7230fc4ae8bf26f64e45aa76011f9c (patch)
tree356f4dc89d3db10e332664c707de837fa8bc7e3e /drivers/gpu/drm/radeon
parent76a0df859defc53e6cb61f698a48ac7da92c8d84 (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.c3
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c3
-rw-r--r--drivers/gpu/drm/radeon/ni.c3
-rw-r--r--drivers/gpu/drm/radeon/r600.c33
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c2
-rw-r--r--drivers/gpu/drm/radeon/rv770.c3
-rw-r--r--drivers/gpu/drm/radeon/si.c3
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 */
2626uint32_t r600_uvd_get_rptr(struct radeon_device *rdev,
2627 struct radeon_ring *ring)
2628{
2629 return RREG32(UVD_RBC_RB_RPTR);
2630}
2631
2632uint32_t r600_uvd_get_wptr(struct radeon_device *rdev,
2633 struct radeon_ring *ring)
2634{
2635 return RREG32(UVD_RBC_RB_WPTR);
2636}
2637
2638void r600_uvd_set_wptr(struct radeon_device *rdev,
2639 struct radeon_ring *ring)
2640{
2641 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
2642}
2643
2626static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test) 2644static 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
1165static struct radeon_asic rv770_asic = { 1165static 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
1601static struct radeon_asic cayman_asic = { 1601static 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 */
427uint32_t r600_uvd_get_rptr(struct radeon_device *rdev,
428 struct radeon_ring *ring);
429uint32_t r600_uvd_get_wptr(struct radeon_device *rdev,
430 struct radeon_ring *ring);
431void r600_uvd_set_wptr(struct radeon_device *rdev,
432 struct radeon_ring *ring);
427int r600_uvd_init(struct radeon_device *rdev, bool ring_test); 433int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
428void r600_uvd_stop(struct radeon_device *rdev); 434void r600_uvd_stop(struct radeon_device *rdev);
429int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); 435int 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)