aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_fence.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/gpu/drm/radeon/radeon_fence.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_fence.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index b1f9a81b5d1d..021d2b6b556f 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -38,6 +38,36 @@
38#include "drm.h" 38#include "drm.h"
39#include "radeon_reg.h" 39#include "radeon_reg.h"
40#include "radeon.h" 40#include "radeon.h"
41#include "radeon_trace.h"
42
43static void radeon_fence_write(struct radeon_device *rdev, u32 seq)
44{
45 if (rdev->wb.enabled) {
46 u32 scratch_index;
47 if (rdev->wb.use_event)
48 scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
49 else
50 scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
51 rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);;
52 } else
53 WREG32(rdev->fence_drv.scratch_reg, seq);
54}
55
56static u32 radeon_fence_read(struct radeon_device *rdev)
57{
58 u32 seq;
59
60 if (rdev->wb.enabled) {
61 u32 scratch_index;
62 if (rdev->wb.use_event)
63 scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
64 else
65 scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
66 seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
67 } else
68 seq = RREG32(rdev->fence_drv.scratch_reg);
69 return seq;
70}
41 71
42int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) 72int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
43{ 73{
@@ -49,17 +79,17 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
49 return 0; 79 return 0;
50 } 80 }
51 fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); 81 fence->seq = atomic_add_return(1, &rdev->fence_drv.seq);
52 if (!rdev->cp.ready) { 82 if (!rdev->cp.ready)
53 /* FIXME: cp is not running assume everythings is done right 83 /* FIXME: cp is not running assume everythings is done right
54 * away 84 * away
55 */ 85 */
56 WREG32(rdev->fence_drv.scratch_reg, fence->seq); 86 radeon_fence_write(rdev, fence->seq);
57 } else 87 else
58 radeon_fence_ring_emit(rdev, fence); 88 radeon_fence_ring_emit(rdev, fence);
59 89
90 trace_radeon_fence_emit(rdev->ddev, fence->seq);
60 fence->emited = true; 91 fence->emited = true;
61 list_del(&fence->list); 92 list_move_tail(&fence->list, &rdev->fence_drv.emited);
62 list_add_tail(&fence->list, &rdev->fence_drv.emited);
63 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 93 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
64 return 0; 94 return 0;
65} 95}
@@ -72,7 +102,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
72 bool wake = false; 102 bool wake = false;
73 unsigned long cjiffies; 103 unsigned long cjiffies;
74 104
75 seq = RREG32(rdev->fence_drv.scratch_reg); 105 seq = radeon_fence_read(rdev);
76 if (seq != rdev->fence_drv.last_seq) { 106 if (seq != rdev->fence_drv.last_seq) {
77 rdev->fence_drv.last_seq = seq; 107 rdev->fence_drv.last_seq = seq;
78 rdev->fence_drv.last_jiffies = jiffies; 108 rdev->fence_drv.last_jiffies = jiffies;
@@ -111,8 +141,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
111 i = n; 141 i = n;
112 do { 142 do {
113 n = i->prev; 143 n = i->prev;
114 list_del(i); 144 list_move_tail(i, &rdev->fence_drv.signaled);
115 list_add_tail(i, &rdev->fence_drv.signaled);
116 fence = list_entry(i, struct radeon_fence, list); 145 fence = list_entry(i, struct radeon_fence, list);
117 fence->signaled = true; 146 fence->signaled = true;
118 i = n; 147 i = n;
@@ -205,6 +234,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
205retry: 234retry:
206 /* save current sequence used to check for GPU lockup */ 235 /* save current sequence used to check for GPU lockup */
207 seq = rdev->fence_drv.last_seq; 236 seq = rdev->fence_drv.last_seq;
237 trace_radeon_fence_wait_begin(rdev->ddev, seq);
208 if (intr) { 238 if (intr) {
209 radeon_irq_kms_sw_irq_get(rdev); 239 radeon_irq_kms_sw_irq_get(rdev);
210 r = wait_event_interruptible_timeout(rdev->fence_drv.queue, 240 r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
@@ -219,6 +249,7 @@ retry:
219 radeon_fence_signaled(fence), timeout); 249 radeon_fence_signaled(fence), timeout);
220 radeon_irq_kms_sw_irq_put(rdev); 250 radeon_irq_kms_sw_irq_put(rdev);
221 } 251 }
252 trace_radeon_fence_wait_end(rdev->ddev, seq);
222 if (unlikely(!radeon_fence_signaled(fence))) { 253 if (unlikely(!radeon_fence_signaled(fence))) {
223 /* we were interrupted for some reason and fence isn't 254 /* we were interrupted for some reason and fence isn't
224 * isn't signaled yet, resume wait 255 * isn't signaled yet, resume wait
@@ -232,7 +263,8 @@ retry:
232 */ 263 */
233 if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { 264 if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) {
234 /* good news we believe it's a lockup */ 265 /* good news we believe it's a lockup */
235 WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); 266 WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n",
267 fence->seq, seq);
236 /* FIXME: what should we do ? marking everyone 268 /* FIXME: what should we do ? marking everyone
237 * as signaled for now 269 * as signaled for now
238 */ 270 */
@@ -240,7 +272,7 @@ retry:
240 r = radeon_gpu_reset(rdev); 272 r = radeon_gpu_reset(rdev);
241 if (r) 273 if (r)
242 return r; 274 return r;
243 WREG32(rdev->fence_drv.scratch_reg, fence->seq); 275 radeon_fence_write(rdev, fence->seq);
244 rdev->gpu_lockup = false; 276 rdev->gpu_lockup = false;
245 } 277 }
246 timeout = RADEON_FENCE_JIFFIES_TIMEOUT; 278 timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
@@ -311,7 +343,7 @@ void radeon_fence_unref(struct radeon_fence **fence)
311 343
312 *fence = NULL; 344 *fence = NULL;
313 if (tmp) { 345 if (tmp) {
314 kref_put(&tmp->kref, &radeon_fence_destroy); 346 kref_put(&tmp->kref, radeon_fence_destroy);
315 } 347 }
316} 348}
317 349
@@ -340,7 +372,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev)
340 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 372 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
341 return r; 373 return r;
342 } 374 }
343 WREG32(rdev->fence_drv.scratch_reg, 0); 375 radeon_fence_write(rdev, 0);
344 atomic_set(&rdev->fence_drv.seq, 0); 376 atomic_set(&rdev->fence_drv.seq, 0);
345 INIT_LIST_HEAD(&rdev->fence_drv.created); 377 INIT_LIST_HEAD(&rdev->fence_drv.created);
346 INIT_LIST_HEAD(&rdev->fence_drv.emited); 378 INIT_LIST_HEAD(&rdev->fence_drv.emited);
@@ -380,7 +412,7 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
380 struct radeon_fence *fence; 412 struct radeon_fence *fence;
381 413
382 seq_printf(m, "Last signaled fence 0x%08X\n", 414 seq_printf(m, "Last signaled fence 0x%08X\n",
383 RREG32(rdev->fence_drv.scratch_reg)); 415 radeon_fence_read(rdev));
384 if (!list_empty(&rdev->fence_drv.emited)) { 416 if (!list_empty(&rdev->fence_drv.emited)) {
385 fence = list_entry(rdev->fence_drv.emited.prev, 417 fence = list_entry(rdev->fence_drv.emited.prev,
386 struct radeon_fence, list); 418 struct radeon_fence, list);