]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/radeon/radeon_ring.c
drm/radeon: make ring rptr and wptr register offsets variable
[karo-tx-linux.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 <linux/slab.h>
30 #include "drmP.h"
31 #include "radeon_drm.h"
32 #include "radeon_reg.h"
33 #include "radeon.h"
34 #include "atom.h"
35
36 int radeon_debugfs_ib_init(struct radeon_device *rdev);
37
38 u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
39 {
40         struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
41         u32 pg_idx, pg_offset;
42         u32 idx_value = 0;
43         int new_page;
44
45         pg_idx = (idx * 4) / PAGE_SIZE;
46         pg_offset = (idx * 4) % PAGE_SIZE;
47
48         if (ibc->kpage_idx[0] == pg_idx)
49                 return ibc->kpage[0][pg_offset/4];
50         if (ibc->kpage_idx[1] == pg_idx)
51                 return ibc->kpage[1][pg_offset/4];
52
53         new_page = radeon_cs_update_pages(p, pg_idx);
54         if (new_page < 0) {
55                 p->parser_error = new_page;
56                 return 0;
57         }
58
59         idx_value = ibc->kpage[new_page][pg_offset/4];
60         return idx_value;
61 }
62
63 void radeon_ring_write(struct radeon_cp *cp, uint32_t v)
64 {
65 #if DRM_DEBUG_CODE
66         if (cp->count_dw <= 0) {
67                 DRM_ERROR("radeon: writting more dword to ring than expected !\n");
68         }
69 #endif
70         cp->ring[cp->wptr++] = v;
71         cp->wptr &= cp->ptr_mask;
72         cp->count_dw--;
73         cp->ring_free_dw--;
74 }
75
76 void radeon_ib_bogus_cleanup(struct radeon_device *rdev)
77 {
78         struct radeon_ib *ib, *n;
79
80         list_for_each_entry_safe(ib, n, &rdev->ib_pool.bogus_ib, list) {
81                 list_del(&ib->list);
82                 vfree(ib->ptr);
83                 kfree(ib);
84         }
85 }
86
87 void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib)
88 {
89         struct radeon_ib *bib;
90
91         bib = kmalloc(sizeof(*bib), GFP_KERNEL);
92         if (bib == NULL)
93                 return;
94         bib->ptr = vmalloc(ib->length_dw * 4);
95         if (bib->ptr == NULL) {
96                 kfree(bib);
97                 return;
98         }
99         memcpy(bib->ptr, ib->ptr, ib->length_dw * 4);
100         bib->length_dw = ib->length_dw;
101         mutex_lock(&rdev->ib_pool.mutex);
102         list_add_tail(&bib->list, &rdev->ib_pool.bogus_ib);
103         mutex_unlock(&rdev->ib_pool.mutex);
104 }
105
106 /*
107  * IB.
108  */
109 int radeon_ib_get(struct radeon_device *rdev, int ring, struct radeon_ib **ib)
110 {
111         struct radeon_fence *fence;
112         struct radeon_ib *nib;
113         int r = 0, i, c;
114
115         *ib = NULL;
116         r = radeon_fence_create(rdev, &fence, ring);
117         if (r) {
118                 dev_err(rdev->dev, "failed to create fence for new IB\n");
119                 return r;
120         }
121         mutex_lock(&rdev->ib_pool.mutex);
122         for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) {
123                 i &= (RADEON_IB_POOL_SIZE - 1);
124                 if (rdev->ib_pool.ibs[i].free) {
125                         nib = &rdev->ib_pool.ibs[i];
126                         break;
127                 }
128         }
129         if (nib == NULL) {
130                 /* This should never happen, it means we allocated all
131                  * IB and haven't scheduled one yet, return EBUSY to
132                  * userspace hoping that on ioctl recall we get better
133                  * luck
134                  */
135                 dev_err(rdev->dev, "no free indirect buffer !\n");
136                 mutex_unlock(&rdev->ib_pool.mutex);
137                 radeon_fence_unref(&fence);
138                 return -EBUSY;
139         }
140         rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1);
141         nib->free = false;
142         if (nib->fence) {
143                 mutex_unlock(&rdev->ib_pool.mutex);
144                 r = radeon_fence_wait(nib->fence, false);
145                 if (r) {
146                         dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n",
147                                 nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw);
148                         mutex_lock(&rdev->ib_pool.mutex);
149                         nib->free = true;
150                         mutex_unlock(&rdev->ib_pool.mutex);
151                         radeon_fence_unref(&fence);
152                         return r;
153                 }
154                 mutex_lock(&rdev->ib_pool.mutex);
155         }
156         radeon_fence_unref(&nib->fence);
157         nib->fence = fence;
158         nib->length_dw = 0;
159         mutex_unlock(&rdev->ib_pool.mutex);
160         *ib = nib;
161         return 0;
162 }
163
164 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
165 {
166         struct radeon_ib *tmp = *ib;
167
168         *ib = NULL;
169         if (tmp == NULL) {
170                 return;
171         }
172         if (!tmp->fence->emitted)
173                 radeon_fence_unref(&tmp->fence);
174         mutex_lock(&rdev->ib_pool.mutex);
175         tmp->free = true;
176         mutex_unlock(&rdev->ib_pool.mutex);
177 }
178
179 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
180 {
181         struct radeon_cp *cp = &rdev->cp;
182         int r = 0;
183
184         if (!ib->length_dw || !cp->ready) {
185                 /* TODO: Nothings in the ib we should report. */
186                 DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
187                 return -EINVAL;
188         }
189
190         /* 64 dwords should be enough for fence too */
191         r = radeon_ring_lock(rdev, cp, 64);
192         if (r) {
193                 DRM_ERROR("radeon: scheduling IB failed (%d).\n", r);
194                 return r;
195         }
196         radeon_ring_ib_execute(rdev, ib);
197         radeon_fence_emit(rdev, ib->fence);
198         mutex_lock(&rdev->ib_pool.mutex);
199         /* once scheduled IB is considered free and protected by the fence */
200         ib->free = true;
201         mutex_unlock(&rdev->ib_pool.mutex);
202         radeon_ring_unlock_commit(rdev, cp);
203         return 0;
204 }
205
206 int radeon_ib_pool_init(struct radeon_device *rdev)
207 {
208         void *ptr;
209         uint64_t gpu_addr;
210         int i;
211         int r = 0;
212
213         if (rdev->ib_pool.robj)
214                 return 0;
215         INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib);
216         /* Allocate 1M object buffer */
217         r = radeon_bo_create(rdev, RADEON_IB_POOL_SIZE*64*1024,
218                              PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT,
219                              &rdev->ib_pool.robj);
220         if (r) {
221                 DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
222                 return r;
223         }
224         r = radeon_bo_reserve(rdev->ib_pool.robj, false);
225         if (unlikely(r != 0))
226                 return r;
227         r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
228         if (r) {
229                 radeon_bo_unreserve(rdev->ib_pool.robj);
230                 DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r);
231                 return r;
232         }
233         r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr);
234         radeon_bo_unreserve(rdev->ib_pool.robj);
235         if (r) {
236                 DRM_ERROR("radeon: failed to map ib pool (%d).\n", r);
237                 return r;
238         }
239         for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
240                 unsigned offset;
241
242                 offset = i * 64 * 1024;
243                 rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset;
244                 rdev->ib_pool.ibs[i].ptr = ptr + offset;
245                 rdev->ib_pool.ibs[i].idx = i;
246                 rdev->ib_pool.ibs[i].length_dw = 0;
247                 rdev->ib_pool.ibs[i].free = true;
248         }
249         rdev->ib_pool.head_id = 0;
250         rdev->ib_pool.ready = true;
251         DRM_INFO("radeon: ib pool ready.\n");
252         if (radeon_debugfs_ib_init(rdev)) {
253                 DRM_ERROR("Failed to register debugfs file for IB !\n");
254         }
255         return r;
256 }
257
258 void radeon_ib_pool_fini(struct radeon_device *rdev)
259 {
260         int r;
261         struct radeon_bo *robj;
262
263         if (!rdev->ib_pool.ready) {
264                 return;
265         }
266         mutex_lock(&rdev->ib_pool.mutex);
267         radeon_ib_bogus_cleanup(rdev);
268         robj = rdev->ib_pool.robj;
269         rdev->ib_pool.robj = NULL;
270         mutex_unlock(&rdev->ib_pool.mutex);
271
272         if (robj) {
273                 r = radeon_bo_reserve(robj, false);
274                 if (likely(r == 0)) {
275                         radeon_bo_kunmap(robj);
276                         radeon_bo_unpin(robj);
277                         radeon_bo_unreserve(robj);
278                 }
279                 radeon_bo_unref(&robj);
280         }
281 }
282
283
284 /*
285  * Ring.
286  */
287 void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp)
288 {
289         if (rdev->wb.enabled)
290                 cp->rptr = le32_to_cpu(rdev->wb.wb[cp->rptr_offs/4]);
291         else
292                 cp->rptr = RREG32(cp->rptr_reg);
293         /* This works because ring_size is a power of 2 */
294         cp->ring_free_dw = (cp->rptr + (cp->ring_size / 4));
295         cp->ring_free_dw -= cp->wptr;
296         cp->ring_free_dw &= cp->ptr_mask;
297         if (!cp->ring_free_dw) {
298                 cp->ring_free_dw = cp->ring_size / 4;
299         }
300 }
301
302
303 int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw)
304 {
305         int r;
306
307         /* Align requested size with padding so unlock_commit can
308          * pad safely */
309         ndw = (ndw + cp->align_mask) & ~cp->align_mask;
310         while (ndw > (cp->ring_free_dw - 1)) {
311                 radeon_ring_free_size(rdev, cp);
312                 if (ndw < cp->ring_free_dw) {
313                         break;
314                 }
315                 r = radeon_fence_wait_next(rdev, RADEON_RING_TYPE_GFX_INDEX);
316                 if (r)
317                         return r;
318         }
319         cp->count_dw = ndw;
320         cp->wptr_old = cp->wptr;
321         return 0;
322 }
323
324 int radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw)
325 {
326         int r;
327
328         mutex_lock(&cp->mutex);
329         r = radeon_ring_alloc(rdev, cp, ndw);
330         if (r) {
331                 mutex_unlock(&cp->mutex);
332                 return r;
333         }
334         return 0;
335 }
336
337 void radeon_ring_commit(struct radeon_device *rdev, struct radeon_cp *cp)
338 {
339         unsigned count_dw_pad;
340         unsigned i;
341
342         /* We pad to match fetch size */
343         count_dw_pad = (cp->align_mask + 1) -
344                        (cp->wptr & cp->align_mask);
345         for (i = 0; i < count_dw_pad; i++) {
346                 radeon_ring_write(cp, 2 << 30);
347         }
348         DRM_MEMORYBARRIER();
349         WREG32(cp->wptr_reg, cp->wptr);
350         (void)RREG32(cp->wptr_reg);
351 }
352
353 void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_cp *cp)
354 {
355         radeon_ring_commit(rdev, cp);
356         mutex_unlock(&cp->mutex);
357 }
358
359 void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_cp *cp)
360 {
361         cp->wptr = cp->wptr_old;
362         mutex_unlock(&cp->mutex);
363 }
364
365 int radeon_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size,
366                      unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg)
367 {
368         int r;
369
370         cp->ring_size = ring_size;
371         cp->rptr_offs = rptr_offs;
372         cp->rptr_reg = rptr_reg;
373         cp->wptr_reg = wptr_reg;
374         /* Allocate ring buffer */
375         if (cp->ring_obj == NULL) {
376                 r = radeon_bo_create(rdev, cp->ring_size, PAGE_SIZE, true,
377                                         RADEON_GEM_DOMAIN_GTT,
378                                         &cp->ring_obj);
379                 if (r) {
380                         dev_err(rdev->dev, "(%d) ring create failed\n", r);
381                         return r;
382                 }
383                 r = radeon_bo_reserve(cp->ring_obj, false);
384                 if (unlikely(r != 0))
385                         return r;
386                 r = radeon_bo_pin(cp->ring_obj, RADEON_GEM_DOMAIN_GTT,
387                                         &cp->gpu_addr);
388                 if (r) {
389                         radeon_bo_unreserve(cp->ring_obj);
390                         dev_err(rdev->dev, "(%d) ring pin failed\n", r);
391                         return r;
392                 }
393                 r = radeon_bo_kmap(cp->ring_obj,
394                                        (void **)&cp->ring);
395                 radeon_bo_unreserve(cp->ring_obj);
396                 if (r) {
397                         dev_err(rdev->dev, "(%d) ring map failed\n", r);
398                         return r;
399                 }
400         }
401         cp->ptr_mask = (cp->ring_size / 4) - 1;
402         cp->ring_free_dw = cp->ring_size / 4;
403         return 0;
404 }
405
406 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_cp *cp)
407 {
408         int r;
409         struct radeon_bo *ring_obj;
410
411         mutex_lock(&cp->mutex);
412         ring_obj = cp->ring_obj;
413         cp->ring = NULL;
414         cp->ring_obj = NULL;
415         mutex_unlock(&cp->mutex);
416
417         if (ring_obj) {
418                 r = radeon_bo_reserve(ring_obj, false);
419                 if (likely(r == 0)) {
420                         radeon_bo_kunmap(ring_obj);
421                         radeon_bo_unpin(ring_obj);
422                         radeon_bo_unreserve(ring_obj);
423                 }
424                 radeon_bo_unref(&ring_obj);
425         }
426 }
427
428 /*
429  * Debugfs info
430  */
431 #if defined(CONFIG_DEBUG_FS)
432 static int radeon_debugfs_ib_info(struct seq_file *m, void *data)
433 {
434         struct drm_info_node *node = (struct drm_info_node *) m->private;
435         struct radeon_ib *ib = node->info_ent->data;
436         unsigned i;
437
438         if (ib == NULL) {
439                 return 0;
440         }
441         seq_printf(m, "IB %04u\n", ib->idx);
442         seq_printf(m, "IB fence %p\n", ib->fence);
443         seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
444         for (i = 0; i < ib->length_dw; i++) {
445                 seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
446         }
447         return 0;
448 }
449
450 static int radeon_debugfs_ib_bogus_info(struct seq_file *m, void *data)
451 {
452         struct drm_info_node *node = (struct drm_info_node *) m->private;
453         struct radeon_device *rdev = node->info_ent->data;
454         struct radeon_ib *ib;
455         unsigned i;
456
457         mutex_lock(&rdev->ib_pool.mutex);
458         if (list_empty(&rdev->ib_pool.bogus_ib)) {
459                 mutex_unlock(&rdev->ib_pool.mutex);
460                 seq_printf(m, "no bogus IB recorded\n");
461                 return 0;
462         }
463         ib = list_first_entry(&rdev->ib_pool.bogus_ib, struct radeon_ib, list);
464         list_del_init(&ib->list);
465         mutex_unlock(&rdev->ib_pool.mutex);
466         seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
467         for (i = 0; i < ib->length_dw; i++) {
468                 seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
469         }
470         vfree(ib->ptr);
471         kfree(ib);
472         return 0;
473 }
474
475 static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
476 static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
477
478 static struct drm_info_list radeon_debugfs_ib_bogus_info_list[] = {
479         {"radeon_ib_bogus", radeon_debugfs_ib_bogus_info, 0, NULL},
480 };
481 #endif
482
483 int radeon_debugfs_ib_init(struct radeon_device *rdev)
484 {
485 #if defined(CONFIG_DEBUG_FS)
486         unsigned i;
487         int r;
488
489         radeon_debugfs_ib_bogus_info_list[0].data = rdev;
490         r = radeon_debugfs_add_files(rdev, radeon_debugfs_ib_bogus_info_list, 1);
491         if (r)
492                 return r;
493         for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
494                 sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
495                 radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i];
496                 radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info;
497                 radeon_debugfs_ib_list[i].driver_features = 0;
498                 radeon_debugfs_ib_list[i].data = &rdev->ib_pool.ibs[i];
499         }
500         return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list,
501                                         RADEON_IB_POOL_SIZE);
502 #else
503         return 0;
504 #endif
505 }