Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6
[pandora-kernel.git] / drivers / gpu / drm / nouveau / nv10_graph.c
1 /*
2  * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "drmP.h"
26 #include "drm.h"
27 #include "nouveau_drm.h"
28 #include "nouveau_drv.h"
29 #include "nouveau_util.h"
30
31 static int  nv10_graph_register(struct drm_device *);
32 static void nv10_graph_isr(struct drm_device *);
33
34 #define NV10_FIFO_NUMBER 32
35
36 struct pipe_state {
37         uint32_t pipe_0x0000[0x040/4];
38         uint32_t pipe_0x0040[0x010/4];
39         uint32_t pipe_0x0200[0x0c0/4];
40         uint32_t pipe_0x4400[0x080/4];
41         uint32_t pipe_0x6400[0x3b0/4];
42         uint32_t pipe_0x6800[0x2f0/4];
43         uint32_t pipe_0x6c00[0x030/4];
44         uint32_t pipe_0x7000[0x130/4];
45         uint32_t pipe_0x7400[0x0c0/4];
46         uint32_t pipe_0x7800[0x0c0/4];
47 };
48
49 static int nv10_graph_ctx_regs[] = {
50         NV10_PGRAPH_CTX_SWITCH(0),
51         NV10_PGRAPH_CTX_SWITCH(1),
52         NV10_PGRAPH_CTX_SWITCH(2),
53         NV10_PGRAPH_CTX_SWITCH(3),
54         NV10_PGRAPH_CTX_SWITCH(4),
55         NV10_PGRAPH_CTX_CACHE(0, 0),
56         NV10_PGRAPH_CTX_CACHE(0, 1),
57         NV10_PGRAPH_CTX_CACHE(0, 2),
58         NV10_PGRAPH_CTX_CACHE(0, 3),
59         NV10_PGRAPH_CTX_CACHE(0, 4),
60         NV10_PGRAPH_CTX_CACHE(1, 0),
61         NV10_PGRAPH_CTX_CACHE(1, 1),
62         NV10_PGRAPH_CTX_CACHE(1, 2),
63         NV10_PGRAPH_CTX_CACHE(1, 3),
64         NV10_PGRAPH_CTX_CACHE(1, 4),
65         NV10_PGRAPH_CTX_CACHE(2, 0),
66         NV10_PGRAPH_CTX_CACHE(2, 1),
67         NV10_PGRAPH_CTX_CACHE(2, 2),
68         NV10_PGRAPH_CTX_CACHE(2, 3),
69         NV10_PGRAPH_CTX_CACHE(2, 4),
70         NV10_PGRAPH_CTX_CACHE(3, 0),
71         NV10_PGRAPH_CTX_CACHE(3, 1),
72         NV10_PGRAPH_CTX_CACHE(3, 2),
73         NV10_PGRAPH_CTX_CACHE(3, 3),
74         NV10_PGRAPH_CTX_CACHE(3, 4),
75         NV10_PGRAPH_CTX_CACHE(4, 0),
76         NV10_PGRAPH_CTX_CACHE(4, 1),
77         NV10_PGRAPH_CTX_CACHE(4, 2),
78         NV10_PGRAPH_CTX_CACHE(4, 3),
79         NV10_PGRAPH_CTX_CACHE(4, 4),
80         NV10_PGRAPH_CTX_CACHE(5, 0),
81         NV10_PGRAPH_CTX_CACHE(5, 1),
82         NV10_PGRAPH_CTX_CACHE(5, 2),
83         NV10_PGRAPH_CTX_CACHE(5, 3),
84         NV10_PGRAPH_CTX_CACHE(5, 4),
85         NV10_PGRAPH_CTX_CACHE(6, 0),
86         NV10_PGRAPH_CTX_CACHE(6, 1),
87         NV10_PGRAPH_CTX_CACHE(6, 2),
88         NV10_PGRAPH_CTX_CACHE(6, 3),
89         NV10_PGRAPH_CTX_CACHE(6, 4),
90         NV10_PGRAPH_CTX_CACHE(7, 0),
91         NV10_PGRAPH_CTX_CACHE(7, 1),
92         NV10_PGRAPH_CTX_CACHE(7, 2),
93         NV10_PGRAPH_CTX_CACHE(7, 3),
94         NV10_PGRAPH_CTX_CACHE(7, 4),
95         NV10_PGRAPH_CTX_USER,
96         NV04_PGRAPH_DMA_START_0,
97         NV04_PGRAPH_DMA_START_1,
98         NV04_PGRAPH_DMA_LENGTH,
99         NV04_PGRAPH_DMA_MISC,
100         NV10_PGRAPH_DMA_PITCH,
101         NV04_PGRAPH_BOFFSET0,
102         NV04_PGRAPH_BBASE0,
103         NV04_PGRAPH_BLIMIT0,
104         NV04_PGRAPH_BOFFSET1,
105         NV04_PGRAPH_BBASE1,
106         NV04_PGRAPH_BLIMIT1,
107         NV04_PGRAPH_BOFFSET2,
108         NV04_PGRAPH_BBASE2,
109         NV04_PGRAPH_BLIMIT2,
110         NV04_PGRAPH_BOFFSET3,
111         NV04_PGRAPH_BBASE3,
112         NV04_PGRAPH_BLIMIT3,
113         NV04_PGRAPH_BOFFSET4,
114         NV04_PGRAPH_BBASE4,
115         NV04_PGRAPH_BLIMIT4,
116         NV04_PGRAPH_BOFFSET5,
117         NV04_PGRAPH_BBASE5,
118         NV04_PGRAPH_BLIMIT5,
119         NV04_PGRAPH_BPITCH0,
120         NV04_PGRAPH_BPITCH1,
121         NV04_PGRAPH_BPITCH2,
122         NV04_PGRAPH_BPITCH3,
123         NV04_PGRAPH_BPITCH4,
124         NV10_PGRAPH_SURFACE,
125         NV10_PGRAPH_STATE,
126         NV04_PGRAPH_BSWIZZLE2,
127         NV04_PGRAPH_BSWIZZLE5,
128         NV04_PGRAPH_BPIXEL,
129         NV10_PGRAPH_NOTIFY,
130         NV04_PGRAPH_PATT_COLOR0,
131         NV04_PGRAPH_PATT_COLOR1,
132         NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
133         0x00400904,
134         0x00400908,
135         0x0040090c,
136         0x00400910,
137         0x00400914,
138         0x00400918,
139         0x0040091c,
140         0x00400920,
141         0x00400924,
142         0x00400928,
143         0x0040092c,
144         0x00400930,
145         0x00400934,
146         0x00400938,
147         0x0040093c,
148         0x00400940,
149         0x00400944,
150         0x00400948,
151         0x0040094c,
152         0x00400950,
153         0x00400954,
154         0x00400958,
155         0x0040095c,
156         0x00400960,
157         0x00400964,
158         0x00400968,
159         0x0040096c,
160         0x00400970,
161         0x00400974,
162         0x00400978,
163         0x0040097c,
164         0x00400980,
165         0x00400984,
166         0x00400988,
167         0x0040098c,
168         0x00400990,
169         0x00400994,
170         0x00400998,
171         0x0040099c,
172         0x004009a0,
173         0x004009a4,
174         0x004009a8,
175         0x004009ac,
176         0x004009b0,
177         0x004009b4,
178         0x004009b8,
179         0x004009bc,
180         0x004009c0,
181         0x004009c4,
182         0x004009c8,
183         0x004009cc,
184         0x004009d0,
185         0x004009d4,
186         0x004009d8,
187         0x004009dc,
188         0x004009e0,
189         0x004009e4,
190         0x004009e8,
191         0x004009ec,
192         0x004009f0,
193         0x004009f4,
194         0x004009f8,
195         0x004009fc,
196         NV04_PGRAPH_PATTERN,    /* 2 values from 0x400808 to 0x40080c */
197         0x0040080c,
198         NV04_PGRAPH_PATTERN_SHAPE,
199         NV03_PGRAPH_MONO_COLOR0,
200         NV04_PGRAPH_ROP3,
201         NV04_PGRAPH_CHROMA,
202         NV04_PGRAPH_BETA_AND,
203         NV04_PGRAPH_BETA_PREMULT,
204         0x00400e70,
205         0x00400e74,
206         0x00400e78,
207         0x00400e7c,
208         0x00400e80,
209         0x00400e84,
210         0x00400e88,
211         0x00400e8c,
212         0x00400ea0,
213         0x00400ea4,
214         0x00400ea8,
215         0x00400e90,
216         0x00400e94,
217         0x00400e98,
218         0x00400e9c,
219         NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
220         NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20-0x400f3c */
221         0x00400f04,
222         0x00400f24,
223         0x00400f08,
224         0x00400f28,
225         0x00400f0c,
226         0x00400f2c,
227         0x00400f10,
228         0x00400f30,
229         0x00400f14,
230         0x00400f34,
231         0x00400f18,
232         0x00400f38,
233         0x00400f1c,
234         0x00400f3c,
235         NV10_PGRAPH_XFMODE0,
236         NV10_PGRAPH_XFMODE1,
237         NV10_PGRAPH_GLOBALSTATE0,
238         NV10_PGRAPH_GLOBALSTATE1,
239         NV04_PGRAPH_STORED_FMT,
240         NV04_PGRAPH_SOURCE_COLOR,
241         NV03_PGRAPH_ABS_X_RAM,  /* 32 values from 0x400400 to 0x40047c */
242         NV03_PGRAPH_ABS_Y_RAM,  /* 32 values from 0x400480 to 0x4004fc */
243         0x00400404,
244         0x00400484,
245         0x00400408,
246         0x00400488,
247         0x0040040c,
248         0x0040048c,
249         0x00400410,
250         0x00400490,
251         0x00400414,
252         0x00400494,
253         0x00400418,
254         0x00400498,
255         0x0040041c,
256         0x0040049c,
257         0x00400420,
258         0x004004a0,
259         0x00400424,
260         0x004004a4,
261         0x00400428,
262         0x004004a8,
263         0x0040042c,
264         0x004004ac,
265         0x00400430,
266         0x004004b0,
267         0x00400434,
268         0x004004b4,
269         0x00400438,
270         0x004004b8,
271         0x0040043c,
272         0x004004bc,
273         0x00400440,
274         0x004004c0,
275         0x00400444,
276         0x004004c4,
277         0x00400448,
278         0x004004c8,
279         0x0040044c,
280         0x004004cc,
281         0x00400450,
282         0x004004d0,
283         0x00400454,
284         0x004004d4,
285         0x00400458,
286         0x004004d8,
287         0x0040045c,
288         0x004004dc,
289         0x00400460,
290         0x004004e0,
291         0x00400464,
292         0x004004e4,
293         0x00400468,
294         0x004004e8,
295         0x0040046c,
296         0x004004ec,
297         0x00400470,
298         0x004004f0,
299         0x00400474,
300         0x004004f4,
301         0x00400478,
302         0x004004f8,
303         0x0040047c,
304         0x004004fc,
305         NV03_PGRAPH_ABS_UCLIP_XMIN,
306         NV03_PGRAPH_ABS_UCLIP_XMAX,
307         NV03_PGRAPH_ABS_UCLIP_YMIN,
308         NV03_PGRAPH_ABS_UCLIP_YMAX,
309         0x00400550,
310         0x00400558,
311         0x00400554,
312         0x0040055c,
313         NV03_PGRAPH_ABS_UCLIPA_XMIN,
314         NV03_PGRAPH_ABS_UCLIPA_XMAX,
315         NV03_PGRAPH_ABS_UCLIPA_YMIN,
316         NV03_PGRAPH_ABS_UCLIPA_YMAX,
317         NV03_PGRAPH_ABS_ICLIP_XMAX,
318         NV03_PGRAPH_ABS_ICLIP_YMAX,
319         NV03_PGRAPH_XY_LOGIC_MISC0,
320         NV03_PGRAPH_XY_LOGIC_MISC1,
321         NV03_PGRAPH_XY_LOGIC_MISC2,
322         NV03_PGRAPH_XY_LOGIC_MISC3,
323         NV03_PGRAPH_CLIPX_0,
324         NV03_PGRAPH_CLIPX_1,
325         NV03_PGRAPH_CLIPY_0,
326         NV03_PGRAPH_CLIPY_1,
327         NV10_PGRAPH_COMBINER0_IN_ALPHA,
328         NV10_PGRAPH_COMBINER1_IN_ALPHA,
329         NV10_PGRAPH_COMBINER0_IN_RGB,
330         NV10_PGRAPH_COMBINER1_IN_RGB,
331         NV10_PGRAPH_COMBINER_COLOR0,
332         NV10_PGRAPH_COMBINER_COLOR1,
333         NV10_PGRAPH_COMBINER0_OUT_ALPHA,
334         NV10_PGRAPH_COMBINER1_OUT_ALPHA,
335         NV10_PGRAPH_COMBINER0_OUT_RGB,
336         NV10_PGRAPH_COMBINER1_OUT_RGB,
337         NV10_PGRAPH_COMBINER_FINAL0,
338         NV10_PGRAPH_COMBINER_FINAL1,
339         0x00400e00,
340         0x00400e04,
341         0x00400e08,
342         0x00400e0c,
343         0x00400e10,
344         0x00400e14,
345         0x00400e18,
346         0x00400e1c,
347         0x00400e20,
348         0x00400e24,
349         0x00400e28,
350         0x00400e2c,
351         0x00400e30,
352         0x00400e34,
353         0x00400e38,
354         0x00400e3c,
355         NV04_PGRAPH_PASSTHRU_0,
356         NV04_PGRAPH_PASSTHRU_1,
357         NV04_PGRAPH_PASSTHRU_2,
358         NV10_PGRAPH_DIMX_TEXTURE,
359         NV10_PGRAPH_WDIMX_TEXTURE,
360         NV10_PGRAPH_DVD_COLORFMT,
361         NV10_PGRAPH_SCALED_FORMAT,
362         NV04_PGRAPH_MISC24_0,
363         NV04_PGRAPH_MISC24_1,
364         NV04_PGRAPH_MISC24_2,
365         NV03_PGRAPH_X_MISC,
366         NV03_PGRAPH_Y_MISC,
367         NV04_PGRAPH_VALID1,
368         NV04_PGRAPH_VALID2,
369 };
370
371 static int nv17_graph_ctx_regs[] = {
372         NV10_PGRAPH_DEBUG_4,
373         0x004006b0,
374         0x00400eac,
375         0x00400eb0,
376         0x00400eb4,
377         0x00400eb8,
378         0x00400ebc,
379         0x00400ec0,
380         0x00400ec4,
381         0x00400ec8,
382         0x00400ecc,
383         0x00400ed0,
384         0x00400ed4,
385         0x00400ed8,
386         0x00400edc,
387         0x00400ee0,
388         0x00400a00,
389         0x00400a04,
390 };
391
392 struct graph_state {
393         int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
394         int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
395         struct pipe_state pipe_state;
396         uint32_t lma_window[4];
397 };
398
399 #define PIPE_SAVE(dev, state, addr)                                     \
400         do {                                                            \
401                 int __i;                                                \
402                 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr);           \
403                 for (__i = 0; __i < ARRAY_SIZE(state); __i++)           \
404                         state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
405         } while (0)
406
407 #define PIPE_RESTORE(dev, state, addr)                                  \
408         do {                                                            \
409                 int __i;                                                \
410                 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr);           \
411                 for (__i = 0; __i < ARRAY_SIZE(state); __i++)           \
412                         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \
413         } while (0)
414
415 static void nv10_graph_save_pipe(struct nouveau_channel *chan)
416 {
417         struct drm_device *dev = chan->dev;
418         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
419         struct pipe_state *pipe = &pgraph_ctx->pipe_state;
420
421         PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
422         PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
423         PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400);
424         PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800);
425         PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00);
426         PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000);
427         PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400);
428         PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800);
429         PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040);
430         PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000);
431 }
432
433 static void nv10_graph_load_pipe(struct nouveau_channel *chan)
434 {
435         struct drm_device *dev = chan->dev;
436         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
437         struct pipe_state *pipe = &pgraph_ctx->pipe_state;
438         uint32_t xfmode0, xfmode1;
439         int i;
440
441         nouveau_wait_for_idle(dev);
442         /* XXX check haiku comments */
443         xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
444         xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
445         nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
446         nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
447         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
448         for (i = 0; i < 4; i++)
449                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
450         for (i = 0; i < 4; i++)
451                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
452
453         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
454         for (i = 0; i < 3; i++)
455                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
456
457         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
458         for (i = 0; i < 3; i++)
459                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
460
461         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
462         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
463
464
465         PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
466         nouveau_wait_for_idle(dev);
467
468         /* restore XFMODE */
469         nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
470         nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
471         PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400);
472         PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800);
473         PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00);
474         PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000);
475         PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400);
476         PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800);
477         PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
478         PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000);
479         PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040);
480         nouveau_wait_for_idle(dev);
481 }
482
483 static void nv10_graph_create_pipe(struct nouveau_channel *chan)
484 {
485         struct drm_device *dev = chan->dev;
486         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
487         struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
488         uint32_t *fifo_pipe_state_addr;
489         int i;
490 #define PIPE_INIT(addr) \
491         do { \
492                 fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
493         } while (0)
494 #define PIPE_INIT_END(addr) \
495         do { \
496                 uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
497                                 ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
498                 if (fifo_pipe_state_addr != __end_addr) \
499                         NV_ERROR(dev, "incomplete pipe init for 0x%x :  %p/%p\n", \
500                                 addr, fifo_pipe_state_addr, __end_addr); \
501         } while (0)
502 #define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
503
504         PIPE_INIT(0x0200);
505         for (i = 0; i < 48; i++)
506                 NV_WRITE_PIPE_INIT(0x00000000);
507         PIPE_INIT_END(0x0200);
508
509         PIPE_INIT(0x6400);
510         for (i = 0; i < 211; i++)
511                 NV_WRITE_PIPE_INIT(0x00000000);
512         NV_WRITE_PIPE_INIT(0x3f800000);
513         NV_WRITE_PIPE_INIT(0x40000000);
514         NV_WRITE_PIPE_INIT(0x40000000);
515         NV_WRITE_PIPE_INIT(0x40000000);
516         NV_WRITE_PIPE_INIT(0x40000000);
517         NV_WRITE_PIPE_INIT(0x00000000);
518         NV_WRITE_PIPE_INIT(0x00000000);
519         NV_WRITE_PIPE_INIT(0x3f800000);
520         NV_WRITE_PIPE_INIT(0x00000000);
521         NV_WRITE_PIPE_INIT(0x3f000000);
522         NV_WRITE_PIPE_INIT(0x3f000000);
523         NV_WRITE_PIPE_INIT(0x00000000);
524         NV_WRITE_PIPE_INIT(0x00000000);
525         NV_WRITE_PIPE_INIT(0x00000000);
526         NV_WRITE_PIPE_INIT(0x00000000);
527         NV_WRITE_PIPE_INIT(0x3f800000);
528         NV_WRITE_PIPE_INIT(0x00000000);
529         NV_WRITE_PIPE_INIT(0x00000000);
530         NV_WRITE_PIPE_INIT(0x00000000);
531         NV_WRITE_PIPE_INIT(0x00000000);
532         NV_WRITE_PIPE_INIT(0x00000000);
533         NV_WRITE_PIPE_INIT(0x3f800000);
534         NV_WRITE_PIPE_INIT(0x3f800000);
535         NV_WRITE_PIPE_INIT(0x3f800000);
536         NV_WRITE_PIPE_INIT(0x3f800000);
537         PIPE_INIT_END(0x6400);
538
539         PIPE_INIT(0x6800);
540         for (i = 0; i < 162; i++)
541                 NV_WRITE_PIPE_INIT(0x00000000);
542         NV_WRITE_PIPE_INIT(0x3f800000);
543         for (i = 0; i < 25; i++)
544                 NV_WRITE_PIPE_INIT(0x00000000);
545         PIPE_INIT_END(0x6800);
546
547         PIPE_INIT(0x6c00);
548         NV_WRITE_PIPE_INIT(0x00000000);
549         NV_WRITE_PIPE_INIT(0x00000000);
550         NV_WRITE_PIPE_INIT(0x00000000);
551         NV_WRITE_PIPE_INIT(0x00000000);
552         NV_WRITE_PIPE_INIT(0xbf800000);
553         NV_WRITE_PIPE_INIT(0x00000000);
554         NV_WRITE_PIPE_INIT(0x00000000);
555         NV_WRITE_PIPE_INIT(0x00000000);
556         NV_WRITE_PIPE_INIT(0x00000000);
557         NV_WRITE_PIPE_INIT(0x00000000);
558         NV_WRITE_PIPE_INIT(0x00000000);
559         NV_WRITE_PIPE_INIT(0x00000000);
560         PIPE_INIT_END(0x6c00);
561
562         PIPE_INIT(0x7000);
563         NV_WRITE_PIPE_INIT(0x00000000);
564         NV_WRITE_PIPE_INIT(0x00000000);
565         NV_WRITE_PIPE_INIT(0x00000000);
566         NV_WRITE_PIPE_INIT(0x00000000);
567         NV_WRITE_PIPE_INIT(0x00000000);
568         NV_WRITE_PIPE_INIT(0x00000000);
569         NV_WRITE_PIPE_INIT(0x00000000);
570         NV_WRITE_PIPE_INIT(0x00000000);
571         NV_WRITE_PIPE_INIT(0x00000000);
572         NV_WRITE_PIPE_INIT(0x00000000);
573         NV_WRITE_PIPE_INIT(0x00000000);
574         NV_WRITE_PIPE_INIT(0x00000000);
575         NV_WRITE_PIPE_INIT(0x7149f2ca);
576         NV_WRITE_PIPE_INIT(0x00000000);
577         NV_WRITE_PIPE_INIT(0x00000000);
578         NV_WRITE_PIPE_INIT(0x00000000);
579         NV_WRITE_PIPE_INIT(0x7149f2ca);
580         NV_WRITE_PIPE_INIT(0x00000000);
581         NV_WRITE_PIPE_INIT(0x00000000);
582         NV_WRITE_PIPE_INIT(0x00000000);
583         NV_WRITE_PIPE_INIT(0x7149f2ca);
584         NV_WRITE_PIPE_INIT(0x00000000);
585         NV_WRITE_PIPE_INIT(0x00000000);
586         NV_WRITE_PIPE_INIT(0x00000000);
587         NV_WRITE_PIPE_INIT(0x7149f2ca);
588         NV_WRITE_PIPE_INIT(0x00000000);
589         NV_WRITE_PIPE_INIT(0x00000000);
590         NV_WRITE_PIPE_INIT(0x00000000);
591         NV_WRITE_PIPE_INIT(0x7149f2ca);
592         NV_WRITE_PIPE_INIT(0x00000000);
593         NV_WRITE_PIPE_INIT(0x00000000);
594         NV_WRITE_PIPE_INIT(0x00000000);
595         NV_WRITE_PIPE_INIT(0x7149f2ca);
596         NV_WRITE_PIPE_INIT(0x00000000);
597         NV_WRITE_PIPE_INIT(0x00000000);
598         NV_WRITE_PIPE_INIT(0x00000000);
599         NV_WRITE_PIPE_INIT(0x7149f2ca);
600         NV_WRITE_PIPE_INIT(0x00000000);
601         NV_WRITE_PIPE_INIT(0x00000000);
602         NV_WRITE_PIPE_INIT(0x00000000);
603         NV_WRITE_PIPE_INIT(0x7149f2ca);
604         for (i = 0; i < 35; i++)
605                 NV_WRITE_PIPE_INIT(0x00000000);
606         PIPE_INIT_END(0x7000);
607
608         PIPE_INIT(0x7400);
609         for (i = 0; i < 48; i++)
610                 NV_WRITE_PIPE_INIT(0x00000000);
611         PIPE_INIT_END(0x7400);
612
613         PIPE_INIT(0x7800);
614         for (i = 0; i < 48; i++)
615                 NV_WRITE_PIPE_INIT(0x00000000);
616         PIPE_INIT_END(0x7800);
617
618         PIPE_INIT(0x4400);
619         for (i = 0; i < 32; i++)
620                 NV_WRITE_PIPE_INIT(0x00000000);
621         PIPE_INIT_END(0x4400);
622
623         PIPE_INIT(0x0000);
624         for (i = 0; i < 16; i++)
625                 NV_WRITE_PIPE_INIT(0x00000000);
626         PIPE_INIT_END(0x0000);
627
628         PIPE_INIT(0x0040);
629         for (i = 0; i < 4; i++)
630                 NV_WRITE_PIPE_INIT(0x00000000);
631         PIPE_INIT_END(0x0040);
632
633 #undef PIPE_INIT
634 #undef PIPE_INIT_END
635 #undef NV_WRITE_PIPE_INIT
636 }
637
638 static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
639 {
640         int i;
641         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
642                 if (nv10_graph_ctx_regs[i] == reg)
643                         return i;
644         }
645         NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
646         return -1;
647 }
648
649 static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
650 {
651         int i;
652         for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
653                 if (nv17_graph_ctx_regs[i] == reg)
654                         return i;
655         }
656         NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
657         return -1;
658 }
659
660 static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
661                                        uint32_t inst)
662 {
663         struct drm_device *dev = chan->dev;
664         struct drm_nouveau_private *dev_priv = dev->dev_private;
665         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
666         uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
667         uint32_t ctx_user, ctx_switch[5];
668         int i, subchan = -1;
669
670         /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
671          * that cannot be restored via MMIO. Do it through the FIFO
672          * instead.
673          */
674
675         /* Look for a celsius object */
676         for (i = 0; i < 8; i++) {
677                 int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
678
679                 if (class == 0x56 || class == 0x96 || class == 0x99) {
680                         subchan = i;
681                         break;
682                 }
683         }
684
685         if (subchan < 0 || !inst)
686                 return;
687
688         /* Save the current ctx object */
689         ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
690         for (i = 0; i < 5; i++)
691                 ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i));
692
693         /* Save the FIFO state */
694         st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
695         st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL);
696         st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH);
697         fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR);
698
699         for (i = 0; i < ARRAY_SIZE(fifo); i++)
700                 fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i);
701
702         /* Switch to the celsius subchannel */
703         for (i = 0; i < 5; i++)
704                 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i),
705                         nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i)));
706         nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
707
708         /* Inject NV10TCL_DMA_VTXBUF */
709         nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
710         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2,
711                 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
712         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
713         nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
714         pgraph->fifo_access(dev, true);
715         pgraph->fifo_access(dev, false);
716
717         /* Restore the FIFO state */
718         for (i = 0; i < ARRAY_SIZE(fifo); i++)
719                 nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]);
720
721         nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
722         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2);
723         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
724         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
725
726         /* Restore the current ctx object */
727         for (i = 0; i < 5; i++)
728                 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
729         nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
730 }
731
732 int nv10_graph_load_context(struct nouveau_channel *chan)
733 {
734         struct drm_device *dev = chan->dev;
735         struct drm_nouveau_private *dev_priv = dev->dev_private;
736         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
737         uint32_t tmp;
738         int i;
739
740         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
741                 nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
742         if (dev_priv->chipset >= 0x17) {
743                 for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
744                         nv_wr32(dev, nv17_graph_ctx_regs[i],
745                                                 pgraph_ctx->nv17[i]);
746         }
747
748         nv10_graph_load_pipe(chan);
749         nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
750                                           & 0xffff));
751
752         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
753         tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
754         nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
755         tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
756         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
757         return 0;
758 }
759
760 int
761 nv10_graph_unload_context(struct drm_device *dev)
762 {
763         struct drm_nouveau_private *dev_priv = dev->dev_private;
764         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
765         struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
766         struct nouveau_channel *chan;
767         struct graph_state *ctx;
768         uint32_t tmp;
769         int i;
770
771         chan = pgraph->channel(dev);
772         if (!chan)
773                 return 0;
774         ctx = chan->pgraph_ctx;
775
776         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
777                 ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
778
779         if (dev_priv->chipset >= 0x17) {
780                 for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
781                         ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
782         }
783
784         nv10_graph_save_pipe(chan);
785
786         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
787         tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
788         tmp |= (pfifo->channels - 1) << 24;
789         nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
790         return 0;
791 }
792
793 static void
794 nv10_graph_context_switch(struct drm_device *dev)
795 {
796         struct drm_nouveau_private *dev_priv = dev->dev_private;
797         struct nouveau_channel *chan = NULL;
798         int chid;
799
800         nouveau_wait_for_idle(dev);
801
802         /* If previous context is valid, we need to save it */
803         nv10_graph_unload_context(dev);
804
805         /* Load context for next channel */
806         chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
807         chan = dev_priv->channels.ptr[chid];
808         if (chan && chan->pgraph_ctx)
809                 nv10_graph_load_context(chan);
810 }
811
812 #define NV_WRITE_CTX(reg, val) do { \
813         int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
814         if (offset > 0) \
815                 pgraph_ctx->nv10[offset] = val; \
816         } while (0)
817
818 #define NV17_WRITE_CTX(reg, val) do { \
819         int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \
820         if (offset > 0) \
821                 pgraph_ctx->nv17[offset] = val; \
822         } while (0)
823
824 struct nouveau_channel *
825 nv10_graph_channel(struct drm_device *dev)
826 {
827         struct drm_nouveau_private *dev_priv = dev->dev_private;
828         int chid = dev_priv->engine.fifo.channels;
829
830         if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000)
831                 chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24;
832
833         if (chid >= dev_priv->engine.fifo.channels)
834                 return NULL;
835
836         return dev_priv->channels.ptr[chid];
837 }
838
839 int nv10_graph_create_context(struct nouveau_channel *chan)
840 {
841         struct drm_device *dev = chan->dev;
842         struct drm_nouveau_private *dev_priv = dev->dev_private;
843         struct graph_state *pgraph_ctx;
844
845         NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
846
847         chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
848                                                 GFP_KERNEL);
849         if (pgraph_ctx == NULL)
850                 return -ENOMEM;
851
852
853         NV_WRITE_CTX(0x00400e88, 0x08000000);
854         NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
855         NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
856         NV_WRITE_CTX(0x00400e10, 0x00001000);
857         NV_WRITE_CTX(0x00400e14, 0x00001000);
858         NV_WRITE_CTX(0x00400e30, 0x00080008);
859         NV_WRITE_CTX(0x00400e34, 0x00080008);
860         if (dev_priv->chipset >= 0x17) {
861                 /* is it really needed ??? */
862                 NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
863                                         nv_rd32(dev, NV10_PGRAPH_DEBUG_4));
864                 NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0));
865                 NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
866                 NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
867                 NV17_WRITE_CTX(0x00400ec0, 0x00000080);
868                 NV17_WRITE_CTX(0x00400ed0, 0x00000080);
869         }
870         NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24);
871
872         nv10_graph_create_pipe(chan);
873         return 0;
874 }
875
876 void nv10_graph_destroy_context(struct nouveau_channel *chan)
877 {
878         struct drm_device *dev = chan->dev;
879         struct drm_nouveau_private *dev_priv = dev->dev_private;
880         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
881         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
882         unsigned long flags;
883
884         spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
885         pgraph->fifo_access(dev, false);
886
887         /* Unload the context if it's the currently active one */
888         if (pgraph->channel(dev) == chan)
889                 pgraph->unload_context(dev);
890
891         /* Free the context resources */
892         kfree(pgraph_ctx);
893         chan->pgraph_ctx = NULL;
894
895         pgraph->fifo_access(dev, true);
896         spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
897 }
898
899 void
900 nv10_graph_set_tile_region(struct drm_device *dev, int i)
901 {
902         struct drm_nouveau_private *dev_priv = dev->dev_private;
903         struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
904
905         nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit);
906         nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch);
907         nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr);
908 }
909
910 int nv10_graph_init(struct drm_device *dev)
911 {
912         struct drm_nouveau_private *dev_priv = dev->dev_private;
913         uint32_t tmp;
914         int ret, i;
915
916         nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
917                         ~NV_PMC_ENABLE_PGRAPH);
918         nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
919                          NV_PMC_ENABLE_PGRAPH);
920
921         ret = nv10_graph_register(dev);
922         if (ret)
923                 return ret;
924
925         nouveau_irq_register(dev, 12, nv10_graph_isr);
926         nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
927         nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
928
929         nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
930         nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
931         nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
932         /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
933         nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
934         nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
935                                       (1<<29) |
936                                       (1<<31));
937         if (dev_priv->chipset >= 0x17) {
938                 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
939                 nv_wr32(dev, 0x400a10, 0x3ff3fb6);
940                 nv_wr32(dev, 0x400838, 0x2f8684);
941                 nv_wr32(dev, 0x40083c, 0x115f3f);
942                 nv_wr32(dev, 0x004006b0, 0x40000020);
943         } else
944                 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
945
946         /* Turn all the tiling regions off. */
947         for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
948                 nv10_graph_set_tile_region(dev, i);
949
950         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
951         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
952         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
953         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
954         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
955         nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
956
957         tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
958         tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
959         nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
960         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
961         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
962
963         return 0;
964 }
965
966 void nv10_graph_takedown(struct drm_device *dev)
967 {
968         nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
969         nouveau_irq_unregister(dev, 12);
970 }
971
972 static int
973 nv17_graph_mthd_lma_window(struct nouveau_channel *chan,
974                            u32 class, u32 mthd, u32 data)
975 {
976         struct drm_device *dev = chan->dev;
977         struct graph_state *ctx = chan->pgraph_ctx;
978         struct pipe_state *pipe = &ctx->pipe_state;
979         uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
980         uint32_t xfmode0, xfmode1;
981         int i;
982
983         ctx->lma_window[(mthd - 0x1638) / 4] = data;
984
985         if (mthd != 0x1644)
986                 return 0;
987
988         nouveau_wait_for_idle(dev);
989
990         PIPE_SAVE(dev, pipe_0x0040, 0x0040);
991         PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
992
993         PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
994
995         nouveau_wait_for_idle(dev);
996
997         xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
998         xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
999
1000         PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
1001         PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
1002         PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
1003         PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
1004
1005         nouveau_wait_for_idle(dev);
1006
1007         nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
1008         nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
1009         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
1010         for (i = 0; i < 4; i++)
1011                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
1012         for (i = 0; i < 4; i++)
1013                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1014
1015         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
1016         for (i = 0; i < 3; i++)
1017                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
1018
1019         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
1020         for (i = 0; i < 3; i++)
1021                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1022
1023         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
1024         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
1025
1026         PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
1027
1028         nouveau_wait_for_idle(dev);
1029
1030         PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
1031
1032         nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
1033         nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
1034
1035         PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
1036         PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
1037         PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
1038         PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
1039
1040         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
1041         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1042
1043         nouveau_wait_for_idle(dev);
1044
1045         return 0;
1046 }
1047
1048 static int
1049 nv17_graph_mthd_lma_enable(struct nouveau_channel *chan,
1050                            u32 class, u32 mthd, u32 data)
1051 {
1052         struct drm_device *dev = chan->dev;
1053
1054         nouveau_wait_for_idle(dev);
1055
1056         nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
1057                 nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
1058         nv_wr32(dev, 0x004006b0,
1059                 nv_rd32(dev, 0x004006b0) | 0x8 << 24);
1060
1061         return 0;
1062 }
1063
1064 static int
1065 nv10_graph_register(struct drm_device *dev)
1066 {
1067         struct drm_nouveau_private *dev_priv = dev->dev_private;
1068
1069         if (dev_priv->engine.graph.registered)
1070                 return 0;
1071
1072         NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
1073         NVOBJ_CLASS(dev, 0x0030, GR); /* null */
1074         NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
1075         NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
1076         NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */
1077         NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
1078         NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
1079         NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
1080         NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
1081         NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
1082         NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
1083         NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
1084         NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
1085         NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
1086         NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */
1087         NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */
1088         NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */
1089         NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */
1090
1091         /* celcius */
1092         if (dev_priv->chipset <= 0x10) {
1093                 NVOBJ_CLASS(dev, 0x0056, GR);
1094         } else
1095         if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) {
1096                 NVOBJ_CLASS(dev, 0x0096, GR);
1097         } else {
1098                 NVOBJ_CLASS(dev, 0x0099, GR);
1099                 NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window);
1100                 NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window);
1101                 NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window);
1102                 NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window);
1103                 NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable);
1104         }
1105
1106         /* nvsw */
1107         NVOBJ_CLASS(dev, 0x506e, SW);
1108         NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
1109
1110         dev_priv->engine.graph.registered = true;
1111         return 0;
1112 }
1113
1114 struct nouveau_bitfield nv10_graph_intr[] = {
1115         { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
1116         { NV_PGRAPH_INTR_ERROR,  "ERROR"  },
1117         {}
1118 };
1119
1120 struct nouveau_bitfield nv10_graph_nstatus[] =
1121 {
1122         { NV10_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
1123         { NV10_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
1124         { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
1125         { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" },
1126         {}
1127 };
1128
1129 static void
1130 nv10_graph_isr(struct drm_device *dev)
1131 {
1132         u32 stat;
1133
1134         while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
1135                 u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
1136                 u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
1137                 u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
1138                 u32 chid = (addr & 0x01f00000) >> 20;
1139                 u32 subc = (addr & 0x00070000) >> 16;
1140                 u32 mthd = (addr & 0x00001ffc);
1141                 u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
1142                 u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff;
1143                 u32 show = stat;
1144
1145                 if (stat & NV_PGRAPH_INTR_ERROR) {
1146                         if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
1147                                 if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
1148                                         show &= ~NV_PGRAPH_INTR_ERROR;
1149                         }
1150                 }
1151
1152                 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1153                         nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1154                         stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1155                         show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1156                         nv10_graph_context_switch(dev);
1157                 }
1158
1159                 nv_wr32(dev, NV03_PGRAPH_INTR, stat);
1160                 nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
1161
1162                 if (show && nouveau_ratelimit()) {
1163                         NV_INFO(dev, "PGRAPH -");
1164                         nouveau_bitfield_print(nv10_graph_intr, show);
1165                         printk(" nsource:");
1166                         nouveau_bitfield_print(nv04_graph_nsource, nsource);
1167                         printk(" nstatus:");
1168                         nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
1169                         printk("\n");
1170                         NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
1171                                      "mthd 0x%04x data 0x%08x\n",
1172                                 chid, subc, class, mthd, data);
1173                 }
1174         }
1175 }