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