1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
34static u32
35nv04_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
351struct 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
359struct 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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444static void
445nv04_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
459static void
460nv04_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
475 if (!(tmp & 0x02000000))
476 valid = 0;
477
478 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
479 valid = 0;
480
481 switch (op) {
482
483 case 0:
484 case 3:
485 break;
486
487 case 1:
488 if (!(tmp & 0x18000000))
489 valid = 0;
490 break;
491
492 case 2:
493 if (!(tmp & 0x20000000))
494 valid = 0;
495 break;
496
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
507static bool
508nv04_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
514 if (data > 2 && class < 0x40)
515 return false;
516 nv04_gr_set_ctx1(device, inst, 0x00038000, data << 15);
517
518 nv04_gr_set_ctx_val(device, inst, 0, 0);
519 return true;
520}
521
522static bool
523nv04_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
529 return false;
530 if (w & 0x8000)
531
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
540static bool
541nv04_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
547 return false;
548 if (w & 0x8000)
549
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
558static u8
559nv04_gr_mthd_bind_class(struct nvkm_device *device, u32 inst)
560{
561 return nvkm_rd32(device, 0x700000 + (inst << 4));
562}
563
564static bool
565nv04_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
580static bool
581nv04_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
600static bool
601nv01_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
614static bool
615nv04_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
628static bool
629nv04_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
642static bool
643nv04_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
656static bool
657nv04_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
670static bool
671nv04_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
684static bool
685nv04_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
698static bool
699nv04_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
712static bool
713nv04_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
726static bool
727nv01_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
740static bool
741nv01_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
748
749
750 case 0x57:
751 nv04_gr_set_ctx1(device, inst, 0x1000, 0x1000);
752 return true;
753 }
754 return false;
755}
756
757static bool
758nv03_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
773static bool
774nv04_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
790static bool
791nv01_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
809static bool
810nv04_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
828static bool
829nv04_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
847static bool
848nv01_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
865static bool
866nv04_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
884static bool
885nv03_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
901static bool
902nv04_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
919static bool
920nv03_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
935static bool
936nv04_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
952static bool
953nv04_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
965static bool
966nv03_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
979static bool
980nv01_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
996static bool
997nv04_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
1014static bool
1015nv04_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
1042static int
1043nv04_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
1062const struct nvkm_object_func
1063nv04_gr_object = {
1064 .bind = nv04_gr_object_bind,
1065};
1066
1067
1068
1069
1070
1071static struct nv04_gr_chan *
1072nv04_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
1084static int
1085nv04_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
1099static int
1100nv04_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
1113static void
1114nv04_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
1124 prev = nv04_gr_channel(gr);
1125 if (prev)
1126 nv04_gr_unload_context(prev);
1127
1128
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
1135static 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
1147static void *
1148nv04_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
1160static int
1161nv04_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
1177static const struct nvkm_object_func
1178nv04_gr_chan = {
1179 .dtor = nv04_gr_chan_dtor,
1180 .fini = nv04_gr_chan_fini,
1181};
1182
1183static int
1184nv04_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
1208
1209
1210bool
1211nv04_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
1232static const struct nvkm_bitfield
1233nv04_gr_intr_name[] = {
1234 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
1235 {}
1236};
1237
1238static const struct nvkm_bitfield
1239nv04_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
1247const struct nvkm_bitfield
1248nv04_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
1271static void
1272nv04_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
1327static int
1328nv04_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
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
1340
1341 nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x1231c000);
1342
1343
1344 nvkm_wr32(device, NV04_PGRAPH_DEBUG_1, 0x72111100);
1345
1346
1347 nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
1348
1349
1350
1351 nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
1352
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
1359 nvkm_wr32(device, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
1360 nvkm_wr32(device, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
1361 return 0;
1362}
1363
1364static const struct nvkm_gr_func
1365nv04_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 },
1371 { -1, -1, 0x0017, &nv04_gr_object },
1372 { -1, -1, 0x0018, &nv04_gr_object },
1373 { -1, -1, 0x0019, &nv04_gr_object },
1374 { -1, -1, 0x001c, &nv04_gr_object },
1375 { -1, -1, 0x001d, &nv04_gr_object },
1376 { -1, -1, 0x001e, &nv04_gr_object },
1377 { -1, -1, 0x001f, &nv04_gr_object },
1378 { -1, -1, 0x0021, &nv04_gr_object },
1379 { -1, -1, 0x0030, &nv04_gr_object },
1380 { -1, -1, 0x0036, &nv04_gr_object },
1381 { -1, -1, 0x0037, &nv04_gr_object },
1382 { -1, -1, 0x0038, &nv04_gr_object },
1383 { -1, -1, 0x0039, &nv04_gr_object },
1384 { -1, -1, 0x0042, &nv04_gr_object },
1385 { -1, -1, 0x0043, &nv04_gr_object },
1386 { -1, -1, 0x0044, &nv04_gr_object },
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 },
1391 { -1, -1, 0x0053, &nv04_gr_object },
1392 { -1, -1, 0x0054, &nv04_gr_object },
1393 { -1, -1, 0x0055, &nv04_gr_object },
1394 { -1, -1, 0x0057, &nv04_gr_object },
1395 { -1, -1, 0x0058, &nv04_gr_object },
1396 { -1, -1, 0x0059, &nv04_gr_object },
1397 { -1, -1, 0x005a, &nv04_gr_object },
1398 { -1, -1, 0x005b, &nv04_gr_object },
1399 { -1, -1, 0x005c, &nv04_gr_object },
1400 { -1, -1, 0x005d, &nv04_gr_object },
1401 { -1, -1, 0x005e, &nv04_gr_object },
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 },
1406 { -1, -1, 0x0065, &nv04_gr_object },
1407 { -1, -1, 0x0066, &nv04_gr_object },
1408 { -1, -1, 0x0072, &nv04_gr_object },
1409 { -1, -1, 0x0076, &nv04_gr_object },
1410 { -1, -1, 0x0077, &nv04_gr_object },
1411 {}
1412 }
1413};
1414
1415int
1416nv04_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, true, &gr->base);
1426}
1427