Subversion Repositories Kolibri OS

Rev

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",