Loading...
1/*
2 * Copyright 2007 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_drm.h"
28#include "nouveau_drv.h"
29#include "nouveau_hw.h"
30#include "nouveau_util.h"
31#include "nouveau_ramht.h"
32
33struct nv04_graph_engine {
34 struct nouveau_exec_engine base;
35};
36
37static uint32_t nv04_graph_ctx_regs[] = {
38 0x0040053c,
39 0x00400544,
40 0x00400540,
41 0x00400548,
42 NV04_PGRAPH_CTX_SWITCH1,
43 NV04_PGRAPH_CTX_SWITCH2,
44 NV04_PGRAPH_CTX_SWITCH3,
45 NV04_PGRAPH_CTX_SWITCH4,
46 NV04_PGRAPH_CTX_CACHE1,
47 NV04_PGRAPH_CTX_CACHE2,
48 NV04_PGRAPH_CTX_CACHE3,
49 NV04_PGRAPH_CTX_CACHE4,
50 0x00400184,
51 0x004001a4,
52 0x004001c4,
53 0x004001e4,
54 0x00400188,
55 0x004001a8,
56 0x004001c8,
57 0x004001e8,
58 0x0040018c,
59 0x004001ac,
60 0x004001cc,
61 0x004001ec,
62 0x00400190,
63 0x004001b0,
64 0x004001d0,
65 0x004001f0,
66 0x00400194,
67 0x004001b4,
68 0x004001d4,
69 0x004001f4,
70 0x00400198,
71 0x004001b8,
72 0x004001d8,
73 0x004001f8,
74 0x0040019c,
75 0x004001bc,
76 0x004001dc,
77 0x004001fc,
78 0x00400174,
79 NV04_PGRAPH_DMA_START_0,
80 NV04_PGRAPH_DMA_START_1,
81 NV04_PGRAPH_DMA_LENGTH,
82 NV04_PGRAPH_DMA_MISC,
83 NV04_PGRAPH_DMA_PITCH,
84 NV04_PGRAPH_BOFFSET0,
85 NV04_PGRAPH_BBASE0,
86 NV04_PGRAPH_BLIMIT0,
87 NV04_PGRAPH_BOFFSET1,
88 NV04_PGRAPH_BBASE1,
89 NV04_PGRAPH_BLIMIT1,
90 NV04_PGRAPH_BOFFSET2,
91 NV04_PGRAPH_BBASE2,
92 NV04_PGRAPH_BLIMIT2,
93 NV04_PGRAPH_BOFFSET3,
94 NV04_PGRAPH_BBASE3,
95 NV04_PGRAPH_BLIMIT3,
96 NV04_PGRAPH_BOFFSET4,
97 NV04_PGRAPH_BBASE4,
98 NV04_PGRAPH_BLIMIT4,
99 NV04_PGRAPH_BOFFSET5,
100 NV04_PGRAPH_BBASE5,
101 NV04_PGRAPH_BLIMIT5,
102 NV04_PGRAPH_BPITCH0,
103 NV04_PGRAPH_BPITCH1,
104 NV04_PGRAPH_BPITCH2,
105 NV04_PGRAPH_BPITCH3,
106 NV04_PGRAPH_BPITCH4,
107 NV04_PGRAPH_SURFACE,
108 NV04_PGRAPH_STATE,
109 NV04_PGRAPH_BSWIZZLE2,
110 NV04_PGRAPH_BSWIZZLE5,
111 NV04_PGRAPH_BPIXEL,
112 NV04_PGRAPH_NOTIFY,
113 NV04_PGRAPH_PATT_COLOR0,
114 NV04_PGRAPH_PATT_COLOR1,
115 NV04_PGRAPH_PATT_COLORRAM+0x00,
116 NV04_PGRAPH_PATT_COLORRAM+0x04,
117 NV04_PGRAPH_PATT_COLORRAM+0x08,
118 NV04_PGRAPH_PATT_COLORRAM+0x0c,
119 NV04_PGRAPH_PATT_COLORRAM+0x10,
120 NV04_PGRAPH_PATT_COLORRAM+0x14,
121 NV04_PGRAPH_PATT_COLORRAM+0x18,
122 NV04_PGRAPH_PATT_COLORRAM+0x1c,
123 NV04_PGRAPH_PATT_COLORRAM+0x20,
124 NV04_PGRAPH_PATT_COLORRAM+0x24,
125 NV04_PGRAPH_PATT_COLORRAM+0x28,
126 NV04_PGRAPH_PATT_COLORRAM+0x2c,
127 NV04_PGRAPH_PATT_COLORRAM+0x30,
128 NV04_PGRAPH_PATT_COLORRAM+0x34,
129 NV04_PGRAPH_PATT_COLORRAM+0x38,
130 NV04_PGRAPH_PATT_COLORRAM+0x3c,
131 NV04_PGRAPH_PATT_COLORRAM+0x40,
132 NV04_PGRAPH_PATT_COLORRAM+0x44,
133 NV04_PGRAPH_PATT_COLORRAM+0x48,
134 NV04_PGRAPH_PATT_COLORRAM+0x4c,
135 NV04_PGRAPH_PATT_COLORRAM+0x50,
136 NV04_PGRAPH_PATT_COLORRAM+0x54,
137 NV04_PGRAPH_PATT_COLORRAM+0x58,
138 NV04_PGRAPH_PATT_COLORRAM+0x5c,
139 NV04_PGRAPH_PATT_COLORRAM+0x60,
140 NV04_PGRAPH_PATT_COLORRAM+0x64,
141 NV04_PGRAPH_PATT_COLORRAM+0x68,
142 NV04_PGRAPH_PATT_COLORRAM+0x6c,
143 NV04_PGRAPH_PATT_COLORRAM+0x70,
144 NV04_PGRAPH_PATT_COLORRAM+0x74,
145 NV04_PGRAPH_PATT_COLORRAM+0x78,
146 NV04_PGRAPH_PATT_COLORRAM+0x7c,
147 NV04_PGRAPH_PATT_COLORRAM+0x80,
148 NV04_PGRAPH_PATT_COLORRAM+0x84,
149 NV04_PGRAPH_PATT_COLORRAM+0x88,
150 NV04_PGRAPH_PATT_COLORRAM+0x8c,
151 NV04_PGRAPH_PATT_COLORRAM+0x90,
152 NV04_PGRAPH_PATT_COLORRAM+0x94,
153 NV04_PGRAPH_PATT_COLORRAM+0x98,
154 NV04_PGRAPH_PATT_COLORRAM+0x9c,
155 NV04_PGRAPH_PATT_COLORRAM+0xa0,
156 NV04_PGRAPH_PATT_COLORRAM+0xa4,
157 NV04_PGRAPH_PATT_COLORRAM+0xa8,
158 NV04_PGRAPH_PATT_COLORRAM+0xac,
159 NV04_PGRAPH_PATT_COLORRAM+0xb0,
160 NV04_PGRAPH_PATT_COLORRAM+0xb4,
161 NV04_PGRAPH_PATT_COLORRAM+0xb8,
162 NV04_PGRAPH_PATT_COLORRAM+0xbc,
163 NV04_PGRAPH_PATT_COLORRAM+0xc0,
164 NV04_PGRAPH_PATT_COLORRAM+0xc4,
165 NV04_PGRAPH_PATT_COLORRAM+0xc8,
166 NV04_PGRAPH_PATT_COLORRAM+0xcc,
167 NV04_PGRAPH_PATT_COLORRAM+0xd0,
168 NV04_PGRAPH_PATT_COLORRAM+0xd4,
169 NV04_PGRAPH_PATT_COLORRAM+0xd8,
170 NV04_PGRAPH_PATT_COLORRAM+0xdc,
171 NV04_PGRAPH_PATT_COLORRAM+0xe0,
172 NV04_PGRAPH_PATT_COLORRAM+0xe4,
173 NV04_PGRAPH_PATT_COLORRAM+0xe8,
174 NV04_PGRAPH_PATT_COLORRAM+0xec,
175 NV04_PGRAPH_PATT_COLORRAM+0xf0,
176 NV04_PGRAPH_PATT_COLORRAM+0xf4,
177 NV04_PGRAPH_PATT_COLORRAM+0xf8,
178 NV04_PGRAPH_PATT_COLORRAM+0xfc,
179 NV04_PGRAPH_PATTERN,
180 0x0040080c,
181 NV04_PGRAPH_PATTERN_SHAPE,
182 0x00400600,
183 NV04_PGRAPH_ROP3,
184 NV04_PGRAPH_CHROMA,
185 NV04_PGRAPH_BETA_AND,
186 NV04_PGRAPH_BETA_PREMULT,
187 NV04_PGRAPH_CONTROL0,
188 NV04_PGRAPH_CONTROL1,
189 NV04_PGRAPH_CONTROL2,
190 NV04_PGRAPH_BLEND,
191 NV04_PGRAPH_STORED_FMT,
192 NV04_PGRAPH_SOURCE_COLOR,
193 0x00400560,
194 0x00400568,
195 0x00400564,
196 0x0040056c,
197 0x00400400,
198 0x00400480,
199 0x00400404,
200 0x00400484,
201 0x00400408,
202 0x00400488,
203 0x0040040c,
204 0x0040048c,
205 0x00400410,
206 0x00400490,
207 0x00400414,
208 0x00400494,
209 0x00400418,
210 0x00400498,
211 0x0040041c,
212 0x0040049c,
213 0x00400420,
214 0x004004a0,
215 0x00400424,
216 0x004004a4,
217 0x00400428,
218 0x004004a8,
219 0x0040042c,
220 0x004004ac,
221 0x00400430,
222 0x004004b0,
223 0x00400434,
224 0x004004b4,
225 0x00400438,
226 0x004004b8,
227 0x0040043c,
228 0x004004bc,
229 0x00400440,
230 0x004004c0,
231 0x00400444,
232 0x004004c4,
233 0x00400448,
234 0x004004c8,
235 0x0040044c,
236 0x004004cc,
237 0x00400450,
238 0x004004d0,
239 0x00400454,
240 0x004004d4,
241 0x00400458,
242 0x004004d8,
243 0x0040045c,
244 0x004004dc,
245 0x00400460,
246 0x004004e0,
247 0x00400464,
248 0x004004e4,
249 0x00400468,
250 0x004004e8,
251 0x0040046c,
252 0x004004ec,
253 0x00400470,
254 0x004004f0,
255 0x00400474,
256 0x004004f4,
257 0x00400478,
258 0x004004f8,
259 0x0040047c,
260 0x004004fc,
261 0x00400534,
262 0x00400538,
263 0x00400514,
264 0x00400518,
265 0x0040051c,
266 0x00400520,
267 0x00400524,
268 0x00400528,
269 0x0040052c,
270 0x00400530,
271 0x00400d00,
272 0x00400d40,
273 0x00400d80,
274 0x00400d04,
275 0x00400d44,
276 0x00400d84,
277 0x00400d08,
278 0x00400d48,
279 0x00400d88,
280 0x00400d0c,
281 0x00400d4c,
282 0x00400d8c,
283 0x00400d10,
284 0x00400d50,
285 0x00400d90,
286 0x00400d14,
287 0x00400d54,
288 0x00400d94,
289 0x00400d18,
290 0x00400d58,
291 0x00400d98,
292 0x00400d1c,
293 0x00400d5c,
294 0x00400d9c,
295 0x00400d20,
296 0x00400d60,
297 0x00400da0,
298 0x00400d24,
299 0x00400d64,
300 0x00400da4,
301 0x00400d28,
302 0x00400d68,
303 0x00400da8,
304 0x00400d2c,
305 0x00400d6c,
306 0x00400dac,
307 0x00400d30,
308 0x00400d70,
309 0x00400db0,
310 0x00400d34,
311 0x00400d74,
312 0x00400db4,
313 0x00400d38,
314 0x00400d78,
315 0x00400db8,
316 0x00400d3c,
317 0x00400d7c,
318 0x00400dbc,
319 0x00400590,
320 0x00400594,
321 0x00400598,
322 0x0040059c,
323 0x004005a8,
324 0x004005ac,
325 0x004005b0,
326 0x004005b4,
327 0x004005c0,
328 0x004005c4,
329 0x004005c8,
330 0x004005cc,
331 0x004005d0,
332 0x004005d4,
333 0x004005d8,
334 0x004005dc,
335 0x004005e0,
336 NV04_PGRAPH_PASSTHRU_0,
337 NV04_PGRAPH_PASSTHRU_1,
338 NV04_PGRAPH_PASSTHRU_2,
339 NV04_PGRAPH_DVD_COLORFMT,
340 NV04_PGRAPH_SCALED_FORMAT,
341 NV04_PGRAPH_MISC24_0,
342 NV04_PGRAPH_MISC24_1,
343 NV04_PGRAPH_MISC24_2,
344 0x00400500,
345 0x00400504,
346 NV04_PGRAPH_VALID1,
347 NV04_PGRAPH_VALID2,
348 NV04_PGRAPH_DEBUG_3
349};
350
351struct graph_state {
352 uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
353};
354
355static struct nouveau_channel *
356nv04_graph_channel(struct drm_device *dev)
357{
358 struct drm_nouveau_private *dev_priv = dev->dev_private;
359 int chid = dev_priv->engine.fifo.channels;
360
361 if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
362 chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
363
364 if (chid >= dev_priv->engine.fifo.channels)
365 return NULL;
366
367 return dev_priv->channels.ptr[chid];
368}
369
370static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg)
371{
372 int i;
373
374 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
375 if (nv04_graph_ctx_regs[i] == reg)
376 return &ctx->nv04[i];
377 }
378
379 return NULL;
380}
381
382static int
383nv04_graph_load_context(struct nouveau_channel *chan)
384{
385 struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
386 struct drm_device *dev = chan->dev;
387 uint32_t tmp;
388 int i;
389
390 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
391 nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
392
393 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
394
395 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
396 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24);
397
398 tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
399 nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
400
401 return 0;
402}
403
404static int
405nv04_graph_unload_context(struct drm_device *dev)
406{
407 struct drm_nouveau_private *dev_priv = dev->dev_private;
408 struct nouveau_channel *chan = NULL;
409 struct graph_state *ctx;
410 uint32_t tmp;
411 int i;
412
413 chan = nv04_graph_channel(dev);
414 if (!chan)
415 return 0;
416 ctx = chan->engctx[NVOBJ_ENGINE_GR];
417
418 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
419 ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
420
421 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
422 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
423 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
424 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
425 return 0;
426}
427
428static int
429nv04_graph_context_new(struct nouveau_channel *chan, int engine)
430{
431 struct graph_state *pgraph_ctx;
432 NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
433
434 pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL);
435 if (pgraph_ctx == NULL)
436 return -ENOMEM;
437
438 *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
439
440 chan->engctx[engine] = pgraph_ctx;
441 return 0;
442}
443
444static void
445nv04_graph_context_del(struct nouveau_channel *chan, int engine)
446{
447 struct drm_device *dev = chan->dev;
448 struct drm_nouveau_private *dev_priv = dev->dev_private;
449 struct graph_state *pgraph_ctx = chan->engctx[engine];
450 unsigned long flags;
451
452 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
453 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
454
455 /* Unload the context if it's the currently active one */
456 if (nv04_graph_channel(dev) == chan)
457 nv04_graph_unload_context(dev);
458
459 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
460 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
461
462 /* Free the context resources */
463 kfree(pgraph_ctx);
464 chan->engctx[engine] = NULL;
465}
466
467int
468nv04_graph_object_new(struct nouveau_channel *chan, int engine,
469 u32 handle, u16 class)
470{
471 struct drm_device *dev = chan->dev;
472 struct nouveau_gpuobj *obj = NULL;
473 int ret;
474
475 ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
476 if (ret)
477 return ret;
478 obj->engine = 1;
479 obj->class = class;
480
481#ifdef __BIG_ENDIAN
482 nv_wo32(obj, 0x00, 0x00080000 | class);
483#else
484 nv_wo32(obj, 0x00, class);
485#endif
486 nv_wo32(obj, 0x04, 0x00000000);
487 nv_wo32(obj, 0x08, 0x00000000);
488 nv_wo32(obj, 0x0c, 0x00000000);
489
490 ret = nouveau_ramht_insert(chan, handle, obj);
491 nouveau_gpuobj_ref(NULL, &obj);
492 return ret;
493}
494
495static int
496nv04_graph_init(struct drm_device *dev, int engine)
497{
498 struct drm_nouveau_private *dev_priv = dev->dev_private;
499 uint32_t tmp;
500
501 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
502 ~NV_PMC_ENABLE_PGRAPH);
503 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
504 NV_PMC_ENABLE_PGRAPH);
505
506 /* Enable PGRAPH interrupts */
507 nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
508 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
509
510 nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
511 nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
512 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
513 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
514 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
515 /*1231C000 blob, 001 haiku*/
516 /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
517 nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
518 /*0x72111100 blob , 01 haiku*/
519 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
520 nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
521 /*haiku same*/
522
523 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
524 nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
525 /*haiku and blob 10d4*/
526
527 nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF);
528 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
529 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
530 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
531 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
532
533 /* These don't belong here, they're part of a per-channel context */
534 nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
535 nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
536
537 return 0;
538}
539
540static int
541nv04_graph_fini(struct drm_device *dev, int engine, bool suspend)
542{
543 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
544 if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
545 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
546 return -EBUSY;
547 }
548 nv04_graph_unload_context(dev);
549 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
550 return 0;
551}
552
553static int
554nv04_graph_mthd_set_ref(struct nouveau_channel *chan,
555 u32 class, u32 mthd, u32 data)
556{
557 atomic_set(&chan->fence.last_sequence_irq, data);
558 return 0;
559}
560
561int
562nv04_graph_mthd_page_flip(struct nouveau_channel *chan,
563 u32 class, u32 mthd, u32 data)
564{
565 struct drm_device *dev = chan->dev;
566 struct nouveau_page_flip_state s;
567
568 if (!nouveau_finish_page_flip(chan, &s))
569 nv_set_crtc_base(dev, s.crtc,
570 s.offset + s.y * s.pitch + s.x * s.bpp / 8);
571
572 return 0;
573}
574
575/*
576 * Software methods, why they are needed, and how they all work:
577 *
578 * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
579 * 2d engine settings are kept inside the grobjs themselves. The grobjs are
580 * 3 words long on both. grobj format on NV04 is:
581 *
582 * word 0:
583 * - bits 0-7: class
584 * - bit 12: color key active
585 * - bit 13: clip rect active
586 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
587 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
588 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
589 * NV03_CONTEXT_SURFACE_DST].
590 * - bits 15-17: 2d operation [aka patch config]
591 * - bit 24: patch valid [enables rendering using this object]
592 * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
593 * word 1:
594 * - bits 0-1: mono format
595 * - bits 8-13: color format
596 * - bits 16-31: DMA_NOTIFY instance
597 * word 2:
598 * - bits 0-15: DMA_A instance
599 * - bits 16-31: DMA_B instance
600 *
601 * On NV05 it's:
602 *
603 * word 0:
604 * - bits 0-7: class
605 * - bit 12: color key active
606 * - bit 13: clip rect active
607 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
608 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
609 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
610 * NV03_CONTEXT_SURFACE_DST].
611 * - bits 15-17: 2d operation [aka patch config]
612 * - bits 20-22: dither mode
613 * - bit 24: patch valid [enables rendering using this object]
614 * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
615 * - bit 26: surface_src/surface_zeta valid
616 * - bit 27: pattern valid
617 * - bit 28: rop valid
618 * - bit 29: beta1 valid
619 * - bit 30: beta4 valid
620 * word 1:
621 * - bits 0-1: mono format
622 * - bits 8-13: color format
623 * - bits 16-31: DMA_NOTIFY instance
624 * word 2:
625 * - bits 0-15: DMA_A instance
626 * - bits 16-31: DMA_B instance
627 *
628 * NV05 will set/unset the relevant valid bits when you poke the relevant
629 * object-binding methods with object of the proper type, or with the NULL
630 * type. It'll only allow rendering using the grobj if all needed objects
631 * are bound. The needed set of objects depends on selected operation: for
632 * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
633 *
634 * NV04 doesn't have these methods implemented at all, and doesn't have the
635 * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
636 * is set. So we have to emulate them in software, internally keeping the
637 * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
638 * but the last word isn't actually used for anything, we abuse it for this
639 * purpose.
640 *
641 * Actually, NV05 can optionally check bit 24 too, but we disable this since
642 * there's no use for it.
643 *
644 * For unknown reasons, NV04 implements surf3d binding in hardware as an
645 * exception. Also for unknown reasons, NV04 doesn't implement the clipping
646 * methods on the surf3d object, so we have to emulate them too.
647 */
648
649static void
650nv04_graph_set_ctx1(struct nouveau_channel *chan, u32 mask, u32 value)
651{
652 struct drm_device *dev = chan->dev;
653 u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
654 int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
655 u32 tmp;
656
657 tmp = nv_ri32(dev, instance);
658 tmp &= ~mask;
659 tmp |= value;
660
661 nv_wi32(dev, instance, tmp);
662 nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
663 nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
664}
665
666static void
667nv04_graph_set_ctx_val(struct nouveau_channel *chan, u32 mask, u32 value)
668{
669 struct drm_device *dev = chan->dev;
670 u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
671 u32 tmp, ctx1;
672 int class, op, valid = 1;
673
674 ctx1 = nv_ri32(dev, instance);
675 class = ctx1 & 0xff;
676 op = (ctx1 >> 15) & 7;
677 tmp = nv_ri32(dev, instance + 0xc);
678 tmp &= ~mask;
679 tmp |= value;
680 nv_wi32(dev, instance + 0xc, tmp);
681
682 /* check for valid surf2d/surf_dst/surf_color */
683 if (!(tmp & 0x02000000))
684 valid = 0;
685 /* check for valid surf_src/surf_zeta */
686 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
687 valid = 0;
688
689 switch (op) {
690 /* SRCCOPY_AND, SRCCOPY: no extra objects required */
691 case 0:
692 case 3:
693 break;
694 /* ROP_AND: requires pattern and rop */
695 case 1:
696 if (!(tmp & 0x18000000))
697 valid = 0;
698 break;
699 /* BLEND_AND: requires beta1 */
700 case 2:
701 if (!(tmp & 0x20000000))
702 valid = 0;
703 break;
704 /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
705 case 4:
706 case 5:
707 if (!(tmp & 0x40000000))
708 valid = 0;
709 break;
710 }
711
712 nv04_graph_set_ctx1(chan, 0x01000000, valid << 24);
713}
714
715static int
716nv04_graph_mthd_set_operation(struct nouveau_channel *chan,
717 u32 class, u32 mthd, u32 data)
718{
719 if (data > 5)
720 return 1;
721 /* Old versions of the objects only accept first three operations. */
722 if (data > 2 && class < 0x40)
723 return 1;
724 nv04_graph_set_ctx1(chan, 0x00038000, data << 15);
725 /* changing operation changes set of objects needed for validation */
726 nv04_graph_set_ctx_val(chan, 0, 0);
727 return 0;
728}
729
730static int
731nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan,
732 u32 class, u32 mthd, u32 data)
733{
734 uint32_t min = data & 0xffff, max;
735 uint32_t w = data >> 16;
736 if (min & 0x8000)
737 /* too large */
738 return 1;
739 if (w & 0x8000)
740 /* yes, it accepts negative for some reason. */
741 w |= 0xffff0000;
742 max = min + w;
743 max &= 0x3ffff;
744 nv_wr32(chan->dev, 0x40053c, min);
745 nv_wr32(chan->dev, 0x400544, max);
746 return 0;
747}
748
749static int
750nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan,
751 u32 class, u32 mthd, u32 data)
752{
753 uint32_t min = data & 0xffff, max;
754 uint32_t w = data >> 16;
755 if (min & 0x8000)
756 /* too large */
757 return 1;
758 if (w & 0x8000)
759 /* yes, it accepts negative for some reason. */
760 w |= 0xffff0000;
761 max = min + w;
762 max &= 0x3ffff;
763 nv_wr32(chan->dev, 0x400540, min);
764 nv_wr32(chan->dev, 0x400548, max);
765 return 0;
766}
767
768static int
769nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan,
770 u32 class, u32 mthd, u32 data)
771{
772 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
773 case 0x30:
774 nv04_graph_set_ctx1(chan, 0x00004000, 0);
775 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
776 return 0;
777 case 0x42:
778 nv04_graph_set_ctx1(chan, 0x00004000, 0);
779 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
780 return 0;
781 }
782 return 1;
783}
784
785static int
786nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan,
787 u32 class, u32 mthd, u32 data)
788{
789 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
790 case 0x30:
791 nv04_graph_set_ctx1(chan, 0x00004000, 0);
792 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
793 return 0;
794 case 0x42:
795 nv04_graph_set_ctx1(chan, 0x00004000, 0);
796 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
797 return 0;
798 case 0x52:
799 nv04_graph_set_ctx1(chan, 0x00004000, 0x00004000);
800 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
801 return 0;
802 }
803 return 1;
804}
805
806static int
807nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan,
808 u32 class, u32 mthd, u32 data)
809{
810 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
811 case 0x30:
812 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
813 return 0;
814 case 0x18:
815 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
816 return 0;
817 }
818 return 1;
819}
820
821static int
822nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan,
823 u32 class, u32 mthd, u32 data)
824{
825 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
826 case 0x30:
827 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
828 return 0;
829 case 0x44:
830 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
831 return 0;
832 }
833 return 1;
834}
835
836static int
837nv04_graph_mthd_bind_rop(struct nouveau_channel *chan,
838 u32 class, u32 mthd, u32 data)
839{
840 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
841 case 0x30:
842 nv04_graph_set_ctx_val(chan, 0x10000000, 0);
843 return 0;
844 case 0x43:
845 nv04_graph_set_ctx_val(chan, 0x10000000, 0x10000000);
846 return 0;
847 }
848 return 1;
849}
850
851static int
852nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan,
853 u32 class, u32 mthd, u32 data)
854{
855 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
856 case 0x30:
857 nv04_graph_set_ctx_val(chan, 0x20000000, 0);
858 return 0;
859 case 0x12:
860 nv04_graph_set_ctx_val(chan, 0x20000000, 0x20000000);
861 return 0;
862 }
863 return 1;
864}
865
866static int
867nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan,
868 u32 class, u32 mthd, u32 data)
869{
870 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
871 case 0x30:
872 nv04_graph_set_ctx_val(chan, 0x40000000, 0);
873 return 0;
874 case 0x72:
875 nv04_graph_set_ctx_val(chan, 0x40000000, 0x40000000);
876 return 0;
877 }
878 return 1;
879}
880
881static int
882nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan,
883 u32 class, u32 mthd, u32 data)
884{
885 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
886 case 0x30:
887 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
888 return 0;
889 case 0x58:
890 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
891 return 0;
892 }
893 return 1;
894}
895
896static int
897nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan,
898 u32 class, u32 mthd, u32 data)
899{
900 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
901 case 0x30:
902 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
903 return 0;
904 case 0x59:
905 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
906 return 0;
907 }
908 return 1;
909}
910
911static int
912nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan,
913 u32 class, u32 mthd, u32 data)
914{
915 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
916 case 0x30:
917 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
918 return 0;
919 case 0x5a:
920 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
921 return 0;
922 }
923 return 1;
924}
925
926static int
927nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan,
928 u32 class, u32 mthd, u32 data)
929{
930 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
931 case 0x30:
932 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
933 return 0;
934 case 0x5b:
935 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
936 return 0;
937 }
938 return 1;
939}
940
941static int
942nv04_graph_mthd_bind_clip(struct nouveau_channel *chan,
943 u32 class, u32 mthd, u32 data)
944{
945 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
946 case 0x30:
947 nv04_graph_set_ctx1(chan, 0x2000, 0);
948 return 0;
949 case 0x19:
950 nv04_graph_set_ctx1(chan, 0x2000, 0x2000);
951 return 0;
952 }
953 return 1;
954}
955
956static int
957nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan,
958 u32 class, u32 mthd, u32 data)
959{
960 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
961 case 0x30:
962 nv04_graph_set_ctx1(chan, 0x1000, 0);
963 return 0;
964 /* Yes, for some reason even the old versions of objects
965 * accept 0x57 and not 0x17. Consistency be damned.
966 */
967 case 0x57:
968 nv04_graph_set_ctx1(chan, 0x1000, 0x1000);
969 return 0;
970 }
971 return 1;
972}
973
974static struct nouveau_bitfield nv04_graph_intr[] = {
975 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
976 {}
977};
978
979static struct nouveau_bitfield nv04_graph_nstatus[] = {
980 { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
981 { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
982 { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
983 { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
984 {}
985};
986
987struct nouveau_bitfield nv04_graph_nsource[] = {
988 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
989 { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
990 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
991 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
992 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
993 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
994 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
995 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
996 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
997 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
998 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
999 { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
1000 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
1001 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
1002 { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
1003 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
1004 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
1005 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
1006 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
1007 {}
1008};
1009
1010static void
1011nv04_graph_context_switch(struct drm_device *dev)
1012{
1013 struct drm_nouveau_private *dev_priv = dev->dev_private;
1014 struct nouveau_channel *chan = NULL;
1015 int chid;
1016
1017 nouveau_wait_for_idle(dev);
1018
1019 /* If previous context is valid, we need to save it */
1020 nv04_graph_unload_context(dev);
1021
1022 /* Load context for next channel */
1023 chid = dev_priv->engine.fifo.channel_id(dev);
1024 chan = dev_priv->channels.ptr[chid];
1025 if (chan)
1026 nv04_graph_load_context(chan);
1027}
1028
1029static void
1030nv04_graph_isr(struct drm_device *dev)
1031{
1032 u32 stat;
1033
1034 while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
1035 u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
1036 u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
1037 u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
1038 u32 chid = (addr & 0x0f000000) >> 24;
1039 u32 subc = (addr & 0x0000e000) >> 13;
1040 u32 mthd = (addr & 0x00001ffc);
1041 u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
1042 u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
1043 u32 show = stat;
1044
1045 if (stat & NV_PGRAPH_INTR_NOTIFY) {
1046 if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
1047 if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
1048 show &= ~NV_PGRAPH_INTR_NOTIFY;
1049 }
1050 }
1051
1052 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1053 nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1054 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1055 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1056 nv04_graph_context_switch(dev);
1057 }
1058
1059 nv_wr32(dev, NV03_PGRAPH_INTR, stat);
1060 nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
1061
1062 if (show && nouveau_ratelimit()) {
1063 NV_INFO(dev, "PGRAPH -");
1064 nouveau_bitfield_print(nv04_graph_intr, show);
1065 printk(" nsource:");
1066 nouveau_bitfield_print(nv04_graph_nsource, nsource);
1067 printk(" nstatus:");
1068 nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
1069 printk("\n");
1070 NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
1071 "mthd 0x%04x data 0x%08x\n",
1072 chid, subc, class, mthd, data);
1073 }
1074 }
1075}
1076
1077static void
1078nv04_graph_destroy(struct drm_device *dev, int engine)
1079{
1080 struct nv04_graph_engine *pgraph = nv_engine(dev, engine);
1081
1082 nouveau_irq_unregister(dev, 12);
1083
1084 NVOBJ_ENGINE_DEL(dev, GR);
1085 kfree(pgraph);
1086}
1087
1088int
1089nv04_graph_create(struct drm_device *dev)
1090{
1091 struct nv04_graph_engine *pgraph;
1092
1093 pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
1094 if (!pgraph)
1095 return -ENOMEM;
1096
1097 pgraph->base.destroy = nv04_graph_destroy;
1098 pgraph->base.init = nv04_graph_init;
1099 pgraph->base.fini = nv04_graph_fini;
1100 pgraph->base.context_new = nv04_graph_context_new;
1101 pgraph->base.context_del = nv04_graph_context_del;
1102 pgraph->base.object_new = nv04_graph_object_new;
1103
1104 NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
1105 nouveau_irq_register(dev, 12, nv04_graph_isr);
1106
1107 /* dvd subpicture */
1108 NVOBJ_CLASS(dev, 0x0038, GR);
1109
1110 /* m2mf */
1111 NVOBJ_CLASS(dev, 0x0039, GR);
1112
1113 /* nv03 gdirect */
1114 NVOBJ_CLASS(dev, 0x004b, GR);
1115 NVOBJ_MTHD (dev, 0x004b, 0x0184, nv04_graph_mthd_bind_nv01_patt);
1116 NVOBJ_MTHD (dev, 0x004b, 0x0188, nv04_graph_mthd_bind_rop);
1117 NVOBJ_MTHD (dev, 0x004b, 0x018c, nv04_graph_mthd_bind_beta1);
1118 NVOBJ_MTHD (dev, 0x004b, 0x0190, nv04_graph_mthd_bind_surf_dst);
1119 NVOBJ_MTHD (dev, 0x004b, 0x02fc, nv04_graph_mthd_set_operation);
1120
1121 /* nv04 gdirect */
1122 NVOBJ_CLASS(dev, 0x004a, GR);
1123 NVOBJ_MTHD (dev, 0x004a, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1124 NVOBJ_MTHD (dev, 0x004a, 0x018c, nv04_graph_mthd_bind_rop);
1125 NVOBJ_MTHD (dev, 0x004a, 0x0190, nv04_graph_mthd_bind_beta1);
1126 NVOBJ_MTHD (dev, 0x004a, 0x0194, nv04_graph_mthd_bind_beta4);
1127 NVOBJ_MTHD (dev, 0x004a, 0x0198, nv04_graph_mthd_bind_surf2d);
1128 NVOBJ_MTHD (dev, 0x004a, 0x02fc, nv04_graph_mthd_set_operation);
1129
1130 /* nv01 imageblit */
1131 NVOBJ_CLASS(dev, 0x001f, GR);
1132 NVOBJ_MTHD (dev, 0x001f, 0x0184, nv04_graph_mthd_bind_chroma);
1133 NVOBJ_MTHD (dev, 0x001f, 0x0188, nv04_graph_mthd_bind_clip);
1134 NVOBJ_MTHD (dev, 0x001f, 0x018c, nv04_graph_mthd_bind_nv01_patt);
1135 NVOBJ_MTHD (dev, 0x001f, 0x0190, nv04_graph_mthd_bind_rop);
1136 NVOBJ_MTHD (dev, 0x001f, 0x0194, nv04_graph_mthd_bind_beta1);
1137 NVOBJ_MTHD (dev, 0x001f, 0x0198, nv04_graph_mthd_bind_surf_dst);
1138 NVOBJ_MTHD (dev, 0x001f, 0x019c, nv04_graph_mthd_bind_surf_src);
1139 NVOBJ_MTHD (dev, 0x001f, 0x02fc, nv04_graph_mthd_set_operation);
1140
1141 /* nv04 imageblit */
1142 NVOBJ_CLASS(dev, 0x005f, GR);
1143 NVOBJ_MTHD (dev, 0x005f, 0x0184, nv04_graph_mthd_bind_chroma);
1144 NVOBJ_MTHD (dev, 0x005f, 0x0188, nv04_graph_mthd_bind_clip);
1145 NVOBJ_MTHD (dev, 0x005f, 0x018c, nv04_graph_mthd_bind_nv04_patt);
1146 NVOBJ_MTHD (dev, 0x005f, 0x0190, nv04_graph_mthd_bind_rop);
1147 NVOBJ_MTHD (dev, 0x005f, 0x0194, nv04_graph_mthd_bind_beta1);
1148 NVOBJ_MTHD (dev, 0x005f, 0x0198, nv04_graph_mthd_bind_beta4);
1149 NVOBJ_MTHD (dev, 0x005f, 0x019c, nv04_graph_mthd_bind_surf2d);
1150 NVOBJ_MTHD (dev, 0x005f, 0x02fc, nv04_graph_mthd_set_operation);
1151
1152 /* nv04 iifc */
1153 NVOBJ_CLASS(dev, 0x0060, GR);
1154 NVOBJ_MTHD (dev, 0x0060, 0x0188, nv04_graph_mthd_bind_chroma);
1155 NVOBJ_MTHD (dev, 0x0060, 0x018c, nv04_graph_mthd_bind_clip);
1156 NVOBJ_MTHD (dev, 0x0060, 0x0190, nv04_graph_mthd_bind_nv04_patt);
1157 NVOBJ_MTHD (dev, 0x0060, 0x0194, nv04_graph_mthd_bind_rop);
1158 NVOBJ_MTHD (dev, 0x0060, 0x0198, nv04_graph_mthd_bind_beta1);
1159 NVOBJ_MTHD (dev, 0x0060, 0x019c, nv04_graph_mthd_bind_beta4);
1160 NVOBJ_MTHD (dev, 0x0060, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf);
1161 NVOBJ_MTHD (dev, 0x0060, 0x03e4, nv04_graph_mthd_set_operation);
1162
1163 /* nv05 iifc */
1164 NVOBJ_CLASS(dev, 0x0064, GR);
1165
1166 /* nv01 ifc */
1167 NVOBJ_CLASS(dev, 0x0021, GR);
1168 NVOBJ_MTHD (dev, 0x0021, 0x0184, nv04_graph_mthd_bind_chroma);
1169 NVOBJ_MTHD (dev, 0x0021, 0x0188, nv04_graph_mthd_bind_clip);
1170 NVOBJ_MTHD (dev, 0x0021, 0x018c, nv04_graph_mthd_bind_nv01_patt);
1171 NVOBJ_MTHD (dev, 0x0021, 0x0190, nv04_graph_mthd_bind_rop);
1172 NVOBJ_MTHD (dev, 0x0021, 0x0194, nv04_graph_mthd_bind_beta1);
1173 NVOBJ_MTHD (dev, 0x0021, 0x0198, nv04_graph_mthd_bind_surf_dst);
1174 NVOBJ_MTHD (dev, 0x0021, 0x02fc, nv04_graph_mthd_set_operation);
1175
1176 /* nv04 ifc */
1177 NVOBJ_CLASS(dev, 0x0061, GR);
1178 NVOBJ_MTHD (dev, 0x0061, 0x0184, nv04_graph_mthd_bind_chroma);
1179 NVOBJ_MTHD (dev, 0x0061, 0x0188, nv04_graph_mthd_bind_clip);
1180 NVOBJ_MTHD (dev, 0x0061, 0x018c, nv04_graph_mthd_bind_nv04_patt);
1181 NVOBJ_MTHD (dev, 0x0061, 0x0190, nv04_graph_mthd_bind_rop);
1182 NVOBJ_MTHD (dev, 0x0061, 0x0194, nv04_graph_mthd_bind_beta1);
1183 NVOBJ_MTHD (dev, 0x0061, 0x0198, nv04_graph_mthd_bind_beta4);
1184 NVOBJ_MTHD (dev, 0x0061, 0x019c, nv04_graph_mthd_bind_surf2d);
1185 NVOBJ_MTHD (dev, 0x0061, 0x02fc, nv04_graph_mthd_set_operation);
1186
1187 /* nv05 ifc */
1188 NVOBJ_CLASS(dev, 0x0065, GR);
1189
1190 /* nv03 sifc */
1191 NVOBJ_CLASS(dev, 0x0036, GR);
1192 NVOBJ_MTHD (dev, 0x0036, 0x0184, nv04_graph_mthd_bind_chroma);
1193 NVOBJ_MTHD (dev, 0x0036, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1194 NVOBJ_MTHD (dev, 0x0036, 0x018c, nv04_graph_mthd_bind_rop);
1195 NVOBJ_MTHD (dev, 0x0036, 0x0190, nv04_graph_mthd_bind_beta1);
1196 NVOBJ_MTHD (dev, 0x0036, 0x0194, nv04_graph_mthd_bind_surf_dst);
1197 NVOBJ_MTHD (dev, 0x0036, 0x02fc, nv04_graph_mthd_set_operation);
1198
1199 /* nv04 sifc */
1200 NVOBJ_CLASS(dev, 0x0076, GR);
1201 NVOBJ_MTHD (dev, 0x0076, 0x0184, nv04_graph_mthd_bind_chroma);
1202 NVOBJ_MTHD (dev, 0x0076, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1203 NVOBJ_MTHD (dev, 0x0076, 0x018c, nv04_graph_mthd_bind_rop);
1204 NVOBJ_MTHD (dev, 0x0076, 0x0190, nv04_graph_mthd_bind_beta1);
1205 NVOBJ_MTHD (dev, 0x0076, 0x0194, nv04_graph_mthd_bind_beta4);
1206 NVOBJ_MTHD (dev, 0x0076, 0x0198, nv04_graph_mthd_bind_surf2d);
1207 NVOBJ_MTHD (dev, 0x0076, 0x02fc, nv04_graph_mthd_set_operation);
1208
1209 /* nv05 sifc */
1210 NVOBJ_CLASS(dev, 0x0066, GR);
1211
1212 /* nv03 sifm */
1213 NVOBJ_CLASS(dev, 0x0037, GR);
1214 NVOBJ_MTHD (dev, 0x0037, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1215 NVOBJ_MTHD (dev, 0x0037, 0x018c, nv04_graph_mthd_bind_rop);
1216 NVOBJ_MTHD (dev, 0x0037, 0x0190, nv04_graph_mthd_bind_beta1);
1217 NVOBJ_MTHD (dev, 0x0037, 0x0194, nv04_graph_mthd_bind_surf_dst);
1218 NVOBJ_MTHD (dev, 0x0037, 0x0304, nv04_graph_mthd_set_operation);
1219
1220 /* nv04 sifm */
1221 NVOBJ_CLASS(dev, 0x0077, GR);
1222 NVOBJ_MTHD (dev, 0x0077, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1223 NVOBJ_MTHD (dev, 0x0077, 0x018c, nv04_graph_mthd_bind_rop);
1224 NVOBJ_MTHD (dev, 0x0077, 0x0190, nv04_graph_mthd_bind_beta1);
1225 NVOBJ_MTHD (dev, 0x0077, 0x0194, nv04_graph_mthd_bind_beta4);
1226 NVOBJ_MTHD (dev, 0x0077, 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf);
1227 NVOBJ_MTHD (dev, 0x0077, 0x0304, nv04_graph_mthd_set_operation);
1228
1229 /* null */
1230 NVOBJ_CLASS(dev, 0x0030, GR);
1231
1232 /* surf2d */
1233 NVOBJ_CLASS(dev, 0x0042, GR);
1234
1235 /* rop */
1236 NVOBJ_CLASS(dev, 0x0043, GR);
1237
1238 /* beta1 */
1239 NVOBJ_CLASS(dev, 0x0012, GR);
1240
1241 /* beta4 */
1242 NVOBJ_CLASS(dev, 0x0072, GR);
1243
1244 /* cliprect */
1245 NVOBJ_CLASS(dev, 0x0019, GR);
1246
1247 /* nv01 pattern */
1248 NVOBJ_CLASS(dev, 0x0018, GR);
1249
1250 /* nv04 pattern */
1251 NVOBJ_CLASS(dev, 0x0044, GR);
1252
1253 /* swzsurf */
1254 NVOBJ_CLASS(dev, 0x0052, GR);
1255
1256 /* surf3d */
1257 NVOBJ_CLASS(dev, 0x0053, GR);
1258 NVOBJ_MTHD (dev, 0x0053, 0x02f8, nv04_graph_mthd_surf3d_clip_h);
1259 NVOBJ_MTHD (dev, 0x0053, 0x02fc, nv04_graph_mthd_surf3d_clip_v);
1260
1261 /* nv03 tex_tri */
1262 NVOBJ_CLASS(dev, 0x0048, GR);
1263 NVOBJ_MTHD (dev, 0x0048, 0x0188, nv04_graph_mthd_bind_clip);
1264 NVOBJ_MTHD (dev, 0x0048, 0x018c, nv04_graph_mthd_bind_surf_color);
1265 NVOBJ_MTHD (dev, 0x0048, 0x0190, nv04_graph_mthd_bind_surf_zeta);
1266
1267 /* tex_tri */
1268 NVOBJ_CLASS(dev, 0x0054, GR);
1269
1270 /* multitex_tri */
1271 NVOBJ_CLASS(dev, 0x0055, GR);
1272
1273 /* nv01 chroma */
1274 NVOBJ_CLASS(dev, 0x0017, GR);
1275
1276 /* nv04 chroma */
1277 NVOBJ_CLASS(dev, 0x0057, GR);
1278
1279 /* surf_dst */
1280 NVOBJ_CLASS(dev, 0x0058, GR);
1281
1282 /* surf_src */
1283 NVOBJ_CLASS(dev, 0x0059, GR);
1284
1285 /* surf_color */
1286 NVOBJ_CLASS(dev, 0x005a, GR);
1287
1288 /* surf_zeta */
1289 NVOBJ_CLASS(dev, 0x005b, GR);
1290
1291 /* nv01 line */
1292 NVOBJ_CLASS(dev, 0x001c, GR);
1293 NVOBJ_MTHD (dev, 0x001c, 0x0184, nv04_graph_mthd_bind_clip);
1294 NVOBJ_MTHD (dev, 0x001c, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1295 NVOBJ_MTHD (dev, 0x001c, 0x018c, nv04_graph_mthd_bind_rop);
1296 NVOBJ_MTHD (dev, 0x001c, 0x0190, nv04_graph_mthd_bind_beta1);
1297 NVOBJ_MTHD (dev, 0x001c, 0x0194, nv04_graph_mthd_bind_surf_dst);
1298 NVOBJ_MTHD (dev, 0x001c, 0x02fc, nv04_graph_mthd_set_operation);
1299
1300 /* nv04 line */
1301 NVOBJ_CLASS(dev, 0x005c, GR);
1302 NVOBJ_MTHD (dev, 0x005c, 0x0184, nv04_graph_mthd_bind_clip);
1303 NVOBJ_MTHD (dev, 0x005c, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1304 NVOBJ_MTHD (dev, 0x005c, 0x018c, nv04_graph_mthd_bind_rop);
1305 NVOBJ_MTHD (dev, 0x005c, 0x0190, nv04_graph_mthd_bind_beta1);
1306 NVOBJ_MTHD (dev, 0x005c, 0x0194, nv04_graph_mthd_bind_beta4);
1307 NVOBJ_MTHD (dev, 0x005c, 0x0198, nv04_graph_mthd_bind_surf2d);
1308 NVOBJ_MTHD (dev, 0x005c, 0x02fc, nv04_graph_mthd_set_operation);
1309
1310 /* nv01 tri */
1311 NVOBJ_CLASS(dev, 0x001d, GR);
1312 NVOBJ_MTHD (dev, 0x001d, 0x0184, nv04_graph_mthd_bind_clip);
1313 NVOBJ_MTHD (dev, 0x001d, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1314 NVOBJ_MTHD (dev, 0x001d, 0x018c, nv04_graph_mthd_bind_rop);
1315 NVOBJ_MTHD (dev, 0x001d, 0x0190, nv04_graph_mthd_bind_beta1);
1316 NVOBJ_MTHD (dev, 0x001d, 0x0194, nv04_graph_mthd_bind_surf_dst);
1317 NVOBJ_MTHD (dev, 0x001d, 0x02fc, nv04_graph_mthd_set_operation);
1318
1319 /* nv04 tri */
1320 NVOBJ_CLASS(dev, 0x005d, GR);
1321 NVOBJ_MTHD (dev, 0x005d, 0x0184, nv04_graph_mthd_bind_clip);
1322 NVOBJ_MTHD (dev, 0x005d, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1323 NVOBJ_MTHD (dev, 0x005d, 0x018c, nv04_graph_mthd_bind_rop);
1324 NVOBJ_MTHD (dev, 0x005d, 0x0190, nv04_graph_mthd_bind_beta1);
1325 NVOBJ_MTHD (dev, 0x005d, 0x0194, nv04_graph_mthd_bind_beta4);
1326 NVOBJ_MTHD (dev, 0x005d, 0x0198, nv04_graph_mthd_bind_surf2d);
1327 NVOBJ_MTHD (dev, 0x005d, 0x02fc, nv04_graph_mthd_set_operation);
1328
1329 /* nv01 rect */
1330 NVOBJ_CLASS(dev, 0x001e, GR);
1331 NVOBJ_MTHD (dev, 0x001e, 0x0184, nv04_graph_mthd_bind_clip);
1332 NVOBJ_MTHD (dev, 0x001e, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1333 NVOBJ_MTHD (dev, 0x001e, 0x018c, nv04_graph_mthd_bind_rop);
1334 NVOBJ_MTHD (dev, 0x001e, 0x0190, nv04_graph_mthd_bind_beta1);
1335 NVOBJ_MTHD (dev, 0x001e, 0x0194, nv04_graph_mthd_bind_surf_dst);
1336 NVOBJ_MTHD (dev, 0x001e, 0x02fc, nv04_graph_mthd_set_operation);
1337
1338 /* nv04 rect */
1339 NVOBJ_CLASS(dev, 0x005e, GR);
1340 NVOBJ_MTHD (dev, 0x005e, 0x0184, nv04_graph_mthd_bind_clip);
1341 NVOBJ_MTHD (dev, 0x005e, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1342 NVOBJ_MTHD (dev, 0x005e, 0x018c, nv04_graph_mthd_bind_rop);
1343 NVOBJ_MTHD (dev, 0x005e, 0x0190, nv04_graph_mthd_bind_beta1);
1344 NVOBJ_MTHD (dev, 0x005e, 0x0194, nv04_graph_mthd_bind_beta4);
1345 NVOBJ_MTHD (dev, 0x005e, 0x0198, nv04_graph_mthd_bind_surf2d);
1346 NVOBJ_MTHD (dev, 0x005e, 0x02fc, nv04_graph_mthd_set_operation);
1347
1348 /* nvsw */
1349 NVOBJ_CLASS(dev, 0x506e, SW);
1350 NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref);
1351 NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
1352 return 0;
1353}
1/*
2 * Copyright 2007 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_drm.h"
28#include "nouveau_drv.h"
29#include "nouveau_hw.h"
30#include "nouveau_util.h"
31#include "nouveau_ramht.h"
32
33struct nv04_graph_engine {
34 struct nouveau_exec_engine base;
35};
36
37static uint32_t nv04_graph_ctx_regs[] = {
38 0x0040053c,
39 0x00400544,
40 0x00400540,
41 0x00400548,
42 NV04_PGRAPH_CTX_SWITCH1,
43 NV04_PGRAPH_CTX_SWITCH2,
44 NV04_PGRAPH_CTX_SWITCH3,
45 NV04_PGRAPH_CTX_SWITCH4,
46 NV04_PGRAPH_CTX_CACHE1,
47 NV04_PGRAPH_CTX_CACHE2,
48 NV04_PGRAPH_CTX_CACHE3,
49 NV04_PGRAPH_CTX_CACHE4,
50 0x00400184,
51 0x004001a4,
52 0x004001c4,
53 0x004001e4,
54 0x00400188,
55 0x004001a8,
56 0x004001c8,
57 0x004001e8,
58 0x0040018c,
59 0x004001ac,
60 0x004001cc,
61 0x004001ec,
62 0x00400190,
63 0x004001b0,
64 0x004001d0,
65 0x004001f0,
66 0x00400194,
67 0x004001b4,
68 0x004001d4,
69 0x004001f4,
70 0x00400198,
71 0x004001b8,
72 0x004001d8,
73 0x004001f8,
74 0x0040019c,
75 0x004001bc,
76 0x004001dc,
77 0x004001fc,
78 0x00400174,
79 NV04_PGRAPH_DMA_START_0,
80 NV04_PGRAPH_DMA_START_1,
81 NV04_PGRAPH_DMA_LENGTH,
82 NV04_PGRAPH_DMA_MISC,
83 NV04_PGRAPH_DMA_PITCH,
84 NV04_PGRAPH_BOFFSET0,
85 NV04_PGRAPH_BBASE0,
86 NV04_PGRAPH_BLIMIT0,
87 NV04_PGRAPH_BOFFSET1,
88 NV04_PGRAPH_BBASE1,
89 NV04_PGRAPH_BLIMIT1,
90 NV04_PGRAPH_BOFFSET2,
91 NV04_PGRAPH_BBASE2,
92 NV04_PGRAPH_BLIMIT2,
93 NV04_PGRAPH_BOFFSET3,
94 NV04_PGRAPH_BBASE3,
95 NV04_PGRAPH_BLIMIT3,
96 NV04_PGRAPH_BOFFSET4,
97 NV04_PGRAPH_BBASE4,
98 NV04_PGRAPH_BLIMIT4,
99 NV04_PGRAPH_BOFFSET5,
100 NV04_PGRAPH_BBASE5,
101 NV04_PGRAPH_BLIMIT5,
102 NV04_PGRAPH_BPITCH0,
103 NV04_PGRAPH_BPITCH1,
104 NV04_PGRAPH_BPITCH2,
105 NV04_PGRAPH_BPITCH3,
106 NV04_PGRAPH_BPITCH4,
107 NV04_PGRAPH_SURFACE,
108 NV04_PGRAPH_STATE,
109 NV04_PGRAPH_BSWIZZLE2,
110 NV04_PGRAPH_BSWIZZLE5,
111 NV04_PGRAPH_BPIXEL,
112 NV04_PGRAPH_NOTIFY,
113 NV04_PGRAPH_PATT_COLOR0,
114 NV04_PGRAPH_PATT_COLOR1,
115 NV04_PGRAPH_PATT_COLORRAM+0x00,
116 NV04_PGRAPH_PATT_COLORRAM+0x04,
117 NV04_PGRAPH_PATT_COLORRAM+0x08,
118 NV04_PGRAPH_PATT_COLORRAM+0x0c,
119 NV04_PGRAPH_PATT_COLORRAM+0x10,
120 NV04_PGRAPH_PATT_COLORRAM+0x14,
121 NV04_PGRAPH_PATT_COLORRAM+0x18,
122 NV04_PGRAPH_PATT_COLORRAM+0x1c,
123 NV04_PGRAPH_PATT_COLORRAM+0x20,
124 NV04_PGRAPH_PATT_COLORRAM+0x24,
125 NV04_PGRAPH_PATT_COLORRAM+0x28,
126 NV04_PGRAPH_PATT_COLORRAM+0x2c,
127 NV04_PGRAPH_PATT_COLORRAM+0x30,
128 NV04_PGRAPH_PATT_COLORRAM+0x34,
129 NV04_PGRAPH_PATT_COLORRAM+0x38,
130 NV04_PGRAPH_PATT_COLORRAM+0x3c,
131 NV04_PGRAPH_PATT_COLORRAM+0x40,
132 NV04_PGRAPH_PATT_COLORRAM+0x44,
133 NV04_PGRAPH_PATT_COLORRAM+0x48,
134 NV04_PGRAPH_PATT_COLORRAM+0x4c,
135 NV04_PGRAPH_PATT_COLORRAM+0x50,
136 NV04_PGRAPH_PATT_COLORRAM+0x54,
137 NV04_PGRAPH_PATT_COLORRAM+0x58,
138 NV04_PGRAPH_PATT_COLORRAM+0x5c,
139 NV04_PGRAPH_PATT_COLORRAM+0x60,
140 NV04_PGRAPH_PATT_COLORRAM+0x64,
141 NV04_PGRAPH_PATT_COLORRAM+0x68,
142 NV04_PGRAPH_PATT_COLORRAM+0x6c,
143 NV04_PGRAPH_PATT_COLORRAM+0x70,
144 NV04_PGRAPH_PATT_COLORRAM+0x74,
145 NV04_PGRAPH_PATT_COLORRAM+0x78,
146 NV04_PGRAPH_PATT_COLORRAM+0x7c,
147 NV04_PGRAPH_PATT_COLORRAM+0x80,
148 NV04_PGRAPH_PATT_COLORRAM+0x84,
149 NV04_PGRAPH_PATT_COLORRAM+0x88,
150 NV04_PGRAPH_PATT_COLORRAM+0x8c,
151 NV04_PGRAPH_PATT_COLORRAM+0x90,
152 NV04_PGRAPH_PATT_COLORRAM+0x94,
153 NV04_PGRAPH_PATT_COLORRAM+0x98,
154 NV04_PGRAPH_PATT_COLORRAM+0x9c,
155 NV04_PGRAPH_PATT_COLORRAM+0xa0,
156 NV04_PGRAPH_PATT_COLORRAM+0xa4,
157 NV04_PGRAPH_PATT_COLORRAM+0xa8,
158 NV04_PGRAPH_PATT_COLORRAM+0xac,
159 NV04_PGRAPH_PATT_COLORRAM+0xb0,
160 NV04_PGRAPH_PATT_COLORRAM+0xb4,
161 NV04_PGRAPH_PATT_COLORRAM+0xb8,
162 NV04_PGRAPH_PATT_COLORRAM+0xbc,
163 NV04_PGRAPH_PATT_COLORRAM+0xc0,
164 NV04_PGRAPH_PATT_COLORRAM+0xc4,
165 NV04_PGRAPH_PATT_COLORRAM+0xc8,
166 NV04_PGRAPH_PATT_COLORRAM+0xcc,
167 NV04_PGRAPH_PATT_COLORRAM+0xd0,
168 NV04_PGRAPH_PATT_COLORRAM+0xd4,
169 NV04_PGRAPH_PATT_COLORRAM+0xd8,
170 NV04_PGRAPH_PATT_COLORRAM+0xdc,
171 NV04_PGRAPH_PATT_COLORRAM+0xe0,
172 NV04_PGRAPH_PATT_COLORRAM+0xe4,
173 NV04_PGRAPH_PATT_COLORRAM+0xe8,
174 NV04_PGRAPH_PATT_COLORRAM+0xec,
175 NV04_PGRAPH_PATT_COLORRAM+0xf0,
176 NV04_PGRAPH_PATT_COLORRAM+0xf4,
177 NV04_PGRAPH_PATT_COLORRAM+0xf8,
178 NV04_PGRAPH_PATT_COLORRAM+0xfc,
179 NV04_PGRAPH_PATTERN,
180 0x0040080c,
181 NV04_PGRAPH_PATTERN_SHAPE,
182 0x00400600,
183 NV04_PGRAPH_ROP3,
184 NV04_PGRAPH_CHROMA,
185 NV04_PGRAPH_BETA_AND,
186 NV04_PGRAPH_BETA_PREMULT,
187 NV04_PGRAPH_CONTROL0,
188 NV04_PGRAPH_CONTROL1,
189 NV04_PGRAPH_CONTROL2,
190 NV04_PGRAPH_BLEND,
191 NV04_PGRAPH_STORED_FMT,
192 NV04_PGRAPH_SOURCE_COLOR,
193 0x00400560,
194 0x00400568,
195 0x00400564,
196 0x0040056c,
197 0x00400400,
198 0x00400480,
199 0x00400404,
200 0x00400484,
201 0x00400408,
202 0x00400488,
203 0x0040040c,
204 0x0040048c,
205 0x00400410,
206 0x00400490,
207 0x00400414,
208 0x00400494,
209 0x00400418,
210 0x00400498,
211 0x0040041c,
212 0x0040049c,
213 0x00400420,
214 0x004004a0,
215 0x00400424,
216 0x004004a4,
217 0x00400428,
218 0x004004a8,
219 0x0040042c,
220 0x004004ac,
221 0x00400430,
222 0x004004b0,
223 0x00400434,
224 0x004004b4,
225 0x00400438,
226 0x004004b8,
227 0x0040043c,
228 0x004004bc,
229 0x00400440,
230 0x004004c0,
231 0x00400444,
232 0x004004c4,
233 0x00400448,
234 0x004004c8,
235 0x0040044c,
236 0x004004cc,
237 0x00400450,
238 0x004004d0,
239 0x00400454,
240 0x004004d4,
241 0x00400458,
242 0x004004d8,
243 0x0040045c,
244 0x004004dc,
245 0x00400460,
246 0x004004e0,
247 0x00400464,
248 0x004004e4,
249 0x00400468,
250 0x004004e8,
251 0x0040046c,
252 0x004004ec,
253 0x00400470,
254 0x004004f0,
255 0x00400474,
256 0x004004f4,
257 0x00400478,
258 0x004004f8,
259 0x0040047c,
260 0x004004fc,
261 0x00400534,
262 0x00400538,
263 0x00400514,
264 0x00400518,
265 0x0040051c,
266 0x00400520,
267 0x00400524,
268 0x00400528,
269 0x0040052c,
270 0x00400530,
271 0x00400d00,
272 0x00400d40,
273 0x00400d80,
274 0x00400d04,
275 0x00400d44,
276 0x00400d84,
277 0x00400d08,
278 0x00400d48,
279 0x00400d88,
280 0x00400d0c,
281 0x00400d4c,
282 0x00400d8c,
283 0x00400d10,
284 0x00400d50,
285 0x00400d90,
286 0x00400d14,
287 0x00400d54,
288 0x00400d94,
289 0x00400d18,
290 0x00400d58,
291 0x00400d98,
292 0x00400d1c,
293 0x00400d5c,
294 0x00400d9c,
295 0x00400d20,
296 0x00400d60,
297 0x00400da0,
298 0x00400d24,
299 0x00400d64,
300 0x00400da4,
301 0x00400d28,
302 0x00400d68,
303 0x00400da8,
304 0x00400d2c,
305 0x00400d6c,
306 0x00400dac,
307 0x00400d30,
308 0x00400d70,
309 0x00400db0,
310 0x00400d34,
311 0x00400d74,
312 0x00400db4,
313 0x00400d38,
314 0x00400d78,
315 0x00400db8,
316 0x00400d3c,
317 0x00400d7c,
318 0x00400dbc,
319 0x00400590,
320 0x00400594,
321 0x00400598,
322 0x0040059c,
323 0x004005a8,
324 0x004005ac,
325 0x004005b0,
326 0x004005b4,
327 0x004005c0,
328 0x004005c4,
329 0x004005c8,
330 0x004005cc,
331 0x004005d0,
332 0x004005d4,
333 0x004005d8,
334 0x004005dc,
335 0x004005e0,
336 NV04_PGRAPH_PASSTHRU_0,
337 NV04_PGRAPH_PASSTHRU_1,
338 NV04_PGRAPH_PASSTHRU_2,
339 NV04_PGRAPH_DVD_COLORFMT,
340 NV04_PGRAPH_SCALED_FORMAT,
341 NV04_PGRAPH_MISC24_0,
342 NV04_PGRAPH_MISC24_1,
343 NV04_PGRAPH_MISC24_2,
344 0x00400500,
345 0x00400504,
346 NV04_PGRAPH_VALID1,
347 NV04_PGRAPH_VALID2,
348 NV04_PGRAPH_DEBUG_3
349};
350
351struct graph_state {
352 uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
353};
354
355static struct nouveau_channel *
356nv04_graph_channel(struct drm_device *dev)
357{
358 struct drm_nouveau_private *dev_priv = dev->dev_private;
359 int chid = 15;
360
361 if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
362 chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
363
364 if (chid > 15)
365 return NULL;
366
367 return dev_priv->channels.ptr[chid];
368}
369
370static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg)
371{
372 int i;
373
374 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
375 if (nv04_graph_ctx_regs[i] == reg)
376 return &ctx->nv04[i];
377 }
378
379 return NULL;
380}
381
382static int
383nv04_graph_load_context(struct nouveau_channel *chan)
384{
385 struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
386 struct drm_device *dev = chan->dev;
387 uint32_t tmp;
388 int i;
389
390 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
391 nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
392
393 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
394
395 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
396 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24);
397
398 tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
399 nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
400
401 return 0;
402}
403
404static int
405nv04_graph_unload_context(struct drm_device *dev)
406{
407 struct nouveau_channel *chan = NULL;
408 struct graph_state *ctx;
409 uint32_t tmp;
410 int i;
411
412 chan = nv04_graph_channel(dev);
413 if (!chan)
414 return 0;
415 ctx = chan->engctx[NVOBJ_ENGINE_GR];
416
417 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
418 ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
419
420 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
421 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
422 tmp |= 15 << 24;
423 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
424 return 0;
425}
426
427static int
428nv04_graph_context_new(struct nouveau_channel *chan, int engine)
429{
430 struct graph_state *pgraph_ctx;
431 NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
432
433 pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL);
434 if (pgraph_ctx == NULL)
435 return -ENOMEM;
436
437 *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
438
439 chan->engctx[engine] = pgraph_ctx;
440 return 0;
441}
442
443static void
444nv04_graph_context_del(struct nouveau_channel *chan, int engine)
445{
446 struct drm_device *dev = chan->dev;
447 struct drm_nouveau_private *dev_priv = dev->dev_private;
448 struct graph_state *pgraph_ctx = chan->engctx[engine];
449 unsigned long flags;
450
451 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
452 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
453
454 /* Unload the context if it's the currently active one */
455 if (nv04_graph_channel(dev) == chan)
456 nv04_graph_unload_context(dev);
457
458 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
459 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
460
461 /* Free the context resources */
462 kfree(pgraph_ctx);
463 chan->engctx[engine] = NULL;
464}
465
466int
467nv04_graph_object_new(struct nouveau_channel *chan, int engine,
468 u32 handle, u16 class)
469{
470 struct drm_device *dev = chan->dev;
471 struct nouveau_gpuobj *obj = NULL;
472 int ret;
473
474 ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
475 if (ret)
476 return ret;
477 obj->engine = 1;
478 obj->class = class;
479
480#ifdef __BIG_ENDIAN
481 nv_wo32(obj, 0x00, 0x00080000 | class);
482#else
483 nv_wo32(obj, 0x00, class);
484#endif
485 nv_wo32(obj, 0x04, 0x00000000);
486 nv_wo32(obj, 0x08, 0x00000000);
487 nv_wo32(obj, 0x0c, 0x00000000);
488
489 ret = nouveau_ramht_insert(chan, handle, obj);
490 nouveau_gpuobj_ref(NULL, &obj);
491 return ret;
492}
493
494static int
495nv04_graph_init(struct drm_device *dev, int engine)
496{
497 uint32_t tmp;
498
499 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
500 ~NV_PMC_ENABLE_PGRAPH);
501 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
502 NV_PMC_ENABLE_PGRAPH);
503
504 /* Enable PGRAPH interrupts */
505 nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
506 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
507
508 nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
509 nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
510 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
511 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
512 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
513 /*1231C000 blob, 001 haiku*/
514 /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
515 nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
516 /*0x72111100 blob , 01 haiku*/
517 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
518 nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
519 /*haiku same*/
520
521 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
522 nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
523 /*haiku and blob 10d4*/
524
525 nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF);
526 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
527 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
528 tmp |= 15 << 24;
529 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
530
531 /* These don't belong here, they're part of a per-channel context */
532 nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
533 nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
534
535 return 0;
536}
537
538static int
539nv04_graph_fini(struct drm_device *dev, int engine, bool suspend)
540{
541 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
542 if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
543 nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
544 return -EBUSY;
545 }
546 nv04_graph_unload_context(dev);
547 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
548 return 0;
549}
550
551/*
552 * Software methods, why they are needed, and how they all work:
553 *
554 * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
555 * 2d engine settings are kept inside the grobjs themselves. The grobjs are
556 * 3 words long on both. grobj format on NV04 is:
557 *
558 * word 0:
559 * - bits 0-7: class
560 * - bit 12: color key active
561 * - bit 13: clip rect active
562 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
563 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
564 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
565 * NV03_CONTEXT_SURFACE_DST].
566 * - bits 15-17: 2d operation [aka patch config]
567 * - bit 24: patch valid [enables rendering using this object]
568 * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
569 * word 1:
570 * - bits 0-1: mono format
571 * - bits 8-13: color format
572 * - bits 16-31: DMA_NOTIFY instance
573 * word 2:
574 * - bits 0-15: DMA_A instance
575 * - bits 16-31: DMA_B instance
576 *
577 * On NV05 it's:
578 *
579 * word 0:
580 * - bits 0-7: class
581 * - bit 12: color key active
582 * - bit 13: clip rect active
583 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
584 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
585 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
586 * NV03_CONTEXT_SURFACE_DST].
587 * - bits 15-17: 2d operation [aka patch config]
588 * - bits 20-22: dither mode
589 * - bit 24: patch valid [enables rendering using this object]
590 * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
591 * - bit 26: surface_src/surface_zeta valid
592 * - bit 27: pattern valid
593 * - bit 28: rop valid
594 * - bit 29: beta1 valid
595 * - bit 30: beta4 valid
596 * word 1:
597 * - bits 0-1: mono format
598 * - bits 8-13: color format
599 * - bits 16-31: DMA_NOTIFY instance
600 * word 2:
601 * - bits 0-15: DMA_A instance
602 * - bits 16-31: DMA_B instance
603 *
604 * NV05 will set/unset the relevant valid bits when you poke the relevant
605 * object-binding methods with object of the proper type, or with the NULL
606 * type. It'll only allow rendering using the grobj if all needed objects
607 * are bound. The needed set of objects depends on selected operation: for
608 * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
609 *
610 * NV04 doesn't have these methods implemented at all, and doesn't have the
611 * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
612 * is set. So we have to emulate them in software, internally keeping the
613 * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
614 * but the last word isn't actually used for anything, we abuse it for this
615 * purpose.
616 *
617 * Actually, NV05 can optionally check bit 24 too, but we disable this since
618 * there's no use for it.
619 *
620 * For unknown reasons, NV04 implements surf3d binding in hardware as an
621 * exception. Also for unknown reasons, NV04 doesn't implement the clipping
622 * methods on the surf3d object, so we have to emulate them too.
623 */
624
625static void
626nv04_graph_set_ctx1(struct nouveau_channel *chan, u32 mask, u32 value)
627{
628 struct drm_device *dev = chan->dev;
629 u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
630 int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
631 u32 tmp;
632
633 tmp = nv_ri32(dev, instance);
634 tmp &= ~mask;
635 tmp |= value;
636
637 nv_wi32(dev, instance, tmp);
638 nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
639 nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
640}
641
642static void
643nv04_graph_set_ctx_val(struct nouveau_channel *chan, u32 mask, u32 value)
644{
645 struct drm_device *dev = chan->dev;
646 u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
647 u32 tmp, ctx1;
648 int class, op, valid = 1;
649
650 ctx1 = nv_ri32(dev, instance);
651 class = ctx1 & 0xff;
652 op = (ctx1 >> 15) & 7;
653 tmp = nv_ri32(dev, instance + 0xc);
654 tmp &= ~mask;
655 tmp |= value;
656 nv_wi32(dev, instance + 0xc, tmp);
657
658 /* check for valid surf2d/surf_dst/surf_color */
659 if (!(tmp & 0x02000000))
660 valid = 0;
661 /* check for valid surf_src/surf_zeta */
662 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
663 valid = 0;
664
665 switch (op) {
666 /* SRCCOPY_AND, SRCCOPY: no extra objects required */
667 case 0:
668 case 3:
669 break;
670 /* ROP_AND: requires pattern and rop */
671 case 1:
672 if (!(tmp & 0x18000000))
673 valid = 0;
674 break;
675 /* BLEND_AND: requires beta1 */
676 case 2:
677 if (!(tmp & 0x20000000))
678 valid = 0;
679 break;
680 /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
681 case 4:
682 case 5:
683 if (!(tmp & 0x40000000))
684 valid = 0;
685 break;
686 }
687
688 nv04_graph_set_ctx1(chan, 0x01000000, valid << 24);
689}
690
691static int
692nv04_graph_mthd_set_operation(struct nouveau_channel *chan,
693 u32 class, u32 mthd, u32 data)
694{
695 if (data > 5)
696 return 1;
697 /* Old versions of the objects only accept first three operations. */
698 if (data > 2 && class < 0x40)
699 return 1;
700 nv04_graph_set_ctx1(chan, 0x00038000, data << 15);
701 /* changing operation changes set of objects needed for validation */
702 nv04_graph_set_ctx_val(chan, 0, 0);
703 return 0;
704}
705
706static int
707nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan,
708 u32 class, u32 mthd, u32 data)
709{
710 uint32_t min = data & 0xffff, max;
711 uint32_t w = data >> 16;
712 if (min & 0x8000)
713 /* too large */
714 return 1;
715 if (w & 0x8000)
716 /* yes, it accepts negative for some reason. */
717 w |= 0xffff0000;
718 max = min + w;
719 max &= 0x3ffff;
720 nv_wr32(chan->dev, 0x40053c, min);
721 nv_wr32(chan->dev, 0x400544, max);
722 return 0;
723}
724
725static int
726nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan,
727 u32 class, u32 mthd, u32 data)
728{
729 uint32_t min = data & 0xffff, max;
730 uint32_t w = data >> 16;
731 if (min & 0x8000)
732 /* too large */
733 return 1;
734 if (w & 0x8000)
735 /* yes, it accepts negative for some reason. */
736 w |= 0xffff0000;
737 max = min + w;
738 max &= 0x3ffff;
739 nv_wr32(chan->dev, 0x400540, min);
740 nv_wr32(chan->dev, 0x400548, max);
741 return 0;
742}
743
744static int
745nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan,
746 u32 class, u32 mthd, u32 data)
747{
748 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
749 case 0x30:
750 nv04_graph_set_ctx1(chan, 0x00004000, 0);
751 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
752 return 0;
753 case 0x42:
754 nv04_graph_set_ctx1(chan, 0x00004000, 0);
755 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
756 return 0;
757 }
758 return 1;
759}
760
761static int
762nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan,
763 u32 class, u32 mthd, u32 data)
764{
765 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
766 case 0x30:
767 nv04_graph_set_ctx1(chan, 0x00004000, 0);
768 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
769 return 0;
770 case 0x42:
771 nv04_graph_set_ctx1(chan, 0x00004000, 0);
772 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
773 return 0;
774 case 0x52:
775 nv04_graph_set_ctx1(chan, 0x00004000, 0x00004000);
776 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
777 return 0;
778 }
779 return 1;
780}
781
782static int
783nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan,
784 u32 class, u32 mthd, u32 data)
785{
786 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
787 case 0x30:
788 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
789 return 0;
790 case 0x18:
791 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
792 return 0;
793 }
794 return 1;
795}
796
797static int
798nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan,
799 u32 class, u32 mthd, u32 data)
800{
801 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
802 case 0x30:
803 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
804 return 0;
805 case 0x44:
806 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
807 return 0;
808 }
809 return 1;
810}
811
812static int
813nv04_graph_mthd_bind_rop(struct nouveau_channel *chan,
814 u32 class, u32 mthd, u32 data)
815{
816 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
817 case 0x30:
818 nv04_graph_set_ctx_val(chan, 0x10000000, 0);
819 return 0;
820 case 0x43:
821 nv04_graph_set_ctx_val(chan, 0x10000000, 0x10000000);
822 return 0;
823 }
824 return 1;
825}
826
827static int
828nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan,
829 u32 class, u32 mthd, u32 data)
830{
831 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
832 case 0x30:
833 nv04_graph_set_ctx_val(chan, 0x20000000, 0);
834 return 0;
835 case 0x12:
836 nv04_graph_set_ctx_val(chan, 0x20000000, 0x20000000);
837 return 0;
838 }
839 return 1;
840}
841
842static int
843nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan,
844 u32 class, u32 mthd, u32 data)
845{
846 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
847 case 0x30:
848 nv04_graph_set_ctx_val(chan, 0x40000000, 0);
849 return 0;
850 case 0x72:
851 nv04_graph_set_ctx_val(chan, 0x40000000, 0x40000000);
852 return 0;
853 }
854 return 1;
855}
856
857static int
858nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan,
859 u32 class, u32 mthd, u32 data)
860{
861 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
862 case 0x30:
863 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
864 return 0;
865 case 0x58:
866 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
867 return 0;
868 }
869 return 1;
870}
871
872static int
873nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan,
874 u32 class, u32 mthd, u32 data)
875{
876 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
877 case 0x30:
878 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
879 return 0;
880 case 0x59:
881 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
882 return 0;
883 }
884 return 1;
885}
886
887static int
888nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan,
889 u32 class, u32 mthd, u32 data)
890{
891 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
892 case 0x30:
893 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
894 return 0;
895 case 0x5a:
896 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
897 return 0;
898 }
899 return 1;
900}
901
902static int
903nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan,
904 u32 class, u32 mthd, u32 data)
905{
906 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
907 case 0x30:
908 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
909 return 0;
910 case 0x5b:
911 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
912 return 0;
913 }
914 return 1;
915}
916
917static int
918nv04_graph_mthd_bind_clip(struct nouveau_channel *chan,
919 u32 class, u32 mthd, u32 data)
920{
921 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
922 case 0x30:
923 nv04_graph_set_ctx1(chan, 0x2000, 0);
924 return 0;
925 case 0x19:
926 nv04_graph_set_ctx1(chan, 0x2000, 0x2000);
927 return 0;
928 }
929 return 1;
930}
931
932static int
933nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan,
934 u32 class, u32 mthd, u32 data)
935{
936 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
937 case 0x30:
938 nv04_graph_set_ctx1(chan, 0x1000, 0);
939 return 0;
940 /* Yes, for some reason even the old versions of objects
941 * accept 0x57 and not 0x17. Consistency be damned.
942 */
943 case 0x57:
944 nv04_graph_set_ctx1(chan, 0x1000, 0x1000);
945 return 0;
946 }
947 return 1;
948}
949
950static struct nouveau_bitfield nv04_graph_intr[] = {
951 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
952 {}
953};
954
955static struct nouveau_bitfield nv04_graph_nstatus[] = {
956 { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
957 { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
958 { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
959 { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
960 {}
961};
962
963struct nouveau_bitfield nv04_graph_nsource[] = {
964 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
965 { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
966 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
967 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
968 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
969 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
970 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
971 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
972 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
973 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
974 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
975 { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
976 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
977 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
978 { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
979 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
980 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
981 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
982 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
983 {}
984};
985
986static void
987nv04_graph_context_switch(struct drm_device *dev)
988{
989 struct drm_nouveau_private *dev_priv = dev->dev_private;
990 struct nouveau_channel *chan = NULL;
991 int chid;
992
993 nouveau_wait_for_idle(dev);
994
995 /* If previous context is valid, we need to save it */
996 nv04_graph_unload_context(dev);
997
998 /* Load context for next channel */
999 chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
1000 NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
1001 chan = dev_priv->channels.ptr[chid];
1002 if (chan)
1003 nv04_graph_load_context(chan);
1004}
1005
1006static void
1007nv04_graph_isr(struct drm_device *dev)
1008{
1009 u32 stat;
1010
1011 while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
1012 u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
1013 u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
1014 u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
1015 u32 chid = (addr & 0x0f000000) >> 24;
1016 u32 subc = (addr & 0x0000e000) >> 13;
1017 u32 mthd = (addr & 0x00001ffc);
1018 u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
1019 u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
1020 u32 show = stat;
1021
1022 if (stat & NV_PGRAPH_INTR_NOTIFY) {
1023 if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
1024 if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
1025 show &= ~NV_PGRAPH_INTR_NOTIFY;
1026 }
1027 }
1028
1029 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1030 nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1031 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1032 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1033 nv04_graph_context_switch(dev);
1034 }
1035
1036 nv_wr32(dev, NV03_PGRAPH_INTR, stat);
1037 nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
1038
1039 if (show && nouveau_ratelimit()) {
1040 NV_INFO(dev, "PGRAPH -");
1041 nouveau_bitfield_print(nv04_graph_intr, show);
1042 printk(" nsource:");
1043 nouveau_bitfield_print(nv04_graph_nsource, nsource);
1044 printk(" nstatus:");
1045 nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
1046 printk("\n");
1047 NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
1048 "mthd 0x%04x data 0x%08x\n",
1049 chid, subc, class, mthd, data);
1050 }
1051 }
1052}
1053
1054static void
1055nv04_graph_destroy(struct drm_device *dev, int engine)
1056{
1057 struct nv04_graph_engine *pgraph = nv_engine(dev, engine);
1058
1059 nouveau_irq_unregister(dev, 12);
1060
1061 NVOBJ_ENGINE_DEL(dev, GR);
1062 kfree(pgraph);
1063}
1064
1065int
1066nv04_graph_create(struct drm_device *dev)
1067{
1068 struct nv04_graph_engine *pgraph;
1069
1070 pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
1071 if (!pgraph)
1072 return -ENOMEM;
1073
1074 pgraph->base.destroy = nv04_graph_destroy;
1075 pgraph->base.init = nv04_graph_init;
1076 pgraph->base.fini = nv04_graph_fini;
1077 pgraph->base.context_new = nv04_graph_context_new;
1078 pgraph->base.context_del = nv04_graph_context_del;
1079 pgraph->base.object_new = nv04_graph_object_new;
1080
1081 NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
1082 nouveau_irq_register(dev, 12, nv04_graph_isr);
1083
1084 /* dvd subpicture */
1085 NVOBJ_CLASS(dev, 0x0038, GR);
1086
1087 /* m2mf */
1088 NVOBJ_CLASS(dev, 0x0039, GR);
1089
1090 /* nv03 gdirect */
1091 NVOBJ_CLASS(dev, 0x004b, GR);
1092 NVOBJ_MTHD (dev, 0x004b, 0x0184, nv04_graph_mthd_bind_nv01_patt);
1093 NVOBJ_MTHD (dev, 0x004b, 0x0188, nv04_graph_mthd_bind_rop);
1094 NVOBJ_MTHD (dev, 0x004b, 0x018c, nv04_graph_mthd_bind_beta1);
1095 NVOBJ_MTHD (dev, 0x004b, 0x0190, nv04_graph_mthd_bind_surf_dst);
1096 NVOBJ_MTHD (dev, 0x004b, 0x02fc, nv04_graph_mthd_set_operation);
1097
1098 /* nv04 gdirect */
1099 NVOBJ_CLASS(dev, 0x004a, GR);
1100 NVOBJ_MTHD (dev, 0x004a, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1101 NVOBJ_MTHD (dev, 0x004a, 0x018c, nv04_graph_mthd_bind_rop);
1102 NVOBJ_MTHD (dev, 0x004a, 0x0190, nv04_graph_mthd_bind_beta1);
1103 NVOBJ_MTHD (dev, 0x004a, 0x0194, nv04_graph_mthd_bind_beta4);
1104 NVOBJ_MTHD (dev, 0x004a, 0x0198, nv04_graph_mthd_bind_surf2d);
1105 NVOBJ_MTHD (dev, 0x004a, 0x02fc, nv04_graph_mthd_set_operation);
1106
1107 /* nv01 imageblit */
1108 NVOBJ_CLASS(dev, 0x001f, GR);
1109 NVOBJ_MTHD (dev, 0x001f, 0x0184, nv04_graph_mthd_bind_chroma);
1110 NVOBJ_MTHD (dev, 0x001f, 0x0188, nv04_graph_mthd_bind_clip);
1111 NVOBJ_MTHD (dev, 0x001f, 0x018c, nv04_graph_mthd_bind_nv01_patt);
1112 NVOBJ_MTHD (dev, 0x001f, 0x0190, nv04_graph_mthd_bind_rop);
1113 NVOBJ_MTHD (dev, 0x001f, 0x0194, nv04_graph_mthd_bind_beta1);
1114 NVOBJ_MTHD (dev, 0x001f, 0x0198, nv04_graph_mthd_bind_surf_dst);
1115 NVOBJ_MTHD (dev, 0x001f, 0x019c, nv04_graph_mthd_bind_surf_src);
1116 NVOBJ_MTHD (dev, 0x001f, 0x02fc, nv04_graph_mthd_set_operation);
1117
1118 /* nv04 imageblit */
1119 NVOBJ_CLASS(dev, 0x005f, GR);
1120 NVOBJ_MTHD (dev, 0x005f, 0x0184, nv04_graph_mthd_bind_chroma);
1121 NVOBJ_MTHD (dev, 0x005f, 0x0188, nv04_graph_mthd_bind_clip);
1122 NVOBJ_MTHD (dev, 0x005f, 0x018c, nv04_graph_mthd_bind_nv04_patt);
1123 NVOBJ_MTHD (dev, 0x005f, 0x0190, nv04_graph_mthd_bind_rop);
1124 NVOBJ_MTHD (dev, 0x005f, 0x0194, nv04_graph_mthd_bind_beta1);
1125 NVOBJ_MTHD (dev, 0x005f, 0x0198, nv04_graph_mthd_bind_beta4);
1126 NVOBJ_MTHD (dev, 0x005f, 0x019c, nv04_graph_mthd_bind_surf2d);
1127 NVOBJ_MTHD (dev, 0x005f, 0x02fc, nv04_graph_mthd_set_operation);
1128
1129 /* nv04 iifc */
1130 NVOBJ_CLASS(dev, 0x0060, GR);
1131 NVOBJ_MTHD (dev, 0x0060, 0x0188, nv04_graph_mthd_bind_chroma);
1132 NVOBJ_MTHD (dev, 0x0060, 0x018c, nv04_graph_mthd_bind_clip);
1133 NVOBJ_MTHD (dev, 0x0060, 0x0190, nv04_graph_mthd_bind_nv04_patt);
1134 NVOBJ_MTHD (dev, 0x0060, 0x0194, nv04_graph_mthd_bind_rop);
1135 NVOBJ_MTHD (dev, 0x0060, 0x0198, nv04_graph_mthd_bind_beta1);
1136 NVOBJ_MTHD (dev, 0x0060, 0x019c, nv04_graph_mthd_bind_beta4);
1137 NVOBJ_MTHD (dev, 0x0060, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf);
1138 NVOBJ_MTHD (dev, 0x0060, 0x03e4, nv04_graph_mthd_set_operation);
1139
1140 /* nv05 iifc */
1141 NVOBJ_CLASS(dev, 0x0064, GR);
1142
1143 /* nv01 ifc */
1144 NVOBJ_CLASS(dev, 0x0021, GR);
1145 NVOBJ_MTHD (dev, 0x0021, 0x0184, nv04_graph_mthd_bind_chroma);
1146 NVOBJ_MTHD (dev, 0x0021, 0x0188, nv04_graph_mthd_bind_clip);
1147 NVOBJ_MTHD (dev, 0x0021, 0x018c, nv04_graph_mthd_bind_nv01_patt);
1148 NVOBJ_MTHD (dev, 0x0021, 0x0190, nv04_graph_mthd_bind_rop);
1149 NVOBJ_MTHD (dev, 0x0021, 0x0194, nv04_graph_mthd_bind_beta1);
1150 NVOBJ_MTHD (dev, 0x0021, 0x0198, nv04_graph_mthd_bind_surf_dst);
1151 NVOBJ_MTHD (dev, 0x0021, 0x02fc, nv04_graph_mthd_set_operation);
1152
1153 /* nv04 ifc */
1154 NVOBJ_CLASS(dev, 0x0061, GR);
1155 NVOBJ_MTHD (dev, 0x0061, 0x0184, nv04_graph_mthd_bind_chroma);
1156 NVOBJ_MTHD (dev, 0x0061, 0x0188, nv04_graph_mthd_bind_clip);
1157 NVOBJ_MTHD (dev, 0x0061, 0x018c, nv04_graph_mthd_bind_nv04_patt);
1158 NVOBJ_MTHD (dev, 0x0061, 0x0190, nv04_graph_mthd_bind_rop);
1159 NVOBJ_MTHD (dev, 0x0061, 0x0194, nv04_graph_mthd_bind_beta1);
1160 NVOBJ_MTHD (dev, 0x0061, 0x0198, nv04_graph_mthd_bind_beta4);
1161 NVOBJ_MTHD (dev, 0x0061, 0x019c, nv04_graph_mthd_bind_surf2d);
1162 NVOBJ_MTHD (dev, 0x0061, 0x02fc, nv04_graph_mthd_set_operation);
1163
1164 /* nv05 ifc */
1165 NVOBJ_CLASS(dev, 0x0065, GR);
1166
1167 /* nv03 sifc */
1168 NVOBJ_CLASS(dev, 0x0036, GR);
1169 NVOBJ_MTHD (dev, 0x0036, 0x0184, nv04_graph_mthd_bind_chroma);
1170 NVOBJ_MTHD (dev, 0x0036, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1171 NVOBJ_MTHD (dev, 0x0036, 0x018c, nv04_graph_mthd_bind_rop);
1172 NVOBJ_MTHD (dev, 0x0036, 0x0190, nv04_graph_mthd_bind_beta1);
1173 NVOBJ_MTHD (dev, 0x0036, 0x0194, nv04_graph_mthd_bind_surf_dst);
1174 NVOBJ_MTHD (dev, 0x0036, 0x02fc, nv04_graph_mthd_set_operation);
1175
1176 /* nv04 sifc */
1177 NVOBJ_CLASS(dev, 0x0076, GR);
1178 NVOBJ_MTHD (dev, 0x0076, 0x0184, nv04_graph_mthd_bind_chroma);
1179 NVOBJ_MTHD (dev, 0x0076, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1180 NVOBJ_MTHD (dev, 0x0076, 0x018c, nv04_graph_mthd_bind_rop);
1181 NVOBJ_MTHD (dev, 0x0076, 0x0190, nv04_graph_mthd_bind_beta1);
1182 NVOBJ_MTHD (dev, 0x0076, 0x0194, nv04_graph_mthd_bind_beta4);
1183 NVOBJ_MTHD (dev, 0x0076, 0x0198, nv04_graph_mthd_bind_surf2d);
1184 NVOBJ_MTHD (dev, 0x0076, 0x02fc, nv04_graph_mthd_set_operation);
1185
1186 /* nv05 sifc */
1187 NVOBJ_CLASS(dev, 0x0066, GR);
1188
1189 /* nv03 sifm */
1190 NVOBJ_CLASS(dev, 0x0037, GR);
1191 NVOBJ_MTHD (dev, 0x0037, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1192 NVOBJ_MTHD (dev, 0x0037, 0x018c, nv04_graph_mthd_bind_rop);
1193 NVOBJ_MTHD (dev, 0x0037, 0x0190, nv04_graph_mthd_bind_beta1);
1194 NVOBJ_MTHD (dev, 0x0037, 0x0194, nv04_graph_mthd_bind_surf_dst);
1195 NVOBJ_MTHD (dev, 0x0037, 0x0304, nv04_graph_mthd_set_operation);
1196
1197 /* nv04 sifm */
1198 NVOBJ_CLASS(dev, 0x0077, GR);
1199 NVOBJ_MTHD (dev, 0x0077, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1200 NVOBJ_MTHD (dev, 0x0077, 0x018c, nv04_graph_mthd_bind_rop);
1201 NVOBJ_MTHD (dev, 0x0077, 0x0190, nv04_graph_mthd_bind_beta1);
1202 NVOBJ_MTHD (dev, 0x0077, 0x0194, nv04_graph_mthd_bind_beta4);
1203 NVOBJ_MTHD (dev, 0x0077, 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf);
1204 NVOBJ_MTHD (dev, 0x0077, 0x0304, nv04_graph_mthd_set_operation);
1205
1206 /* null */
1207 NVOBJ_CLASS(dev, 0x0030, GR);
1208
1209 /* surf2d */
1210 NVOBJ_CLASS(dev, 0x0042, GR);
1211
1212 /* rop */
1213 NVOBJ_CLASS(dev, 0x0043, GR);
1214
1215 /* beta1 */
1216 NVOBJ_CLASS(dev, 0x0012, GR);
1217
1218 /* beta4 */
1219 NVOBJ_CLASS(dev, 0x0072, GR);
1220
1221 /* cliprect */
1222 NVOBJ_CLASS(dev, 0x0019, GR);
1223
1224 /* nv01 pattern */
1225 NVOBJ_CLASS(dev, 0x0018, GR);
1226
1227 /* nv04 pattern */
1228 NVOBJ_CLASS(dev, 0x0044, GR);
1229
1230 /* swzsurf */
1231 NVOBJ_CLASS(dev, 0x0052, GR);
1232
1233 /* surf3d */
1234 NVOBJ_CLASS(dev, 0x0053, GR);
1235 NVOBJ_MTHD (dev, 0x0053, 0x02f8, nv04_graph_mthd_surf3d_clip_h);
1236 NVOBJ_MTHD (dev, 0x0053, 0x02fc, nv04_graph_mthd_surf3d_clip_v);
1237
1238 /* nv03 tex_tri */
1239 NVOBJ_CLASS(dev, 0x0048, GR);
1240 NVOBJ_MTHD (dev, 0x0048, 0x0188, nv04_graph_mthd_bind_clip);
1241 NVOBJ_MTHD (dev, 0x0048, 0x018c, nv04_graph_mthd_bind_surf_color);
1242 NVOBJ_MTHD (dev, 0x0048, 0x0190, nv04_graph_mthd_bind_surf_zeta);
1243
1244 /* tex_tri */
1245 NVOBJ_CLASS(dev, 0x0054, GR);
1246
1247 /* multitex_tri */
1248 NVOBJ_CLASS(dev, 0x0055, GR);
1249
1250 /* nv01 chroma */
1251 NVOBJ_CLASS(dev, 0x0017, GR);
1252
1253 /* nv04 chroma */
1254 NVOBJ_CLASS(dev, 0x0057, GR);
1255
1256 /* surf_dst */
1257 NVOBJ_CLASS(dev, 0x0058, GR);
1258
1259 /* surf_src */
1260 NVOBJ_CLASS(dev, 0x0059, GR);
1261
1262 /* surf_color */
1263 NVOBJ_CLASS(dev, 0x005a, GR);
1264
1265 /* surf_zeta */
1266 NVOBJ_CLASS(dev, 0x005b, GR);
1267
1268 /* nv01 line */
1269 NVOBJ_CLASS(dev, 0x001c, GR);
1270 NVOBJ_MTHD (dev, 0x001c, 0x0184, nv04_graph_mthd_bind_clip);
1271 NVOBJ_MTHD (dev, 0x001c, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1272 NVOBJ_MTHD (dev, 0x001c, 0x018c, nv04_graph_mthd_bind_rop);
1273 NVOBJ_MTHD (dev, 0x001c, 0x0190, nv04_graph_mthd_bind_beta1);
1274 NVOBJ_MTHD (dev, 0x001c, 0x0194, nv04_graph_mthd_bind_surf_dst);
1275 NVOBJ_MTHD (dev, 0x001c, 0x02fc, nv04_graph_mthd_set_operation);
1276
1277 /* nv04 line */
1278 NVOBJ_CLASS(dev, 0x005c, GR);
1279 NVOBJ_MTHD (dev, 0x005c, 0x0184, nv04_graph_mthd_bind_clip);
1280 NVOBJ_MTHD (dev, 0x005c, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1281 NVOBJ_MTHD (dev, 0x005c, 0x018c, nv04_graph_mthd_bind_rop);
1282 NVOBJ_MTHD (dev, 0x005c, 0x0190, nv04_graph_mthd_bind_beta1);
1283 NVOBJ_MTHD (dev, 0x005c, 0x0194, nv04_graph_mthd_bind_beta4);
1284 NVOBJ_MTHD (dev, 0x005c, 0x0198, nv04_graph_mthd_bind_surf2d);
1285 NVOBJ_MTHD (dev, 0x005c, 0x02fc, nv04_graph_mthd_set_operation);
1286
1287 /* nv01 tri */
1288 NVOBJ_CLASS(dev, 0x001d, GR);
1289 NVOBJ_MTHD (dev, 0x001d, 0x0184, nv04_graph_mthd_bind_clip);
1290 NVOBJ_MTHD (dev, 0x001d, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1291 NVOBJ_MTHD (dev, 0x001d, 0x018c, nv04_graph_mthd_bind_rop);
1292 NVOBJ_MTHD (dev, 0x001d, 0x0190, nv04_graph_mthd_bind_beta1);
1293 NVOBJ_MTHD (dev, 0x001d, 0x0194, nv04_graph_mthd_bind_surf_dst);
1294 NVOBJ_MTHD (dev, 0x001d, 0x02fc, nv04_graph_mthd_set_operation);
1295
1296 /* nv04 tri */
1297 NVOBJ_CLASS(dev, 0x005d, GR);
1298 NVOBJ_MTHD (dev, 0x005d, 0x0184, nv04_graph_mthd_bind_clip);
1299 NVOBJ_MTHD (dev, 0x005d, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1300 NVOBJ_MTHD (dev, 0x005d, 0x018c, nv04_graph_mthd_bind_rop);
1301 NVOBJ_MTHD (dev, 0x005d, 0x0190, nv04_graph_mthd_bind_beta1);
1302 NVOBJ_MTHD (dev, 0x005d, 0x0194, nv04_graph_mthd_bind_beta4);
1303 NVOBJ_MTHD (dev, 0x005d, 0x0198, nv04_graph_mthd_bind_surf2d);
1304 NVOBJ_MTHD (dev, 0x005d, 0x02fc, nv04_graph_mthd_set_operation);
1305
1306 /* nv01 rect */
1307 NVOBJ_CLASS(dev, 0x001e, GR);
1308 NVOBJ_MTHD (dev, 0x001e, 0x0184, nv04_graph_mthd_bind_clip);
1309 NVOBJ_MTHD (dev, 0x001e, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1310 NVOBJ_MTHD (dev, 0x001e, 0x018c, nv04_graph_mthd_bind_rop);
1311 NVOBJ_MTHD (dev, 0x001e, 0x0190, nv04_graph_mthd_bind_beta1);
1312 NVOBJ_MTHD (dev, 0x001e, 0x0194, nv04_graph_mthd_bind_surf_dst);
1313 NVOBJ_MTHD (dev, 0x001e, 0x02fc, nv04_graph_mthd_set_operation);
1314
1315 /* nv04 rect */
1316 NVOBJ_CLASS(dev, 0x005e, GR);
1317 NVOBJ_MTHD (dev, 0x005e, 0x0184, nv04_graph_mthd_bind_clip);
1318 NVOBJ_MTHD (dev, 0x005e, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1319 NVOBJ_MTHD (dev, 0x005e, 0x018c, nv04_graph_mthd_bind_rop);
1320 NVOBJ_MTHD (dev, 0x005e, 0x0190, nv04_graph_mthd_bind_beta1);
1321 NVOBJ_MTHD (dev, 0x005e, 0x0194, nv04_graph_mthd_bind_beta4);
1322 NVOBJ_MTHD (dev, 0x005e, 0x0198, nv04_graph_mthd_bind_surf2d);
1323 NVOBJ_MTHD (dev, 0x005e, 0x02fc, nv04_graph_mthd_set_operation);
1324
1325 return 0;
1326}