Rev 1986 | Rev 2005 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1986 | Rev 2004 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | * Jerome Glisse |
28 | * Jerome Glisse |
29 | * Dave Airlie |
29 | * Dave Airlie |
30 | */ |
30 | */ |
31 | #include |
31 | #include |
32 | #include |
32 | #include |
33 | #include |
33 | //#include |
34 | #include |
34 | #include |
35 | #include |
35 | #include |
36 | #include |
36 | #include |
37 | #include "drmP.h" |
37 | #include "drmP.h" |
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" |
Line -... | Line 41... | ||
- | 41 | ||
- | 42 | static void radeon_fence_write(struct radeon_device *rdev, u32 seq) |
|
- | 43 | { |
|
- | 44 | if (rdev->wb.enabled) { |
|
- | 45 | u32 scratch_index; |
|
- | 46 | if (rdev->wb.use_event) |
|
- | 47 | scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
|
- | 48 | else |
|
- | 49 | scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
|
- | 50 | rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);; |
|
- | 51 | } else |
|
- | 52 | WREG32(rdev->fence_drv.scratch_reg, seq); |
|
- | 53 | } |
|
- | 54 | ||
- | 55 | static u32 radeon_fence_read(struct radeon_device *rdev) |
|
- | 56 | { |
|
- | 57 | u32 seq; |
|
- | 58 | ||
- | 59 | if (rdev->wb.enabled) { |
|
- | 60 | u32 scratch_index; |
|
- | 61 | if (rdev->wb.use_event) |
|
- | 62 | scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
|
- | 63 | else |
|
- | 64 | scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
|
- | 65 | seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); |
|
- | 66 | } else |
|
- | 67 | seq = RREG32(rdev->fence_drv.scratch_reg); |
|
- | 68 | return seq; |
|
- | 69 | } |
|
41 | 70 | ||
42 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) |
71 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) |
43 | { |
72 | { |
Line 44... | Line 73... | ||
44 | unsigned long irq_flags; |
73 | unsigned long irq_flags; |
45 | 74 | ||
46 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
75 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
47 | if (fence->emited) { |
76 | if (fence->emited) { |
48 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
77 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
49 | return 0; |
78 | return 0; |
50 | } |
79 | } |
51 | fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); |
80 | fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); |
52 | if (!rdev->cp.ready) { |
81 | if (!rdev->cp.ready) |
53 | /* FIXME: cp is not running assume everythings is done right |
82 | /* FIXME: cp is not running assume everythings is done right |
54 | * away |
83 | * away |
55 | */ |
84 | */ |
56 | WREG32(rdev->fence_drv.scratch_reg, fence->seq); |
85 | radeon_fence_write(rdev, fence->seq); |
Line 57... | Line 86... | ||
57 | } else |
86 | else |
58 | radeon_fence_ring_emit(rdev, fence); |
87 | radeon_fence_ring_emit(rdev, fence); |
59 | 88 | ||
60 | trace_radeon_fence_emit(rdev->ddev, fence->seq); |
89 | // trace_radeon_fence_emit(rdev->ddev, fence->seq); |
61 | fence->emited = true; |
90 | fence->emited = true; |
62 | list_move_tail(&fence->list, &rdev->fence_drv.emited); |
91 | list_move_tail(&fence->list, &rdev->fence_drv.emited); |
Line 70... | Line 99... | ||
70 | struct list_head *i, *n; |
99 | struct list_head *i, *n; |
71 | uint32_t seq; |
100 | uint32_t seq; |
72 | bool wake = false; |
101 | bool wake = false; |
73 | unsigned long cjiffies; |
102 | unsigned long cjiffies; |
Line 74... | Line -... | ||
74 | - | ||
75 | if (rdev->wb.enabled) { |
- | |
76 | u32 scratch_index; |
- | |
77 | if (rdev->wb.use_event) |
- | |
78 | scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
103 | |
79 | else |
- | |
80 | scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
- | |
81 | seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); |
- | |
82 | } else |
104 | #if 0 |
83 | seq = RREG32(rdev->fence_drv.scratch_reg); |
105 | seq = radeon_fence_read(rdev); |
84 | if (seq != rdev->fence_drv.last_seq) { |
106 | if (seq != rdev->fence_drv.last_seq) { |
85 | rdev->fence_drv.last_seq = seq; |
107 | rdev->fence_drv.last_seq = seq; |
86 | rdev->fence_drv.last_jiffies = jiffies; |
108 | rdev->fence_drv.last_jiffies = jiffies; |
87 | rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
109 | // rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
88 | } else { |
110 | } else { |
89 | cjiffies = jiffies; |
111 | cjiffies = jiffies; |
90 | if (time_after(cjiffies, rdev->fence_drv.last_jiffies)) { |
112 | if (time_after(cjiffies, rdev->fence_drv.last_jiffies)) { |
91 | cjiffies -= rdev->fence_drv.last_jiffies; |
113 | cjiffies -= rdev->fence_drv.last_jiffies; |
Line 124... | Line 146... | ||
124 | fence->signaled = true; |
146 | fence->signaled = true; |
125 | i = n; |
147 | i = n; |
126 | } while (i != &rdev->fence_drv.emited); |
148 | } while (i != &rdev->fence_drv.emited); |
127 | wake = true; |
149 | wake = true; |
128 | } |
150 | } |
- | 151 | #endif |
|
129 | return wake; |
152 | return wake; |
130 | } |
153 | } |
Line 131... | Line 154... | ||
131 | 154 | ||
132 | static void radeon_fence_destroy(struct kref *kref) |
155 | static void radeon_fence_destroy(struct kref *kref) |
Line 148... | Line 171... | ||
148 | 171 | ||
149 | *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); |
172 | *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); |
150 | if ((*fence) == NULL) { |
173 | if ((*fence) == NULL) { |
151 | return -ENOMEM; |
174 | return -ENOMEM; |
152 | } |
175 | } |
153 | kref_init(&((*fence)->kref)); |
176 | // kref_init(&((*fence)->kref)); |
154 | (*fence)->rdev = rdev; |
177 | (*fence)->rdev = rdev; |
155 | (*fence)->emited = false; |
178 | (*fence)->emited = false; |
156 | (*fence)->signaled = false; |
179 | (*fence)->signaled = false; |
157 | (*fence)->seq = 0; |
180 | (*fence)->seq = 0; |
Line 206... | Line 229... | ||
206 | } |
229 | } |
207 | rdev = fence->rdev; |
230 | rdev = fence->rdev; |
208 | if (radeon_fence_signaled(fence)) { |
231 | if (radeon_fence_signaled(fence)) { |
209 | return 0; |
232 | return 0; |
210 | } |
233 | } |
- | 234 | ||
- | 235 | #if 0 |
|
211 | timeout = rdev->fence_drv.last_timeout; |
236 | timeout = rdev->fence_drv.last_timeout; |
212 | retry: |
237 | retry: |
213 | /* save current sequence used to check for GPU lockup */ |
238 | /* save current sequence used to check for GPU lockup */ |
214 | seq = rdev->fence_drv.last_seq; |
239 | seq = rdev->fence_drv.last_seq; |
215 | trace_radeon_fence_wait_begin(rdev->ddev, seq); |
240 | // trace_radeon_fence_wait_begin(rdev->ddev, seq); |
216 | if (intr) { |
241 | if (intr) { |
217 | radeon_irq_kms_sw_irq_get(rdev); |
242 | radeon_irq_kms_sw_irq_get(rdev); |
218 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
243 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
219 | radeon_fence_signaled(fence), timeout); |
244 | radeon_fence_signaled(fence), timeout); |
220 | radeon_irq_kms_sw_irq_put(rdev); |
245 | radeon_irq_kms_sw_irq_put(rdev); |
Line 225... | Line 250... | ||
225 | radeon_irq_kms_sw_irq_get(rdev); |
250 | radeon_irq_kms_sw_irq_get(rdev); |
226 | r = wait_event_timeout(rdev->fence_drv.queue, |
251 | r = wait_event_timeout(rdev->fence_drv.queue, |
227 | radeon_fence_signaled(fence), timeout); |
252 | radeon_fence_signaled(fence), timeout); |
228 | radeon_irq_kms_sw_irq_put(rdev); |
253 | radeon_irq_kms_sw_irq_put(rdev); |
229 | } |
254 | } |
230 | trace_radeon_fence_wait_end(rdev->ddev, seq); |
255 | // trace_radeon_fence_wait_end(rdev->ddev, seq); |
231 | if (unlikely(!radeon_fence_signaled(fence))) { |
256 | if (unlikely(!radeon_fence_signaled(fence))) { |
232 | /* we were interrupted for some reason and fence isn't |
257 | /* we were interrupted for some reason and fence isn't |
233 | * isn't signaled yet, resume wait |
258 | * isn't signaled yet, resume wait |
234 | */ |
259 | */ |
235 | if (r) { |
260 | if (r) { |
Line 248... | Line 273... | ||
248 | */ |
273 | */ |
249 | rdev->gpu_lockup = true; |
274 | rdev->gpu_lockup = true; |
250 | r = radeon_gpu_reset(rdev); |
275 | r = radeon_gpu_reset(rdev); |
251 | if (r) |
276 | if (r) |
252 | return r; |
277 | return r; |
253 | WREG32(rdev->fence_drv.scratch_reg, fence->seq); |
278 | radeon_fence_write(rdev, fence->seq); |
254 | rdev->gpu_lockup = false; |
279 | rdev->gpu_lockup = false; |
255 | } |
280 | } |
256 | timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
281 | // timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
257 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
282 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
258 | rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
283 | // rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
259 | rdev->fence_drv.last_jiffies = jiffies; |
284 | // rdev->fence_drv.last_jiffies = jiffies; |
260 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
285 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
261 | goto retry; |
286 | goto retry; |
262 | } |
287 | } |
- | 288 | #endif |
|
263 | return 0; |
289 | return 0; |
264 | } |
290 | } |
Line -... | Line 291... | ||
- | 291 | ||
265 | 292 | #if 0 |
|
266 | int radeon_fence_wait_next(struct radeon_device *rdev) |
293 | int radeon_fence_wait_next(struct radeon_device *rdev) |
267 | { |
294 | { |
268 | unsigned long irq_flags; |
295 | unsigned long irq_flags; |
269 | struct radeon_fence *fence; |
296 | struct radeon_fence *fence; |
Line 313... | Line 340... | ||
313 | { |
340 | { |
314 | kref_get(&fence->kref); |
341 | kref_get(&fence->kref); |
315 | return fence; |
342 | return fence; |
316 | } |
343 | } |
Line -... | Line 344... | ||
- | 344 | ||
- | 345 | #endif |
|
317 | 346 | ||
318 | void radeon_fence_unref(struct radeon_fence **fence) |
347 | void radeon_fence_unref(struct radeon_fence **fence) |
319 | { |
348 | { |
Line 320... | Line 349... | ||
320 | struct radeon_fence *tmp = *fence; |
349 | struct radeon_fence *tmp = *fence; |
321 | - | ||
322 | *fence = NULL; |
- | |
323 | if (tmp) { |
- | |
324 | kref_put(&tmp->kref, radeon_fence_destroy); |
350 | |
Line -... | Line 351... | ||
- | 351 | *fence = NULL; |
|
325 | } |
352 | } |
326 | } |
353 | |
327 | 354 | #if 0 |
|
328 | void radeon_fence_process(struct radeon_device *rdev) |
355 | void radeon_fence_process(struct radeon_device *rdev) |
Line 336... | Line 363... | ||
336 | if (wake) { |
363 | if (wake) { |
337 | wake_up_all(&rdev->fence_drv.queue); |
364 | wake_up_all(&rdev->fence_drv.queue); |
338 | } |
365 | } |
339 | } |
366 | } |
Line -... | Line 367... | ||
- | 367 | ||
- | 368 | #endif |
|
340 | 369 | ||
341 | int radeon_fence_driver_init(struct radeon_device *rdev) |
370 | int radeon_fence_driver_init(struct radeon_device *rdev) |
342 | { |
371 | { |
343 | unsigned long irq_flags; |
372 | unsigned long irq_flags; |
Line 348... | Line 377... | ||
348 | if (r) { |
377 | if (r) { |
349 | dev_err(rdev->dev, "fence failed to get scratch register\n"); |
378 | dev_err(rdev->dev, "fence failed to get scratch register\n"); |
350 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
379 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
351 | return r; |
380 | return r; |
352 | } |
381 | } |
353 | WREG32(rdev->fence_drv.scratch_reg, 0); |
382 | radeon_fence_write(rdev, 0); |
354 | atomic_set(&rdev->fence_drv.seq, 0); |
383 | atomic_set(&rdev->fence_drv.seq, 0); |
355 | INIT_LIST_HEAD(&rdev->fence_drv.created); |
384 | INIT_LIST_HEAD(&rdev->fence_drv.created); |
356 | INIT_LIST_HEAD(&rdev->fence_drv.emited); |
385 | INIT_LIST_HEAD(&rdev->fence_drv.emited); |
357 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); |
386 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); |
358 | init_waitqueue_head(&rdev->fence_drv.queue); |
387 | // init_waitqueue_head(&rdev->fence_drv.queue); |
359 | rdev->fence_drv.initialized = true; |
388 | rdev->fence_drv.initialized = true; |
360 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
389 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
361 | if (radeon_debugfs_fence_init(rdev)) { |
- | |
362 | dev_err(rdev->dev, "fence debugfs file creation failed\n"); |
- | |
363 | } |
- | |
364 | return 0; |
390 | return 0; |
365 | } |
391 | } |
Line 366... | Line -... | ||
366 | - | ||
367 | void radeon_fence_driver_fini(struct radeon_device *rdev) |
- | |
368 | { |
- | |
369 | unsigned long irq_flags; |
- | |
370 | - | ||
371 | if (!rdev->fence_drv.initialized) |
- | |
372 | return; |
- | |
373 | wake_up_all(&rdev->fence_drv.queue); |
- | |
374 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
- | |
375 | radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); |
- | |
376 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
- | |
377 | rdev->fence_drv.initialized = false; |
- | |
378 | } |
- | |
Line 379... | Line 392... | ||
379 | 392 | ||
380 | 393 | ||
381 | /* |
394 | /* |
382 | * Fence debugfs |
395 | * Fence debugfs |
Line 388... | Line 401... | ||
388 | struct drm_device *dev = node->minor->dev; |
401 | struct drm_device *dev = node->minor->dev; |
389 | struct radeon_device *rdev = dev->dev_private; |
402 | struct radeon_device *rdev = dev->dev_private; |
390 | struct radeon_fence *fence; |
403 | struct radeon_fence *fence; |
Line 391... | Line 404... | ||
391 | 404 | ||
392 | seq_printf(m, "Last signaled fence 0x%08X\n", |
405 | seq_printf(m, "Last signaled fence 0x%08X\n", |
393 | RREG32(rdev->fence_drv.scratch_reg)); |
406 | radeon_fence_read(rdev)); |
394 | if (!list_empty(&rdev->fence_drv.emited)) { |
407 | if (!list_empty(&rdev->fence_drv.emited)) { |
395 | fence = list_entry(rdev->fence_drv.emited.prev, |
408 | fence = list_entry(rdev->fence_drv.emited.prev, |
396 | struct radeon_fence, list); |
409 | struct radeon_fence, list); |
397 | seq_printf(m, "Last emited fence %p with 0x%08X\n", |
410 | seq_printf(m, "Last emited fence %p with 0x%08X\n", |