radeon_fence.c revision 3b7a2b24ea2b703b3af595d0d4ee233ab0b36377
1771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
2771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2009 Jerome Glisse.
3771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * All Rights Reserved.
4771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
5771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a
6771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * copy of this software and associated documentation files (the
7771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * "Software"), to deal in the Software without restriction, including
8771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * without limitation the rights to use, copy, modify, merge, publish,
9771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * distribute, sub license, and/or sell copies of the Software, and to
10771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * permit persons to whom the Software is furnished to do so, subject to
11771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * the following conditions:
12771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
13771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE.
20771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
21771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * The above copyright notice and this permission notice (including the
22771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * next paragraph) shall be included in all copies or substantial portions
23771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * of the Software.
24771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
25771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
26771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
27771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Authors:
28771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *    Jerome Glisse <glisse@freedesktop.org>
29771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *    Dave Airlie
30771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
31771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/seq_file.h>
3260063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h>
33771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/wait.h>
34771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/list.h>
35771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/kref.h>
365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
37771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "drmP.h"
38771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "drm.h"
39771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon_reg.h"
40771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon.h"
4199ee7fac189893c90145a22b86bbcfdc98f69a9cDave Airlie#include "radeon_trace.h"
42771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
437465280c076d6440e5908c158c83b542dc063a30Alex Deucherstatic void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
44b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher{
45b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher	if (rdev->wb.enabled) {
4630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		*rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq);
4730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	} else {
487465280c076d6440e5908c158c83b542dc063a30Alex Deucher		WREG32(rdev->fence_drv[ring].scratch_reg, seq);
4930eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	}
50b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher}
51b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher
527465280c076d6440e5908c158c83b542dc063a30Alex Deucherstatic u32 radeon_fence_read(struct radeon_device *rdev, int ring)
53b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher{
547465280c076d6440e5908c158c83b542dc063a30Alex Deucher	u32 seq = 0;
55b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher
56b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher	if (rdev->wb.enabled) {
5730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr);
5830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	} else {
597465280c076d6440e5908c158c83b542dc063a30Alex Deucher		seq = RREG32(rdev->fence_drv[ring].scratch_reg);
6030eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	}
61b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher	return seq;
62b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher}
63b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher
64771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
65771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
663b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	/* we are protected by the ring emission mutex */
67bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	if (fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) {
68771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return 0;
69771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
70bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	fence->seq = ++rdev->fence_drv[fence->ring].seq;
7125a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König	radeon_fence_ring_emit(rdev, fence->ring, fence);
7299ee7fac189893c90145a22b86bbcfdc98f69a9cDave Airlie	trace_radeon_fence_emit(rdev->ddev, fence->seq);
73771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
74771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
75771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
763b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissevoid radeon_fence_process(struct radeon_device *rdev, int ring)
77771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
78bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	uint64_t seq, last_seq;
79bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	unsigned count_loop = 0;
80771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	bool wake = false;
81771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
82bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	/* Note there is a scenario here for an infinite loop but it's
83bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * very unlikely to happen. For it to happen, the current polling
84bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * process need to be interrupted by another process and another
85bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * process needs to update the last_seq btw the atomic read and
86bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * xchg of the current process.
87bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 *
88bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * More over for this to go in infinite loop there need to be
89bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * continuously new fence signaled ie radeon_fence_read needs
90bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * to return a different value each time for both the currently
91bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * polling process and the other process that xchg the last_seq
92bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * btw atomic read and xchg of the current process. And the
93bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * value the other process set as last seq must be higher than
94bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * the seq value we just read. Which means that current process
95bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * need to be interrupted after radeon_fence_read and before
96bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * atomic xchg.
97bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 *
98bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * To be even more safe we count the number of time we loop and
99bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * we bail after 10 loop just accepting the fact that we might
100bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * have temporarly set the last_seq not to the true real last
101bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 * seq but to an older one.
102bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	 */
103bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
104bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	do {
105bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		seq = radeon_fence_read(rdev, ring);
106bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		seq |= last_seq & 0xffffffff00000000LL;
107bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		if (seq < last_seq) {
108bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			seq += 0x100000000LL;
109bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		}
11036abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König
1113b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		if (seq == last_seq) {
1123b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			break;
113bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		}
114bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		/* If we loop over we don't want to return without
115bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		 * checking if a fence is signaled as it means that the
116bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		 * seq we just read is different from the previous on.
117bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		 */
118bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		wake = true;
1193b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		last_seq = seq;
120bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		if ((count_loop++) > 10) {
121bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			/* We looped over too many time leave with the
122bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			 * fact that we might have set an older fence
123bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			 * seq then the current real last seq as signaled
124bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			 * by the hw.
125bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			 */
126bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			break;
127bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		}
128bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	} while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq);
129bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse
1303b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (wake) {
1313b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		rdev->fence_drv[ring].last_activity = jiffies;
1323b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		wake_up_all(&rdev->fence_drv[ring].queue);
133771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
134771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
135771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
136771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic void radeon_fence_destroy(struct kref *kref)
137771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
1383b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	struct radeon_fence *fence;
139771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
140771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	fence = container_of(kref, struct radeon_fence, kref);
141bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	fence->seq = RADEON_FENCE_NOTEMITED_SEQ;
14293504fce28b1a387ec01f81b26637d237dca2b36Christian König	if (fence->semaphore)
14393504fce28b1a387ec01f81b26637d237dca2b36Christian König		radeon_semaphore_free(fence->rdev, fence->semaphore);
144771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	kfree(fence);
145771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
146771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
1477465280c076d6440e5908c158c83b542dc063a30Alex Deucherint radeon_fence_create(struct radeon_device *rdev,
1487465280c076d6440e5908c158c83b542dc063a30Alex Deucher			struct radeon_fence **fence,
1497465280c076d6440e5908c158c83b542dc063a30Alex Deucher			int ring)
150771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
151771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	*fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
152771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if ((*fence) == NULL) {
153771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return -ENOMEM;
154771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
155771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	kref_init(&((*fence)->kref));
156771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	(*fence)->rdev = rdev;
157bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	(*fence)->seq = RADEON_FENCE_NOTEMITED_SEQ;
1587465280c076d6440e5908c158c83b542dc063a30Alex Deucher	(*fence)->ring = ring;
15993504fce28b1a387ec01f81b26637d237dca2b36Christian König	(*fence)->semaphore = NULL;
160771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
161771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
162771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
1633b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissestatic bool radeon_fence_seq_signaled(struct radeon_device *rdev,
1643b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				      u64 seq, unsigned ring)
165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
1663b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
1673b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return true;
1683b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	}
1693b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	/* poll new last sequence at least once */
1703b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	radeon_fence_process(rdev, ring);
1713b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
172771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return true;
1733b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	}
1743b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	return false;
1753b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse}
1763655d54af8dd85788c3e5088387469703a0f8f12Darren Jenkins
1773b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissebool radeon_fence_signaled(struct radeon_fence *fence)
1783b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse{
1793b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (!fence) {
1803b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return true;
181771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
182bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	if (fence->seq == RADEON_FENCE_NOTEMITED_SEQ) {
183851a6bd99edda0094def3b0b81bb1c7c0e886e65Christian König		WARN(1, "Querying an unemitted fence : %p !\n", fence);
1843b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return true;
185771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
1863b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (fence->seq == RADEON_FENCE_SIGNALED_SEQ) {
1873b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return true;
188771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
1893b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) {
1903b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		fence->seq = RADEON_FENCE_SIGNALED_SEQ;
1913b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return true;
1923b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	}
1933b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	return false;
194771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
195771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
1963b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissestatic int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq,
1973b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				 unsigned ring, bool intr)
198771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
1993b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	unsigned long timeout, last_activity;
200bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	uint64_t seq;
2013b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	unsigned i;
20236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König	bool signaled;
2033b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	int r;
204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
2053b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	while (target_seq > atomic64_read(&rdev->fence_drv[ring].last_seq)) {
2063b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		if (!rdev->ring[ring].ready) {
2073b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			return -EBUSY;
2083b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		}
20936abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König
21036abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
2113b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		if (time_after(rdev->fence_drv[ring].last_activity, timeout)) {
21236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			/* the normal case, timeout is somewhere before last_activity */
2133b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			timeout = rdev->fence_drv[ring].last_activity - timeout;
21436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		} else {
21536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			/* either jiffies wrapped around, or no fence was signaled in the last 500ms
2163b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			 * anyway we will just wait for the minimum amount and then check for a lockup
2173b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			 */
21836abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			timeout = 1;
21936abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		}
2203b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
221bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		/* Save current last activity valuee, used to check for GPU lockups */
2223b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		last_activity = rdev->fence_drv[ring].last_activity;
22336abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König
22436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		trace_radeon_fence_wait_begin(rdev->ddev, seq);
2253b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		radeon_irq_kms_sw_irq_get(rdev, ring);
22636abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		if (intr) {
2273b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			r = wait_event_interruptible_timeout(rdev->fence_drv[ring].queue,
2283b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				(signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)),
2293b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				timeout);
2303b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse                } else {
2313b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			r = wait_event_timeout(rdev->fence_drv[ring].queue,
2323b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				(signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)),
2333b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				timeout);
23436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		}
2353b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		radeon_irq_kms_sw_irq_put(rdev, ring);
23690aca4d2740255bd130ea71a91530b9920c70abeJerome Glisse		if (unlikely(r < 0)) {
2375cc6fbab9da5680e7e5d2507d0f0c2c52ff18031Thomas Hellstrom			return r;
23890aca4d2740255bd130ea71a91530b9920c70abeJerome Glisse		}
23936abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		trace_radeon_fence_wait_end(rdev->ddev, seq);
24025a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König
24136abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König		if (unlikely(!signaled)) {
24236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			/* we were interrupted for some reason and fence
24336abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			 * isn't signaled yet, resume waiting */
24436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			if (r) {
24536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König				continue;
24636abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			}
24725a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König
2483b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			/* check if sequence value has changed since last_activity */
2493b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			if (seq != atomic64_read(&rdev->fence_drv[ring].last_seq)) {
2503b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				continue;
2513b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			}
252bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			/* test if somebody else has already decided that this is a lockup */
2533b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			if (last_activity != rdev->fence_drv[ring].last_activity) {
25436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König				continue;
25536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			}
25636abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König
2573b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
25836abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König				/* good news we believe it's a lockup */
259bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse				dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n",
2603b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse					 target_seq, seq);
2613b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse
2623b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				/* change last activity so nobody else think there is a lockup */
2633b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				for (i = 0; i < RADEON_NUM_RINGS; ++i) {
2643b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse					rdev->fence_drv[i].last_activity = jiffies;
2653b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				}
266bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse
267bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse				/* change last activity so nobody else think there is a lockup */
268bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse				for (i = 0; i < RADEON_NUM_RINGS; ++i) {
269bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse					rdev->fence_drv[i].last_activity = jiffies;
270bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse				}
27136abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König
27236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König				/* mark the ring as not ready any more */
2733b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse				rdev->ring[ring].ready = false;
2746c6f478370eccfbfafbdc6fc55c0def03e58f124Christian König				return -EDEADLK;
27536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König			}
276771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
277771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
278771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
279771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
280771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
2813b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseint radeon_fence_wait(struct radeon_fence *fence, bool intr)
282771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
283771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r;
284771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
2853b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (fence == NULL) {
2863b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		WARN(1, "Querying an invalid fence : %p !\n", fence);
2873b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return -EINVAL;
28825a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König	}
2893b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse
2903b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	r = radeon_fence_wait_seq(fence->rdev, fence->seq, fence->ring, intr);
2913b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (r) {
2923b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		return r;
293771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
2943b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	fence->seq = RADEON_FENCE_SIGNALED_SEQ;
2953b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	return 0;
296771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
297771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
2983b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseint radeon_fence_wait_next(struct radeon_device *rdev, int ring)
299771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
3003b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	uint64_t seq;
301771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
3023b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	/* We are not protected by ring lock when reading current seq but
3033b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 * it's ok as worst case is we return to early while we could have
3043b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 * wait.
3053b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 */
3063b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
3073b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (seq >= rdev->fence_drv[ring].seq) {
3083b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		/* nothing to wait for, last_seq is already the last emited fence */
309771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return 0;
310771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
3113b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	return radeon_fence_wait_seq(rdev, seq, ring, false);
3123b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse}
3133b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse
3143b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseint radeon_fence_wait_empty(struct radeon_device *rdev, int ring)
3153b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse{
3163b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	/* We are not protected by ring lock when reading current seq
3173b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 * but it's ok as wait empty is call from place where no more
3183b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 * activity can be scheduled so there won't be concurrent access
3193b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 * to seq value.
3203b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 */
3213b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].seq, ring, false);
322771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
323771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
324771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestruct radeon_fence *radeon_fence_ref(struct radeon_fence *fence)
325771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
326771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	kref_get(&fence->kref);
327771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return fence;
328771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
329771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
330771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_fence_unref(struct radeon_fence **fence)
331771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
332771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct radeon_fence *tmp = *fence;
333771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
334771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	*fence = NULL;
335771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (tmp) {
336cdb650a4b5eaf1c0aedbfd7dd6afd6d465c3b0a0Paul Bolle		kref_put(&tmp->kref, radeon_fence_destroy);
337771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
338771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
339771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
3403b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseunsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring)
341771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
3423b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	uint64_t emitted;
343771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
3443b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	radeon_fence_process(rdev, ring);
3453b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	/* We are not protected by ring lock when reading the last sequence
3463b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 * but it's ok to report slightly wrong fence count here.
3473b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	 */
3483b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	emitted = rdev->fence_drv[ring].seq - atomic64_read(&rdev->fence_drv[ring].last_seq);
3493b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	/* to avoid 32bits warp around */
3503b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	if (emitted > 0x10000000) {
3513b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		emitted = 0x10000000;
35247492a23a128e953bd5087b1cac909cd8124ca5eChristian König	}
3533b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	return (unsigned)emitted;
35447492a23a128e953bd5087b1cac909cd8124ca5eChristian König}
35547492a23a128e953bd5087b1cac909cd8124ca5eChristian König
35630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisseint radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
357771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
35830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	uint64_t index;
35930eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	int r;
360771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
36130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
36230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	if (rdev->wb.use_event) {
36330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		rdev->fence_drv[ring].scratch_reg = 0;
36430eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		index = R600_WB_EVENT_OFFSET + ring * 4;
36530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	} else {
3667465280c076d6440e5908c158c83b542dc063a30Alex Deucher		r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg);
3677465280c076d6440e5908c158c83b542dc063a30Alex Deucher		if (r) {
3687465280c076d6440e5908c158c83b542dc063a30Alex Deucher			dev_err(rdev->dev, "fence failed to get scratch register\n");
3697465280c076d6440e5908c158c83b542dc063a30Alex Deucher			return r;
3707465280c076d6440e5908c158c83b542dc063a30Alex Deucher		}
37130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		index = RADEON_WB_SCRATCH_OFFSET +
37230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse			rdev->fence_drv[ring].scratch_reg -
37330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse			rdev->scratch.reg_base;
3747465280c076d6440e5908c158c83b542dc063a30Alex Deucher	}
37530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
37630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
377bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	radeon_fence_write(rdev, rdev->fence_drv[ring].seq, ring);
37830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].initialized = true;
3793b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n",
38030eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		 ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr);
38130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	return 0;
38230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse}
38330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse
38430eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glissestatic void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
38530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse{
38630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].scratch_reg = -1;
38730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].cpu_addr = NULL;
38830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].gpu_addr = 0;
389bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	rdev->fence_drv[ring].seq = 0;
390bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse	atomic64_set(&rdev->fence_drv[ring].last_seq, 0);
3913b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse	rdev->fence_drv[ring].last_activity = jiffies;
39230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	init_waitqueue_head(&rdev->fence_drv[ring].queue);
39330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	rdev->fence_drv[ring].initialized = false;
39430eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse}
39530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse
39630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisseint radeon_fence_driver_init(struct radeon_device *rdev)
39730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse{
39830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	int ring;
39930eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse
40030eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse	for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
40130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse		radeon_fence_driver_init_ring(rdev, ring);
402771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
403771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (radeon_debugfs_fence_init(rdev)) {
4040a0c7596c643239e8d4c3eaaba43b74a96f2411eJerome Glisse		dev_err(rdev->dev, "fence debugfs file creation failed\n");
405771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
406771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
407771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
408771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
409771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_fence_driver_fini(struct radeon_device *rdev)
410771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
4117465280c076d6440e5908c158c83b542dc063a30Alex Deucher	int ring;
4127465280c076d6440e5908c158c83b542dc063a30Alex Deucher
4137465280c076d6440e5908c158c83b542dc063a30Alex Deucher	for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
4147465280c076d6440e5908c158c83b542dc063a30Alex Deucher		if (!rdev->fence_drv[ring].initialized)
4157465280c076d6440e5908c158c83b542dc063a30Alex Deucher			continue;
416adea5c27694d2f6a783abb250b8e6def250928baChristian König		radeon_fence_wait_empty(rdev, ring);
4177465280c076d6440e5908c158c83b542dc063a30Alex Deucher		wake_up_all(&rdev->fence_drv[ring].queue);
4187465280c076d6440e5908c158c83b542dc063a30Alex Deucher		radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
4197465280c076d6440e5908c158c83b542dc063a30Alex Deucher		rdev->fence_drv[ring].initialized = false;
4207465280c076d6440e5908c158c83b542dc063a30Alex Deucher	}
421771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
422771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
423771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
424771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
425771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Fence debugfs
426771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
427771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS)
428771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_fence_info(struct seq_file *m, void *data)
429771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
430771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct drm_info_node *node = (struct drm_info_node *)m->private;
431771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct drm_device *dev = node->minor->dev;
432771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct radeon_device *rdev = dev->dev_private;
4337465280c076d6440e5908c158c83b542dc063a30Alex Deucher	int i;
4347465280c076d6440e5908c158c83b542dc063a30Alex Deucher
4357465280c076d6440e5908c158c83b542dc063a30Alex Deucher	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
4367465280c076d6440e5908c158c83b542dc063a30Alex Deucher		if (!rdev->fence_drv[i].initialized)
4377465280c076d6440e5908c158c83b542dc063a30Alex Deucher			continue;
4387465280c076d6440e5908c158c83b542dc063a30Alex Deucher
4397465280c076d6440e5908c158c83b542dc063a30Alex Deucher		seq_printf(m, "--- ring %d ---\n", i);
440bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse		seq_printf(m, "Last signaled fence 0x%016lx\n",
441bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse			   atomic64_read(&rdev->fence_drv[i].last_seq));
4423b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse		seq_printf(m, "Last emitted  0x%016llx\n",
4433b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse			   rdev->fence_drv[i].seq);
444771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
445771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
446771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
447771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
448771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_fence_list[] = {
449771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	{"radeon_fence_info", &radeon_debugfs_fence_info, 0, NULL},
450771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse};
451771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif
452771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
453771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_fence_init(struct radeon_device *rdev)
454771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
455771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS)
456771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return radeon_debugfs_add_files(rdev, radeon_debugfs_fence_list, 1);
457771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else
458771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
459771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif
460771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
461