return 0;
 }
 
-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
-                             struct radeon_ring *ring)
+u32 cik_gfx_get_rptr(struct radeon_device *rdev,
+                    struct radeon_ring *ring)
 {
        u32 rptr;
 
+       if (rdev->wb.enabled)
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       else
+               rptr = RREG32(CP_RB0_RPTR);
+
+       return rptr;
+}
+
+u32 cik_gfx_get_wptr(struct radeon_device *rdev,
+                    struct radeon_ring *ring)
+{
+       u32 wptr;
+
+       wptr = RREG32(CP_RB0_WPTR);
 
+       return wptr;
+}
+
+void cik_gfx_set_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring)
+{
+       WREG32(CP_RB0_WPTR, ring->wptr);
+       (void)RREG32(CP_RB0_WPTR);
+}
+
+u32 cik_compute_get_rptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring)
+{
+       u32 rptr;
 
        if (rdev->wb.enabled) {
-               rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
        } else {
                mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
        return rptr;
 }
 
-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
-                             struct radeon_ring *ring)
+u32 cik_compute_get_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring)
 {
        u32 wptr;
 
        if (rdev->wb.enabled) {
-               wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
+               /* XXX check if swapping is necessary on BE */
+               wptr = rdev->wb.wb[ring->wptr_offs/4];
        } else {
                mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
        return wptr;
 }
 
-void cik_compute_ring_set_wptr(struct radeon_device *rdev,
-                              struct radeon_ring *ring)
+void cik_compute_set_wptr(struct radeon_device *rdev,
+                         struct radeon_ring *ring)
 {
-       rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(ring->wptr);
+       /* XXX check if swapping is necessary on BE */
+       rdev->wb.wb[ring->wptr_offs/4] = ring->wptr;
        WDOORBELL32(ring->doorbell_index, ring->wptr);
 }
 
 
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-                            CP_RB0_RPTR, CP_RB0_WPTR,
                             PACKET3(PACKET3_NOP, 0x3FFF));
        if (r)
                return r;
        /* type-2 packets are deprecated on MEC, use type-3 instead */
        ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
-                            CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
                             PACKET3(PACKET3_NOP, 0x3FFF));
        if (r)
                return r;
        /* type-2 packets are deprecated on MEC, use type-3 instead */
        ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
-                            CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
                             PACKET3(PACKET3_NOP, 0x3FFF));
        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,
-                            SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET,
-                            SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET,
                             SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
        if (r)
                return r;
 
        ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-                            SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET,
-                            SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET,
                             SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
        if (r)
                return r;
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
                r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-                                    UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     RADEON_CP_PACKET2);
                if (!r)
                        r = uvd_v1_0_init(rdev);
 
  * buffers.
  */
 
+/**
+ * cik_sdma_get_rptr - get the current read pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current rptr from the hardware (CIK+).
+ */
+uint32_t cik_sdma_get_rptr(struct radeon_device *rdev,
+                          struct radeon_ring *ring)
+{
+       u32 rptr, reg;
+
+       if (rdev->wb.enabled) {
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       } else {
+               if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+                       reg = SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET;
+               else
+                       reg = SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET;
+
+               rptr = RREG32(reg);
+       }
+
+       return (rptr & 0x3fffc) >> 2;
+}
+
+/**
+ * cik_sdma_get_wptr - get the current write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current wptr from the hardware (CIK+).
+ */
+uint32_t cik_sdma_get_wptr(struct radeon_device *rdev,
+                          struct radeon_ring *ring)
+{
+       u32 reg;
+
+       if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+               reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
+       else
+               reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
+
+       return (RREG32(reg) & 0x3fffc) >> 2;
+}
+
+/**
+ * cik_sdma_set_wptr - commit the write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Write the wptr back to the hardware (CIK+).
+ */
+void cik_sdma_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring)
+{
+       u32 reg;
+
+       if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+               reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
+       else
+               reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
+
+       WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+}
+
 /**
  * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine
  *
 
 
        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,
                             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,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0));
        if (r)
                return r;
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
                r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-                                    UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     RADEON_CP_PACKET2);
                if (!r)
                        r = uvd_v1_0_init(rdev);
 
        }
 }
 
+u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
+                       struct radeon_ring *ring)
+{
+       u32 rptr;
+
+       if (rdev->wb.enabled)
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       else {
+               if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
+                       rptr = RREG32(CP_RB0_RPTR);
+               else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
+                       rptr = RREG32(CP_RB1_RPTR);
+               else
+                       rptr = RREG32(CP_RB2_RPTR);
+       }
+
+       return rptr;
+}
+
+u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
+                       struct radeon_ring *ring)
+{
+       u32 wptr;
+
+       if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
+               wptr = RREG32(CP_RB0_WPTR);
+       else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
+               wptr = RREG32(CP_RB1_WPTR);
+       else
+               wptr = RREG32(CP_RB2_WPTR);
+
+       return wptr;
+}
+
+void cayman_gfx_set_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring)
+{
+       if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
+               WREG32(CP_RB0_WPTR, ring->wptr);
+               (void)RREG32(CP_RB0_WPTR);
+       } else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
+               WREG32(CP_RB1_WPTR, ring->wptr);
+               (void)RREG32(CP_RB1_WPTR);
+       } else {
+               WREG32(CP_RB2_WPTR, ring->wptr);
+               (void)RREG32(CP_RB2_WPTR);
+       }
+}
+
 static int cayman_cp_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data;
                CP_RB1_BASE,
                CP_RB2_BASE
        };
+       static const unsigned cp_rb_rptr[] = {
+               CP_RB0_RPTR,
+               CP_RB1_RPTR,
+               CP_RB2_RPTR
+       };
+       static const unsigned cp_rb_wptr[] = {
+               CP_RB0_WPTR,
+               CP_RB1_WPTR,
+               CP_RB2_WPTR
+       };
        struct radeon_ring *ring;
        int i, r;
 
                WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
 
                ring->rptr = ring->wptr = 0;
-               WREG32(ring->rptr_reg, ring->rptr);
-               WREG32(ring->wptr_reg, ring->wptr);
+               WREG32(cp_rb_rptr[i], ring->rptr);
+               WREG32(cp_rb_wptr[i], ring->wptr);
 
                mdelay(1);
                WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
        evergreen_irq_set(rdev);
 
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-                            CP_RB0_RPTR, CP_RB0_WPTR,
                             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 + DMA0_REGISTER_OFFSET,
-                            DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
        if (r)
                return r;
 
        ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-                            DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
-                            DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
        if (r)
                return r;
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
                r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-                                    UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     RADEON_CP_PACKET2);
                if (!r)
                        r = uvd_v1_0_init(rdev);
 
  * Cayman and newer support two asynchronous DMA engines.
  */
 
+/**
+ * cayman_dma_get_rptr - get the current read pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current rptr from the hardware (cayman+).
+ */
+uint32_t cayman_dma_get_rptr(struct radeon_device *rdev,
+                            struct radeon_ring *ring)
+{
+       u32 rptr, reg;
+
+       if (rdev->wb.enabled) {
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       } else {
+               if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+                       reg = DMA_RB_RPTR + DMA0_REGISTER_OFFSET;
+               else
+                       reg = DMA_RB_RPTR + DMA1_REGISTER_OFFSET;
+
+               rptr = RREG32(reg);
+       }
+
+       return (rptr & 0x3fffc) >> 2;
+}
+
+/**
+ * cayman_dma_get_wptr - get the current write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current wptr from the hardware (cayman+).
+ */
+uint32_t cayman_dma_get_wptr(struct radeon_device *rdev,
+                          struct radeon_ring *ring)
+{
+       u32 reg;
+
+       if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+               reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
+       else
+               reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;
+
+       return (RREG32(reg) & 0x3fffc) >> 2;
+}
+
+/**
+ * cayman_dma_set_wptr - commit the write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Write the wptr back to the hardware (cayman+).
+ */
+void cayman_dma_set_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring)
+{
+       u32 reg;
+
+       if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+               reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
+       else
+               reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;
+
+       WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+}
+
 /**
  * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
  *
 
        return err;
 }
 
+u32 r100_gfx_get_rptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring)
+{
+       u32 rptr;
+
+       if (rdev->wb.enabled)
+               rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+       else
+               rptr = RREG32(RADEON_CP_RB_RPTR);
+
+       return rptr;
+}
+
+u32 r100_gfx_get_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring)
+{
+       u32 wptr;
+
+       wptr = RREG32(RADEON_CP_RB_WPTR);
+
+       return wptr;
+}
+
+void r100_gfx_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring)
+{
+       WREG32(RADEON_CP_RB_WPTR, ring->wptr);
+       (void)RREG32(RADEON_CP_RB_WPTR);
+}
+
 static void r100_cp_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data;
        ring_size = (1 << (rb_bufsz + 1)) * 4;
        r100_cp_load_microcode(rdev);
        r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET,
-                            RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR,
                             RADEON_CP_PACKET2);
        if (r) {
                return r;
 
        return err;
 }
 
+u32 r600_gfx_get_rptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring)
+{
+       u32 rptr;
+
+       if (rdev->wb.enabled)
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       else
+               rptr = RREG32(R600_CP_RB_RPTR);
+
+       return rptr;
+}
+
+u32 r600_gfx_get_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring)
+{
+       u32 wptr;
+
+       wptr = RREG32(R600_CP_RB_WPTR);
+
+       return wptr;
+}
+
+void r600_gfx_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring)
+{
+       WREG32(R600_CP_RB_WPTR, ring->wptr);
+       (void)RREG32(R600_CP_RB_WPTR);
+}
+
 static int r600_cp_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data;
 
        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,
                             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,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
        if (r)
                return r;
 
 uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
                           struct radeon_ring *ring)
 {
-       return (radeon_ring_generic_get_rptr(rdev, ring) & 0x3fffc) >> 2;
+       u32 rptr;
+
+       if (rdev->wb.enabled)
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       else
+               rptr = RREG32(DMA_RB_RPTR);
+
+       return (rptr & 0x3fffc) >> 2;
 }
 
 /**
 uint32_t r600_dma_get_wptr(struct radeon_device *rdev,
                           struct radeon_ring *ring)
 {
-       return (RREG32(ring->wptr_reg) & 0x3fffc) >> 2;
+       return (RREG32(DMA_RB_WPTR) & 0x3fffc) >> 2;
 }
 
 /**
 void r600_dma_set_wptr(struct radeon_device *rdev,
                       struct radeon_ring *ring)
 {
-       WREG32(ring->wptr_reg, (ring->wptr << 2) & 0x3fffc);
+       WREG32(DMA_RB_WPTR, (ring->wptr << 2) & 0x3fffc);
 }
 
 /**
 
        volatile uint32_t       *ring;
        unsigned                rptr;
        unsigned                rptr_offs;
-       unsigned                rptr_reg;
        unsigned                rptr_save_reg;
        u64                     next_rptr_gpu_addr;
        volatile u32            *next_rptr_cpu_addr;
        unsigned                wptr;
        unsigned                wptr_old;
-       unsigned                wptr_reg;
        unsigned                ring_size;
        unsigned                ring_free_dw;
        int                     count_dw;
 int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
                        unsigned size, uint32_t *data);
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size,
-                    unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 nop);
+                    unsigned rptr_offs, u32 nop);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
 
 
 
        .ring_test = &r100_ring_test,
        .ib_test = &r100_ib_test,
        .is_lockup = &r100_gpu_is_lockup,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &r100_gfx_get_rptr,
+       .get_wptr = &r100_gfx_get_wptr,
+       .set_wptr = &r100_gfx_set_wptr,
 };
 
 static struct radeon_asic r100_asic = {
        .ring_test = &r100_ring_test,
        .ib_test = &r100_ib_test,
        .is_lockup = &r100_gpu_is_lockup,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &r100_gfx_get_rptr,
+       .get_wptr = &r100_gfx_get_wptr,
+       .set_wptr = &r100_gfx_set_wptr,
 };
 
 static struct radeon_asic r300_asic = {
        .ring_test = &r600_ring_test,
        .ib_test = &r600_ib_test,
        .is_lockup = &r600_gfx_is_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_gfx_get_rptr,
+       .get_wptr = &r600_gfx_get_wptr,
+       .set_wptr = &r600_gfx_set_wptr,
 };
 
 static struct radeon_asic_ring r600_dma_ring = {
        .ring_test = &r600_ring_test,
        .ib_test = &r600_ib_test,
        .is_lockup = &evergreen_gfx_is_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_gfx_get_rptr,
+       .get_wptr = &r600_gfx_get_wptr,
+       .set_wptr = &r600_gfx_set_wptr,
 };
 
 static struct radeon_asic_ring evergreen_dma_ring = {
        .ib_test = &r600_ib_test,
        .is_lockup = &cayman_gfx_is_lockup,
        .vm_flush = &cayman_vm_flush,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &cayman_gfx_get_rptr,
+       .get_wptr = &cayman_gfx_get_wptr,
+       .set_wptr = &cayman_gfx_set_wptr,
 };
 
 static struct radeon_asic_ring cayman_dma_ring = {
        .ib_test = &r600_dma_ib_test,
        .is_lockup = &cayman_dma_is_lockup,
        .vm_flush = &cayman_dma_vm_flush,
-       .get_rptr = &r600_dma_get_rptr,
-       .get_wptr = &r600_dma_get_wptr,
-       .set_wptr = &r600_dma_set_wptr
+       .get_rptr = &cayman_dma_get_rptr,
+       .get_wptr = &cayman_dma_get_wptr,
+       .set_wptr = &cayman_dma_set_wptr
 };
 
 static struct radeon_asic_ring cayman_uvd_ring = {
        .ib_test = &r600_ib_test,
        .is_lockup = &si_gfx_is_lockup,
        .vm_flush = &si_vm_flush,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &cayman_gfx_get_rptr,
+       .get_wptr = &cayman_gfx_get_wptr,
+       .set_wptr = &cayman_gfx_set_wptr,
 };
 
 static struct radeon_asic_ring si_dma_ring = {
        .ib_test = &r600_dma_ib_test,
        .is_lockup = &si_dma_is_lockup,
        .vm_flush = &si_dma_vm_flush,
-       .get_rptr = &r600_dma_get_rptr,
-       .get_wptr = &r600_dma_get_wptr,
-       .set_wptr = &r600_dma_set_wptr,
+       .get_rptr = &cayman_dma_get_rptr,
+       .get_wptr = &cayman_dma_get_wptr,
+       .set_wptr = &cayman_dma_set_wptr,
 };
 
 static struct radeon_asic si_asic = {
        .ib_test = &cik_ib_test,
        .is_lockup = &cik_gfx_is_lockup,
        .vm_flush = &cik_vm_flush,
-       .get_rptr = &radeon_ring_generic_get_rptr,
-       .get_wptr = &radeon_ring_generic_get_wptr,
-       .set_wptr = &radeon_ring_generic_set_wptr,
+       .get_rptr = &cik_gfx_get_rptr,
+       .get_wptr = &cik_gfx_get_wptr,
+       .set_wptr = &cik_gfx_set_wptr,
 };
 
 static struct radeon_asic_ring ci_cp_ring = {
        .ib_test = &cik_ib_test,
        .is_lockup = &cik_gfx_is_lockup,
        .vm_flush = &cik_vm_flush,
-       .get_rptr = &cik_compute_ring_get_rptr,
-       .get_wptr = &cik_compute_ring_get_wptr,
-       .set_wptr = &cik_compute_ring_set_wptr,
+       .get_rptr = &cik_compute_get_rptr,
+       .get_wptr = &cik_compute_get_wptr,
+       .set_wptr = &cik_compute_set_wptr,
 };
 
 static struct radeon_asic_ring ci_dma_ring = {
        .ib_test = &cik_sdma_ib_test,
        .is_lockup = &cik_sdma_is_lockup,
        .vm_flush = &cik_dma_vm_flush,
-       .get_rptr = &r600_dma_get_rptr,
-       .get_wptr = &r600_dma_get_wptr,
-       .set_wptr = &r600_dma_set_wptr,
+       .get_rptr = &cik_sdma_get_rptr,
+       .get_wptr = &cik_sdma_get_wptr,
+       .set_wptr = &cik_sdma_set_wptr,
 };
 
 static struct radeon_asic ci_asic = {
 
 void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
 u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
 
-u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
-                                struct radeon_ring *ring);
-u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
-                                struct radeon_ring *ring);
-void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
-                                 struct radeon_ring *ring);
-
 /*
  * r100,rv100,rs100,rv200,rs200
  */
 extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
 
+u32 r100_gfx_get_rptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+u32 r100_gfx_get_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+void r100_gfx_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring);
+
 /*
  * r200,rv250,rs300,rv280
  */
 int r600_pcie_gart_init(struct radeon_device *rdev);
 void r600_scratch_init(struct radeon_device *rdev);
 int r600_init_microcode(struct radeon_device *rdev);
+u32 r600_gfx_get_rptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+u32 r600_gfx_get_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+void r600_gfx_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring);
 /* r600 irq */
 int r600_irq_process(struct radeon_device *rdev);
 int r600_irq_init(struct radeon_device *rdev);
 
 void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 
+u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
+                       struct radeon_ring *ring);
+u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
+                       struct radeon_ring *ring);
+void cayman_gfx_set_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring);
+uint32_t cayman_dma_get_rptr(struct radeon_device *rdev,
+                            struct radeon_ring *ring);
+uint32_t cayman_dma_get_wptr(struct radeon_device *rdev,
+                            struct radeon_ring *ring);
+void cayman_dma_set_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring);
+
 int ni_dpm_init(struct radeon_device *rdev);
 void ni_dpm_setup_asic(struct radeon_device *rdev);
 int ni_dpm_enable(struct radeon_device *rdev);
                          uint32_t incr, uint32_t flags);
 void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
-                             struct radeon_ring *ring);
-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
-                             struct radeon_ring *ring);
-void cik_compute_ring_set_wptr(struct radeon_device *rdev,
-                              struct radeon_ring *ring);
+u32 cik_gfx_get_rptr(struct radeon_device *rdev,
+                    struct radeon_ring *ring);
+u32 cik_gfx_get_wptr(struct radeon_device *rdev,
+                    struct radeon_ring *ring);
+void cik_gfx_set_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+u32 cik_compute_get_rptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring);
+u32 cik_compute_get_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring);
+void cik_compute_set_wptr(struct radeon_device *rdev,
+                         struct radeon_ring *ring);
+u32 cik_sdma_get_rptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+u32 cik_sdma_get_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring);
+void cik_sdma_set_wptr(struct radeon_device *rdev,
+                      struct radeon_ring *ring);
 int ci_get_temp(struct radeon_device *rdev);
 int kv_get_temp(struct radeon_device *rdev);
 
 
        }
 }
 
-u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
-                                struct radeon_ring *ring)
-{
-       u32 rptr;
-
-       if (rdev->wb.enabled)
-               rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
-       else
-               rptr = RREG32(ring->rptr_reg);
-
-       return rptr;
-}
-
-u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
-                                struct radeon_ring *ring)
-{
-       u32 wptr;
-
-       wptr = RREG32(ring->wptr_reg);
-
-       return wptr;
-}
-
-void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
-                                 struct radeon_ring *ring)
-{
-       WREG32(ring->wptr_reg, ring->wptr);
-       (void)RREG32(ring->wptr_reg);
-}
-
 /**
  * radeon_ring_free_size - update the free size
  *
  * @ring: radeon_ring structure holding ring information
  * @ring_size: size of the ring
  * @rptr_offs: offset of the rptr writeback location in the WB buffer
- * @rptr_reg: MMIO offset of the rptr register
- * @wptr_reg: MMIO offset of the wptr register
  * @nop: nop packet for this ring
  *
  * Initialize the driver information for the selected ring (all asics).
  * Returns 0 on success, error on failure.
  */
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size,
-                    unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 nop)
+                    unsigned rptr_offs, u32 nop)
 {
        int r;
 
        ring->ring_size = ring_size;
        ring->rptr_offs = rptr_offs;
-       ring->rptr_reg = rptr_reg;
-       ring->wptr_reg = wptr_reg;
        ring->nop = nop;
        /* Allocate ring buffer */
        if (ring->ring_obj == NULL) {
        count = (ring->ring_size / 4) - ring->ring_free_dw;
 
        wptr = radeon_ring_get_wptr(rdev, ring);
-       seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n",
-                  ring->wptr_reg, wptr, wptr);
+       seq_printf(m, "wptr: 0x%08x [%5d]\n",
+                  wptr, wptr);
 
        rptr = radeon_ring_get_rptr(rdev, ring);
-       seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n",
-                  ring->rptr_reg, rptr, rptr);
+       seq_printf(m, "rptr: 0x%08x [%5d]\n",
+                  rptr, rptr);
 
        if (ring->rptr_save_reg) {
                rptr_next = RREG32(ring->rptr_save_reg);
 
 
        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,
                             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,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
        if (r)
                return r;
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
                r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-                                    UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     RADEON_CP_PACKET2);
                if (!r)
                        r = uvd_v1_0_init(rdev);
 
 
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-                            CP_RB0_RPTR, CP_RB0_WPTR,
                             RADEON_CP_PACKET2);
        if (r)
                return r;
 
        ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
-                            CP_RB1_RPTR, CP_RB1_WPTR,
                             RADEON_CP_PACKET2);
        if (r)
                return r;
 
        ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
-                            CP_RB2_RPTR, CP_RB2_WPTR,
                             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 + DMA0_REGISTER_OFFSET,
-                            DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
        if (r)
                return r;
 
        ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-                            DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
-                            DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
                             DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
        if (r)
                return r;
                ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
                if (ring->ring_size) {
                        r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-                                            UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                             RADEON_CP_PACKET2);
                        if (!r)
                                r = uvd_v1_0_init(rdev);