]> Pileus Git - ~andy/linux/blob - drivers/gpu/drm/radeon/radeon_ring.c
drm/radeon/kms: add r600 KMS support
[~andy/linux] / 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         unsigned long i;
45         int r = 0;
46
47         *ib = NULL;
48         r = radeon_fence_create(rdev, &fence);
49         if (r) {
50                 DRM_ERROR("failed to create fence for new IB\n");
51                 return r;
52         }
53         mutex_lock(&rdev->ib_pool.mutex);
54         i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
55         if (i < RADEON_IB_POOL_SIZE) {
56                 set_bit(i, rdev->ib_pool.alloc_bm);
57                 rdev->ib_pool.ibs[i].length_dw = 0;
58                 *ib = &rdev->ib_pool.ibs[i];
59                 goto out;
60         }
61         if (list_empty(&rdev->ib_pool.scheduled_ibs)) {
62                 /* we go do nothings here */
63                 DRM_ERROR("all IB allocated none scheduled.\n");
64                 r = -EINVAL;
65                 goto out;
66         }
67         /* get the first ib on the scheduled list */
68         nib = list_entry(rdev->ib_pool.scheduled_ibs.next,
69                          struct radeon_ib, list);
70         if (nib->fence == NULL) {
71                 /* we go do nothings here */
72                 DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx);
73                 r = -EINVAL;
74                 goto out;
75         }
76         r = radeon_fence_wait(nib->fence, false);
77         if (r) {
78                 DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx,
79                           (unsigned long)nib->gpu_addr, nib->length_dw);
80                 DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n");
81                 goto out;
82         }
83         radeon_fence_unref(&nib->fence);
84         nib->length_dw = 0;
85         list_del(&nib->list);
86         INIT_LIST_HEAD(&nib->list);
87         *ib = nib;
88 out:
89         mutex_unlock(&rdev->ib_pool.mutex);
90         if (r) {
91                 radeon_fence_unref(&fence);
92         } else {
93                 (*ib)->fence = fence;
94         }
95         return r;
96 }
97
98 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
99 {
100         struct radeon_ib *tmp = *ib;
101
102         *ib = NULL;
103         if (tmp == NULL) {
104                 return;
105         }
106         mutex_lock(&rdev->ib_pool.mutex);
107         if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) {
108                 /* IB is scheduled & not signaled don't do anythings */
109                 mutex_unlock(&rdev->ib_pool.mutex);
110                 return;
111         }
112         list_del(&tmp->list);
113         if (tmp->fence) {
114                 radeon_fence_unref(&tmp->fence);
115         }
116         tmp->length_dw = 0;
117         clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
118         mutex_unlock(&rdev->ib_pool.mutex);
119 }
120
121 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
122 {
123         int r = 0;
124
125         mutex_lock(&rdev->ib_pool.mutex);
126         if (!ib->length_dw || !rdev->cp.ready) {
127                 /* TODO: Nothings in the ib we should report. */
128                 mutex_unlock(&rdev->ib_pool.mutex);
129                 DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx);
130                 return -EINVAL;
131         }
132         /* 64 dwords should be enough for fence too */
133         r = radeon_ring_lock(rdev, 64);
134         if (r) {
135                 DRM_ERROR("radeon: scheduling IB failled (%d).\n", r);
136                 mutex_unlock(&rdev->ib_pool.mutex);
137                 return r;
138         }
139         radeon_ring_ib_execute(rdev, ib);
140         radeon_fence_emit(rdev, ib->fence);
141         radeon_ring_unlock_commit(rdev);
142         list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs);
143         mutex_unlock(&rdev->ib_pool.mutex);
144         return 0;
145 }
146
147 int radeon_ib_pool_init(struct radeon_device *rdev)
148 {
149         void *ptr;
150         uint64_t gpu_addr;
151         int i;
152         int r = 0;
153
154         /* Allocate 1M object buffer */
155         INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
156         r = radeon_object_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
157                                  true, RADEON_GEM_DOMAIN_GTT,
158                                  false, &rdev->ib_pool.robj);
159         if (r) {
160                 DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
161                 return r;
162         }
163         r = radeon_object_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
164         if (r) {
165                 DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r);
166                 return r;
167         }
168         r = radeon_object_kmap(rdev->ib_pool.robj, &ptr);
169         if (r) {
170                 DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
171                 return r;
172         }
173         for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
174                 unsigned offset;
175
176                 offset = i * 64 * 1024;
177                 rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset;
178                 rdev->ib_pool.ibs[i].ptr = ptr + offset;
179                 rdev->ib_pool.ibs[i].idx = i;
180                 rdev->ib_pool.ibs[i].length_dw = 0;
181                 INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list);
182         }
183         bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
184         rdev->ib_pool.ready = true;
185         DRM_INFO("radeon: ib pool ready.\n");
186         if (radeon_debugfs_ib_init(rdev)) {
187                 DRM_ERROR("Failed to register debugfs file for IB !\n");
188         }
189         return r;
190 }
191
192 void radeon_ib_pool_fini(struct radeon_device *rdev)
193 {
194         if (!rdev->ib_pool.ready) {
195                 return;
196         }
197         mutex_lock(&rdev->ib_pool.mutex);
198         bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
199         if (rdev->ib_pool.robj) {
200                 radeon_object_kunmap(rdev->ib_pool.robj);
201                 radeon_object_unref(&rdev->ib_pool.robj);
202                 rdev->ib_pool.robj = NULL;
203         }
204         mutex_unlock(&rdev->ib_pool.mutex);
205 }
206
207
208 /*
209  * Ring.
210  */
211 void radeon_ring_free_size(struct radeon_device *rdev)
212 {
213         if (rdev->family >= CHIP_R600)
214                 rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
215         else
216                 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
217         /* This works because ring_size is a power of 2 */
218         rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4));
219         rdev->cp.ring_free_dw -= rdev->cp.wptr;
220         rdev->cp.ring_free_dw &= rdev->cp.ptr_mask;
221         if (!rdev->cp.ring_free_dw) {
222                 rdev->cp.ring_free_dw = rdev->cp.ring_size / 4;
223         }
224 }
225
226 int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw)
227 {
228         int r;
229
230         /* Align requested size with padding so unlock_commit can
231          * pad safely */
232         ndw = (ndw + rdev->cp.align_mask) & ~rdev->cp.align_mask;
233         mutex_lock(&rdev->cp.mutex);
234         while (ndw > (rdev->cp.ring_free_dw - 1)) {
235                 radeon_ring_free_size(rdev);
236                 if (ndw < rdev->cp.ring_free_dw) {
237                         break;
238                 }
239                 r = radeon_fence_wait_next(rdev);
240                 if (r) {
241                         mutex_unlock(&rdev->cp.mutex);
242                         return r;
243                 }
244         }
245         rdev->cp.count_dw = ndw;
246         rdev->cp.wptr_old = rdev->cp.wptr;
247         return 0;
248 }
249
250 void radeon_ring_unlock_commit(struct radeon_device *rdev)
251 {
252         unsigned count_dw_pad;
253         unsigned i;
254
255         /* We pad to match fetch size */
256         count_dw_pad = (rdev->cp.align_mask + 1) -
257                        (rdev->cp.wptr & rdev->cp.align_mask);
258         for (i = 0; i < count_dw_pad; i++) {
259                 radeon_ring_write(rdev, 2 << 30);
260         }
261         DRM_MEMORYBARRIER();
262         radeon_cp_commit(rdev);
263         mutex_unlock(&rdev->cp.mutex);
264 }
265
266 void radeon_ring_unlock_undo(struct radeon_device *rdev)
267 {
268         rdev->cp.wptr = rdev->cp.wptr_old;
269         mutex_unlock(&rdev->cp.mutex);
270 }
271
272 int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
273 {
274         int r;
275
276         rdev->cp.ring_size = ring_size;
277         /* Allocate ring buffer */
278         if (rdev->cp.ring_obj == NULL) {
279                 r = radeon_object_create(rdev, NULL, rdev->cp.ring_size,
280                                          true,
281                                          RADEON_GEM_DOMAIN_GTT,
282                                          false,
283                                          &rdev->cp.ring_obj);
284                 if (r) {
285                         DRM_ERROR("radeon: failed to create ring buffer (%d).\n", r);
286                         mutex_unlock(&rdev->cp.mutex);
287                         return r;
288                 }
289                 r = radeon_object_pin(rdev->cp.ring_obj,
290                                       RADEON_GEM_DOMAIN_GTT,
291                                       &rdev->cp.gpu_addr);
292                 if (r) {
293                         DRM_ERROR("radeon: failed to pin ring buffer (%d).\n", r);
294                         mutex_unlock(&rdev->cp.mutex);
295                         return r;
296                 }
297                 r = radeon_object_kmap(rdev->cp.ring_obj,
298                                        (void **)&rdev->cp.ring);
299                 if (r) {
300                         DRM_ERROR("radeon: failed to map ring buffer (%d).\n", r);
301                         mutex_unlock(&rdev->cp.mutex);
302                         return r;
303                 }
304         }
305         rdev->cp.ptr_mask = (rdev->cp.ring_size / 4) - 1;
306         rdev->cp.ring_free_dw = rdev->cp.ring_size / 4;
307         return 0;
308 }
309
310 void radeon_ring_fini(struct radeon_device *rdev)
311 {
312         mutex_lock(&rdev->cp.mutex);
313         if (rdev->cp.ring_obj) {
314                 radeon_object_kunmap(rdev->cp.ring_obj);
315                 radeon_object_unpin(rdev->cp.ring_obj);
316                 radeon_object_unref(&rdev->cp.ring_obj);
317                 rdev->cp.ring = NULL;
318                 rdev->cp.ring_obj = NULL;
319         }
320         mutex_unlock(&rdev->cp.mutex);
321 }
322
323
324 /*
325  * Debugfs info
326  */
327 #if defined(CONFIG_DEBUG_FS)
328 static int radeon_debugfs_ib_info(struct seq_file *m, void *data)
329 {
330         struct drm_info_node *node = (struct drm_info_node *) m->private;
331         struct radeon_ib *ib = node->info_ent->data;
332         unsigned i;
333
334         if (ib == NULL) {
335                 return 0;
336         }
337         seq_printf(m, "IB %04lu\n", ib->idx);
338         seq_printf(m, "IB fence %p\n", ib->fence);
339         seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
340         for (i = 0; i < ib->length_dw; i++) {
341                 seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
342         }
343         return 0;
344 }
345
346 static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
347 static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
348 #endif
349
350 int radeon_debugfs_ib_init(struct radeon_device *rdev)
351 {
352 #if defined(CONFIG_DEBUG_FS)
353         unsigned i;
354
355         for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
356                 sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
357                 radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i];
358                 radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info;
359                 radeon_debugfs_ib_list[i].driver_features = 0;
360                 radeon_debugfs_ib_list[i].data = &rdev->ib_pool.ibs[i];
361         }
362         return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list,
363                                         RADEON_IB_POOL_SIZE);
364 #else
365         return 0;
366 #endif
367 }