Merge git://git.infradead.org/mtd-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
30 #define NV10_FIFO_NUMBER 32
31
32 struct pipe_state {
33         uint32_t pipe_0x0000[0x040/4];
34         uint32_t pipe_0x0040[0x010/4];
35         uint32_t pipe_0x0200[0x0c0/4];
36         uint32_t pipe_0x4400[0x080/4];
37         uint32_t pipe_0x6400[0x3b0/4];
38         uint32_t pipe_0x6800[0x2f0/4];
39         uint32_t pipe_0x6c00[0x030/4];
40         uint32_t pipe_0x7000[0x130/4];
41         uint32_t pipe_0x7400[0x0c0/4];
42         uint32_t pipe_0x7800[0x0c0/4];
43 };
44
45 static int nv10_graph_ctx_regs[] = {
46         NV10_PGRAPH_CTX_SWITCH(0),
47         NV10_PGRAPH_CTX_SWITCH(1),
48         NV10_PGRAPH_CTX_SWITCH(2),
49         NV10_PGRAPH_CTX_SWITCH(3),
50         NV10_PGRAPH_CTX_SWITCH(4),
51         NV10_PGRAPH_CTX_CACHE(0, 0),
52         NV10_PGRAPH_CTX_CACHE(0, 1),
53         NV10_PGRAPH_CTX_CACHE(0, 2),
54         NV10_PGRAPH_CTX_CACHE(0, 3),
55         NV10_PGRAPH_CTX_CACHE(0, 4),
56         NV10_PGRAPH_CTX_CACHE(1, 0),
57         NV10_PGRAPH_CTX_CACHE(1, 1),
58         NV10_PGRAPH_CTX_CACHE(1, 2),
59         NV10_PGRAPH_CTX_CACHE(1, 3),
60         NV10_PGRAPH_CTX_CACHE(1, 4),
61         NV10_PGRAPH_CTX_CACHE(2, 0),
62         NV10_PGRAPH_CTX_CACHE(2, 1),
63         NV10_PGRAPH_CTX_CACHE(2, 2),
64         NV10_PGRAPH_CTX_CACHE(2, 3),
65         NV10_PGRAPH_CTX_CACHE(2, 4),
66         NV10_PGRAPH_CTX_CACHE(3, 0),
67         NV10_PGRAPH_CTX_CACHE(3, 1),
68         NV10_PGRAPH_CTX_CACHE(3, 2),
69         NV10_PGRAPH_CTX_CACHE(3, 3),
70         NV10_PGRAPH_CTX_CACHE(3, 4),
71         NV10_PGRAPH_CTX_CACHE(4, 0),
72         NV10_PGRAPH_CTX_CACHE(4, 1),
73         NV10_PGRAPH_CTX_CACHE(4, 2),
74         NV10_PGRAPH_CTX_CACHE(4, 3),
75         NV10_PGRAPH_CTX_CACHE(4, 4),
76         NV10_PGRAPH_CTX_CACHE(5, 0),
77         NV10_PGRAPH_CTX_CACHE(5, 1),
78         NV10_PGRAPH_CTX_CACHE(5, 2),
79         NV10_PGRAPH_CTX_CACHE(5, 3),
80         NV10_PGRAPH_CTX_CACHE(5, 4),
81         NV10_PGRAPH_CTX_CACHE(6, 0),
82         NV10_PGRAPH_CTX_CACHE(6, 1),
83         NV10_PGRAPH_CTX_CACHE(6, 2),
84         NV10_PGRAPH_CTX_CACHE(6, 3),
85         NV10_PGRAPH_CTX_CACHE(6, 4),
86         NV10_PGRAPH_CTX_CACHE(7, 0),
87         NV10_PGRAPH_CTX_CACHE(7, 1),
88         NV10_PGRAPH_CTX_CACHE(7, 2),
89         NV10_PGRAPH_CTX_CACHE(7, 3),
90         NV10_PGRAPH_CTX_CACHE(7, 4),
91         NV10_PGRAPH_CTX_USER,
92         NV04_PGRAPH_DMA_START_0,
93         NV04_PGRAPH_DMA_START_1,
94         NV04_PGRAPH_DMA_LENGTH,
95         NV04_PGRAPH_DMA_MISC,
96         NV10_PGRAPH_DMA_PITCH,
97         NV04_PGRAPH_BOFFSET0,
98         NV04_PGRAPH_BBASE0,
99         NV04_PGRAPH_BLIMIT0,
100         NV04_PGRAPH_BOFFSET1,
101         NV04_PGRAPH_BBASE1,
102         NV04_PGRAPH_BLIMIT1,
103         NV04_PGRAPH_BOFFSET2,
104         NV04_PGRAPH_BBASE2,
105         NV04_PGRAPH_BLIMIT2,
106         NV04_PGRAPH_BOFFSET3,
107         NV04_PGRAPH_BBASE3,
108         NV04_PGRAPH_BLIMIT3,
109         NV04_PGRAPH_BOFFSET4,
110         NV04_PGRAPH_BBASE4,
111         NV04_PGRAPH_BLIMIT4,
112         NV04_PGRAPH_BOFFSET5,
113         NV04_PGRAPH_BBASE5,
114         NV04_PGRAPH_BLIMIT5,
115         NV04_PGRAPH_BPITCH0,
116         NV04_PGRAPH_BPITCH1,
117         NV04_PGRAPH_BPITCH2,
118         NV04_PGRAPH_BPITCH3,
119         NV04_PGRAPH_BPITCH4,
120         NV10_PGRAPH_SURFACE,
121         NV10_PGRAPH_STATE,
122         NV04_PGRAPH_BSWIZZLE2,
123         NV04_PGRAPH_BSWIZZLE5,
124         NV04_PGRAPH_BPIXEL,
125         NV10_PGRAPH_NOTIFY,
126         NV04_PGRAPH_PATT_COLOR0,
127         NV04_PGRAPH_PATT_COLOR1,
128         NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
129         0x00400904,
130         0x00400908,
131         0x0040090c,
132         0x00400910,
133         0x00400914,
134         0x00400918,
135         0x0040091c,
136         0x00400920,
137         0x00400924,
138         0x00400928,
139         0x0040092c,
140         0x00400930,
141         0x00400934,
142         0x00400938,
143         0x0040093c,
144         0x00400940,
145         0x00400944,
146         0x00400948,
147         0x0040094c,
148         0x00400950,
149         0x00400954,
150         0x00400958,
151         0x0040095c,
152         0x00400960,
153         0x00400964,
154         0x00400968,
155         0x0040096c,
156         0x00400970,
157         0x00400974,
158         0x00400978,
159         0x0040097c,
160         0x00400980,
161         0x00400984,
162         0x00400988,
163         0x0040098c,
164         0x00400990,
165         0x00400994,
166         0x00400998,
167         0x0040099c,
168         0x004009a0,
169         0x004009a4,
170         0x004009a8,
171         0x004009ac,
172         0x004009b0,
173         0x004009b4,
174         0x004009b8,
175         0x004009bc,
176         0x004009c0,
177         0x004009c4,
178         0x004009c8,
179         0x004009cc,
180         0x004009d0,
181         0x004009d4,
182         0x004009d8,
183         0x004009dc,
184         0x004009e0,
185         0x004009e4,
186         0x004009e8,
187         0x004009ec,
188         0x004009f0,
189         0x004009f4,
190         0x004009f8,
191         0x004009fc,
192         NV04_PGRAPH_PATTERN,    /* 2 values from 0x400808 to 0x40080c */
193         0x0040080c,
194         NV04_PGRAPH_PATTERN_SHAPE,
195         NV03_PGRAPH_MONO_COLOR0,
196         NV04_PGRAPH_ROP3,
197         NV04_PGRAPH_CHROMA,
198         NV04_PGRAPH_BETA_AND,
199         NV04_PGRAPH_BETA_PREMULT,
200         0x00400e70,
201         0x00400e74,
202         0x00400e78,
203         0x00400e7c,
204         0x00400e80,
205         0x00400e84,
206         0x00400e88,
207         0x00400e8c,
208         0x00400ea0,
209         0x00400ea4,
210         0x00400ea8,
211         0x00400e90,
212         0x00400e94,
213         0x00400e98,
214         0x00400e9c,
215         NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
216         NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20-0x400f3c */
217         0x00400f04,
218         0x00400f24,
219         0x00400f08,
220         0x00400f28,
221         0x00400f0c,
222         0x00400f2c,
223         0x00400f10,
224         0x00400f30,
225         0x00400f14,
226         0x00400f34,
227         0x00400f18,
228         0x00400f38,
229         0x00400f1c,
230         0x00400f3c,
231         NV10_PGRAPH_XFMODE0,
232         NV10_PGRAPH_XFMODE1,
233         NV10_PGRAPH_GLOBALSTATE0,
234         NV10_PGRAPH_GLOBALSTATE1,
235         NV04_PGRAPH_STORED_FMT,
236         NV04_PGRAPH_SOURCE_COLOR,
237         NV03_PGRAPH_ABS_X_RAM,  /* 32 values from 0x400400 to 0x40047c */
238         NV03_PGRAPH_ABS_Y_RAM,  /* 32 values from 0x400480 to 0x4004fc */
239         0x00400404,
240         0x00400484,
241         0x00400408,
242         0x00400488,
243         0x0040040c,
244         0x0040048c,
245         0x00400410,
246         0x00400490,
247         0x00400414,
248         0x00400494,
249         0x00400418,
250         0x00400498,
251         0x0040041c,
252         0x0040049c,
253         0x00400420,
254         0x004004a0,
255         0x00400424,
256         0x004004a4,
257         0x00400428,
258         0x004004a8,
259         0x0040042c,
260         0x004004ac,
261         0x00400430,
262         0x004004b0,
263         0x00400434,
264         0x004004b4,
265         0x00400438,
266         0x004004b8,
267         0x0040043c,
268         0x004004bc,
269         0x00400440,
270         0x004004c0,
271         0x00400444,
272         0x004004c4,
273         0x00400448,
274         0x004004c8,
275         0x0040044c,
276         0x004004cc,
277         0x00400450,
278         0x004004d0,
279         0x00400454,
280         0x004004d4,
281         0x00400458,
282         0x004004d8,
283         0x0040045c,
284         0x004004dc,
285         0x00400460,
286         0x004004e0,
287         0x00400464,
288         0x004004e4,
289         0x00400468,
290         0x004004e8,
291         0x0040046c,
292         0x004004ec,
293         0x00400470,
294         0x004004f0,
295         0x00400474,
296         0x004004f4,
297         0x00400478,
298         0x004004f8,
299         0x0040047c,
300         0x004004fc,
301         NV03_PGRAPH_ABS_UCLIP_XMIN,
302         NV03_PGRAPH_ABS_UCLIP_XMAX,
303         NV03_PGRAPH_ABS_UCLIP_YMIN,
304         NV03_PGRAPH_ABS_UCLIP_YMAX,
305         0x00400550,
306         0x00400558,
307         0x00400554,
308         0x0040055c,
309         NV03_PGRAPH_ABS_UCLIPA_XMIN,
310         NV03_PGRAPH_ABS_UCLIPA_XMAX,
311         NV03_PGRAPH_ABS_UCLIPA_YMIN,
312         NV03_PGRAPH_ABS_UCLIPA_YMAX,
313         NV03_PGRAPH_ABS_ICLIP_XMAX,
314         NV03_PGRAPH_ABS_ICLIP_YMAX,
315         NV03_PGRAPH_XY_LOGIC_MISC0,
316         NV03_PGRAPH_XY_LOGIC_MISC1,
317         NV03_PGRAPH_XY_LOGIC_MISC2,
318         NV03_PGRAPH_XY_LOGIC_MISC3,
319         NV03_PGRAPH_CLIPX_0,
320         NV03_PGRAPH_CLIPX_1,
321         NV03_PGRAPH_CLIPY_0,
322         NV03_PGRAPH_CLIPY_1,
323         NV10_PGRAPH_COMBINER0_IN_ALPHA,
324         NV10_PGRAPH_COMBINER1_IN_ALPHA,
325         NV10_PGRAPH_COMBINER0_IN_RGB,
326         NV10_PGRAPH_COMBINER1_IN_RGB,
327         NV10_PGRAPH_COMBINER_COLOR0,
328         NV10_PGRAPH_COMBINER_COLOR1,
329         NV10_PGRAPH_COMBINER0_OUT_ALPHA,
330         NV10_PGRAPH_COMBINER1_OUT_ALPHA,
331         NV10_PGRAPH_COMBINER0_OUT_RGB,
332         NV10_PGRAPH_COMBINER1_OUT_RGB,
333         NV10_PGRAPH_COMBINER_FINAL0,
334         NV10_PGRAPH_COMBINER_FINAL1,
335         0x00400e00,
336         0x00400e04,
337         0x00400e08,
338         0x00400e0c,
339         0x00400e10,
340         0x00400e14,
341         0x00400e18,
342         0x00400e1c,
343         0x00400e20,
344         0x00400e24,
345         0x00400e28,
346         0x00400e2c,
347         0x00400e30,
348         0x00400e34,
349         0x00400e38,
350         0x00400e3c,
351         NV04_PGRAPH_PASSTHRU_0,
352         NV04_PGRAPH_PASSTHRU_1,
353         NV04_PGRAPH_PASSTHRU_2,
354         NV10_PGRAPH_DIMX_TEXTURE,
355         NV10_PGRAPH_WDIMX_TEXTURE,
356         NV10_PGRAPH_DVD_COLORFMT,
357         NV10_PGRAPH_SCALED_FORMAT,
358         NV04_PGRAPH_MISC24_0,
359         NV04_PGRAPH_MISC24_1,
360         NV04_PGRAPH_MISC24_2,
361         NV03_PGRAPH_X_MISC,
362         NV03_PGRAPH_Y_MISC,
363         NV04_PGRAPH_VALID1,
364         NV04_PGRAPH_VALID2,
365 };
366
367 static int nv17_graph_ctx_regs[] = {
368         NV10_PGRAPH_DEBUG_4,
369         0x004006b0,
370         0x00400eac,
371         0x00400eb0,
372         0x00400eb4,
373         0x00400eb8,
374         0x00400ebc,
375         0x00400ec0,
376         0x00400ec4,
377         0x00400ec8,
378         0x00400ecc,
379         0x00400ed0,
380         0x00400ed4,
381         0x00400ed8,
382         0x00400edc,
383         0x00400ee0,
384         0x00400a00,
385         0x00400a04,
386 };
387
388 struct graph_state {
389         int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
390         int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
391         struct pipe_state pipe_state;
392         uint32_t lma_window[4];
393 };
394
395 #define PIPE_SAVE(dev, state, addr)                                     \
396         do {                                                            \
397                 int __i;                                                \
398                 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr);           \
399                 for (__i = 0; __i < ARRAY_SIZE(state); __i++)           \
400                         state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
401         } while (0)
402
403 #define PIPE_RESTORE(dev, state, addr)                                  \
404         do {                                                            \
405                 int __i;                                                \
406                 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr);           \
407                 for (__i = 0; __i < ARRAY_SIZE(state); __i++)           \
408                         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \
409         } while (0)
410
411 static void nv10_graph_save_pipe(struct nouveau_channel *chan)
412 {
413         struct drm_device *dev = chan->dev;
414         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
415         struct pipe_state *pipe = &pgraph_ctx->pipe_state;
416
417         PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
418         PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
419         PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400);
420         PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800);
421         PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00);
422         PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000);
423         PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400);
424         PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800);
425         PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040);
426         PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000);
427 }
428
429 static void nv10_graph_load_pipe(struct nouveau_channel *chan)
430 {
431         struct drm_device *dev = chan->dev;
432         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
433         struct pipe_state *pipe = &pgraph_ctx->pipe_state;
434         uint32_t xfmode0, xfmode1;
435         int i;
436
437         nouveau_wait_for_idle(dev);
438         /* XXX check haiku comments */
439         xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
440         xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
441         nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
442         nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
443         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
444         for (i = 0; i < 4; i++)
445                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
446         for (i = 0; i < 4; i++)
447                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
448
449         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
450         for (i = 0; i < 3; i++)
451                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
452
453         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
454         for (i = 0; i < 3; i++)
455                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
456
457         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
458         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
459
460
461         PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
462         nouveau_wait_for_idle(dev);
463
464         /* restore XFMODE */
465         nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
466         nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
467         PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400);
468         PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800);
469         PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00);
470         PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000);
471         PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400);
472         PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800);
473         PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
474         PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000);
475         PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040);
476         nouveau_wait_for_idle(dev);
477 }
478
479 static void nv10_graph_create_pipe(struct nouveau_channel *chan)
480 {
481         struct drm_device *dev = chan->dev;
482         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
483         struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
484         uint32_t *fifo_pipe_state_addr;
485         int i;
486 #define PIPE_INIT(addr) \
487         do { \
488                 fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
489         } while (0)
490 #define PIPE_INIT_END(addr) \
491         do { \
492                 uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
493                                 ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
494                 if (fifo_pipe_state_addr != __end_addr) \
495                         NV_ERROR(dev, "incomplete pipe init for 0x%x :  %p/%p\n", \
496                                 addr, fifo_pipe_state_addr, __end_addr); \
497         } while (0)
498 #define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
499
500         PIPE_INIT(0x0200);
501         for (i = 0; i < 48; i++)
502                 NV_WRITE_PIPE_INIT(0x00000000);
503         PIPE_INIT_END(0x0200);
504
505         PIPE_INIT(0x6400);
506         for (i = 0; i < 211; i++)
507                 NV_WRITE_PIPE_INIT(0x00000000);
508         NV_WRITE_PIPE_INIT(0x3f800000);
509         NV_WRITE_PIPE_INIT(0x40000000);
510         NV_WRITE_PIPE_INIT(0x40000000);
511         NV_WRITE_PIPE_INIT(0x40000000);
512         NV_WRITE_PIPE_INIT(0x40000000);
513         NV_WRITE_PIPE_INIT(0x00000000);
514         NV_WRITE_PIPE_INIT(0x00000000);
515         NV_WRITE_PIPE_INIT(0x3f800000);
516         NV_WRITE_PIPE_INIT(0x00000000);
517         NV_WRITE_PIPE_INIT(0x3f000000);
518         NV_WRITE_PIPE_INIT(0x3f000000);
519         NV_WRITE_PIPE_INIT(0x00000000);
520         NV_WRITE_PIPE_INIT(0x00000000);
521         NV_WRITE_PIPE_INIT(0x00000000);
522         NV_WRITE_PIPE_INIT(0x00000000);
523         NV_WRITE_PIPE_INIT(0x3f800000);
524         NV_WRITE_PIPE_INIT(0x00000000);
525         NV_WRITE_PIPE_INIT(0x00000000);
526         NV_WRITE_PIPE_INIT(0x00000000);
527         NV_WRITE_PIPE_INIT(0x00000000);
528         NV_WRITE_PIPE_INIT(0x00000000);
529         NV_WRITE_PIPE_INIT(0x3f800000);
530         NV_WRITE_PIPE_INIT(0x3f800000);
531         NV_WRITE_PIPE_INIT(0x3f800000);
532         NV_WRITE_PIPE_INIT(0x3f800000);
533         PIPE_INIT_END(0x6400);
534
535         PIPE_INIT(0x6800);
536         for (i = 0; i < 162; i++)
537                 NV_WRITE_PIPE_INIT(0x00000000);
538         NV_WRITE_PIPE_INIT(0x3f800000);
539         for (i = 0; i < 25; i++)
540                 NV_WRITE_PIPE_INIT(0x00000000);
541         PIPE_INIT_END(0x6800);
542
543         PIPE_INIT(0x6c00);
544         NV_WRITE_PIPE_INIT(0x00000000);
545         NV_WRITE_PIPE_INIT(0x00000000);
546         NV_WRITE_PIPE_INIT(0x00000000);
547         NV_WRITE_PIPE_INIT(0x00000000);
548         NV_WRITE_PIPE_INIT(0xbf800000);
549         NV_WRITE_PIPE_INIT(0x00000000);
550         NV_WRITE_PIPE_INIT(0x00000000);
551         NV_WRITE_PIPE_INIT(0x00000000);
552         NV_WRITE_PIPE_INIT(0x00000000);
553         NV_WRITE_PIPE_INIT(0x00000000);
554         NV_WRITE_PIPE_INIT(0x00000000);
555         NV_WRITE_PIPE_INIT(0x00000000);
556         PIPE_INIT_END(0x6c00);
557
558         PIPE_INIT(0x7000);
559         NV_WRITE_PIPE_INIT(0x00000000);
560         NV_WRITE_PIPE_INIT(0x00000000);
561         NV_WRITE_PIPE_INIT(0x00000000);
562         NV_WRITE_PIPE_INIT(0x00000000);
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(0x7149f2ca);
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         for (i = 0; i < 35; i++)
601                 NV_WRITE_PIPE_INIT(0x00000000);
602         PIPE_INIT_END(0x7000);
603
604         PIPE_INIT(0x7400);
605         for (i = 0; i < 48; i++)
606                 NV_WRITE_PIPE_INIT(0x00000000);
607         PIPE_INIT_END(0x7400);
608
609         PIPE_INIT(0x7800);
610         for (i = 0; i < 48; i++)
611                 NV_WRITE_PIPE_INIT(0x00000000);
612         PIPE_INIT_END(0x7800);
613
614         PIPE_INIT(0x4400);
615         for (i = 0; i < 32; i++)
616                 NV_WRITE_PIPE_INIT(0x00000000);
617         PIPE_INIT_END(0x4400);
618
619         PIPE_INIT(0x0000);
620         for (i = 0; i < 16; i++)
621                 NV_WRITE_PIPE_INIT(0x00000000);
622         PIPE_INIT_END(0x0000);
623
624         PIPE_INIT(0x0040);
625         for (i = 0; i < 4; i++)
626                 NV_WRITE_PIPE_INIT(0x00000000);
627         PIPE_INIT_END(0x0040);
628
629 #undef PIPE_INIT
630 #undef PIPE_INIT_END
631 #undef NV_WRITE_PIPE_INIT
632 }
633
634 static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
635 {
636         int i;
637         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
638                 if (nv10_graph_ctx_regs[i] == reg)
639                         return i;
640         }
641         NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
642         return -1;
643 }
644
645 static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
646 {
647         int i;
648         for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
649                 if (nv17_graph_ctx_regs[i] == reg)
650                         return i;
651         }
652         NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
653         return -1;
654 }
655
656 static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
657                                        uint32_t inst)
658 {
659         struct drm_device *dev = chan->dev;
660         struct drm_nouveau_private *dev_priv = dev->dev_private;
661         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
662         uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
663         uint32_t ctx_user, ctx_switch[5];
664         int i, subchan = -1;
665
666         /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
667          * that cannot be restored via MMIO. Do it through the FIFO
668          * instead.
669          */
670
671         /* Look for a celsius object */
672         for (i = 0; i < 8; i++) {
673                 int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
674
675                 if (class == 0x56 || class == 0x96 || class == 0x99) {
676                         subchan = i;
677                         break;
678                 }
679         }
680
681         if (subchan < 0 || !inst)
682                 return;
683
684         /* Save the current ctx object */
685         ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
686         for (i = 0; i < 5; i++)
687                 ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i));
688
689         /* Save the FIFO state */
690         st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
691         st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL);
692         st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH);
693         fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR);
694
695         for (i = 0; i < ARRAY_SIZE(fifo); i++)
696                 fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i);
697
698         /* Switch to the celsius subchannel */
699         for (i = 0; i < 5; i++)
700                 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i),
701                         nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i)));
702         nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
703
704         /* Inject NV10TCL_DMA_VTXBUF */
705         nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
706         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2,
707                 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
708         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
709         nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
710         pgraph->fifo_access(dev, true);
711         pgraph->fifo_access(dev, false);
712
713         /* Restore the FIFO state */
714         for (i = 0; i < ARRAY_SIZE(fifo); i++)
715                 nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]);
716
717         nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
718         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2);
719         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
720         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
721
722         /* Restore the current ctx object */
723         for (i = 0; i < 5; i++)
724                 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
725         nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
726 }
727
728 int nv10_graph_load_context(struct nouveau_channel *chan)
729 {
730         struct drm_device *dev = chan->dev;
731         struct drm_nouveau_private *dev_priv = dev->dev_private;
732         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
733         uint32_t tmp;
734         int i;
735
736         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
737                 nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
738         if (dev_priv->chipset >= 0x17) {
739                 for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
740                         nv_wr32(dev, nv17_graph_ctx_regs[i],
741                                                 pgraph_ctx->nv17[i]);
742         }
743
744         nv10_graph_load_pipe(chan);
745         nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
746                                           & 0xffff));
747
748         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
749         tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
750         nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
751         tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
752         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
753         return 0;
754 }
755
756 int
757 nv10_graph_unload_context(struct drm_device *dev)
758 {
759         struct drm_nouveau_private *dev_priv = dev->dev_private;
760         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
761         struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
762         struct nouveau_channel *chan;
763         struct graph_state *ctx;
764         uint32_t tmp;
765         int i;
766
767         chan = pgraph->channel(dev);
768         if (!chan)
769                 return 0;
770         ctx = chan->pgraph_ctx;
771
772         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
773                 ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
774
775         if (dev_priv->chipset >= 0x17) {
776                 for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
777                         ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
778         }
779
780         nv10_graph_save_pipe(chan);
781
782         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
783         tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
784         tmp |= (pfifo->channels - 1) << 24;
785         nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
786         return 0;
787 }
788
789 void
790 nv10_graph_context_switch(struct drm_device *dev)
791 {
792         struct drm_nouveau_private *dev_priv = dev->dev_private;
793         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
794         struct nouveau_channel *chan = NULL;
795         int chid;
796
797         pgraph->fifo_access(dev, false);
798         nouveau_wait_for_idle(dev);
799
800         /* If previous context is valid, we need to save it */
801         nv10_graph_unload_context(dev);
802
803         /* Load context for next channel */
804         chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
805         chan = dev_priv->fifos[chid];
806         if (chan)
807                 nv10_graph_load_context(chan);
808
809         pgraph->fifo_access(dev, true);
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->fifos[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 graph_state *pgraph_ctx = chan->pgraph_ctx;
879
880         kfree(pgraph_ctx);
881         chan->pgraph_ctx = NULL;
882 }
883
884 void
885 nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
886                              uint32_t size, uint32_t pitch)
887 {
888         uint32_t limit = max(1u, addr + size) - 1;
889
890         if (pitch)
891                 addr |= 1 << 31;
892
893         nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit);
894         nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch);
895         nv_wr32(dev, NV10_PGRAPH_TILE(i), addr);
896 }
897
898 int nv10_graph_init(struct drm_device *dev)
899 {
900         struct drm_nouveau_private *dev_priv = dev->dev_private;
901         uint32_t tmp;
902         int i;
903
904         nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
905                         ~NV_PMC_ENABLE_PGRAPH);
906         nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
907                          NV_PMC_ENABLE_PGRAPH);
908
909         nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
910         nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
911
912         nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
913         nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
914         nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
915         /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
916         nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
917         nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
918                                       (1<<29) |
919                                       (1<<31));
920         if (dev_priv->chipset >= 0x17) {
921                 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
922                 nv_wr32(dev, 0x400a10, 0x3ff3fb6);
923                 nv_wr32(dev, 0x400838, 0x2f8684);
924                 nv_wr32(dev, 0x40083c, 0x115f3f);
925                 nv_wr32(dev, 0x004006b0, 0x40000020);
926         } else
927                 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
928
929         /* Turn all the tiling regions off. */
930         for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
931                 nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
932
933         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
934         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
935         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
936         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
937         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
938         nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
939
940         tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
941         tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
942         nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
943         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
944         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
945
946         return 0;
947 }
948
949 void nv10_graph_takedown(struct drm_device *dev)
950 {
951 }
952
953 static int
954 nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass,
955                            int mthd, uint32_t data)
956 {
957         struct drm_device *dev = chan->dev;
958         struct graph_state *ctx = chan->pgraph_ctx;
959         struct pipe_state *pipe = &ctx->pipe_state;
960         struct drm_nouveau_private *dev_priv = dev->dev_private;
961         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
962         uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
963         uint32_t xfmode0, xfmode1;
964         int i;
965
966         ctx->lma_window[(mthd - 0x1638) / 4] = data;
967
968         if (mthd != 0x1644)
969                 return 0;
970
971         nouveau_wait_for_idle(dev);
972
973         PIPE_SAVE(dev, pipe_0x0040, 0x0040);
974         PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
975
976         PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
977
978         nouveau_wait_for_idle(dev);
979
980         xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
981         xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
982
983         PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
984         PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
985         PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
986         PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
987
988         nouveau_wait_for_idle(dev);
989
990         nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
991         nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
992         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
993         for (i = 0; i < 4; i++)
994                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
995         for (i = 0; i < 4; i++)
996                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
997
998         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
999         for (i = 0; i < 3; i++)
1000                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
1001
1002         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
1003         for (i = 0; i < 3; i++)
1004                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1005
1006         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
1007         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
1008
1009         PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
1010
1011         nouveau_wait_for_idle(dev);
1012
1013         PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
1014
1015         nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
1016         nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
1017
1018         PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
1019         PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
1020         PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
1021         PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
1022
1023         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
1024         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1025
1026         nouveau_wait_for_idle(dev);
1027
1028         pgraph->fifo_access(dev, true);
1029
1030         return 0;
1031 }
1032
1033 static int
1034 nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass,
1035                            int mthd, uint32_t data)
1036 {
1037         struct drm_device *dev = chan->dev;
1038         struct drm_nouveau_private *dev_priv = dev->dev_private;
1039         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
1040
1041         nouveau_wait_for_idle(dev);
1042
1043         nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
1044                 nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
1045         nv_wr32(dev, 0x004006b0,
1046                 nv_rd32(dev, 0x004006b0) | 0x8 << 24);
1047
1048         pgraph->fifo_access(dev, true);
1049
1050         return 0;
1051 }
1052
1053 static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = {
1054         { 0x1638, nv17_graph_mthd_lma_window },
1055         { 0x163c, nv17_graph_mthd_lma_window },
1056         { 0x1640, nv17_graph_mthd_lma_window },
1057         { 0x1644, nv17_graph_mthd_lma_window },
1058         { 0x1658, nv17_graph_mthd_lma_enable },
1059         {}
1060 };
1061
1062 struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
1063         { 0x0030, false, NULL }, /* null */
1064         { 0x0039, false, NULL }, /* m2mf */
1065         { 0x004a, false, NULL }, /* gdirect */
1066         { 0x005f, false, NULL }, /* imageblit */
1067         { 0x009f, false, NULL }, /* imageblit (nv12) */
1068         { 0x008a, false, NULL }, /* ifc */
1069         { 0x0089, false, NULL }, /* sifm */
1070         { 0x0062, false, NULL }, /* surf2d */
1071         { 0x0043, false, NULL }, /* rop */
1072         { 0x0012, false, NULL }, /* beta1 */
1073         { 0x0072, false, NULL }, /* beta4 */
1074         { 0x0019, false, NULL }, /* cliprect */
1075         { 0x0044, false, NULL }, /* pattern */
1076         { 0x0052, false, NULL }, /* swzsurf */
1077         { 0x0093, false, NULL }, /* surf3d */
1078         { 0x0094, false, NULL }, /* tex_tri */
1079         { 0x0095, false, NULL }, /* multitex_tri */
1080         { 0x0056, false, NULL }, /* celcius (nv10) */
1081         { 0x0096, false, NULL }, /* celcius (nv11) */
1082         { 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */
1083         {}
1084 };