xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/radeon/radeon_fence.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2009 Jerome Glisse.
3*4882a593Smuzhiyun  * All Rights Reserved.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
6*4882a593Smuzhiyun  * copy of this software and associated documentation files (the
7*4882a593Smuzhiyun  * "Software"), to deal in the Software without restriction, including
8*4882a593Smuzhiyun  * without limitation the rights to use, copy, modify, merge, publish,
9*4882a593Smuzhiyun  * distribute, sub license, and/or sell copies of the Software, and to
10*4882a593Smuzhiyun  * permit persons to whom the Software is furnished to do so, subject to
11*4882a593Smuzhiyun  * the following conditions:
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16*4882a593Smuzhiyun  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17*4882a593Smuzhiyun  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18*4882a593Smuzhiyun  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19*4882a593Smuzhiyun  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the
22*4882a593Smuzhiyun  * next paragraph) shall be included in all copies or substantial portions
23*4882a593Smuzhiyun  * of the Software.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  */
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun  * Authors:
28*4882a593Smuzhiyun  *    Jerome Glisse <glisse@freedesktop.org>
29*4882a593Smuzhiyun  *    Dave Airlie
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #include <linux/atomic.h>
33*4882a593Smuzhiyun #include <linux/firmware.h>
34*4882a593Smuzhiyun #include <linux/kref.h>
35*4882a593Smuzhiyun #include <linux/sched/signal.h>
36*4882a593Smuzhiyun #include <linux/seq_file.h>
37*4882a593Smuzhiyun #include <linux/slab.h>
38*4882a593Smuzhiyun #include <linux/wait.h>
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #include <drm/drm_debugfs.h>
41*4882a593Smuzhiyun #include <drm/drm_device.h>
42*4882a593Smuzhiyun #include <drm/drm_file.h>
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #include "radeon.h"
45*4882a593Smuzhiyun #include "radeon_reg.h"
46*4882a593Smuzhiyun #include "radeon_trace.h"
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun  * Fences
50*4882a593Smuzhiyun  * Fences mark an event in the GPUs pipeline and are used
51*4882a593Smuzhiyun  * for GPU/CPU synchronization.  When the fence is written,
52*4882a593Smuzhiyun  * it is expected that all buffers associated with that fence
53*4882a593Smuzhiyun  * are no longer in use by the associated ring on the GPU and
54*4882a593Smuzhiyun  * that the the relevant GPU caches have been flushed.  Whether
55*4882a593Smuzhiyun  * we use a scratch register or memory location depends on the asic
56*4882a593Smuzhiyun  * and whether writeback is enabled.
57*4882a593Smuzhiyun  */
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /**
60*4882a593Smuzhiyun  * radeon_fence_write - write a fence value
61*4882a593Smuzhiyun  *
62*4882a593Smuzhiyun  * @rdev: radeon_device pointer
63*4882a593Smuzhiyun  * @seq: sequence number to write
64*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
65*4882a593Smuzhiyun  *
66*4882a593Smuzhiyun  * Writes a fence value to memory or a scratch register (all asics).
67*4882a593Smuzhiyun  */
radeon_fence_write(struct radeon_device * rdev,u32 seq,int ring)68*4882a593Smuzhiyun static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
71*4882a593Smuzhiyun 	if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
72*4882a593Smuzhiyun 		if (drv->cpu_addr) {
73*4882a593Smuzhiyun 			*drv->cpu_addr = cpu_to_le32(seq);
74*4882a593Smuzhiyun 		}
75*4882a593Smuzhiyun 	} else {
76*4882a593Smuzhiyun 		WREG32(drv->scratch_reg, seq);
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /**
81*4882a593Smuzhiyun  * radeon_fence_read - read a fence value
82*4882a593Smuzhiyun  *
83*4882a593Smuzhiyun  * @rdev: radeon_device pointer
84*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  * Reads a fence value from memory or a scratch register (all asics).
87*4882a593Smuzhiyun  * Returns the value of the fence read from memory or register.
88*4882a593Smuzhiyun  */
radeon_fence_read(struct radeon_device * rdev,int ring)89*4882a593Smuzhiyun static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
92*4882a593Smuzhiyun 	u32 seq = 0;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
95*4882a593Smuzhiyun 		if (drv->cpu_addr) {
96*4882a593Smuzhiyun 			seq = le32_to_cpu(*drv->cpu_addr);
97*4882a593Smuzhiyun 		} else {
98*4882a593Smuzhiyun 			seq = lower_32_bits(atomic64_read(&drv->last_seq));
99*4882a593Smuzhiyun 		}
100*4882a593Smuzhiyun 	} else {
101*4882a593Smuzhiyun 		seq = RREG32(drv->scratch_reg);
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 	return seq;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun  * radeon_fence_schedule_check - schedule lockup check
108*4882a593Smuzhiyun  *
109*4882a593Smuzhiyun  * @rdev: radeon_device pointer
110*4882a593Smuzhiyun  * @ring: ring index we should work with
111*4882a593Smuzhiyun  *
112*4882a593Smuzhiyun  * Queues a delayed work item to check for lockups.
113*4882a593Smuzhiyun  */
radeon_fence_schedule_check(struct radeon_device * rdev,int ring)114*4882a593Smuzhiyun static void radeon_fence_schedule_check(struct radeon_device *rdev, int ring)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	/*
117*4882a593Smuzhiyun 	 * Do not reset the timer here with mod_delayed_work,
118*4882a593Smuzhiyun 	 * this can livelock in an interaction with TTM delayed destroy.
119*4882a593Smuzhiyun 	 */
120*4882a593Smuzhiyun 	queue_delayed_work(system_power_efficient_wq,
121*4882a593Smuzhiyun 			   &rdev->fence_drv[ring].lockup_work,
122*4882a593Smuzhiyun 			   RADEON_FENCE_JIFFIES_TIMEOUT);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun /**
126*4882a593Smuzhiyun  * radeon_fence_emit - emit a fence on the requested ring
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  * @rdev: radeon_device pointer
129*4882a593Smuzhiyun  * @fence: radeon fence object
130*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
131*4882a593Smuzhiyun  *
132*4882a593Smuzhiyun  * Emits a fence command on the requested ring (all asics).
133*4882a593Smuzhiyun  * Returns 0 on success, -ENOMEM on failure.
134*4882a593Smuzhiyun  */
radeon_fence_emit(struct radeon_device * rdev,struct radeon_fence ** fence,int ring)135*4882a593Smuzhiyun int radeon_fence_emit(struct radeon_device *rdev,
136*4882a593Smuzhiyun 		      struct radeon_fence **fence,
137*4882a593Smuzhiyun 		      int ring)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	u64 seq;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	/* we are protected by the ring emission mutex */
142*4882a593Smuzhiyun 	*fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
143*4882a593Smuzhiyun 	if ((*fence) == NULL) {
144*4882a593Smuzhiyun 		return -ENOMEM;
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun 	(*fence)->rdev = rdev;
147*4882a593Smuzhiyun 	(*fence)->seq = seq = ++rdev->fence_drv[ring].sync_seq[ring];
148*4882a593Smuzhiyun 	(*fence)->ring = ring;
149*4882a593Smuzhiyun 	(*fence)->is_vm_update = false;
150*4882a593Smuzhiyun 	dma_fence_init(&(*fence)->base, &radeon_fence_ops,
151*4882a593Smuzhiyun 		       &rdev->fence_queue.lock,
152*4882a593Smuzhiyun 		       rdev->fence_context + ring,
153*4882a593Smuzhiyun 		       seq);
154*4882a593Smuzhiyun 	radeon_fence_ring_emit(rdev, ring, *fence);
155*4882a593Smuzhiyun 	trace_radeon_fence_emit(rdev->ddev, ring, (*fence)->seq);
156*4882a593Smuzhiyun 	radeon_fence_schedule_check(rdev, ring);
157*4882a593Smuzhiyun 	return 0;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /**
161*4882a593Smuzhiyun  * radeon_fence_check_signaled - callback from fence_queue
162*4882a593Smuzhiyun  *
163*4882a593Smuzhiyun  * this function is called with fence_queue lock held, which is also used
164*4882a593Smuzhiyun  * for the fence locking itself, so unlocked variants are used for
165*4882a593Smuzhiyun  * fence_signal, and remove_wait_queue.
166*4882a593Smuzhiyun  */
radeon_fence_check_signaled(wait_queue_entry_t * wait,unsigned mode,int flags,void * key)167*4882a593Smuzhiyun static int radeon_fence_check_signaled(wait_queue_entry_t *wait, unsigned mode, int flags, void *key)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	struct radeon_fence *fence;
170*4882a593Smuzhiyun 	u64 seq;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	fence = container_of(wait, struct radeon_fence, fence_wake);
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	/*
175*4882a593Smuzhiyun 	 * We cannot use radeon_fence_process here because we're already
176*4882a593Smuzhiyun 	 * in the waitqueue, in a call from wake_up_all.
177*4882a593Smuzhiyun 	 */
178*4882a593Smuzhiyun 	seq = atomic64_read(&fence->rdev->fence_drv[fence->ring].last_seq);
179*4882a593Smuzhiyun 	if (seq >= fence->seq) {
180*4882a593Smuzhiyun 		int ret = dma_fence_signal_locked(&fence->base);
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 		if (!ret)
183*4882a593Smuzhiyun 			DMA_FENCE_TRACE(&fence->base, "signaled from irq context\n");
184*4882a593Smuzhiyun 		else
185*4882a593Smuzhiyun 			DMA_FENCE_TRACE(&fence->base, "was already signaled\n");
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		radeon_irq_kms_sw_irq_put(fence->rdev, fence->ring);
188*4882a593Smuzhiyun 		__remove_wait_queue(&fence->rdev->fence_queue, &fence->fence_wake);
189*4882a593Smuzhiyun 		dma_fence_put(&fence->base);
190*4882a593Smuzhiyun 	} else
191*4882a593Smuzhiyun 		DMA_FENCE_TRACE(&fence->base, "pending\n");
192*4882a593Smuzhiyun 	return 0;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /**
196*4882a593Smuzhiyun  * radeon_fence_activity - check for fence activity
197*4882a593Smuzhiyun  *
198*4882a593Smuzhiyun  * @rdev: radeon_device pointer
199*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
200*4882a593Smuzhiyun  *
201*4882a593Smuzhiyun  * Checks the current fence value and calculates the last
202*4882a593Smuzhiyun  * signalled fence value. Returns true if activity occured
203*4882a593Smuzhiyun  * on the ring, and the fence_queue should be waken up.
204*4882a593Smuzhiyun  */
radeon_fence_activity(struct radeon_device * rdev,int ring)205*4882a593Smuzhiyun static bool radeon_fence_activity(struct radeon_device *rdev, int ring)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	uint64_t seq, last_seq, last_emitted;
208*4882a593Smuzhiyun 	unsigned count_loop = 0;
209*4882a593Smuzhiyun 	bool wake = false;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	/* Note there is a scenario here for an infinite loop but it's
212*4882a593Smuzhiyun 	 * very unlikely to happen. For it to happen, the current polling
213*4882a593Smuzhiyun 	 * process need to be interrupted by another process and another
214*4882a593Smuzhiyun 	 * process needs to update the last_seq btw the atomic read and
215*4882a593Smuzhiyun 	 * xchg of the current process.
216*4882a593Smuzhiyun 	 *
217*4882a593Smuzhiyun 	 * More over for this to go in infinite loop there need to be
218*4882a593Smuzhiyun 	 * continuously new fence signaled ie radeon_fence_read needs
219*4882a593Smuzhiyun 	 * to return a different value each time for both the currently
220*4882a593Smuzhiyun 	 * polling process and the other process that xchg the last_seq
221*4882a593Smuzhiyun 	 * btw atomic read and xchg of the current process. And the
222*4882a593Smuzhiyun 	 * value the other process set as last seq must be higher than
223*4882a593Smuzhiyun 	 * the seq value we just read. Which means that current process
224*4882a593Smuzhiyun 	 * need to be interrupted after radeon_fence_read and before
225*4882a593Smuzhiyun 	 * atomic xchg.
226*4882a593Smuzhiyun 	 *
227*4882a593Smuzhiyun 	 * To be even more safe we count the number of time we loop and
228*4882a593Smuzhiyun 	 * we bail after 10 loop just accepting the fact that we might
229*4882a593Smuzhiyun 	 * have temporarly set the last_seq not to the true real last
230*4882a593Smuzhiyun 	 * seq but to an older one.
231*4882a593Smuzhiyun 	 */
232*4882a593Smuzhiyun 	last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
233*4882a593Smuzhiyun 	do {
234*4882a593Smuzhiyun 		last_emitted = rdev->fence_drv[ring].sync_seq[ring];
235*4882a593Smuzhiyun 		seq = radeon_fence_read(rdev, ring);
236*4882a593Smuzhiyun 		seq |= last_seq & 0xffffffff00000000LL;
237*4882a593Smuzhiyun 		if (seq < last_seq) {
238*4882a593Smuzhiyun 			seq &= 0xffffffff;
239*4882a593Smuzhiyun 			seq |= last_emitted & 0xffffffff00000000LL;
240*4882a593Smuzhiyun 		}
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 		if (seq <= last_seq || seq > last_emitted) {
243*4882a593Smuzhiyun 			break;
244*4882a593Smuzhiyun 		}
245*4882a593Smuzhiyun 		/* If we loop over we don't want to return without
246*4882a593Smuzhiyun 		 * checking if a fence is signaled as it means that the
247*4882a593Smuzhiyun 		 * seq we just read is different from the previous on.
248*4882a593Smuzhiyun 		 */
249*4882a593Smuzhiyun 		wake = true;
250*4882a593Smuzhiyun 		last_seq = seq;
251*4882a593Smuzhiyun 		if ((count_loop++) > 10) {
252*4882a593Smuzhiyun 			/* We looped over too many time leave with the
253*4882a593Smuzhiyun 			 * fact that we might have set an older fence
254*4882a593Smuzhiyun 			 * seq then the current real last seq as signaled
255*4882a593Smuzhiyun 			 * by the hw.
256*4882a593Smuzhiyun 			 */
257*4882a593Smuzhiyun 			break;
258*4882a593Smuzhiyun 		}
259*4882a593Smuzhiyun 	} while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq);
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	if (seq < last_emitted)
262*4882a593Smuzhiyun 		radeon_fence_schedule_check(rdev, ring);
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	return wake;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /**
268*4882a593Smuzhiyun  * radeon_fence_check_lockup - check for hardware lockup
269*4882a593Smuzhiyun  *
270*4882a593Smuzhiyun  * @work: delayed work item
271*4882a593Smuzhiyun  *
272*4882a593Smuzhiyun  * Checks for fence activity and if there is none probe
273*4882a593Smuzhiyun  * the hardware if a lockup occured.
274*4882a593Smuzhiyun  */
radeon_fence_check_lockup(struct work_struct * work)275*4882a593Smuzhiyun static void radeon_fence_check_lockup(struct work_struct *work)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun 	struct radeon_fence_driver *fence_drv;
278*4882a593Smuzhiyun 	struct radeon_device *rdev;
279*4882a593Smuzhiyun 	int ring;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	fence_drv = container_of(work, struct radeon_fence_driver,
282*4882a593Smuzhiyun 				 lockup_work.work);
283*4882a593Smuzhiyun 	rdev = fence_drv->rdev;
284*4882a593Smuzhiyun 	ring = fence_drv - &rdev->fence_drv[0];
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	if (!down_read_trylock(&rdev->exclusive_lock)) {
287*4882a593Smuzhiyun 		/* just reschedule the check if a reset is going on */
288*4882a593Smuzhiyun 		radeon_fence_schedule_check(rdev, ring);
289*4882a593Smuzhiyun 		return;
290*4882a593Smuzhiyun 	}
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	if (fence_drv->delayed_irq && rdev->ddev->irq_enabled) {
293*4882a593Smuzhiyun 		unsigned long irqflags;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 		fence_drv->delayed_irq = false;
296*4882a593Smuzhiyun 		spin_lock_irqsave(&rdev->irq.lock, irqflags);
297*4882a593Smuzhiyun 		radeon_irq_set(rdev);
298*4882a593Smuzhiyun 		spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
299*4882a593Smuzhiyun 	}
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	if (radeon_fence_activity(rdev, ring))
302*4882a593Smuzhiyun 		wake_up_all(&rdev->fence_queue);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	else if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 		/* good news we believe it's a lockup */
307*4882a593Smuzhiyun 		dev_warn(rdev->dev, "GPU lockup (current fence id "
308*4882a593Smuzhiyun 			 "0x%016llx last fence id 0x%016llx on ring %d)\n",
309*4882a593Smuzhiyun 			 (uint64_t)atomic64_read(&fence_drv->last_seq),
310*4882a593Smuzhiyun 			 fence_drv->sync_seq[ring], ring);
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 		/* remember that we need an reset */
313*4882a593Smuzhiyun 		rdev->needs_reset = true;
314*4882a593Smuzhiyun 		wake_up_all(&rdev->fence_queue);
315*4882a593Smuzhiyun 	}
316*4882a593Smuzhiyun 	up_read(&rdev->exclusive_lock);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun /**
320*4882a593Smuzhiyun  * radeon_fence_process - process a fence
321*4882a593Smuzhiyun  *
322*4882a593Smuzhiyun  * @rdev: radeon_device pointer
323*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
324*4882a593Smuzhiyun  *
325*4882a593Smuzhiyun  * Checks the current fence value and wakes the fence queue
326*4882a593Smuzhiyun  * if the sequence number has increased (all asics).
327*4882a593Smuzhiyun  */
radeon_fence_process(struct radeon_device * rdev,int ring)328*4882a593Smuzhiyun void radeon_fence_process(struct radeon_device *rdev, int ring)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun 	if (radeon_fence_activity(rdev, ring))
331*4882a593Smuzhiyun 		wake_up_all(&rdev->fence_queue);
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun /**
335*4882a593Smuzhiyun  * radeon_fence_seq_signaled - check if a fence sequence number has signaled
336*4882a593Smuzhiyun  *
337*4882a593Smuzhiyun  * @rdev: radeon device pointer
338*4882a593Smuzhiyun  * @seq: sequence number
339*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
340*4882a593Smuzhiyun  *
341*4882a593Smuzhiyun  * Check if the last signaled fence sequnce number is >= the requested
342*4882a593Smuzhiyun  * sequence number (all asics).
343*4882a593Smuzhiyun  * Returns true if the fence has signaled (current fence value
344*4882a593Smuzhiyun  * is >= requested value) or false if it has not (current fence
345*4882a593Smuzhiyun  * value is < the requested value.  Helper function for
346*4882a593Smuzhiyun  * radeon_fence_signaled().
347*4882a593Smuzhiyun  */
radeon_fence_seq_signaled(struct radeon_device * rdev,u64 seq,unsigned ring)348*4882a593Smuzhiyun static bool radeon_fence_seq_signaled(struct radeon_device *rdev,
349*4882a593Smuzhiyun 				      u64 seq, unsigned ring)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
352*4882a593Smuzhiyun 		return true;
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun 	/* poll new last sequence at least once */
355*4882a593Smuzhiyun 	radeon_fence_process(rdev, ring);
356*4882a593Smuzhiyun 	if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
357*4882a593Smuzhiyun 		return true;
358*4882a593Smuzhiyun 	}
359*4882a593Smuzhiyun 	return false;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
radeon_fence_is_signaled(struct dma_fence * f)362*4882a593Smuzhiyun static bool radeon_fence_is_signaled(struct dma_fence *f)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun 	struct radeon_fence *fence = to_radeon_fence(f);
365*4882a593Smuzhiyun 	struct radeon_device *rdev = fence->rdev;
366*4882a593Smuzhiyun 	unsigned ring = fence->ring;
367*4882a593Smuzhiyun 	u64 seq = fence->seq;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
370*4882a593Smuzhiyun 		return true;
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	if (down_read_trylock(&rdev->exclusive_lock)) {
374*4882a593Smuzhiyun 		radeon_fence_process(rdev, ring);
375*4882a593Smuzhiyun 		up_read(&rdev->exclusive_lock);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 		if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
378*4882a593Smuzhiyun 			return true;
379*4882a593Smuzhiyun 		}
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 	return false;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun /**
385*4882a593Smuzhiyun  * radeon_fence_enable_signaling - enable signalling on fence
386*4882a593Smuzhiyun  * @fence: fence
387*4882a593Smuzhiyun  *
388*4882a593Smuzhiyun  * This function is called with fence_queue lock held, and adds a callback
389*4882a593Smuzhiyun  * to fence_queue that checks if this fence is signaled, and if so it
390*4882a593Smuzhiyun  * signals the fence and removes itself.
391*4882a593Smuzhiyun  */
radeon_fence_enable_signaling(struct dma_fence * f)392*4882a593Smuzhiyun static bool radeon_fence_enable_signaling(struct dma_fence *f)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun 	struct radeon_fence *fence = to_radeon_fence(f);
395*4882a593Smuzhiyun 	struct radeon_device *rdev = fence->rdev;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	if (atomic64_read(&rdev->fence_drv[fence->ring].last_seq) >= fence->seq)
398*4882a593Smuzhiyun 		return false;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	if (down_read_trylock(&rdev->exclusive_lock)) {
401*4882a593Smuzhiyun 		radeon_irq_kms_sw_irq_get(rdev, fence->ring);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 		if (radeon_fence_activity(rdev, fence->ring))
404*4882a593Smuzhiyun 			wake_up_all_locked(&rdev->fence_queue);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 		/* did fence get signaled after we enabled the sw irq? */
407*4882a593Smuzhiyun 		if (atomic64_read(&rdev->fence_drv[fence->ring].last_seq) >= fence->seq) {
408*4882a593Smuzhiyun 			radeon_irq_kms_sw_irq_put(rdev, fence->ring);
409*4882a593Smuzhiyun 			up_read(&rdev->exclusive_lock);
410*4882a593Smuzhiyun 			return false;
411*4882a593Smuzhiyun 		}
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 		up_read(&rdev->exclusive_lock);
414*4882a593Smuzhiyun 	} else {
415*4882a593Smuzhiyun 		/* we're probably in a lockup, lets not fiddle too much */
416*4882a593Smuzhiyun 		if (radeon_irq_kms_sw_irq_get_delayed(rdev, fence->ring))
417*4882a593Smuzhiyun 			rdev->fence_drv[fence->ring].delayed_irq = true;
418*4882a593Smuzhiyun 		radeon_fence_schedule_check(rdev, fence->ring);
419*4882a593Smuzhiyun 	}
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	fence->fence_wake.flags = 0;
422*4882a593Smuzhiyun 	fence->fence_wake.private = NULL;
423*4882a593Smuzhiyun 	fence->fence_wake.func = radeon_fence_check_signaled;
424*4882a593Smuzhiyun 	__add_wait_queue(&rdev->fence_queue, &fence->fence_wake);
425*4882a593Smuzhiyun 	dma_fence_get(f);
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", fence->ring);
428*4882a593Smuzhiyun 	return true;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun /**
432*4882a593Smuzhiyun  * radeon_fence_signaled - check if a fence has signaled
433*4882a593Smuzhiyun  *
434*4882a593Smuzhiyun  * @fence: radeon fence object
435*4882a593Smuzhiyun  *
436*4882a593Smuzhiyun  * Check if the requested fence has signaled (all asics).
437*4882a593Smuzhiyun  * Returns true if the fence has signaled or false if it has not.
438*4882a593Smuzhiyun  */
radeon_fence_signaled(struct radeon_fence * fence)439*4882a593Smuzhiyun bool radeon_fence_signaled(struct radeon_fence *fence)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun 	if (!fence)
442*4882a593Smuzhiyun 		return true;
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 	if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) {
445*4882a593Smuzhiyun 		int ret;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 		ret = dma_fence_signal(&fence->base);
448*4882a593Smuzhiyun 		if (!ret)
449*4882a593Smuzhiyun 			DMA_FENCE_TRACE(&fence->base, "signaled from radeon_fence_signaled\n");
450*4882a593Smuzhiyun 		return true;
451*4882a593Smuzhiyun 	}
452*4882a593Smuzhiyun 	return false;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun /**
456*4882a593Smuzhiyun  * radeon_fence_any_seq_signaled - check if any sequence number is signaled
457*4882a593Smuzhiyun  *
458*4882a593Smuzhiyun  * @rdev: radeon device pointer
459*4882a593Smuzhiyun  * @seq: sequence numbers
460*4882a593Smuzhiyun  *
461*4882a593Smuzhiyun  * Check if the last signaled fence sequnce number is >= the requested
462*4882a593Smuzhiyun  * sequence number (all asics).
463*4882a593Smuzhiyun  * Returns true if any has signaled (current value is >= requested value)
464*4882a593Smuzhiyun  * or false if it has not. Helper function for radeon_fence_wait_seq.
465*4882a593Smuzhiyun  */
radeon_fence_any_seq_signaled(struct radeon_device * rdev,u64 * seq)466*4882a593Smuzhiyun static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun 	unsigned i;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
471*4882a593Smuzhiyun 		if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i))
472*4882a593Smuzhiyun 			return true;
473*4882a593Smuzhiyun 	}
474*4882a593Smuzhiyun 	return false;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun /**
478*4882a593Smuzhiyun  * radeon_fence_wait_seq_timeout - wait for a specific sequence numbers
479*4882a593Smuzhiyun  *
480*4882a593Smuzhiyun  * @rdev: radeon device pointer
481*4882a593Smuzhiyun  * @target_seq: sequence number(s) we want to wait for
482*4882a593Smuzhiyun  * @intr: use interruptable sleep
483*4882a593Smuzhiyun  * @timeout: maximum time to wait, or MAX_SCHEDULE_TIMEOUT for infinite wait
484*4882a593Smuzhiyun  *
485*4882a593Smuzhiyun  * Wait for the requested sequence number(s) to be written by any ring
486*4882a593Smuzhiyun  * (all asics).  Sequnce number array is indexed by ring id.
487*4882a593Smuzhiyun  * @intr selects whether to use interruptable (true) or non-interruptable
488*4882a593Smuzhiyun  * (false) sleep when waiting for the sequence number.  Helper function
489*4882a593Smuzhiyun  * for radeon_fence_wait_*().
490*4882a593Smuzhiyun  * Returns remaining time if the sequence number has passed, 0 when
491*4882a593Smuzhiyun  * the wait timeout, or an error for all other cases.
492*4882a593Smuzhiyun  * -EDEADLK is returned when a GPU lockup has been detected.
493*4882a593Smuzhiyun  */
radeon_fence_wait_seq_timeout(struct radeon_device * rdev,u64 * target_seq,bool intr,long timeout)494*4882a593Smuzhiyun static long radeon_fence_wait_seq_timeout(struct radeon_device *rdev,
495*4882a593Smuzhiyun 					  u64 *target_seq, bool intr,
496*4882a593Smuzhiyun 					  long timeout)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	long r;
499*4882a593Smuzhiyun 	int i;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	if (radeon_fence_any_seq_signaled(rdev, target_seq))
502*4882a593Smuzhiyun 		return timeout;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	/* enable IRQs and tracing */
505*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
506*4882a593Smuzhiyun 		if (!target_seq[i])
507*4882a593Smuzhiyun 			continue;
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 		trace_radeon_fence_wait_begin(rdev->ddev, i, target_seq[i]);
510*4882a593Smuzhiyun 		radeon_irq_kms_sw_irq_get(rdev, i);
511*4882a593Smuzhiyun 	}
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	if (intr) {
514*4882a593Smuzhiyun 		r = wait_event_interruptible_timeout(rdev->fence_queue, (
515*4882a593Smuzhiyun 			radeon_fence_any_seq_signaled(rdev, target_seq)
516*4882a593Smuzhiyun 			 || rdev->needs_reset), timeout);
517*4882a593Smuzhiyun 	} else {
518*4882a593Smuzhiyun 		r = wait_event_timeout(rdev->fence_queue, (
519*4882a593Smuzhiyun 			radeon_fence_any_seq_signaled(rdev, target_seq)
520*4882a593Smuzhiyun 			 || rdev->needs_reset), timeout);
521*4882a593Smuzhiyun 	}
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	if (rdev->needs_reset)
524*4882a593Smuzhiyun 		r = -EDEADLK;
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
527*4882a593Smuzhiyun 		if (!target_seq[i])
528*4882a593Smuzhiyun 			continue;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 		radeon_irq_kms_sw_irq_put(rdev, i);
531*4882a593Smuzhiyun 		trace_radeon_fence_wait_end(rdev->ddev, i, target_seq[i]);
532*4882a593Smuzhiyun 	}
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	return r;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun /**
538*4882a593Smuzhiyun  * radeon_fence_wait_timeout - wait for a fence to signal with timeout
539*4882a593Smuzhiyun  *
540*4882a593Smuzhiyun  * @fence: radeon fence object
541*4882a593Smuzhiyun  * @intr: use interruptible sleep
542*4882a593Smuzhiyun  *
543*4882a593Smuzhiyun  * Wait for the requested fence to signal (all asics).
544*4882a593Smuzhiyun  * @intr selects whether to use interruptable (true) or non-interruptable
545*4882a593Smuzhiyun  * (false) sleep when waiting for the fence.
546*4882a593Smuzhiyun  * @timeout: maximum time to wait, or MAX_SCHEDULE_TIMEOUT for infinite wait
547*4882a593Smuzhiyun  * Returns remaining time if the sequence number has passed, 0 when
548*4882a593Smuzhiyun  * the wait timeout, or an error for all other cases.
549*4882a593Smuzhiyun  */
radeon_fence_wait_timeout(struct radeon_fence * fence,bool intr,long timeout)550*4882a593Smuzhiyun long radeon_fence_wait_timeout(struct radeon_fence *fence, bool intr, long timeout)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	uint64_t seq[RADEON_NUM_RINGS] = {};
553*4882a593Smuzhiyun 	long r;
554*4882a593Smuzhiyun 	int r_sig;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	/*
557*4882a593Smuzhiyun 	 * This function should not be called on !radeon fences.
558*4882a593Smuzhiyun 	 * If this is the case, it would mean this function can
559*4882a593Smuzhiyun 	 * also be called on radeon fences belonging to another card.
560*4882a593Smuzhiyun 	 * exclusive_lock is not held in that case.
561*4882a593Smuzhiyun 	 */
562*4882a593Smuzhiyun 	if (WARN_ON_ONCE(!to_radeon_fence(&fence->base)))
563*4882a593Smuzhiyun 		return dma_fence_wait(&fence->base, intr);
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	seq[fence->ring] = fence->seq;
566*4882a593Smuzhiyun 	r = radeon_fence_wait_seq_timeout(fence->rdev, seq, intr, timeout);
567*4882a593Smuzhiyun 	if (r <= 0) {
568*4882a593Smuzhiyun 		return r;
569*4882a593Smuzhiyun 	}
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	r_sig = dma_fence_signal(&fence->base);
572*4882a593Smuzhiyun 	if (!r_sig)
573*4882a593Smuzhiyun 		DMA_FENCE_TRACE(&fence->base, "signaled from fence_wait\n");
574*4882a593Smuzhiyun 	return r;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun /**
578*4882a593Smuzhiyun  * radeon_fence_wait - wait for a fence to signal
579*4882a593Smuzhiyun  *
580*4882a593Smuzhiyun  * @fence: radeon fence object
581*4882a593Smuzhiyun  * @intr: use interruptible sleep
582*4882a593Smuzhiyun  *
583*4882a593Smuzhiyun  * Wait for the requested fence to signal (all asics).
584*4882a593Smuzhiyun  * @intr selects whether to use interruptable (true) or non-interruptable
585*4882a593Smuzhiyun  * (false) sleep when waiting for the fence.
586*4882a593Smuzhiyun  * Returns 0 if the fence has passed, error for all other cases.
587*4882a593Smuzhiyun  */
radeon_fence_wait(struct radeon_fence * fence,bool intr)588*4882a593Smuzhiyun int radeon_fence_wait(struct radeon_fence *fence, bool intr)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun 	long r = radeon_fence_wait_timeout(fence, intr, MAX_SCHEDULE_TIMEOUT);
591*4882a593Smuzhiyun 	if (r > 0) {
592*4882a593Smuzhiyun 		return 0;
593*4882a593Smuzhiyun 	} else {
594*4882a593Smuzhiyun 		return r;
595*4882a593Smuzhiyun 	}
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun /**
599*4882a593Smuzhiyun  * radeon_fence_wait_any - wait for a fence to signal on any ring
600*4882a593Smuzhiyun  *
601*4882a593Smuzhiyun  * @rdev: radeon device pointer
602*4882a593Smuzhiyun  * @fences: radeon fence object(s)
603*4882a593Smuzhiyun  * @intr: use interruptable sleep
604*4882a593Smuzhiyun  *
605*4882a593Smuzhiyun  * Wait for any requested fence to signal (all asics).  Fence
606*4882a593Smuzhiyun  * array is indexed by ring id.  @intr selects whether to use
607*4882a593Smuzhiyun  * interruptable (true) or non-interruptable (false) sleep when
608*4882a593Smuzhiyun  * waiting for the fences. Used by the suballocator.
609*4882a593Smuzhiyun  * Returns 0 if any fence has passed, error for all other cases.
610*4882a593Smuzhiyun  */
radeon_fence_wait_any(struct radeon_device * rdev,struct radeon_fence ** fences,bool intr)611*4882a593Smuzhiyun int radeon_fence_wait_any(struct radeon_device *rdev,
612*4882a593Smuzhiyun 			  struct radeon_fence **fences,
613*4882a593Smuzhiyun 			  bool intr)
614*4882a593Smuzhiyun {
615*4882a593Smuzhiyun 	uint64_t seq[RADEON_NUM_RINGS];
616*4882a593Smuzhiyun 	unsigned i, num_rings = 0;
617*4882a593Smuzhiyun 	long r;
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
620*4882a593Smuzhiyun 		seq[i] = 0;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 		if (!fences[i]) {
623*4882a593Smuzhiyun 			continue;
624*4882a593Smuzhiyun 		}
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 		seq[i] = fences[i]->seq;
627*4882a593Smuzhiyun 		++num_rings;
628*4882a593Smuzhiyun 	}
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	/* nothing to wait for ? */
631*4882a593Smuzhiyun 	if (num_rings == 0)
632*4882a593Smuzhiyun 		return -ENOENT;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	r = radeon_fence_wait_seq_timeout(rdev, seq, intr, MAX_SCHEDULE_TIMEOUT);
635*4882a593Smuzhiyun 	if (r < 0) {
636*4882a593Smuzhiyun 		return r;
637*4882a593Smuzhiyun 	}
638*4882a593Smuzhiyun 	return 0;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun /**
642*4882a593Smuzhiyun  * radeon_fence_wait_next - wait for the next fence to signal
643*4882a593Smuzhiyun  *
644*4882a593Smuzhiyun  * @rdev: radeon device pointer
645*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
646*4882a593Smuzhiyun  *
647*4882a593Smuzhiyun  * Wait for the next fence on the requested ring to signal (all asics).
648*4882a593Smuzhiyun  * Returns 0 if the next fence has passed, error for all other cases.
649*4882a593Smuzhiyun  * Caller must hold ring lock.
650*4882a593Smuzhiyun  */
radeon_fence_wait_next(struct radeon_device * rdev,int ring)651*4882a593Smuzhiyun int radeon_fence_wait_next(struct radeon_device *rdev, int ring)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun 	uint64_t seq[RADEON_NUM_RINGS] = {};
654*4882a593Smuzhiyun 	long r;
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 	seq[ring] = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
657*4882a593Smuzhiyun 	if (seq[ring] >= rdev->fence_drv[ring].sync_seq[ring]) {
658*4882a593Smuzhiyun 		/* nothing to wait for, last_seq is
659*4882a593Smuzhiyun 		   already the last emited fence */
660*4882a593Smuzhiyun 		return -ENOENT;
661*4882a593Smuzhiyun 	}
662*4882a593Smuzhiyun 	r = radeon_fence_wait_seq_timeout(rdev, seq, false, MAX_SCHEDULE_TIMEOUT);
663*4882a593Smuzhiyun 	if (r < 0)
664*4882a593Smuzhiyun 		return r;
665*4882a593Smuzhiyun 	return 0;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun /**
669*4882a593Smuzhiyun  * radeon_fence_wait_empty - wait for all fences to signal
670*4882a593Smuzhiyun  *
671*4882a593Smuzhiyun  * @rdev: radeon device pointer
672*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
673*4882a593Smuzhiyun  *
674*4882a593Smuzhiyun  * Wait for all fences on the requested ring to signal (all asics).
675*4882a593Smuzhiyun  * Returns 0 if the fences have passed, error for all other cases.
676*4882a593Smuzhiyun  * Caller must hold ring lock.
677*4882a593Smuzhiyun  */
radeon_fence_wait_empty(struct radeon_device * rdev,int ring)678*4882a593Smuzhiyun int radeon_fence_wait_empty(struct radeon_device *rdev, int ring)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	uint64_t seq[RADEON_NUM_RINGS] = {};
681*4882a593Smuzhiyun 	long r;
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	seq[ring] = rdev->fence_drv[ring].sync_seq[ring];
684*4882a593Smuzhiyun 	if (!seq[ring])
685*4882a593Smuzhiyun 		return 0;
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	r = radeon_fence_wait_seq_timeout(rdev, seq, false, MAX_SCHEDULE_TIMEOUT);
688*4882a593Smuzhiyun 	if (r < 0) {
689*4882a593Smuzhiyun 		if (r == -EDEADLK)
690*4882a593Smuzhiyun 			return -EDEADLK;
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 		dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%ld)\n",
693*4882a593Smuzhiyun 			ring, r);
694*4882a593Smuzhiyun 	}
695*4882a593Smuzhiyun 	return 0;
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun /**
699*4882a593Smuzhiyun  * radeon_fence_ref - take a ref on a fence
700*4882a593Smuzhiyun  *
701*4882a593Smuzhiyun  * @fence: radeon fence object
702*4882a593Smuzhiyun  *
703*4882a593Smuzhiyun  * Take a reference on a fence (all asics).
704*4882a593Smuzhiyun  * Returns the fence.
705*4882a593Smuzhiyun  */
radeon_fence_ref(struct radeon_fence * fence)706*4882a593Smuzhiyun struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence)
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun 	dma_fence_get(&fence->base);
709*4882a593Smuzhiyun 	return fence;
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun /**
713*4882a593Smuzhiyun  * radeon_fence_unref - remove a ref on a fence
714*4882a593Smuzhiyun  *
715*4882a593Smuzhiyun  * @fence: radeon fence object
716*4882a593Smuzhiyun  *
717*4882a593Smuzhiyun  * Remove a reference on a fence (all asics).
718*4882a593Smuzhiyun  */
radeon_fence_unref(struct radeon_fence ** fence)719*4882a593Smuzhiyun void radeon_fence_unref(struct radeon_fence **fence)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun 	struct radeon_fence *tmp = *fence;
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	*fence = NULL;
724*4882a593Smuzhiyun 	if (tmp) {
725*4882a593Smuzhiyun 		dma_fence_put(&tmp->base);
726*4882a593Smuzhiyun 	}
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun /**
730*4882a593Smuzhiyun  * radeon_fence_count_emitted - get the count of emitted fences
731*4882a593Smuzhiyun  *
732*4882a593Smuzhiyun  * @rdev: radeon device pointer
733*4882a593Smuzhiyun  * @ring: ring index the fence is associated with
734*4882a593Smuzhiyun  *
735*4882a593Smuzhiyun  * Get the number of fences emitted on the requested ring (all asics).
736*4882a593Smuzhiyun  * Returns the number of emitted fences on the ring.  Used by the
737*4882a593Smuzhiyun  * dynpm code to ring track activity.
738*4882a593Smuzhiyun  */
radeon_fence_count_emitted(struct radeon_device * rdev,int ring)739*4882a593Smuzhiyun unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun 	uint64_t emitted;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	/* We are not protected by ring lock when reading the last sequence
744*4882a593Smuzhiyun 	 * but it's ok to report slightly wrong fence count here.
745*4882a593Smuzhiyun 	 */
746*4882a593Smuzhiyun 	radeon_fence_process(rdev, ring);
747*4882a593Smuzhiyun 	emitted = rdev->fence_drv[ring].sync_seq[ring]
748*4882a593Smuzhiyun 		- atomic64_read(&rdev->fence_drv[ring].last_seq);
749*4882a593Smuzhiyun 	/* to avoid 32bits warp around */
750*4882a593Smuzhiyun 	if (emitted > 0x10000000) {
751*4882a593Smuzhiyun 		emitted = 0x10000000;
752*4882a593Smuzhiyun 	}
753*4882a593Smuzhiyun 	return (unsigned)emitted;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun /**
757*4882a593Smuzhiyun  * radeon_fence_need_sync - do we need a semaphore
758*4882a593Smuzhiyun  *
759*4882a593Smuzhiyun  * @fence: radeon fence object
760*4882a593Smuzhiyun  * @dst_ring: which ring to check against
761*4882a593Smuzhiyun  *
762*4882a593Smuzhiyun  * Check if the fence needs to be synced against another ring
763*4882a593Smuzhiyun  * (all asics).  If so, we need to emit a semaphore.
764*4882a593Smuzhiyun  * Returns true if we need to sync with another ring, false if
765*4882a593Smuzhiyun  * not.
766*4882a593Smuzhiyun  */
radeon_fence_need_sync(struct radeon_fence * fence,int dst_ring)767*4882a593Smuzhiyun bool radeon_fence_need_sync(struct radeon_fence *fence, int dst_ring)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun 	struct radeon_fence_driver *fdrv;
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 	if (!fence) {
772*4882a593Smuzhiyun 		return false;
773*4882a593Smuzhiyun 	}
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 	if (fence->ring == dst_ring) {
776*4882a593Smuzhiyun 		return false;
777*4882a593Smuzhiyun 	}
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	/* we are protected by the ring mutex */
780*4882a593Smuzhiyun 	fdrv = &fence->rdev->fence_drv[dst_ring];
781*4882a593Smuzhiyun 	if (fence->seq <= fdrv->sync_seq[fence->ring]) {
782*4882a593Smuzhiyun 		return false;
783*4882a593Smuzhiyun 	}
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	return true;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun /**
789*4882a593Smuzhiyun  * radeon_fence_note_sync - record the sync point
790*4882a593Smuzhiyun  *
791*4882a593Smuzhiyun  * @fence: radeon fence object
792*4882a593Smuzhiyun  * @dst_ring: which ring to check against
793*4882a593Smuzhiyun  *
794*4882a593Smuzhiyun  * Note the sequence number at which point the fence will
795*4882a593Smuzhiyun  * be synced with the requested ring (all asics).
796*4882a593Smuzhiyun  */
radeon_fence_note_sync(struct radeon_fence * fence,int dst_ring)797*4882a593Smuzhiyun void radeon_fence_note_sync(struct radeon_fence *fence, int dst_ring)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun 	struct radeon_fence_driver *dst, *src;
800*4882a593Smuzhiyun 	unsigned i;
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	if (!fence) {
803*4882a593Smuzhiyun 		return;
804*4882a593Smuzhiyun 	}
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	if (fence->ring == dst_ring) {
807*4882a593Smuzhiyun 		return;
808*4882a593Smuzhiyun 	}
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 	/* we are protected by the ring mutex */
811*4882a593Smuzhiyun 	src = &fence->rdev->fence_drv[fence->ring];
812*4882a593Smuzhiyun 	dst = &fence->rdev->fence_drv[dst_ring];
813*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
814*4882a593Smuzhiyun 		if (i == dst_ring) {
815*4882a593Smuzhiyun 			continue;
816*4882a593Smuzhiyun 		}
817*4882a593Smuzhiyun 		dst->sync_seq[i] = max(dst->sync_seq[i], src->sync_seq[i]);
818*4882a593Smuzhiyun 	}
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun /**
822*4882a593Smuzhiyun  * radeon_fence_driver_start_ring - make the fence driver
823*4882a593Smuzhiyun  * ready for use on the requested ring.
824*4882a593Smuzhiyun  *
825*4882a593Smuzhiyun  * @rdev: radeon device pointer
826*4882a593Smuzhiyun  * @ring: ring index to start the fence driver on
827*4882a593Smuzhiyun  *
828*4882a593Smuzhiyun  * Make the fence driver ready for processing (all asics).
829*4882a593Smuzhiyun  * Not all asics have all rings, so each asic will only
830*4882a593Smuzhiyun  * start the fence driver on the rings it has.
831*4882a593Smuzhiyun  * Returns 0 for success, errors for failure.
832*4882a593Smuzhiyun  */
radeon_fence_driver_start_ring(struct radeon_device * rdev,int ring)833*4882a593Smuzhiyun int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun 	uint64_t index;
836*4882a593Smuzhiyun 	int r;
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 	radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
839*4882a593Smuzhiyun 	if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) {
840*4882a593Smuzhiyun 		rdev->fence_drv[ring].scratch_reg = 0;
841*4882a593Smuzhiyun 		if (ring != R600_RING_TYPE_UVD_INDEX) {
842*4882a593Smuzhiyun 			index = R600_WB_EVENT_OFFSET + ring * 4;
843*4882a593Smuzhiyun 			rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
844*4882a593Smuzhiyun 			rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr +
845*4882a593Smuzhiyun 							 index;
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 		} else {
848*4882a593Smuzhiyun 			/* put fence directly behind firmware */
849*4882a593Smuzhiyun 			index = ALIGN(rdev->uvd_fw->size, 8);
850*4882a593Smuzhiyun 			rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
851*4882a593Smuzhiyun 			rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
852*4882a593Smuzhiyun 		}
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	} else {
855*4882a593Smuzhiyun 		r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg);
856*4882a593Smuzhiyun 		if (r) {
857*4882a593Smuzhiyun 			dev_err(rdev->dev, "fence failed to get scratch register\n");
858*4882a593Smuzhiyun 			return r;
859*4882a593Smuzhiyun 		}
860*4882a593Smuzhiyun 		index = RADEON_WB_SCRATCH_OFFSET +
861*4882a593Smuzhiyun 			rdev->fence_drv[ring].scratch_reg -
862*4882a593Smuzhiyun 			rdev->scratch.reg_base;
863*4882a593Smuzhiyun 		rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
864*4882a593Smuzhiyun 		rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
865*4882a593Smuzhiyun 	}
866*4882a593Smuzhiyun 	radeon_fence_write(rdev, atomic64_read(&rdev->fence_drv[ring].last_seq), ring);
867*4882a593Smuzhiyun 	rdev->fence_drv[ring].initialized = true;
868*4882a593Smuzhiyun 	dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx\n",
869*4882a593Smuzhiyun 		 ring, rdev->fence_drv[ring].gpu_addr);
870*4882a593Smuzhiyun 	return 0;
871*4882a593Smuzhiyun }
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun /**
874*4882a593Smuzhiyun  * radeon_fence_driver_init_ring - init the fence driver
875*4882a593Smuzhiyun  * for the requested ring.
876*4882a593Smuzhiyun  *
877*4882a593Smuzhiyun  * @rdev: radeon device pointer
878*4882a593Smuzhiyun  * @ring: ring index to start the fence driver on
879*4882a593Smuzhiyun  *
880*4882a593Smuzhiyun  * Init the fence driver for the requested ring (all asics).
881*4882a593Smuzhiyun  * Helper function for radeon_fence_driver_init().
882*4882a593Smuzhiyun  */
radeon_fence_driver_init_ring(struct radeon_device * rdev,int ring)883*4882a593Smuzhiyun static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
884*4882a593Smuzhiyun {
885*4882a593Smuzhiyun 	int i;
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun 	rdev->fence_drv[ring].scratch_reg = -1;
888*4882a593Smuzhiyun 	rdev->fence_drv[ring].cpu_addr = NULL;
889*4882a593Smuzhiyun 	rdev->fence_drv[ring].gpu_addr = 0;
890*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i)
891*4882a593Smuzhiyun 		rdev->fence_drv[ring].sync_seq[i] = 0;
892*4882a593Smuzhiyun 	atomic64_set(&rdev->fence_drv[ring].last_seq, 0);
893*4882a593Smuzhiyun 	rdev->fence_drv[ring].initialized = false;
894*4882a593Smuzhiyun 	INIT_DELAYED_WORK(&rdev->fence_drv[ring].lockup_work,
895*4882a593Smuzhiyun 			  radeon_fence_check_lockup);
896*4882a593Smuzhiyun 	rdev->fence_drv[ring].rdev = rdev;
897*4882a593Smuzhiyun }
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun /**
900*4882a593Smuzhiyun  * radeon_fence_driver_init - init the fence driver
901*4882a593Smuzhiyun  * for all possible rings.
902*4882a593Smuzhiyun  *
903*4882a593Smuzhiyun  * @rdev: radeon device pointer
904*4882a593Smuzhiyun  *
905*4882a593Smuzhiyun  * Init the fence driver for all possible rings (all asics).
906*4882a593Smuzhiyun  * Not all asics have all rings, so each asic will only
907*4882a593Smuzhiyun  * start the fence driver on the rings it has using
908*4882a593Smuzhiyun  * radeon_fence_driver_start_ring().
909*4882a593Smuzhiyun  * Returns 0 for success.
910*4882a593Smuzhiyun  */
radeon_fence_driver_init(struct radeon_device * rdev)911*4882a593Smuzhiyun int radeon_fence_driver_init(struct radeon_device *rdev)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun 	int ring;
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun 	init_waitqueue_head(&rdev->fence_queue);
916*4882a593Smuzhiyun 	for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
917*4882a593Smuzhiyun 		radeon_fence_driver_init_ring(rdev, ring);
918*4882a593Smuzhiyun 	}
919*4882a593Smuzhiyun 	if (radeon_debugfs_fence_init(rdev)) {
920*4882a593Smuzhiyun 		dev_err(rdev->dev, "fence debugfs file creation failed\n");
921*4882a593Smuzhiyun 	}
922*4882a593Smuzhiyun 	return 0;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun /**
926*4882a593Smuzhiyun  * radeon_fence_driver_fini - tear down the fence driver
927*4882a593Smuzhiyun  * for all possible rings.
928*4882a593Smuzhiyun  *
929*4882a593Smuzhiyun  * @rdev: radeon device pointer
930*4882a593Smuzhiyun  *
931*4882a593Smuzhiyun  * Tear down the fence driver for all possible rings (all asics).
932*4882a593Smuzhiyun  */
radeon_fence_driver_fini(struct radeon_device * rdev)933*4882a593Smuzhiyun void radeon_fence_driver_fini(struct radeon_device *rdev)
934*4882a593Smuzhiyun {
935*4882a593Smuzhiyun 	int ring, r;
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	mutex_lock(&rdev->ring_lock);
938*4882a593Smuzhiyun 	for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
939*4882a593Smuzhiyun 		if (!rdev->fence_drv[ring].initialized)
940*4882a593Smuzhiyun 			continue;
941*4882a593Smuzhiyun 		r = radeon_fence_wait_empty(rdev, ring);
942*4882a593Smuzhiyun 		if (r) {
943*4882a593Smuzhiyun 			/* no need to trigger GPU reset as we are unloading */
944*4882a593Smuzhiyun 			radeon_fence_driver_force_completion(rdev, ring);
945*4882a593Smuzhiyun 		}
946*4882a593Smuzhiyun 		cancel_delayed_work_sync(&rdev->fence_drv[ring].lockup_work);
947*4882a593Smuzhiyun 		wake_up_all(&rdev->fence_queue);
948*4882a593Smuzhiyun 		radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
949*4882a593Smuzhiyun 		rdev->fence_drv[ring].initialized = false;
950*4882a593Smuzhiyun 	}
951*4882a593Smuzhiyun 	mutex_unlock(&rdev->ring_lock);
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun /**
955*4882a593Smuzhiyun  * radeon_fence_driver_force_completion - force all fence waiter to complete
956*4882a593Smuzhiyun  *
957*4882a593Smuzhiyun  * @rdev: radeon device pointer
958*4882a593Smuzhiyun  * @ring: the ring to complete
959*4882a593Smuzhiyun  *
960*4882a593Smuzhiyun  * In case of GPU reset failure make sure no process keep waiting on fence
961*4882a593Smuzhiyun  * that will never complete.
962*4882a593Smuzhiyun  */
radeon_fence_driver_force_completion(struct radeon_device * rdev,int ring)963*4882a593Smuzhiyun void radeon_fence_driver_force_completion(struct radeon_device *rdev, int ring)
964*4882a593Smuzhiyun {
965*4882a593Smuzhiyun 	if (rdev->fence_drv[ring].initialized) {
966*4882a593Smuzhiyun 		radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
967*4882a593Smuzhiyun 		cancel_delayed_work_sync(&rdev->fence_drv[ring].lockup_work);
968*4882a593Smuzhiyun 	}
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 
972*4882a593Smuzhiyun /*
973*4882a593Smuzhiyun  * Fence debugfs
974*4882a593Smuzhiyun  */
975*4882a593Smuzhiyun #if defined(CONFIG_DEBUG_FS)
radeon_debugfs_fence_info(struct seq_file * m,void * data)976*4882a593Smuzhiyun static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun 	struct drm_info_node *node = (struct drm_info_node *)m->private;
979*4882a593Smuzhiyun 	struct drm_device *dev = node->minor->dev;
980*4882a593Smuzhiyun 	struct radeon_device *rdev = dev->dev_private;
981*4882a593Smuzhiyun 	int i, j;
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
984*4882a593Smuzhiyun 		if (!rdev->fence_drv[i].initialized)
985*4882a593Smuzhiyun 			continue;
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun 		radeon_fence_process(rdev, i);
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 		seq_printf(m, "--- ring %d ---\n", i);
990*4882a593Smuzhiyun 		seq_printf(m, "Last signaled fence 0x%016llx\n",
991*4882a593Smuzhiyun 			   (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq));
992*4882a593Smuzhiyun 		seq_printf(m, "Last emitted        0x%016llx\n",
993*4882a593Smuzhiyun 			   rdev->fence_drv[i].sync_seq[i]);
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 		for (j = 0; j < RADEON_NUM_RINGS; ++j) {
996*4882a593Smuzhiyun 			if (i != j && rdev->fence_drv[j].initialized)
997*4882a593Smuzhiyun 				seq_printf(m, "Last sync to ring %d 0x%016llx\n",
998*4882a593Smuzhiyun 					   j, rdev->fence_drv[i].sync_seq[j]);
999*4882a593Smuzhiyun 		}
1000*4882a593Smuzhiyun 	}
1001*4882a593Smuzhiyun 	return 0;
1002*4882a593Smuzhiyun }
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun /**
1005*4882a593Smuzhiyun  * radeon_debugfs_gpu_reset - manually trigger a gpu reset
1006*4882a593Smuzhiyun  *
1007*4882a593Smuzhiyun  * Manually trigger a gpu reset at the next fence wait.
1008*4882a593Smuzhiyun  */
radeon_debugfs_gpu_reset(struct seq_file * m,void * data)1009*4882a593Smuzhiyun static int radeon_debugfs_gpu_reset(struct seq_file *m, void *data)
1010*4882a593Smuzhiyun {
1011*4882a593Smuzhiyun 	struct drm_info_node *node = (struct drm_info_node *) m->private;
1012*4882a593Smuzhiyun 	struct drm_device *dev = node->minor->dev;
1013*4882a593Smuzhiyun 	struct radeon_device *rdev = dev->dev_private;
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun 	down_read(&rdev->exclusive_lock);
1016*4882a593Smuzhiyun 	seq_printf(m, "%d\n", rdev->needs_reset);
1017*4882a593Smuzhiyun 	rdev->needs_reset = true;
1018*4882a593Smuzhiyun 	wake_up_all(&rdev->fence_queue);
1019*4882a593Smuzhiyun 	up_read(&rdev->exclusive_lock);
1020*4882a593Smuzhiyun 
1021*4882a593Smuzhiyun 	return 0;
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun static struct drm_info_list radeon_debugfs_fence_list[] = {
1025*4882a593Smuzhiyun 	{"radeon_fence_info", &radeon_debugfs_fence_info, 0, NULL},
1026*4882a593Smuzhiyun 	{"radeon_gpu_reset", &radeon_debugfs_gpu_reset, 0, NULL}
1027*4882a593Smuzhiyun };
1028*4882a593Smuzhiyun #endif
1029*4882a593Smuzhiyun 
radeon_debugfs_fence_init(struct radeon_device * rdev)1030*4882a593Smuzhiyun int radeon_debugfs_fence_init(struct radeon_device *rdev)
1031*4882a593Smuzhiyun {
1032*4882a593Smuzhiyun #if defined(CONFIG_DEBUG_FS)
1033*4882a593Smuzhiyun 	return radeon_debugfs_add_files(rdev, radeon_debugfs_fence_list, 2);
1034*4882a593Smuzhiyun #else
1035*4882a593Smuzhiyun 	return 0;
1036*4882a593Smuzhiyun #endif
1037*4882a593Smuzhiyun }
1038*4882a593Smuzhiyun 
radeon_fence_get_driver_name(struct dma_fence * fence)1039*4882a593Smuzhiyun static const char *radeon_fence_get_driver_name(struct dma_fence *fence)
1040*4882a593Smuzhiyun {
1041*4882a593Smuzhiyun 	return "radeon";
1042*4882a593Smuzhiyun }
1043*4882a593Smuzhiyun 
radeon_fence_get_timeline_name(struct dma_fence * f)1044*4882a593Smuzhiyun static const char *radeon_fence_get_timeline_name(struct dma_fence *f)
1045*4882a593Smuzhiyun {
1046*4882a593Smuzhiyun 	struct radeon_fence *fence = to_radeon_fence(f);
1047*4882a593Smuzhiyun 	switch (fence->ring) {
1048*4882a593Smuzhiyun 	case RADEON_RING_TYPE_GFX_INDEX: return "radeon.gfx";
1049*4882a593Smuzhiyun 	case CAYMAN_RING_TYPE_CP1_INDEX: return "radeon.cp1";
1050*4882a593Smuzhiyun 	case CAYMAN_RING_TYPE_CP2_INDEX: return "radeon.cp2";
1051*4882a593Smuzhiyun 	case R600_RING_TYPE_DMA_INDEX: return "radeon.dma";
1052*4882a593Smuzhiyun 	case CAYMAN_RING_TYPE_DMA1_INDEX: return "radeon.dma1";
1053*4882a593Smuzhiyun 	case R600_RING_TYPE_UVD_INDEX: return "radeon.uvd";
1054*4882a593Smuzhiyun 	case TN_RING_TYPE_VCE1_INDEX: return "radeon.vce1";
1055*4882a593Smuzhiyun 	case TN_RING_TYPE_VCE2_INDEX: return "radeon.vce2";
1056*4882a593Smuzhiyun 	default: WARN_ON_ONCE(1); return "radeon.unk";
1057*4882a593Smuzhiyun 	}
1058*4882a593Smuzhiyun }
1059*4882a593Smuzhiyun 
radeon_test_signaled(struct radeon_fence * fence)1060*4882a593Smuzhiyun static inline bool radeon_test_signaled(struct radeon_fence *fence)
1061*4882a593Smuzhiyun {
1062*4882a593Smuzhiyun 	return test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags);
1063*4882a593Smuzhiyun }
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun struct radeon_wait_cb {
1066*4882a593Smuzhiyun 	struct dma_fence_cb base;
1067*4882a593Smuzhiyun 	struct task_struct *task;
1068*4882a593Smuzhiyun };
1069*4882a593Smuzhiyun 
1070*4882a593Smuzhiyun static void
radeon_fence_wait_cb(struct dma_fence * fence,struct dma_fence_cb * cb)1071*4882a593Smuzhiyun radeon_fence_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
1072*4882a593Smuzhiyun {
1073*4882a593Smuzhiyun 	struct radeon_wait_cb *wait =
1074*4882a593Smuzhiyun 		container_of(cb, struct radeon_wait_cb, base);
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun 	wake_up_process(wait->task);
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun 
radeon_fence_default_wait(struct dma_fence * f,bool intr,signed long t)1079*4882a593Smuzhiyun static signed long radeon_fence_default_wait(struct dma_fence *f, bool intr,
1080*4882a593Smuzhiyun 					     signed long t)
1081*4882a593Smuzhiyun {
1082*4882a593Smuzhiyun 	struct radeon_fence *fence = to_radeon_fence(f);
1083*4882a593Smuzhiyun 	struct radeon_device *rdev = fence->rdev;
1084*4882a593Smuzhiyun 	struct radeon_wait_cb cb;
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun 	cb.task = current;
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	if (dma_fence_add_callback(f, &cb.base, radeon_fence_wait_cb))
1089*4882a593Smuzhiyun 		return t;
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	while (t > 0) {
1092*4882a593Smuzhiyun 		if (intr)
1093*4882a593Smuzhiyun 			set_current_state(TASK_INTERRUPTIBLE);
1094*4882a593Smuzhiyun 		else
1095*4882a593Smuzhiyun 			set_current_state(TASK_UNINTERRUPTIBLE);
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun 		/*
1098*4882a593Smuzhiyun 		 * radeon_test_signaled must be called after
1099*4882a593Smuzhiyun 		 * set_current_state to prevent a race with wake_up_process
1100*4882a593Smuzhiyun 		 */
1101*4882a593Smuzhiyun 		if (radeon_test_signaled(fence))
1102*4882a593Smuzhiyun 			break;
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun 		if (rdev->needs_reset) {
1105*4882a593Smuzhiyun 			t = -EDEADLK;
1106*4882a593Smuzhiyun 			break;
1107*4882a593Smuzhiyun 		}
1108*4882a593Smuzhiyun 
1109*4882a593Smuzhiyun 		t = schedule_timeout(t);
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 		if (t > 0 && intr && signal_pending(current))
1112*4882a593Smuzhiyun 			t = -ERESTARTSYS;
1113*4882a593Smuzhiyun 	}
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	__set_current_state(TASK_RUNNING);
1116*4882a593Smuzhiyun 	dma_fence_remove_callback(f, &cb.base);
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	return t;
1119*4882a593Smuzhiyun }
1120*4882a593Smuzhiyun 
1121*4882a593Smuzhiyun const struct dma_fence_ops radeon_fence_ops = {
1122*4882a593Smuzhiyun 	.get_driver_name = radeon_fence_get_driver_name,
1123*4882a593Smuzhiyun 	.get_timeline_name = radeon_fence_get_timeline_name,
1124*4882a593Smuzhiyun 	.enable_signaling = radeon_fence_enable_signaling,
1125*4882a593Smuzhiyun 	.signaled = radeon_fence_is_signaled,
1126*4882a593Smuzhiyun 	.wait = radeon_fence_default_wait,
1127*4882a593Smuzhiyun 	.release = NULL,
1128*4882a593Smuzhiyun };
1129