drm/radeon: rework UVD writeback & [rw]ptr handling
authorChristian König <christian.koenig@amd.com>
Tue, 13 Aug 2013 09:56:51 +0000 (11:56 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 30 Aug 2013 20:30:40 +0000 (16:30 -0400)
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>
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c

index e661aec734b241494b04aae2c92cd1bf1b83628e..ce7036ae9f5a3e6a21187f4bcf3498688ac65509 100644 (file)
@@ -7705,8 +7705,7 @@ static int cik_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
-               r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                    R600_WB_UVD_RPTR_OFFSET,
+               r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
                                     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     0, 0xfffff, RADEON_CP_PACKET2);
                if (!r)
index 710c1d4ae5db7911d8ca34edb977aae2ff3580ee..2139f6c64341f944bf1e6f7f640e50f09c7299a9 100644 (file)
@@ -5291,8 +5291,7 @@ static int evergreen_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
-               r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                    R600_WB_UVD_RPTR_OFFSET,
+               r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
                                     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     0, 0xfffff, RADEON_CP_PACKET2);
                if (!r)
index bc298a3500a42f239a504f535127443f83757525..f543f4ca4ddaadb8d3b339e521969eab34ba962a 100644 (file)
@@ -2225,8 +2225,7 @@ static int cayman_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
-               r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                    R600_WB_UVD_RPTR_OFFSET,
+               r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
                                     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     0, 0xfffff, RADEON_CP_PACKET2);
                if (!r)
index 8a600153ef6cf221004c69dafa22cce1710e85f0..c1b0aba4431ae03e44f4ae347ccd0a01bf1579b9 100644 (file)
@@ -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;
index b26a20fe2859533f4b4b9949c4d4e41b8e8c65f4..2eab174bf22e0de5ee1dc6d526dfa1b9cc1f80db 100644 (file)
@@ -1027,7 +1027,6 @@ struct radeon_wb {
 #define R600_WB_DMA_RPTR_OFFSET   1792
 #define R600_WB_IH_WPTR_OFFSET   2048
 #define CAYMAN_WB_DMA1_RPTR_OFFSET   2304
-#define R600_WB_UVD_RPTR_OFFSET  2560
 #define R600_WB_EVENT_OFFSET     3072
 #define CIK_WB_CP1_WPTR_OFFSET     3328
 #define CIK_WB_CP2_WPTR_OFFSET     3584
index 012fe7218c741c2e3f00f1102134b60ba9733a47..7432247a812afb0b0b3eaafe6b5951f69ca30ba2 100644 (file)
@@ -1157,9 +1157,9 @@ static struct radeon_asic_ring rv770_uvd_ring = {
        .ring_test = &r600_uvd_ring_test,
        .ib_test = &r600_uvd_ib_test,
        .is_lockup = &radeon_ring_test_lockup,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &r600_uvd_get_rptr,
+       .get_wptr = &r600_uvd_get_wptr,
+       .set_wptr = &r600_uvd_set_wptr,
 };
 
 static struct radeon_asic rv770_asic = {
@@ -1593,9 +1593,9 @@ static struct radeon_asic_ring cayman_uvd_ring = {
        .ring_test = &r600_uvd_ring_test,
        .ib_test = &r600_uvd_ib_test,
        .is_lockup = &radeon_ring_test_lockup,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &r600_uvd_get_rptr,
+       .get_wptr = &r600_uvd_get_wptr,
+       .set_wptr = &r600_uvd_set_wptr,
 };
 
 static struct radeon_asic cayman_asic = {
index 5630291c4b06b733e254a653e2ce81453fbd22dd..37baf9c696f0ac21a8453109c74433665193437e 100644 (file)
@@ -424,6 +424,12 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
                                                       struct seq_file *m);
 
 /* uvd */
+uint32_t r600_uvd_get_rptr(struct radeon_device *rdev,
+                           struct radeon_ring *ring);
+uint32_t r600_uvd_get_wptr(struct radeon_device *rdev,
+                           struct radeon_ring *ring);
+void r600_uvd_set_wptr(struct radeon_device *rdev,
+                       struct radeon_ring *ring);
 int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
 void r600_uvd_stop(struct radeon_device *rdev);
 int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
index fb5ea6208970638d67240f16b0cd3947108ad624..cb4b931d8d9f2f6be1cd82f4f148ca450a605508 100644 (file)
@@ -363,7 +363,7 @@ u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
 {
        u32 rptr;
 
-       if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
+       if (rdev->wb.enabled)
                rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
        else
                rptr = RREG32(ring->rptr_reg);
index 52253b2ab0d5a0f24534011021f8d3a9fa77d67c..1e8cf49d5871f0ef73236b34e0e0611cd02bc399 100644 (file)
@@ -1923,8 +1923,7 @@ static int rv770_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
-               r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                    R600_WB_UVD_RPTR_OFFSET,
+               r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
                                     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     0, 0xfffff, RADEON_CP_PACKET2);
                if (!r)
index da23ce8f4388d33caf3a648f7b0c162b84c7b152..4ff59c8f508f6c32d2b6f1b2caaf1d4c8200556a 100644 (file)
@@ -6416,8 +6416,7 @@ static int si_startup(struct radeon_device *rdev)
        if (rdev->has_uvd) {
                ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
                if (ring->ring_size) {
-                       r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                            R600_WB_UVD_RPTR_OFFSET,
+                       r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
                                             UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                             0, 0xfffff, RADEON_CP_PACKET2);
                        if (!r)