xref: /openbmc/linux/drivers/gpu/drm/radeon/radeon_ib.c (revision f28be8101116c832c94b4473abf193850bf6c931)
1*f28be810SChristian König /*
2*f28be810SChristian König  * Copyright 2008 Advanced Micro Devices, Inc.
3*f28be810SChristian König  * Copyright 2008 Red Hat Inc.
4*f28be810SChristian König  * Copyright 2009 Jerome Glisse.
5*f28be810SChristian König  *
6*f28be810SChristian König  * Permission is hereby granted, free of charge, to any person obtaining a
7*f28be810SChristian König  * copy of this software and associated documentation files (the "Software"),
8*f28be810SChristian König  * to deal in the Software without restriction, including without limitation
9*f28be810SChristian König  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*f28be810SChristian König  * and/or sell copies of the Software, and to permit persons to whom the
11*f28be810SChristian König  * Software is furnished to do so, subject to the following conditions:
12*f28be810SChristian König  *
13*f28be810SChristian König  * The above copyright notice and this permission notice shall be included in
14*f28be810SChristian König  * all copies or substantial portions of the Software.
15*f28be810SChristian König  *
16*f28be810SChristian König  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*f28be810SChristian König  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*f28be810SChristian König  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19*f28be810SChristian König  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*f28be810SChristian König  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*f28be810SChristian König  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*f28be810SChristian König  * OTHER DEALINGS IN THE SOFTWARE.
23*f28be810SChristian König  *
24*f28be810SChristian König  * Authors: Dave Airlie
25*f28be810SChristian König  *          Alex Deucher
26*f28be810SChristian König  *          Jerome Glisse
27*f28be810SChristian König  *          Christian König
28*f28be810SChristian König  */
29*f28be810SChristian König #include <drm/drmP.h>
30*f28be810SChristian König #include "radeon.h"
31*f28be810SChristian König 
32*f28be810SChristian König /*
33*f28be810SChristian König  * IB
34*f28be810SChristian König  * IBs (Indirect Buffers) and areas of GPU accessible memory where
35*f28be810SChristian König  * commands are stored.  You can put a pointer to the IB in the
36*f28be810SChristian König  * command ring and the hw will fetch the commands from the IB
37*f28be810SChristian König  * and execute them.  Generally userspace acceleration drivers
38*f28be810SChristian König  * produce command buffers which are send to the kernel and
39*f28be810SChristian König  * put in IBs for execution by the requested ring.
40*f28be810SChristian König  */
41*f28be810SChristian König static int radeon_debugfs_sa_init(struct radeon_device *rdev);
42*f28be810SChristian König 
43*f28be810SChristian König /**
44*f28be810SChristian König  * radeon_ib_get - request an IB (Indirect Buffer)
45*f28be810SChristian König  *
46*f28be810SChristian König  * @rdev: radeon_device pointer
47*f28be810SChristian König  * @ring: ring index the IB is associated with
48*f28be810SChristian König  * @ib: IB object returned
49*f28be810SChristian König  * @size: requested IB size
50*f28be810SChristian König  *
51*f28be810SChristian König  * Request an IB (all asics).  IBs are allocated using the
52*f28be810SChristian König  * suballocator.
53*f28be810SChristian König  * Returns 0 on success, error on failure.
54*f28be810SChristian König  */
55*f28be810SChristian König int radeon_ib_get(struct radeon_device *rdev, int ring,
56*f28be810SChristian König 		  struct radeon_ib *ib, struct radeon_vm *vm,
57*f28be810SChristian König 		  unsigned size)
58*f28be810SChristian König {
59*f28be810SChristian König 	int r;
60*f28be810SChristian König 
61*f28be810SChristian König 	r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256);
62*f28be810SChristian König 	if (r) {
63*f28be810SChristian König 		dev_err(rdev->dev, "failed to get a new IB (%d)\n", r);
64*f28be810SChristian König 		return r;
65*f28be810SChristian König 	}
66*f28be810SChristian König 
67*f28be810SChristian König 	r = radeon_semaphore_create(rdev, &ib->semaphore);
68*f28be810SChristian König 	if (r) {
69*f28be810SChristian König 		return r;
70*f28be810SChristian König 	}
71*f28be810SChristian König 
72*f28be810SChristian König 	ib->ring = ring;
73*f28be810SChristian König 	ib->fence = NULL;
74*f28be810SChristian König 	ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo);
75*f28be810SChristian König 	ib->vm = vm;
76*f28be810SChristian König 	if (vm) {
77*f28be810SChristian König 		/* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address
78*f28be810SChristian König 		 * space and soffset is the offset inside the pool bo
79*f28be810SChristian König 		 */
80*f28be810SChristian König 		ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET;
81*f28be810SChristian König 	} else {
82*f28be810SChristian König 		ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
83*f28be810SChristian König 	}
84*f28be810SChristian König 	ib->is_const_ib = false;
85*f28be810SChristian König 
86*f28be810SChristian König 	return 0;
87*f28be810SChristian König }
88*f28be810SChristian König 
89*f28be810SChristian König /**
90*f28be810SChristian König  * radeon_ib_free - free an IB (Indirect Buffer)
91*f28be810SChristian König  *
92*f28be810SChristian König  * @rdev: radeon_device pointer
93*f28be810SChristian König  * @ib: IB object to free
94*f28be810SChristian König  *
95*f28be810SChristian König  * Free an IB (all asics).
96*f28be810SChristian König  */
97*f28be810SChristian König void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
98*f28be810SChristian König {
99*f28be810SChristian König 	radeon_semaphore_free(rdev, &ib->semaphore, ib->fence);
100*f28be810SChristian König 	radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence);
101*f28be810SChristian König 	radeon_fence_unref(&ib->fence);
102*f28be810SChristian König }
103*f28be810SChristian König 
104*f28be810SChristian König /**
105*f28be810SChristian König  * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring
106*f28be810SChristian König  *
107*f28be810SChristian König  * @rdev: radeon_device pointer
108*f28be810SChristian König  * @ib: IB object to schedule
109*f28be810SChristian König  * @const_ib: Const IB to schedule (SI only)
110*f28be810SChristian König  *
111*f28be810SChristian König  * Schedule an IB on the associated ring (all asics).
112*f28be810SChristian König  * Returns 0 on success, error on failure.
113*f28be810SChristian König  *
114*f28be810SChristian König  * On SI, there are two parallel engines fed from the primary ring,
115*f28be810SChristian König  * the CE (Constant Engine) and the DE (Drawing Engine).  Since
116*f28be810SChristian König  * resource descriptors have moved to memory, the CE allows you to
117*f28be810SChristian König  * prime the caches while the DE is updating register state so that
118*f28be810SChristian König  * the resource descriptors will be already in cache when the draw is
119*f28be810SChristian König  * processed.  To accomplish this, the userspace driver submits two
120*f28be810SChristian König  * IBs, one for the CE and one for the DE.  If there is a CE IB (called
121*f28be810SChristian König  * a CONST_IB), it will be put on the ring prior to the DE IB.  Prior
122*f28be810SChristian König  * to SI there was just a DE IB.
123*f28be810SChristian König  */
124*f28be810SChristian König int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
125*f28be810SChristian König 		       struct radeon_ib *const_ib)
126*f28be810SChristian König {
127*f28be810SChristian König 	struct radeon_ring *ring = &rdev->ring[ib->ring];
128*f28be810SChristian König 	int r = 0;
129*f28be810SChristian König 
130*f28be810SChristian König 	if (!ib->length_dw || !ring->ready) {
131*f28be810SChristian König 		/* TODO: Nothings in the ib we should report. */
132*f28be810SChristian König 		dev_err(rdev->dev, "couldn't schedule ib\n");
133*f28be810SChristian König 		return -EINVAL;
134*f28be810SChristian König 	}
135*f28be810SChristian König 
136*f28be810SChristian König 	/* 64 dwords should be enough for fence too */
137*f28be810SChristian König 	r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8);
138*f28be810SChristian König 	if (r) {
139*f28be810SChristian König 		dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
140*f28be810SChristian König 		return r;
141*f28be810SChristian König 	}
142*f28be810SChristian König 
143*f28be810SChristian König 	/* grab a vm id if necessary */
144*f28be810SChristian König 	if (ib->vm) {
145*f28be810SChristian König 		struct radeon_fence *vm_id_fence;
146*f28be810SChristian König 		vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring);
147*f28be810SChristian König         	radeon_semaphore_sync_to(ib->semaphore, vm_id_fence);
148*f28be810SChristian König 	}
149*f28be810SChristian König 
150*f28be810SChristian König 	/* sync with other rings */
151*f28be810SChristian König 	r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring);
152*f28be810SChristian König 	if (r) {
153*f28be810SChristian König 		dev_err(rdev->dev, "failed to sync rings (%d)\n", r);
154*f28be810SChristian König 		radeon_ring_unlock_undo(rdev, ring);
155*f28be810SChristian König 		return r;
156*f28be810SChristian König 	}
157*f28be810SChristian König 
158*f28be810SChristian König 	if (ib->vm)
159*f28be810SChristian König 		radeon_vm_flush(rdev, ib->vm, ib->ring);
160*f28be810SChristian König 
161*f28be810SChristian König 	if (const_ib) {
162*f28be810SChristian König 		radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
163*f28be810SChristian König 		radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
164*f28be810SChristian König 	}
165*f28be810SChristian König 	radeon_ring_ib_execute(rdev, ib->ring, ib);
166*f28be810SChristian König 	r = radeon_fence_emit(rdev, &ib->fence, ib->ring);
167*f28be810SChristian König 	if (r) {
168*f28be810SChristian König 		dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r);
169*f28be810SChristian König 		radeon_ring_unlock_undo(rdev, ring);
170*f28be810SChristian König 		return r;
171*f28be810SChristian König 	}
172*f28be810SChristian König 	if (const_ib) {
173*f28be810SChristian König 		const_ib->fence = radeon_fence_ref(ib->fence);
174*f28be810SChristian König 	}
175*f28be810SChristian König 
176*f28be810SChristian König 	if (ib->vm)
177*f28be810SChristian König 		radeon_vm_fence(rdev, ib->vm, ib->fence);
178*f28be810SChristian König 
179*f28be810SChristian König 	radeon_ring_unlock_commit(rdev, ring);
180*f28be810SChristian König 	return 0;
181*f28be810SChristian König }
182*f28be810SChristian König 
183*f28be810SChristian König /**
184*f28be810SChristian König  * radeon_ib_pool_init - Init the IB (Indirect Buffer) pool
185*f28be810SChristian König  *
186*f28be810SChristian König  * @rdev: radeon_device pointer
187*f28be810SChristian König  *
188*f28be810SChristian König  * Initialize the suballocator to manage a pool of memory
189*f28be810SChristian König  * for use as IBs (all asics).
190*f28be810SChristian König  * Returns 0 on success, error on failure.
191*f28be810SChristian König  */
192*f28be810SChristian König int radeon_ib_pool_init(struct radeon_device *rdev)
193*f28be810SChristian König {
194*f28be810SChristian König 	int r;
195*f28be810SChristian König 
196*f28be810SChristian König 	if (rdev->ib_pool_ready) {
197*f28be810SChristian König 		return 0;
198*f28be810SChristian König 	}
199*f28be810SChristian König 
200*f28be810SChristian König 	if (rdev->family >= CHIP_BONAIRE) {
201*f28be810SChristian König 		r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
202*f28be810SChristian König 					      RADEON_IB_POOL_SIZE*64*1024,
203*f28be810SChristian König 					      RADEON_GPU_PAGE_SIZE,
204*f28be810SChristian König 					      RADEON_GEM_DOMAIN_GTT,
205*f28be810SChristian König 					      RADEON_GEM_GTT_WC);
206*f28be810SChristian König 	} else {
207*f28be810SChristian König 		/* Before CIK, it's better to stick to cacheable GTT due
208*f28be810SChristian König 		 * to the command stream checking
209*f28be810SChristian König 		 */
210*f28be810SChristian König 		r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
211*f28be810SChristian König 					      RADEON_IB_POOL_SIZE*64*1024,
212*f28be810SChristian König 					      RADEON_GPU_PAGE_SIZE,
213*f28be810SChristian König 					      RADEON_GEM_DOMAIN_GTT, 0);
214*f28be810SChristian König 	}
215*f28be810SChristian König 	if (r) {
216*f28be810SChristian König 		return r;
217*f28be810SChristian König 	}
218*f28be810SChristian König 
219*f28be810SChristian König 	r = radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo);
220*f28be810SChristian König 	if (r) {
221*f28be810SChristian König 		return r;
222*f28be810SChristian König 	}
223*f28be810SChristian König 
224*f28be810SChristian König 	rdev->ib_pool_ready = true;
225*f28be810SChristian König 	if (radeon_debugfs_sa_init(rdev)) {
226*f28be810SChristian König 		dev_err(rdev->dev, "failed to register debugfs file for SA\n");
227*f28be810SChristian König 	}
228*f28be810SChristian König 	return 0;
229*f28be810SChristian König }
230*f28be810SChristian König 
231*f28be810SChristian König /**
232*f28be810SChristian König  * radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool
233*f28be810SChristian König  *
234*f28be810SChristian König  * @rdev: radeon_device pointer
235*f28be810SChristian König  *
236*f28be810SChristian König  * Tear down the suballocator managing the pool of memory
237*f28be810SChristian König  * for use as IBs (all asics).
238*f28be810SChristian König  */
239*f28be810SChristian König void radeon_ib_pool_fini(struct radeon_device *rdev)
240*f28be810SChristian König {
241*f28be810SChristian König 	if (rdev->ib_pool_ready) {
242*f28be810SChristian König 		radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo);
243*f28be810SChristian König 		radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo);
244*f28be810SChristian König 		rdev->ib_pool_ready = false;
245*f28be810SChristian König 	}
246*f28be810SChristian König }
247*f28be810SChristian König 
248*f28be810SChristian König /**
249*f28be810SChristian König  * radeon_ib_ring_tests - test IBs on the rings
250*f28be810SChristian König  *
251*f28be810SChristian König  * @rdev: radeon_device pointer
252*f28be810SChristian König  *
253*f28be810SChristian König  * Test an IB (Indirect Buffer) on each ring.
254*f28be810SChristian König  * If the test fails, disable the ring.
255*f28be810SChristian König  * Returns 0 on success, error if the primary GFX ring
256*f28be810SChristian König  * IB test fails.
257*f28be810SChristian König  */
258*f28be810SChristian König int radeon_ib_ring_tests(struct radeon_device *rdev)
259*f28be810SChristian König {
260*f28be810SChristian König 	unsigned i;
261*f28be810SChristian König 	int r;
262*f28be810SChristian König 
263*f28be810SChristian König 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
264*f28be810SChristian König 		struct radeon_ring *ring = &rdev->ring[i];
265*f28be810SChristian König 
266*f28be810SChristian König 		if (!ring->ready)
267*f28be810SChristian König 			continue;
268*f28be810SChristian König 
269*f28be810SChristian König 		r = radeon_ib_test(rdev, i, ring);
270*f28be810SChristian König 		if (r) {
271*f28be810SChristian König 			ring->ready = false;
272*f28be810SChristian König 			rdev->needs_reset = false;
273*f28be810SChristian König 
274*f28be810SChristian König 			if (i == RADEON_RING_TYPE_GFX_INDEX) {
275*f28be810SChristian König 				/* oh, oh, that's really bad */
276*f28be810SChristian König 				DRM_ERROR("radeon: failed testing IB on GFX ring (%d).\n", r);
277*f28be810SChristian König 		                rdev->accel_working = false;
278*f28be810SChristian König 				return r;
279*f28be810SChristian König 
280*f28be810SChristian König 			} else {
281*f28be810SChristian König 				/* still not good, but we can live with it */
282*f28be810SChristian König 				DRM_ERROR("radeon: failed testing IB on ring %d (%d).\n", i, r);
283*f28be810SChristian König 			}
284*f28be810SChristian König 		}
285*f28be810SChristian König 	}
286*f28be810SChristian König 	return 0;
287*f28be810SChristian König }
288*f28be810SChristian König 
289*f28be810SChristian König /*
290*f28be810SChristian König  * Debugfs info
291*f28be810SChristian König  */
292*f28be810SChristian König #if defined(CONFIG_DEBUG_FS)
293*f28be810SChristian König 
294*f28be810SChristian König static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
295*f28be810SChristian König {
296*f28be810SChristian König 	struct drm_info_node *node = (struct drm_info_node *) m->private;
297*f28be810SChristian König 	struct drm_device *dev = node->minor->dev;
298*f28be810SChristian König 	struct radeon_device *rdev = dev->dev_private;
299*f28be810SChristian König 
300*f28be810SChristian König 	radeon_sa_bo_dump_debug_info(&rdev->ring_tmp_bo, m);
301*f28be810SChristian König 
302*f28be810SChristian König 	return 0;
303*f28be810SChristian König 
304*f28be810SChristian König }
305*f28be810SChristian König 
306*f28be810SChristian König static struct drm_info_list radeon_debugfs_sa_list[] = {
307*f28be810SChristian König         {"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL},
308*f28be810SChristian König };
309*f28be810SChristian König 
310*f28be810SChristian König #endif
311*f28be810SChristian König 
312*f28be810SChristian König static int radeon_debugfs_sa_init(struct radeon_device *rdev)
313*f28be810SChristian König {
314*f28be810SChristian König #if defined(CONFIG_DEBUG_FS)
315*f28be810SChristian König 	return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
316*f28be810SChristian König #else
317*f28be810SChristian König 	return 0;
318*f28be810SChristian König #endif
319*f28be810SChristian König }
320