drm/radeon: remove special handling for the DMA ring
[linux-2.6-block.git] / drivers / gpu / drm / radeon / r600.c
index e66e7207735036e2ffab5e18f37854384595bf80..30849eca6e07353ef35997831218a8cbca5debaa 100644 (file)
@@ -2504,6 +2504,49 @@ void r600_cp_fini(struct radeon_device *rdev)
  * solid fills, and a number of other things.  It also
  * has support for tiling/detiling of buffers.
  */
+
+/**
+ * r600_dma_get_rptr - get the current read pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current rptr from the hardware (r6xx+).
+ */
+uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
+                          struct radeon_ring *ring)
+{
+       return (radeon_ring_generic_get_rptr(rdev, ring) & 0x3fffc) >> 2;
+}
+
+/**
+ * r600_dma_get_wptr - get the current write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current wptr from the hardware (r6xx+).
+ */
+uint32_t r600_dma_get_wptr(struct radeon_device *rdev,
+                          struct radeon_ring *ring)
+{
+       return (RREG32(ring->wptr_reg) & 0x3fffc) >> 2;
+}
+
+/**
+ * r600_dma_set_wptr - commit the write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Write the wptr back to the hardware (r6xx+).
+ */
+void r600_dma_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring)
+{
+       WREG32(ring->wptr_reg, (ring->wptr << 2) & 0x3fffc);
+}
+
 /**
  * r600_dma_stop - stop the async dma engine
  *
@@ -2623,31 +2666,38 @@ void r600_dma_fini(struct radeon_device *rdev)
 /*
  * UVD
  */
-int r600_uvd_rbc_start(struct radeon_device *rdev)
+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,49 +2712,49 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
        /* 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);
 
-       ring->ready = true;
-       r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
-       if (r) {
-               ring->ready = false;
-               return r;
-       }
+       if (ring_test) {
+               ring->ready = true;
+               r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
+               if (r) {
+                       ring->ready = false;
+                       return r;
+               }
 
-       r = radeon_ring_lock(rdev, ring, 10);
-       if (r) {
-               DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
-               return r;
-       }
+               r = radeon_ring_lock(rdev, ring, 10);
+               if (r) {
+                       DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
+                       return r;
+               }
 
-       tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
-       radeon_ring_write(ring, tmp);
-       radeon_ring_write(ring, 0xFFFFF);
+               tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
+               radeon_ring_write(ring, tmp);
+               radeon_ring_write(ring, 0xFFFFF);
 
-       tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
-       radeon_ring_write(ring, tmp);
-       radeon_ring_write(ring, 0xFFFFF);
+               tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
+               radeon_ring_write(ring, tmp);
+               radeon_ring_write(ring, 0xFFFFF);
 
-       tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
-       radeon_ring_write(ring, tmp);
-       radeon_ring_write(ring, 0xFFFFF);
+               tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
+               radeon_ring_write(ring, tmp);
+               radeon_ring_write(ring, 0xFFFFF);
 
-       /* Clear timeout status bits */
-       radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
-       radeon_ring_write(ring, 0x8);
+               /* Clear timeout status bits */
+               radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
+               radeon_ring_write(ring, 0x8);
 
-       radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
-       radeon_ring_write(ring, 3);
+               radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
+               radeon_ring_write(ring, 3);
 
-       radeon_ring_unlock_commit(rdev, ring);
+               radeon_ring_unlock_commit(rdev, ring);
+       }
 
        return 0;
 }
 
-void r600_uvd_stop(struct radeon_device *rdev)
+void r600_do_uvd_stop(struct radeon_device *rdev)
 {
-       struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
-
        /* force RBC into idle state */
        WREG32(UVD_RBC_RB_CNTL, 0x11010101);
 
@@ -2723,11 +2773,17 @@ void r600_uvd_stop(struct radeon_device *rdev)
        /* Unstall UMC and register bus */
        WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
        WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
+}
+
+void r600_uvd_stop(struct radeon_device *rdev)
+{
+       struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 
+       r600_do_uvd_stop(rdev);
        ring->ready = false;
 }
 
-int r600_uvd_init(struct radeon_device *rdev)
+int r600_uvd_init(struct radeon_device *rdev, bool ring_test)
 {
        int i, j, r;
        /* disable byte swapping */
@@ -2815,17 +2871,17 @@ int r600_uvd_init(struct radeon_device *rdev)
 
        if (r) {
                DRM_ERROR("UVD not responding, giving up!!!\n");
-               radeon_set_uvd_clocks(rdev, 0, 0);
-               return r;
+               goto done;
        }
 
        /* enable interupt */
        WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
 
-       r = r600_uvd_rbc_start(rdev);
+       r = r600_uvd_rbc_start(rdev, ring_test);
        if (!r)
                DRM_INFO("UVD initialized successfully.\n");
 
+done:
        /* lower clocks again */
        radeon_set_uvd_clocks(rdev, 0, 0);
 
@@ -3136,25 +3192,6 @@ void r600_uvd_semaphore_emit(struct radeon_device *rdev,
        radeon_ring_write(ring, emit_wait ? 1 : 0);
 }
 
-int r600_copy_blit(struct radeon_device *rdev,
-                  uint64_t src_offset,
-                  uint64_t dst_offset,
-                  unsigned num_gpu_pages,
-                  struct radeon_fence **fence)
-{
-       struct radeon_semaphore *sem = NULL;
-       struct radeon_sa_bo *vb = NULL;
-       int r;
-
-       r = r600_blit_prepare_copy(rdev, num_gpu_pages, fence, &vb, &sem);
-       if (r) {
-               return r;
-       }
-       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages, vb);
-       r600_blit_done_copy(rdev, fence, vb, sem);
-       return 0;
-}
-
 /**
  * r600_copy_cpdma - copy pages using the CP DMA engine
  *
@@ -3356,12 +3393,6 @@ static int r600_startup(struct radeon_device *rdev)
                        return r;
        }
        r600_gpu_init(rdev);
-       r = r600_blit_init(rdev);
-       if (r) {
-               r600_blit_fini(rdev);
-               rdev->asic->copy.copy = NULL;
-               dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
-       }
 
        /* allocate wb buffer */
        r = radeon_wb_init(rdev);
@@ -3398,14 +3429,14 @@ static int r600_startup(struct radeon_device *rdev)
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
                             R600_CP_RB_RPTR, R600_CP_RB_WPTR,
-                            0, 0xfffff, RADEON_CP_PACKET2);
+                            RADEON_CP_PACKET2);
        if (r)
                return r;
 
        ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
                             DMA_RB_RPTR, DMA_RB_WPTR,
-                            2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+                            DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
        if (r)
                return r;
 
@@ -3574,7 +3605,6 @@ int r600_init(struct radeon_device *rdev)
 void r600_fini(struct radeon_device *rdev)
 {
        r600_audio_fini(rdev);
-       r600_blit_fini(rdev);
        r600_cp_fini(rdev);
        r600_dma_fini(rdev);
        r600_irq_fini(rdev);