aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/cik_sdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/cik_sdma.c')
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c120
1 files changed, 106 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index d08b83c6267b..1ecb3f1070e3 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -52,6 +52,75 @@ u32 cik_gpu_check_soft_reset(struct radeon_device *rdev);
52 */ 52 */
53 53
54/** 54/**
55 * cik_sdma_get_rptr - get the current read pointer
56 *
57 * @rdev: radeon_device pointer
58 * @ring: radeon ring pointer
59 *
60 * Get the current rptr from the hardware (CIK+).
61 */
62uint32_t cik_sdma_get_rptr(struct radeon_device *rdev,
63 struct radeon_ring *ring)
64{
65 u32 rptr, reg;
66
67 if (rdev->wb.enabled) {
68 rptr = rdev->wb.wb[ring->rptr_offs/4];
69 } else {
70 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
71 reg = SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET;
72 else
73 reg = SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET;
74
75 rptr = RREG32(reg);
76 }
77
78 return (rptr & 0x3fffc) >> 2;
79}
80
81/**
82 * cik_sdma_get_wptr - get the current write pointer
83 *
84 * @rdev: radeon_device pointer
85 * @ring: radeon ring pointer
86 *
87 * Get the current wptr from the hardware (CIK+).
88 */
89uint32_t cik_sdma_get_wptr(struct radeon_device *rdev,
90 struct radeon_ring *ring)
91{
92 u32 reg;
93
94 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
95 reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
96 else
97 reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
98
99 return (RREG32(reg) & 0x3fffc) >> 2;
100}
101
102/**
103 * cik_sdma_set_wptr - commit the write pointer
104 *
105 * @rdev: radeon_device pointer
106 * @ring: radeon ring pointer
107 *
108 * Write the wptr back to the hardware (CIK+).
109 */
110void cik_sdma_set_wptr(struct radeon_device *rdev,
111 struct radeon_ring *ring)
112{
113 u32 reg;
114
115 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
116 reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
117 else
118 reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
119
120 WREG32(reg, (ring->wptr << 2) & 0x3fffc);
121}
122
123/**
55 * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine 124 * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine
56 * 125 *
57 * @rdev: radeon_device pointer 126 * @rdev: radeon_device pointer
@@ -88,6 +157,35 @@ void cik_sdma_ring_ib_execute(struct radeon_device *rdev,
88} 157}
89 158
90/** 159/**
160 * cik_sdma_hdp_flush_ring_emit - emit an hdp flush on the DMA ring
161 *
162 * @rdev: radeon_device pointer
163 * @ridx: radeon ring index
164 *
165 * Emit an hdp flush packet on the requested DMA ring.
166 */
167static void cik_sdma_hdp_flush_ring_emit(struct radeon_device *rdev,
168 int ridx)
169{
170 struct radeon_ring *ring = &rdev->ring[ridx];
171 u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) |
172 SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */
173 u32 ref_and_mask;
174
175 if (ridx == R600_RING_TYPE_DMA_INDEX)
176 ref_and_mask = SDMA0;
177 else
178 ref_and_mask = SDMA1;
179
180 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
181 radeon_ring_write(ring, GPU_HDP_FLUSH_DONE);
182 radeon_ring_write(ring, GPU_HDP_FLUSH_REQ);
183 radeon_ring_write(ring, ref_and_mask); /* reference */
184 radeon_ring_write(ring, ref_and_mask); /* mask */
185 radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */
186}
187
188/**
91 * cik_sdma_fence_ring_emit - emit a fence on the DMA ring 189 * cik_sdma_fence_ring_emit - emit a fence on the DMA ring
92 * 190 *
93 * @rdev: radeon_device pointer 191 * @rdev: radeon_device pointer
@@ -111,12 +209,7 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
111 /* generate an interrupt */ 209 /* generate an interrupt */
112 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0)); 210 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0));
113 /* flush HDP */ 211 /* flush HDP */
114 /* We should be using the new POLL_REG_MEM special op packet here 212 cik_sdma_hdp_flush_ring_emit(rdev, fence->ring);
115 * but it causes sDMA to hang sometimes
116 */
117 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
118 radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
119 radeon_ring_write(ring, 0);
120} 213}
121 214
122/** 215/**
@@ -157,7 +250,9 @@ static void cik_sdma_gfx_stop(struct radeon_device *rdev)
157 u32 rb_cntl, reg_offset; 250 u32 rb_cntl, reg_offset;
158 int i; 251 int i;
159 252
160 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); 253 if ((rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) ||
254 (rdev->asic->copy.copy_ring_index == CAYMAN_RING_TYPE_DMA1_INDEX))
255 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
161 256
162 for (i = 0; i < 2; i++) { 257 for (i = 0; i < 2; i++) {
163 if (i == 0) 258 if (i == 0)
@@ -288,7 +383,9 @@ static int cik_sdma_gfx_resume(struct radeon_device *rdev)
288 } 383 }
289 } 384 }
290 385
291 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); 386 if ((rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) ||
387 (rdev->asic->copy.copy_ring_index == CAYMAN_RING_TYPE_DMA1_INDEX))
388 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
292 389
293 return 0; 390 return 0;
294} 391}
@@ -747,12 +844,7 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm
747 radeon_ring_write(ring, VMID(0)); 844 radeon_ring_write(ring, VMID(0));
748 845
749 /* flush HDP */ 846 /* flush HDP */
750 /* We should be using the new POLL_REG_MEM special op packet here 847 cik_sdma_hdp_flush_ring_emit(rdev, ridx);
751 * but it causes sDMA to hang sometimes
752 */
753 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
754 radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
755 radeon_ring_write(ring, 0);
756 848
757 /* flush TLB */ 849 /* flush TLB */
758 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 850 radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));