drm/nouveau/fifo: turn all fifo modules into engine modules
[deliverable/linux.git] / drivers / gpu / drm / nouveau / nv04_fifo.c
CommitLineData
6ee73861 1/*
c420b2dc 2 * Copyright (C) 2012 Ben Skeggs.
6ee73861
BS
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include "drmP.h"
28#include "drm.h"
29#include "nouveau_drv.h"
c420b2dc 30#include "nouveau_fifo.h"
5178d40d 31#include "nouveau_util.h"
c420b2dc
BS
32#include "nouveau_ramht.h"
33#include "nouveau_software.h"
34
35static struct ramfc_desc {
36 unsigned bits:6;
37 unsigned ctxs:5;
38 unsigned ctxp:8;
39 unsigned regs:5;
40 unsigned regp;
41} nv04_ramfc[] = {
42 { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
43 { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
44 { 16, 0, 0x08, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
45 { 16, 16, 0x08, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
46 { 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_STATE },
47 { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
48 { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_ENGINE },
49 { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_PULL1 },
50 {}
51};
52
53struct nv04_fifo_priv {
54 struct nouveau_fifo_priv base;
55 struct ramfc_desc *ramfc_desc;
56};
57
58struct nv04_fifo_chan {
59 struct nouveau_fifo_chan base;
60 struct nouveau_gpuobj *ramfc;
61};
6ee73861 62
588d7d12
FJ
63bool
64nv04_fifo_cache_pull(struct drm_device *dev, bool enable)
65{
9f56b126
FJ
66 int pull = nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 1, enable);
67
68 if (!enable) {
69 /* In some cases the PFIFO puller may be left in an
70 * inconsistent state if you try to stop it when it's
71 * busy translating handles. Sometimes you get a
72 * PFIFO_CACHE_ERROR, sometimes it just fails silently
73 * sending incorrect instance offsets to PGRAPH after
74 * it's started up again. To avoid the latter we
75 * invalidate the most recently calculated instance.
76 */
77 if (!nv_wait(dev, NV04_PFIFO_CACHE1_PULL0,
c420b2dc 78 NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0))
9f56b126
FJ
79 NV_ERROR(dev, "Timeout idling the PFIFO puller.\n");
80
81 if (nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0) &
c420b2dc 82 NV04_PFIFO_CACHE1_PULL0_HASH_FAILED)
9f56b126 83 nv_wr32(dev, NV03_PFIFO_INTR_0,
c420b2dc 84 NV_PFIFO_INTR_CACHE_ERROR);
588d7d12 85
588d7d12
FJ
86 nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
87 }
88
9f56b126 89 return pull & 1;
588d7d12
FJ
90}
91
c420b2dc
BS
92static int
93nv04_fifo_context_new(struct nouveau_channel *chan, int engine)
6ee73861
BS
94{
95 struct drm_device *dev = chan->dev;
96 struct drm_nouveau_private *dev_priv = dev->dev_private;
c420b2dc
BS
97 struct nv04_fifo_priv *priv = nv_engine(dev, engine);
98 struct nv04_fifo_chan *fctx;
ff9e5279 99 unsigned long flags;
6ee73861
BS
100 int ret;
101
c420b2dc
BS
102 fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
103 if (!fctx)
104 return -ENOMEM;
6ee73861 105
c420b2dc 106 /* map channel control registers */
d908175c
BS
107 chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
108 NV03_USER(chan->id), PAGE_SIZE);
c420b2dc
BS
109 if (!chan->user) {
110 ret = -ENOMEM;
111 goto error;
112 }
6ee73861 113
c420b2dc
BS
114 /* initialise default fifo context */
115 ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramfc->pinst +
116 chan->id * 32, ~0, 32,
117 NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc);
118 if (ret)
119 goto error;
120
121 nv_wo32(fctx->ramfc, 0x00, chan->pushbuf_base);
122 nv_wo32(fctx->ramfc, 0x04, chan->pushbuf_base);
123 nv_wo32(fctx->ramfc, 0x08, chan->pushbuf->pinst >> 4);
124 nv_wo32(fctx->ramfc, 0x0c, 0x00000000);
125 nv_wo32(fctx->ramfc, 0x10, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
126 NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
127#ifdef __BIG_ENDIAN
128 NV_PFIFO_CACHE1_BIG_ENDIAN |
129#endif
130 NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
131 nv_wo32(fctx->ramfc, 0x14, 0x00000000);
132 nv_wo32(fctx->ramfc, 0x18, 0x00000000);
133 nv_wo32(fctx->ramfc, 0x1c, 0x00000000);
ff9e5279 134
c420b2dc
BS
135 /* enable dma mode on the channel */
136 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
137 nv_mask(dev, NV04_PFIFO_MODE, (1 << chan->id), (1 << chan->id));
ff9e5279 138 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
c420b2dc
BS
139
140error:
141 if (ret)
142 priv->base.base.context_del(chan, engine);
143 return ret;
6ee73861
BS
144}
145
146void
c420b2dc 147nv04_fifo_context_del(struct nouveau_channel *chan, int engine)
6ee73861
BS
148{
149 struct drm_device *dev = chan->dev;
3945e475 150 struct drm_nouveau_private *dev_priv = dev->dev_private;
c420b2dc
BS
151 struct nv04_fifo_priv *priv = nv_engine(chan->dev, engine);
152 struct nv04_fifo_chan *fctx = chan->engctx[engine];
153 struct ramfc_desc *c = priv->ramfc_desc;
3945e475 154 unsigned long flags;
c420b2dc 155 int chid;
6ee73861 156
c420b2dc 157 /* prevent fifo context switches */
3945e475 158 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
67b342ef 159 nv_wr32(dev, NV03_PFIFO_CACHES, 0);
3945e475 160
c420b2dc
BS
161 /* if this channel is active, replace it with a null context */
162 chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & priv->base.channels;
163 if (chid == chan->id) {
67b342ef
BS
164 nv_mask(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0);
165 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
166 nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
c420b2dc
BS
167
168 do {
169 u32 mask = ((1ULL << c->bits) - 1) << c->regs;
170 nv_mask(dev, c->regp, mask, 0x00000000);
171 } while ((++c)->bits);
172
173 nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
174 nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
175 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, priv->base.channels);
67b342ef
BS
176 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
177 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
3945e475
FJ
178 }
179
c420b2dc 180 /* restore normal operation, after disabling dma mode */
3945e475 181 nv_mask(dev, NV04_PFIFO_MODE, 1 << chan->id, 0);
67b342ef 182 nv_wr32(dev, NV03_PFIFO_CACHES, 1);
3945e475 183 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
6ee73861 184
c420b2dc
BS
185 /* clean up */
186 nouveau_gpuobj_ref(NULL, &fctx->ramfc);
187 nouveau_gpuobj_ref(NULL, &chan->ramfc); /*XXX: nv40 */
d908175c
BS
188 if (chan->user) {
189 iounmap(chan->user);
190 chan->user = NULL;
191 }
6ee73861
BS
192}
193
194int
c420b2dc 195nv04_fifo_init(struct drm_device *dev, int engine)
6ee73861
BS
196{
197 struct drm_nouveau_private *dev_priv = dev->dev_private;
c420b2dc
BS
198 struct nv04_fifo_priv *priv = nv_engine(dev, engine);
199 int i;
6ee73861 200
c420b2dc
BS
201 nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, 0);
202 nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, NV_PMC_ENABLE_PFIFO);
6ee73861 203
c420b2dc
BS
204 nv_wr32(dev, NV04_PFIFO_DELAY_0, 0x000000ff);
205 nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
6ee73861
BS
206
207 nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
e05c5a31
BS
208 ((dev_priv->ramht->bits - 9) << 16) |
209 (dev_priv->ramht->gpuobj->pinst >> 8));
210 nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
211 nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8);
6ee73861 212
c420b2dc 213 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, priv->base.channels);
6ee73861 214
c420b2dc
BS
215 nv_wr32(dev, NV03_PFIFO_INTR_0, 0xffffffff);
216 nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xffffffff);
6ee73861 217
67b342ef
BS
218 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
219 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
220 nv_wr32(dev, NV03_PFIFO_CACHES, 1);
6ee73861 221
c420b2dc
BS
222 for (i = 0; i < priv->base.channels; i++) {
223 if (dev_priv->channels.ptr[i])
224 nv_mask(dev, NV04_PFIFO_MODE, (1 << i), (1 << i));
6ee73861
BS
225 }
226
227 return 0;
228}
229
c420b2dc
BS
230int
231nv04_fifo_fini(struct drm_device *dev, int engine, bool suspend)
5178d40d 232{
c420b2dc
BS
233 struct drm_nouveau_private *dev_priv = dev->dev_private;
234 struct nv04_fifo_priv *priv = nv_engine(dev, engine);
235 struct nouveau_channel *chan;
236 int chid;
237
238 /* prevent context switches and halt fifo operation */
239 nv_wr32(dev, NV03_PFIFO_CACHES, 0);
240 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
241 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
242 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 0);
243
244 /* store current fifo context in ramfc */
245 chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & priv->base.channels;
246 chan = dev_priv->channels.ptr[chid];
247 if (suspend && chid != priv->base.channels && chan) {
248 struct nv04_fifo_chan *fctx = chan->engctx[engine];
249 struct nouveau_gpuobj *ctx = fctx->ramfc;
250 struct ramfc_desc *c = priv->ramfc_desc;
251 do {
252 u32 rm = ((1ULL << c->bits) - 1) << c->regs;
253 u32 cm = ((1ULL << c->bits) - 1) << c->ctxs;
254 u32 rv = (nv_rd32(dev, c->regp) & rm) >> c->regs;
255 u32 cv = (nv_ro32(ctx, c->ctxp) & ~cm);
256 nv_wo32(ctx, c->ctxp, cv | (rv << c->ctxs));
257 } while ((++c)->bits);
258 }
259
260 nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0x00000000);
261 return 0;
5178d40d
BS
262}
263
264static bool
265nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data)
266{
c420b2dc 267 struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
5178d40d
BS
268 struct drm_nouveau_private *dev_priv = dev->dev_private;
269 struct nouveau_channel *chan = NULL;
270 struct nouveau_gpuobj *obj;
271 unsigned long flags;
272 const int subc = (addr >> 13) & 0x7;
273 const int mthd = addr & 0x1ffc;
274 bool handled = false;
275 u32 engine;
276
277 spin_lock_irqsave(&dev_priv->channels.lock, flags);
c420b2dc 278 if (likely(chid >= 0 && chid < pfifo->channels))
5178d40d
BS
279 chan = dev_priv->channels.ptr[chid];
280 if (unlikely(!chan))
281 goto out;
282
283 switch (mthd) {
284 case 0x0000: /* bind object to subchannel */
285 obj = nouveau_ramht_find(chan, data);
286 if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW))
287 break;
288
5178d40d
BS
289 engine = 0x0000000f << (subc * 4);
290
291 nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000);
292 handled = true;
293 break;
294 default:
295 engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE);
296 if (unlikely(((engine >> (subc * 4)) & 0xf) != 0))
297 break;
298
c420b2dc 299 if (!nouveau_gpuobj_mthd_call(chan, nouveau_software_class(dev),
5178d40d
BS
300 mthd, data))
301 handled = true;
302 break;
303 }
304
305out:
306 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
307 return handled;
308}
309
32484216
MS
310static const char *nv_dma_state_err(u32 state)
311{
312 static const char * const desc[] = {
313 "NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD", "RET_SUBR_INACTIVE",
314 "INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT", "UNK"
315 };
316 return desc[(state >> 29) & 0x7];
317}
318
5178d40d
BS
319void
320nv04_fifo_isr(struct drm_device *dev)
321{
c420b2dc 322 struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
5178d40d 323 struct drm_nouveau_private *dev_priv = dev->dev_private;
5178d40d
BS
324 uint32_t status, reassign;
325 int cnt = 0;
326
327 reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1;
328 while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
329 uint32_t chid, get;
330
331 nv_wr32(dev, NV03_PFIFO_CACHES, 0);
332
c420b2dc 333 chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & pfifo->channels;
5178d40d
BS
334 get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET);
335
336 if (status & NV_PFIFO_INTR_CACHE_ERROR) {
337 uint32_t mthd, data;
338 int ptr;
339
340 /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before
341 * wrapping on my G80 chips, but CACHE1 isn't big
342 * enough for this much data.. Tests show that it
343 * wraps around to the start at GET=0x800.. No clue
344 * as to why..
345 */
346 ptr = (get & 0x7ff) >> 2;
347
348 if (dev_priv->card_type < NV_40) {
349 mthd = nv_rd32(dev,
350 NV04_PFIFO_CACHE1_METHOD(ptr));
351 data = nv_rd32(dev,
352 NV04_PFIFO_CACHE1_DATA(ptr));
353 } else {
354 mthd = nv_rd32(dev,
355 NV40_PFIFO_CACHE1_METHOD(ptr));
356 data = nv_rd32(dev,
357 NV40_PFIFO_CACHE1_DATA(ptr));
358 }
359
360 if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) {
361 NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d "
362 "Mthd 0x%04x Data 0x%08x\n",
363 chid, (mthd >> 13) & 7, mthd & 0x1ffc,
364 data);
365 }
366
367 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
368 nv_wr32(dev, NV03_PFIFO_INTR_0,
369 NV_PFIFO_INTR_CACHE_ERROR);
370
371 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
372 nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1);
373 nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
374 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
375 nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1);
376 nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
377
378 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH,
379 nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
380 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
381
382 status &= ~NV_PFIFO_INTR_CACHE_ERROR;
383 }
384
385 if (status & NV_PFIFO_INTR_DMA_PUSHER) {
386 u32 dma_get = nv_rd32(dev, 0x003244);
387 u32 dma_put = nv_rd32(dev, 0x003240);
388 u32 push = nv_rd32(dev, 0x003220);
389 u32 state = nv_rd32(dev, 0x003228);
390
391 if (dev_priv->card_type == NV_50) {
392 u32 ho_get = nv_rd32(dev, 0x003328);
393 u32 ho_put = nv_rd32(dev, 0x003320);
394 u32 ib_get = nv_rd32(dev, 0x003334);
395 u32 ib_put = nv_rd32(dev, 0x003330);
396
397 if (nouveau_ratelimit())
398 NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
399 "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
32484216 400 "State 0x%08x (err: %s) Push 0x%08x\n",
5178d40d
BS
401 chid, ho_get, dma_get, ho_put,
402 dma_put, ib_get, ib_put, state,
32484216 403 nv_dma_state_err(state),
5178d40d
BS
404 push);
405
406 /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
407 nv_wr32(dev, 0x003364, 0x00000000);
408 if (dma_get != dma_put || ho_get != ho_put) {
409 nv_wr32(dev, 0x003244, dma_put);
410 nv_wr32(dev, 0x003328, ho_put);
411 } else
412 if (ib_get != ib_put) {
413 nv_wr32(dev, 0x003334, ib_put);
414 }
415 } else {
416 NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x "
32484216
MS
417 "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n",
418 chid, dma_get, dma_put, state,
419 nv_dma_state_err(state), push);
5178d40d
BS
420
421 if (dma_get != dma_put)
422 nv_wr32(dev, 0x003244, dma_put);
423 }
424
425 nv_wr32(dev, 0x003228, 0x00000000);
426 nv_wr32(dev, 0x003220, 0x00000001);
427 nv_wr32(dev, 0x002100, NV_PFIFO_INTR_DMA_PUSHER);
428 status &= ~NV_PFIFO_INTR_DMA_PUSHER;
429 }
430
431 if (status & NV_PFIFO_INTR_SEMAPHORE) {
432 uint32_t sem;
433
434 status &= ~NV_PFIFO_INTR_SEMAPHORE;
435 nv_wr32(dev, NV03_PFIFO_INTR_0,
436 NV_PFIFO_INTR_SEMAPHORE);
437
438 sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE);
439 nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
440
441 nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
442 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
443 }
444
445 if (dev_priv->card_type == NV_50) {
446 if (status & 0x00000010) {
6fdb383e 447 nv50_fb_vm_trap(dev, nouveau_ratelimit());
5178d40d
BS
448 status &= ~0x00000010;
449 nv_wr32(dev, 0x002100, 0x00000010);
450 }
451 }
452
453 if (status) {
454 if (nouveau_ratelimit())
455 NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
456 status, chid);
457 nv_wr32(dev, NV03_PFIFO_INTR_0, status);
458 status = 0;
459 }
460
461 nv_wr32(dev, NV03_PFIFO_CACHES, reassign);
462 }
463
464 if (status) {
465 NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt);
466 nv_wr32(dev, 0x2140, 0);
467 nv_wr32(dev, 0x140, 0);
468 }
469
470 nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);
471}
c420b2dc
BS
472
473void
474nv04_fifo_destroy(struct drm_device *dev, int engine)
475{
476 struct drm_nouveau_private *dev_priv = dev->dev_private;
477 struct nv04_fifo_priv *priv = nv_engine(dev, engine);
478
479 nouveau_irq_unregister(dev, 8);
480
481 dev_priv->eng[engine] = NULL;
482 kfree(priv);
483}
484
485int
486nv04_fifo_create(struct drm_device *dev)
487{
488 struct drm_nouveau_private *dev_priv = dev->dev_private;
489 struct nv04_fifo_priv *priv;
490
491 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
492 if (!priv)
493 return -ENOMEM;
494
495 priv->base.base.destroy = nv04_fifo_destroy;
496 priv->base.base.init = nv04_fifo_init;
497 priv->base.base.fini = nv04_fifo_fini;
498 priv->base.base.context_new = nv04_fifo_context_new;
499 priv->base.base.context_del = nv04_fifo_context_del;
500 priv->base.channels = 15;
501 priv->ramfc_desc = nv04_ramfc;
502 dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
503
504 nouveau_irq_register(dev, 8, nv04_fifo_isr);
505 return 0;
506}
This page took 0.196539 seconds and 5 git commands to generate.