drm/radeon/kms: fix indirect buffer management V2
[sfrench/cifs-2.6.git] / drivers / gpu / drm / radeon / radeon_ring.c
1 /*
2  * Copyright 2008 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  * Copyright 2009 Jerome Glisse.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  *          Jerome Glisse
27  */
28 #include <linux/seq_file.h>
29 #include "drmP.h"
30 #include "radeon_drm.h"
31 #include "radeon_reg.h"
32 #include "radeon.h"
33 #include "atom.h"
34
35 int radeon_debugfs_ib_init(struct radeon_device *rdev);
36
37 /*
38  * IB.
39  */
40 int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
41 {
42         struct radeon_fence *fence;
43         struct radeon_ib *nib;
44         int r = 0, i, c;
45
46         *ib = NULL;
47         r = radeon_fence_create(rdev, &fence);
48         if (r) {
49                 dev_err(rdev->dev, "failed to create fence for new IB\n");
50                 return r;
51         }
52         mutex_lock(&rdev->ib_pool.mutex);
53         for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) {
54                 i &= (RADEON_IB_POOL_SIZE - 1);
55                 if (rdev->ib_pool.ibs[i].free) {
56                         nib = &rdev->ib_pool.ibs[i];
57                         break;
58                 }
59         }
60         if (nib == NULL) {
61                 /* This should never happen, it means we allocated all
62                  * IB and haven't scheduled one yet, return EBUSY to
63                  * userspace hoping that on ioctl recall we get better
64                  * luck
65                  */
66                 dev_err(rdev->dev, "no free indirect buffer !\n");
67                 mutex_unlock(&rdev->ib_pool.mutex);
68                 radeon_fence_unref(&fence);
69                 return -EBUSY;
70         }
71         rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1);
72         nib->free = false;
73         if (nib->fence) {
74                 mutex_unlock(&rdev->ib_pool.mutex);
75                 r = radeon_fence_wait(nib->fence, false);
76                 if (r) {
77                         dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n",
78                                 nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw);
79                         mutex_lock(&rdev->ib_pool.mutex);
80                         nib->free = true;
81                         mutex_unlock(&rdev->ib_pool.mutex);
82                         radeon_fence_unref(&fence);
83                         return r;
84                 }
85                 mutex_lock(&rdev->ib_pool.mutex);
86         }
87         radeon_fence_unref(&nib->fence);
88         nib->fence = fence;
89         nib->length_dw = 0;
90         mutex_unlock(&rdev->ib_pool.mutex);
91         *ib = nib;
92         return 0;
93 }
94
95 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
96 {
97         struct radeon_ib *tmp = *ib;
98
99         *ib = NULL;
100         if (tmp == NULL) {
101                 return;
102         }
103         mutex_lock(&rdev->ib_pool.mutex);
104         tmp->free = true;
105         mutex_unlock(&rdev->ib_pool.mutex);
106 }
107
108 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
109 {
110         int r = 0;
111
112         if (!ib->length_dw || !rdev->cp.ready) {
113                 /* TODO: Nothings in the ib we should report. */
114                 DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
115                 return -EINVAL;
116         }
117
118         /* 64 dwords should be enough for fence too */
119         r = radeon_ring_lock(rdev, 64);
120         if (r) {
121                 DRM_ERROR("radeon: scheduling IB failled (%d).\n", r);
122                 return r;
123         }
124         radeon_ring_ib_execute(rdev, ib);
125         radeon_fence_emit(rdev, ib->fence);
126         mutex_lock(&rdev->ib_pool.mutex);
127         /* once scheduled IB is considered free and protected by the fence */
128         ib->free = true;
129         mutex_unlock(&rdev->ib_pool.mutex);
130         radeon_ring_unlock_commit(rdev);
131         return 0;
132 }
133
134 int radeon_ib_pool_init(struct radeon_device *rdev)
135 {
136         void *ptr;
137         uint64_t gpu_addr;
138         int i;
139         int r = 0;
140
141         if (rdev->ib_pool.robj)
142                 return 0;
143         /* Allocate 1M object buffer */
144         r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
145                                 true, RADEON_GEM_DOMAIN_GTT,
146                                 &rdev->ib_pool.robj);
147         if (r) {
148                 DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
149                 return r;
150         }
151         r = radeon_bo_reserve(rdev->ib_pool.robj, false);
152         if (unlikely(r != 0))
153                 return r;
154         r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
155         if (r) {
156                 radeon_bo_unreserve(rdev->ib_pool.robj);
157                 DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r);
158                 return r;
159         }
160         r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr);
161         radeon_bo_unreserve(rdev->ib_pool.robj);
162         if (r) {
163                 DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
164                 return r;
165         }
166         for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
167                 unsigned offset;
168
169                 offset = i * 64 * 1024;
170                 rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset;
171                 rdev->ib_pool.ibs[i].ptr = ptr + offset;
172                 rdev->ib_pool.ibs[i].idx = i;
173                 rdev->ib_pool.ibs[i].length_dw = 0;
174                 rdev->ib_pool.ibs[i].free = true;
175         }
176         rdev->ib_pool.head_id = 0;
177         rdev->ib_pool.ready = true;
178         DRM_INFO("radeon: ib pool ready.\n");
179         if (radeon_debugfs_ib_init(rdev)) {
180                 DRM_ERROR("Failed to register debugfs file for IB !\n");
181         }
182         return r;
183 }
184
185 void radeon_ib_pool_fini(struct radeon_device *rdev)
186 {
187         int r;
188
189         if (!rdev->ib_pool.ready) {
190                 return;
191         }
192         mutex_lock(&rdev->ib_pool.mutex);
193         if (rdev->ib_pool.robj) {
194                 r = radeon_bo_reserve(rdev->ib_pool.robj, false);
195                 if (likely(r == 0)) {
196                         radeon_bo_kunmap(rdev->ib_pool.robj);
197                         radeon_bo_unpin(rdev->ib_pool.robj);
198                         radeon_bo_unreserve(rdev->ib_pool.robj);
199                 }
200                 radeon_bo_unref(&rdev->ib_pool.robj);
201                 rdev->ib_pool.robj = NULL;
202         }
203         mutex_unlock(&rdev->ib_pool.mutex);
204 }
205
206
207 /*
208  * Ring.
209  */
210 void radeon_ring_free_size(struct radeon_device *rdev)
211 {
212         if (rdev->family >= CHIP_R600)
213                 rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
214         else
215                 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
216         /* This works because ring_size is a power of 2 */
217         rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4));
218         rdev->cp.ring_free_dw -= rdev->cp.wptr;
219         rdev->cp.ring_free_dw &= rdev->cp.ptr_mask;
220         if (!rdev->cp.ring_free_dw) {
221                 rdev->cp.ring_free_dw = rdev->cp.ring_size / 4;
222         }
223 }
224
225 int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw)
226 {
227         int r;
228
229         /* Align requested size with padding so unlock_commit can
230          * pad safely */
231         ndw = (ndw + rdev->cp.align_mask) & ~rdev->cp.align_mask;
232         mutex_lock(&rdev->cp.mutex);
233         while (ndw > (rdev->cp.ring_free_dw - 1)) {
234                 radeon_ring_free_size(rdev);
235                 if (ndw < rdev->cp.ring_free_dw) {
236                         break;
237                 }
238                 r = radeon_fence_wait_next(rdev);
239                 if (r) {
240                         mutex_unlock(&rdev->cp.mutex);
241                         return r;
242                 }
243         }
244         rdev->cp.count_dw = ndw;
245         rdev->cp.wptr_old = rdev->cp.wptr;
246         return 0;
247 }
248
249 void radeon_ring_unlock_commit(struct radeon_device *rdev)
250 {
251         unsigned count_dw_pad;
252         unsigned i;
253
254         /* We pad to match fetch size */
255         count_dw_pad = (rdev->cp.align_mask + 1) -
256                        (rdev->cp.wptr & rdev->cp.align_mask);
257         for (i = 0; i < count_dw_pad; i++) {
258                 radeon_ring_write(rdev, 2 << 30);
259         }
260         DRM_MEMORYBARRIER();
261         radeon_cp_commit(rdev);
262         mutex_unlock(&rdev->cp.mutex);
263 }
264
265 void radeon_ring_unlock_undo(struct radeon_device *rdev)
266 {
267         rdev->cp.wptr = rdev->cp.wptr_old;
268         mutex_unlock(&rdev->cp.mutex);
269 }
270
271 int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
272 {
273         int r;
274
275         rdev->cp.ring_size = ring_size;
276         /* Allocate ring buffer */
277         if (rdev->cp.ring_obj == NULL) {
278                 r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
279                                         RADEON_GEM_DOMAIN_GTT,
280                                         &rdev->cp.ring_obj);
281                 if (r) {
282                         dev_err(rdev->dev, "(%d) ring create failed\n", r);
283                         return r;
284                 }
285                 r = radeon_bo_reserve(rdev->cp.ring_obj, false);
286                 if (unlikely(r != 0))
287                         return r;
288                 r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT,
289                                         &rdev->cp.gpu_addr);
290                 if (r) {
291                         radeon_bo_unreserve(rdev->cp.ring_obj);
292                         dev_err(rdev->dev, "(%d) ring pin failed\n", r);
293                         return r;
294                 }
295                 r = radeon_bo_kmap(rdev->cp.ring_obj,
296                                        (void **)&rdev->cp.ring);
297                 radeon_bo_unreserve(rdev->cp.ring_obj);
298                 if (r) {
299                         dev_err(rdev->dev, "(%d) ring map failed\n", r);
300                         return r;
301                 }
302         }
303         rdev->cp.ptr_mask = (rdev->cp.ring_size / 4) - 1;
304         rdev->cp.ring_free_dw = rdev->cp.ring_size / 4;
305         return 0;
306 }
307
308 void radeon_ring_fini(struct radeon_device *rdev)
309 {
310         int r;
311
312         mutex_lock(&rdev->cp.mutex);
313         if (rdev->cp.ring_obj) {
314                 r = radeon_bo_reserve(rdev->cp.ring_obj, false);
315                 if (likely(r == 0)) {
316                         radeon_bo_kunmap(rdev->cp.ring_obj);
317                         radeon_bo_unpin(rdev->cp.ring_obj);
318                         radeon_bo_unreserve(rdev->cp.ring_obj);
319                 }
320                 radeon_bo_unref(&rdev->cp.ring_obj);
321                 rdev->cp.ring = NULL;
322                 rdev->cp.ring_obj = NULL;
323         }
324         mutex_unlock(&rdev->cp.mutex);
325 }
326
327
328 /*
329  * Debugfs info
330  */
331 #if defined(CONFIG_DEBUG_FS)
332 static int radeon_debugfs_ib_info(struct seq_file *m, void *data)
333 {
334         struct drm_info_node *node = (struct drm_info_node *) m->private;
335         struct radeon_ib *ib = node->info_ent->data;
336         unsigned i;
337
338         if (ib == NULL) {
339                 return 0;
340         }
341         seq_printf(m, "IB %04u\n", ib->idx);
342         seq_printf(m, "IB fence %p\n", ib->fence);
343         seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
344         for (i = 0; i < ib->length_dw; i++) {
345                 seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
346         }
347         return 0;
348 }
349
350 static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
351 static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
352 #endif
353
354 int radeon_debugfs_ib_init(struct radeon_device *rdev)
355 {
356 #if defined(CONFIG_DEBUG_FS)
357         unsigned i;
358
359         for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
360                 sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
361                 radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i];
362                 radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info;
363                 radeon_debugfs_ib_list[i].driver_features = 0;
364                 radeon_debugfs_ib_list[i].data = &rdev->ib_pool.ibs[i];
365         }
366         return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list,
367                                         RADEON_IB_POOL_SIZE);
368 #else
369         return 0;
370 #endif
371 }