drm/nouveau: Implement weak channel references.
[cascardo/linux.git] / drivers / gpu / drm / nouveau / nouveau_channel.c
1 /*
2  * Copyright 2005-2006 Stephane Marchesin
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * 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  * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "drmP.h"
26 #include "drm.h"
27 #include "nouveau_drv.h"
28 #include "nouveau_drm.h"
29 #include "nouveau_dma.h"
30
31 static int
32 nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
33 {
34         struct drm_device *dev = chan->dev;
35         struct drm_nouveau_private *dev_priv = dev->dev_private;
36         struct nouveau_bo *pb = chan->pushbuf_bo;
37         struct nouveau_gpuobj *pushbuf = NULL;
38         int ret;
39
40         if (dev_priv->card_type >= NV_50) {
41                 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
42                                              dev_priv->vm_end, NV_DMA_ACCESS_RO,
43                                              NV_DMA_TARGET_AGP, &pushbuf);
44                 chan->pushbuf_base = pb->bo.offset;
45         } else
46         if (pb->bo.mem.mem_type == TTM_PL_TT) {
47                 ret = nouveau_gpuobj_gart_dma_new(chan, 0,
48                                                   dev_priv->gart_info.aper_size,
49                                                   NV_DMA_ACCESS_RO, &pushbuf,
50                                                   NULL);
51                 chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT;
52         } else
53         if (dev_priv->card_type != NV_04) {
54                 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
55                                              dev_priv->fb_available_size,
56                                              NV_DMA_ACCESS_RO,
57                                              NV_DMA_TARGET_VIDMEM, &pushbuf);
58                 chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT;
59         } else {
60                 /* NV04 cmdbuf hack, from original ddx.. not sure of it's
61                  * exact reason for existing :)  PCI access to cmdbuf in
62                  * VRAM.
63                  */
64                 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
65                                              pci_resource_start(dev->pdev,
66                                              1),
67                                              dev_priv->fb_available_size,
68                                              NV_DMA_ACCESS_RO,
69                                              NV_DMA_TARGET_PCI, &pushbuf);
70                 chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT;
71         }
72
73         nouveau_gpuobj_ref(pushbuf, &chan->pushbuf);
74         nouveau_gpuobj_ref(NULL, &pushbuf);
75         return 0;
76 }
77
78 static struct nouveau_bo *
79 nouveau_channel_user_pushbuf_alloc(struct drm_device *dev)
80 {
81         struct nouveau_bo *pushbuf = NULL;
82         int location, ret;
83
84         if (nouveau_vram_pushbuf)
85                 location = TTM_PL_FLAG_VRAM;
86         else
87                 location = TTM_PL_FLAG_TT;
88
89         ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, false,
90                              true, &pushbuf);
91         if (ret) {
92                 NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret);
93                 return NULL;
94         }
95
96         ret = nouveau_bo_pin(pushbuf, location);
97         if (ret) {
98                 NV_ERROR(dev, "error pinning DMA push buffer: %d\n", ret);
99                 nouveau_bo_ref(NULL, &pushbuf);
100                 return NULL;
101         }
102
103         return pushbuf;
104 }
105
106 /* allocates and initializes a fifo for user space consumption */
107 int
108 nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
109                       struct drm_file *file_priv,
110                       uint32_t vram_handle, uint32_t gart_handle)
111 {
112         struct drm_nouveau_private *dev_priv = dev->dev_private;
113         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
114         struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
115         struct nouveau_channel *chan;
116         unsigned long flags;
117         int user, ret;
118
119         /* allocate and lock channel structure */
120         chan = kzalloc(sizeof(*chan), GFP_KERNEL);
121         if (!chan)
122                 return -ENOMEM;
123         chan->dev = dev;
124         chan->file_priv = file_priv;
125         chan->vram_handle = vram_handle;
126         chan->gart_handle = gart_handle;
127
128         kref_init(&chan->ref);
129         atomic_set(&chan->users, 1);
130         mutex_init(&chan->mutex);
131         mutex_lock(&chan->mutex);
132
133         /* allocate hw channel id */
134         spin_lock_irqsave(&dev_priv->channels.lock, flags);
135         for (chan->id = 0; chan->id < pfifo->channels; chan->id++) {
136                 if (!dev_priv->channels.ptr[chan->id]) {
137                         nouveau_channel_ref(chan, &dev_priv->channels.ptr[chan->id]);
138                         break;
139                 }
140         }
141         spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
142
143         if (chan->id == pfifo->channels) {
144                 mutex_unlock(&chan->mutex);
145                 kfree(chan);
146                 return -ENODEV;
147         }
148
149         NV_DEBUG(dev, "initialising channel %d\n", chan->id);
150         INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
151         INIT_LIST_HEAD(&chan->fence.pending);
152
153         /* Allocate DMA push buffer */
154         chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev);
155         if (!chan->pushbuf_bo) {
156                 ret = -ENOMEM;
157                 NV_ERROR(dev, "pushbuf %d\n", ret);
158                 nouveau_channel_put(&chan);
159                 return ret;
160         }
161
162         nouveau_dma_pre_init(chan);
163
164         /* Locate channel's user control regs */
165         if (dev_priv->card_type < NV_40)
166                 user = NV03_USER(chan->id);
167         else
168         if (dev_priv->card_type < NV_50)
169                 user = NV40_USER(chan->id);
170         else
171                 user = NV50_USER(chan->id);
172
173         chan->user = ioremap(pci_resource_start(dev->pdev, 0) + user,
174                                                                 PAGE_SIZE);
175         if (!chan->user) {
176                 NV_ERROR(dev, "ioremap of regs failed.\n");
177                 nouveau_channel_put(&chan);
178                 return -ENOMEM;
179         }
180         chan->user_put = 0x40;
181         chan->user_get = 0x44;
182
183         /* Allocate space for per-channel fixed notifier memory */
184         ret = nouveau_notifier_init_channel(chan);
185         if (ret) {
186                 NV_ERROR(dev, "ntfy %d\n", ret);
187                 nouveau_channel_put(&chan);
188                 return ret;
189         }
190
191         /* Setup channel's default objects */
192         ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle);
193         if (ret) {
194                 NV_ERROR(dev, "gpuobj %d\n", ret);
195                 nouveau_channel_put(&chan);
196                 return ret;
197         }
198
199         /* Create a dma object for the push buffer */
200         ret = nouveau_channel_pushbuf_ctxdma_init(chan);
201         if (ret) {
202                 NV_ERROR(dev, "pbctxdma %d\n", ret);
203                 nouveau_channel_put(&chan);
204                 return ret;
205         }
206
207         /* disable the fifo caches */
208         pfifo->reassign(dev, false);
209
210         /* Create a graphics context for new channel */
211         ret = pgraph->create_context(chan);
212         if (ret) {
213                 nouveau_channel_put(&chan);
214                 return ret;
215         }
216
217         /* Construct inital RAMFC for new channel */
218         ret = pfifo->create_context(chan);
219         if (ret) {
220                 nouveau_channel_put(&chan);
221                 return ret;
222         }
223
224         pfifo->reassign(dev, true);
225
226         ret = nouveau_dma_init(chan);
227         if (!ret)
228                 ret = nouveau_fence_channel_init(chan);
229         if (ret) {
230                 nouveau_channel_put(&chan);
231                 return ret;
232         }
233
234         nouveau_debugfs_channel_init(chan);
235
236         NV_DEBUG(dev, "channel %d initialised\n", chan->id);
237         *chan_ret = chan;
238         return 0;
239 }
240
241 struct nouveau_channel *
242 nouveau_channel_get_unlocked(struct nouveau_channel *ref)
243 {
244         struct nouveau_channel *chan = NULL;
245
246         if (likely(ref && atomic_inc_not_zero(&ref->users)))
247                 nouveau_channel_ref(ref, &chan);
248
249         return chan;
250 }
251
252 struct nouveau_channel *
253 nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id)
254 {
255         struct drm_nouveau_private *dev_priv = dev->dev_private;
256         struct nouveau_channel *chan;
257         unsigned long flags;
258
259         spin_lock_irqsave(&dev_priv->channels.lock, flags);
260         chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]);
261         spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
262
263         if (unlikely(!chan))
264                 return ERR_PTR(-EINVAL);
265
266         if (unlikely(file_priv && chan->file_priv != file_priv)) {
267                 nouveau_channel_put_unlocked(&chan);
268                 return ERR_PTR(-EINVAL);
269         }
270
271         mutex_lock(&chan->mutex);
272         return chan;
273 }
274
275 void
276 nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
277 {
278         struct nouveau_channel *chan = *pchan;
279         struct drm_device *dev = chan->dev;
280         struct drm_nouveau_private *dev_priv = dev->dev_private;
281         struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
282         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
283         unsigned long flags;
284         int ret;
285
286         /* decrement the refcount, and we're done if there's still refs */
287         if (likely(!atomic_dec_and_test(&chan->users))) {
288                 nouveau_channel_ref(NULL, pchan);
289                 return;
290         }
291
292         /* noone wants the channel anymore */
293         NV_DEBUG(dev, "freeing channel %d\n", chan->id);
294         nouveau_debugfs_channel_fini(chan);
295
296         /* give it chance to idle */
297         nouveau_fence_update(chan);
298         if (chan->fence.sequence != chan->fence.sequence_ack) {
299                 struct nouveau_fence *fence = NULL;
300
301                 ret = nouveau_fence_new(chan, &fence, true);
302                 if (ret == 0) {
303                         ret = nouveau_fence_wait(fence, NULL, false, false);
304                         nouveau_fence_unref((void *)&fence);
305                 }
306
307                 if (ret)
308                         NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id);
309         }
310
311         /* ensure all outstanding fences are signaled.  they should be if the
312          * above attempts at idling were OK, but if we failed this'll tell TTM
313          * we're done with the buffers.
314          */
315         nouveau_fence_channel_fini(chan);
316
317         /* boot it off the hardware */
318         pfifo->reassign(dev, false);
319
320         /* We want to give pgraph a chance to idle and get rid of all
321          * potential errors. We need to do this without the context
322          * switch lock held, otherwise the irq handler is unable to
323          * process them.
324          */
325         if (pgraph->channel(dev) == chan)
326                 nouveau_wait_for_idle(dev);
327
328         /* destroy the engine specific contexts */
329         pfifo->destroy_context(chan);
330         pgraph->destroy_context(chan);
331
332         pfifo->reassign(dev, true);
333
334         /* aside from its resources, the channel should now be dead,
335          * remove it from the channel list
336          */
337         spin_lock_irqsave(&dev_priv->channels.lock, flags);
338         nouveau_channel_ref(NULL, &dev_priv->channels.ptr[chan->id]);
339         spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
340
341         /* destroy any resources the channel owned */
342         nouveau_gpuobj_ref(NULL, &chan->pushbuf);
343         if (chan->pushbuf_bo) {
344                 nouveau_bo_unmap(chan->pushbuf_bo);
345                 nouveau_bo_unpin(chan->pushbuf_bo);
346                 nouveau_bo_ref(NULL, &chan->pushbuf_bo);
347         }
348         nouveau_gpuobj_channel_takedown(chan);
349         nouveau_notifier_takedown_channel(chan);
350
351         nouveau_channel_ref(NULL, pchan);
352 }
353
354 void
355 nouveau_channel_put(struct nouveau_channel **pchan)
356 {
357         mutex_unlock(&(*pchan)->mutex);
358         nouveau_channel_put_unlocked(pchan);
359 }
360
361 static void
362 nouveau_channel_del(struct kref *ref)
363 {
364         struct nouveau_channel *chan =
365                 container_of(ref, struct nouveau_channel, ref);
366
367         if (chan->user)
368                 iounmap(chan->user);
369
370         kfree(chan);
371 }
372
373 void
374 nouveau_channel_ref(struct nouveau_channel *chan,
375                     struct nouveau_channel **pchan)
376 {
377         if (chan)
378                 kref_get(&chan->ref);
379
380         if (*pchan)
381                 kref_put(&(*pchan)->ref, nouveau_channel_del);
382
383         *pchan = chan;
384 }
385
386 /* cleans up all the fifos from file_priv */
387 void
388 nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv)
389 {
390         struct drm_nouveau_private *dev_priv = dev->dev_private;
391         struct nouveau_engine *engine = &dev_priv->engine;
392         struct nouveau_channel *chan;
393         int i;
394
395         NV_DEBUG(dev, "clearing FIFO enables from file_priv\n");
396         for (i = 0; i < engine->fifo.channels; i++) {
397                 chan = nouveau_channel_get(dev, file_priv, i);
398                 if (IS_ERR(chan))
399                         continue;
400
401                 atomic_dec(&chan->users);
402                 nouveau_channel_put(&chan);
403         }
404 }
405
406
407 /***********************************
408  * ioctls wrapping the functions
409  ***********************************/
410
411 static int
412 nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
413                          struct drm_file *file_priv)
414 {
415         struct drm_nouveau_private *dev_priv = dev->dev_private;
416         struct drm_nouveau_channel_alloc *init = data;
417         struct nouveau_channel *chan;
418         int ret;
419
420         if (dev_priv->engine.graph.accel_blocked)
421                 return -ENODEV;
422
423         if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
424                 return -EINVAL;
425
426         ret = nouveau_channel_alloc(dev, &chan, file_priv,
427                                     init->fb_ctxdma_handle,
428                                     init->tt_ctxdma_handle);
429         if (ret)
430                 return ret;
431         init->channel  = chan->id;
432
433         if (chan->dma.ib_max)
434                 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
435                                         NOUVEAU_GEM_DOMAIN_GART;
436         else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM)
437                 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
438         else
439                 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
440
441         init->subchan[0].handle = NvM2MF;
442         if (dev_priv->card_type < NV_50)
443                 init->subchan[0].grclass = 0x0039;
444         else
445                 init->subchan[0].grclass = 0x5039;
446         init->subchan[1].handle = NvSw;
447         init->subchan[1].grclass = NV_SW;
448         init->nr_subchan = 2;
449
450         /* Named memory object area */
451         ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
452                                     &init->notifier_handle);
453
454         if (ret == 0)
455                 atomic_inc(&chan->users); /* userspace reference */
456         nouveau_channel_put(&chan);
457         return ret;
458 }
459
460 static int
461 nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
462                         struct drm_file *file_priv)
463 {
464         struct drm_nouveau_channel_free *req = data;
465         struct nouveau_channel *chan;
466
467         chan = nouveau_channel_get(dev, file_priv, req->channel);
468         if (IS_ERR(chan))
469                 return PTR_ERR(chan);
470
471         atomic_dec(&chan->users);
472         nouveau_channel_put(&chan);
473         return 0;
474 }
475
476 /***********************************
477  * finally, the ioctl table
478  ***********************************/
479
480 struct drm_ioctl_desc nouveau_ioctls[] = {
481         DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH),
482         DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
483         DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_UNLOCKED|DRM_AUTH),
484         DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_UNLOCKED|DRM_AUTH),
485         DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH),
486         DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_UNLOCKED|DRM_AUTH),
487         DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH),
488         DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH),
489         DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH),
490         DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
491         DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
492         DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH),
493 };
494
495 int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);