diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/gpu/drm/radeon/radeon_fence.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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.c | 58 |
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 | |||
43 | static 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 | |||
56 | static 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 | ||
42 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) | 72 | int 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) | |||
205 | retry: | 234 | retry: |
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); |