Subversion Repositories Kolibri OS

Rev

Rev 1404 | Rev 1986 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1404 Rev 1963
Line 55... Line 55...
55
		WREG32(rdev->fence_drv.scratch_reg, fence->seq);
55
		WREG32(rdev->fence_drv.scratch_reg, fence->seq);
56
	} else
56
	} else
57
		radeon_fence_ring_emit(rdev, fence);
57
		radeon_fence_ring_emit(rdev, fence);
Line 58... Line 58...
58
 
58
 
59
	fence->emited = true;
-
 
60
	fence->timeout = jiffies + ((2000 * HZ) / 1000);
59
	fence->emited = true;
61
	list_del(&fence->list);
60
	list_del(&fence->list);
62
	list_add_tail(&fence->list, &rdev->fence_drv.emited);
61
	list_add_tail(&fence->list, &rdev->fence_drv.emited);
63
	write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
62
	write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
64
	return 0;
63
	return 0;
Line 68... Line 67...
68
{
67
{
69
	struct radeon_fence *fence;
68
	struct radeon_fence *fence;
70
	struct list_head *i, *n;
69
	struct list_head *i, *n;
71
	uint32_t seq;
70
	uint32_t seq;
72
	bool wake = false;
71
	bool wake = false;
-
 
72
	unsigned long cjiffies;
Line 73... Line 73...
73
 
73
 
74
	if (rdev == NULL) {
74
	if (rdev->wb.enabled) {
75
		return true;
-
 
76
	}
75
		u32 scratch_index;
-
 
76
		if (rdev->wb.use_event)
77
	if (rdev->shutdown) {
77
			scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
-
 
78
		else
-
 
79
			scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
78
		return true;
80
		seq = rdev->wb.wb[scratch_index/4];
79
	}
81
	} else
-
 
82
	seq = RREG32(rdev->fence_drv.scratch_reg);
80
	seq = RREG32(rdev->fence_drv.scratch_reg);
83
	if (seq != rdev->fence_drv.last_seq) {
-
 
84
		rdev->fence_drv.last_seq = seq;
-
 
85
		rdev->fence_drv.last_jiffies = jiffies;
-
 
86
		rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
-
 
87
	} else {
-
 
88
		cjiffies = jiffies;
-
 
89
		if (time_after(cjiffies, rdev->fence_drv.last_jiffies)) {
-
 
90
			cjiffies -= rdev->fence_drv.last_jiffies;
-
 
91
			if (time_after(rdev->fence_drv.last_timeout, cjiffies)) {
-
 
92
				/* update the timeout */
-
 
93
				rdev->fence_drv.last_timeout -= cjiffies;
-
 
94
			} else {
-
 
95
				/* the 500ms timeout is elapsed we should test
-
 
96
				 * for GPU lockup
-
 
97
				 */
-
 
98
				rdev->fence_drv.last_timeout = 1;
-
 
99
			}
-
 
100
		} else {
-
 
101
			/* wrap around update last jiffies, we will just wait
-
 
102
			 * a little longer
-
 
103
			 */
-
 
104
			rdev->fence_drv.last_jiffies = cjiffies;
-
 
105
	}
-
 
106
		return false;
81
	rdev->fence_drv.last_seq = seq;
107
	}
82
	n = NULL;
108
	n = NULL;
83
	list_for_each(i, &rdev->fence_drv.emited) {
109
	list_for_each(i, &rdev->fence_drv.emited) {
84
		fence = list_entry(i, struct radeon_fence, list);
110
		fence = list_entry(i, struct radeon_fence, list);
85
		if (fence->seq == seq) {
111
		if (fence->seq == seq) {
Line 168... Line 194...
168
}
194
}
Line 169... Line 195...
169
 
195
 
170
int radeon_fence_wait(struct radeon_fence *fence, bool intr)
196
int radeon_fence_wait(struct radeon_fence *fence, bool intr)
171
{
197
{
172
	struct radeon_device *rdev;
-
 
173
	unsigned long cur_jiffies;
198
	struct radeon_device *rdev;
174
	unsigned long timeout;
199
	unsigned long irq_flags, timeout;
175
	bool expired = false;
200
	u32 seq;
Line 176... Line 201...
176
	int r;
201
	int r;
177
 
202
 
178
	if (fence == NULL) {
203
	if (fence == NULL) {
179
		WARN(1, "Querying an invalid fence : %p !\n", fence);
204
		WARN(1, "Querying an invalid fence : %p !\n", fence);
180
		return 0;
205
		return 0;
181
	}
206
	}
182
	rdev = fence->rdev;
207
	rdev = fence->rdev;
183
	if (radeon_fence_signaled(fence)) {
208
	if (radeon_fence_signaled(fence)) {
184
		return 0;
-
 
-
 
209
		return 0;
185
	}
210
	}
186
 
-
 
187
retry:
-
 
188
	cur_jiffies = jiffies;
211
	timeout = rdev->fence_drv.last_timeout;
189
	timeout = HZ / 100;
212
retry:
190
	if (time_after(fence->timeout, cur_jiffies)) {
-
 
191
		timeout = fence->timeout - cur_jiffies;
-
 
192
	}
213
	/* save current sequence used to check for GPU lockup */
193
 
214
	seq = rdev->fence_drv.last_seq;
194
	if (intr) {
215
	if (intr) {
195
		radeon_irq_kms_sw_irq_get(rdev);
216
		radeon_irq_kms_sw_irq_get(rdev);
196
		r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
217
		r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
197
				radeon_fence_signaled(fence), timeout);
218
				radeon_fence_signaled(fence), timeout);
198
		radeon_irq_kms_sw_irq_put(rdev);
219
		radeon_irq_kms_sw_irq_put(rdev);
-
 
220
		if (unlikely(r < 0)) {
199
		if (unlikely(r < 0))
221
			return r;
200
			return r;
222
		}
201
	} else {
223
	} else {
202
		radeon_irq_kms_sw_irq_get(rdev);
224
		radeon_irq_kms_sw_irq_get(rdev);
203
		r = wait_event_timeout(rdev->fence_drv.queue,
225
		r = wait_event_timeout(rdev->fence_drv.queue,
204
			 radeon_fence_signaled(fence), timeout);
226
			 radeon_fence_signaled(fence), timeout);
205
		radeon_irq_kms_sw_irq_put(rdev);
227
		radeon_irq_kms_sw_irq_put(rdev);
-
 
228
	}
-
 
229
	if (unlikely(!radeon_fence_signaled(fence))) {
-
 
230
		/* we were interrupted for some reason and fence isn't
206
	}
231
		 * isn't signaled yet, resume wait
207
	if (unlikely(!radeon_fence_signaled(fence))) {
232
		 */
-
 
233
		if (r) {
208
		if (unlikely(r == 0)) {
234
			timeout = r;
209
			expired = true;
-
 
210
		}
-
 
211
		if (unlikely(expired)) {
235
			goto retry;
212
			timeout = 1;
236
		}
213
			if (time_after(cur_jiffies, fence->timeout)) {
237
		/* don't protect read access to rdev->fence_drv.last_seq
-
 
238
		 * if we experiencing a lockup the value doesn't change
214
				timeout = cur_jiffies - fence->timeout;
239
		 */
-
 
240
		if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) {
215
			}
241
			/* good news we believe it's a lockup */
216
			timeout = jiffies_to_msecs(timeout);
242
			WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n",
217
			if (timeout > 500) {
243
			     fence->seq, seq);
-
 
244
			/* FIXME: what should we do ? marking everyone
218
				DRM_ERROR("fence(%p:0x%08X) %lums timeout "
245
			 * as signaled for now
219
					  "going to reset GPU\n",
246
			 */
-
 
247
			rdev->gpu_lockup = true;
-
 
248
			r = radeon_gpu_reset(rdev);
220
					  fence, fence->seq, timeout);
249
			if (r)
-
 
250
				return r;
221
				radeon_gpu_reset(rdev);
251
				WREG32(rdev->fence_drv.scratch_reg, fence->seq);
222
				WREG32(rdev->fence_drv.scratch_reg, fence->seq);
-
 
-
 
252
			rdev->gpu_lockup = false;
-
 
253
			}
-
 
254
		timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
-
 
255
		write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
-
 
256
		rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
223
			}
257
		rdev->fence_drv.last_jiffies = jiffies;
224
		}
258
		write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
225
		goto retry;
-
 
226
	}
-
 
227
	if (unlikely(expired)) {
-
 
228
		rdev->fence_drv.count_timeout++;
-
 
229
		cur_jiffies = jiffies;
-
 
230
		timeout = 1;
-
 
231
		if (time_after(cur_jiffies, fence->timeout)) {
-
 
232
			timeout = cur_jiffies - fence->timeout;
-
 
233
		}
-
 
234
		timeout = jiffies_to_msecs(timeout);
-
 
235
		DRM_ERROR("fence(%p:0x%08X) %lums timeout\n",
-
 
236
			  fence, fence->seq, timeout);
-
 
237
		DRM_ERROR("last signaled fence(0x%08X)\n",
-
 
238
			  rdev->fence_drv.last_seq);
259
		goto retry;
239
	}
260
	}
Line 240... Line 261...
240
	return 0;
261
	return 0;
241
}
262
}
Line 330... Line 351...
330
	WREG32(rdev->fence_drv.scratch_reg, 0);
351
	WREG32(rdev->fence_drv.scratch_reg, 0);
331
	atomic_set(&rdev->fence_drv.seq, 0);
352
	atomic_set(&rdev->fence_drv.seq, 0);
332
	INIT_LIST_HEAD(&rdev->fence_drv.created);
353
	INIT_LIST_HEAD(&rdev->fence_drv.created);
333
	INIT_LIST_HEAD(&rdev->fence_drv.emited);
354
	INIT_LIST_HEAD(&rdev->fence_drv.emited);
334
	INIT_LIST_HEAD(&rdev->fence_drv.signaled);
355
	INIT_LIST_HEAD(&rdev->fence_drv.signaled);
335
	rdev->fence_drv.count_timeout = 0;
-
 
336
	init_waitqueue_head(&rdev->fence_drv.queue);
356
	init_waitqueue_head(&rdev->fence_drv.queue);
337
	rdev->fence_drv.initialized = true;
357
	rdev->fence_drv.initialized = true;
338
	write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
358
	write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
339
	if (radeon_debugfs_fence_init(rdev)) {
359
	if (radeon_debugfs_fence_init(rdev)) {
340
		dev_err(rdev->dev, "fence debugfs file creation failed\n");
360
		dev_err(rdev->dev, "fence debugfs file creation failed\n");