Fix usb_serial_probe() problem introduced by the recent kfifo changes
[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_SWITCH1,
47         NV10_PGRAPH_CTX_SWITCH2,
48         NV10_PGRAPH_CTX_SWITCH3,
49         NV10_PGRAPH_CTX_SWITCH4,
50         NV10_PGRAPH_CTX_SWITCH5,
51         NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */
52         NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */
53         NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */
54         NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */
55         NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */
56         0x00400164,
57         0x00400184,
58         0x004001a4,
59         0x004001c4,
60         0x004001e4,
61         0x00400168,
62         0x00400188,
63         0x004001a8,
64         0x004001c8,
65         0x004001e8,
66         0x0040016c,
67         0x0040018c,
68         0x004001ac,
69         0x004001cc,
70         0x004001ec,
71         0x00400170,
72         0x00400190,
73         0x004001b0,
74         0x004001d0,
75         0x004001f0,
76         0x00400174,
77         0x00400194,
78         0x004001b4,
79         0x004001d4,
80         0x004001f4,
81         0x00400178,
82         0x00400198,
83         0x004001b8,
84         0x004001d8,
85         0x004001f8,
86         0x0040017c,
87         0x0040019c,
88         0x004001bc,
89         0x004001dc,
90         0x004001fc,
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 };
393
394 static void nv10_graph_save_pipe(struct nouveau_channel *chan)
395 {
396         struct drm_device *dev = chan->dev;
397         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
398         struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
399         int i;
400 #define PIPE_SAVE(addr) \
401         do { \
402                 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
403                 for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \
404                         fifo_pipe_state->pipe_##addr[i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
405         } while (0)
406
407         PIPE_SAVE(0x4400);
408         PIPE_SAVE(0x0200);
409         PIPE_SAVE(0x6400);
410         PIPE_SAVE(0x6800);
411         PIPE_SAVE(0x6c00);
412         PIPE_SAVE(0x7000);
413         PIPE_SAVE(0x7400);
414         PIPE_SAVE(0x7800);
415         PIPE_SAVE(0x0040);
416         PIPE_SAVE(0x0000);
417
418 #undef PIPE_SAVE
419 }
420
421 static void nv10_graph_load_pipe(struct nouveau_channel *chan)
422 {
423         struct drm_device *dev = chan->dev;
424         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
425         struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
426         int i;
427         uint32_t xfmode0, xfmode1;
428 #define PIPE_RESTORE(addr) \
429         do { \
430                 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
431                 for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \
432                         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \
433         } while (0)
434
435
436         nouveau_wait_for_idle(dev);
437         /* XXX check haiku comments */
438         xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
439         xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
440         nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
441         nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
442         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
443         for (i = 0; i < 4; i++)
444                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
445         for (i = 0; i < 4; i++)
446                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
447
448         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
449         for (i = 0; i < 3; i++)
450                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
451
452         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
453         for (i = 0; i < 3; i++)
454                 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
455
456         nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
457         nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
458
459
460         PIPE_RESTORE(0x0200);
461         nouveau_wait_for_idle(dev);
462
463         /* restore XFMODE */
464         nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
465         nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
466         PIPE_RESTORE(0x6400);
467         PIPE_RESTORE(0x6800);
468         PIPE_RESTORE(0x6c00);
469         PIPE_RESTORE(0x7000);
470         PIPE_RESTORE(0x7400);
471         PIPE_RESTORE(0x7800);
472         PIPE_RESTORE(0x4400);
473         PIPE_RESTORE(0x0000);
474         PIPE_RESTORE(0x0040);
475         nouveau_wait_for_idle(dev);
476
477 #undef PIPE_RESTORE
478 }
479
480 static void nv10_graph_create_pipe(struct nouveau_channel *chan)
481 {
482         struct drm_device *dev = chan->dev;
483         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
484         struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
485         uint32_t *fifo_pipe_state_addr;
486         int i;
487 #define PIPE_INIT(addr) \
488         do { \
489                 fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
490         } while (0)
491 #define PIPE_INIT_END(addr) \
492         do { \
493                 uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
494                                 ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
495                 if (fifo_pipe_state_addr != __end_addr) \
496                         NV_ERROR(dev, "incomplete pipe init for 0x%x :  %p/%p\n", \
497                                 addr, fifo_pipe_state_addr, __end_addr); \
498         } while (0)
499 #define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
500
501         PIPE_INIT(0x0200);
502         for (i = 0; i < 48; i++)
503                 NV_WRITE_PIPE_INIT(0x00000000);
504         PIPE_INIT_END(0x0200);
505
506         PIPE_INIT(0x6400);
507         for (i = 0; i < 211; i++)
508                 NV_WRITE_PIPE_INIT(0x00000000);
509         NV_WRITE_PIPE_INIT(0x3f800000);
510         NV_WRITE_PIPE_INIT(0x40000000);
511         NV_WRITE_PIPE_INIT(0x40000000);
512         NV_WRITE_PIPE_INIT(0x40000000);
513         NV_WRITE_PIPE_INIT(0x40000000);
514         NV_WRITE_PIPE_INIT(0x00000000);
515         NV_WRITE_PIPE_INIT(0x00000000);
516         NV_WRITE_PIPE_INIT(0x3f800000);
517         NV_WRITE_PIPE_INIT(0x00000000);
518         NV_WRITE_PIPE_INIT(0x3f000000);
519         NV_WRITE_PIPE_INIT(0x3f000000);
520         NV_WRITE_PIPE_INIT(0x00000000);
521         NV_WRITE_PIPE_INIT(0x00000000);
522         NV_WRITE_PIPE_INIT(0x00000000);
523         NV_WRITE_PIPE_INIT(0x00000000);
524         NV_WRITE_PIPE_INIT(0x3f800000);
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(0x00000000);
530         NV_WRITE_PIPE_INIT(0x3f800000);
531         NV_WRITE_PIPE_INIT(0x3f800000);
532         NV_WRITE_PIPE_INIT(0x3f800000);
533         NV_WRITE_PIPE_INIT(0x3f800000);
534         PIPE_INIT_END(0x6400);
535
536         PIPE_INIT(0x6800);
537         for (i = 0; i < 162; i++)
538                 NV_WRITE_PIPE_INIT(0x00000000);
539         NV_WRITE_PIPE_INIT(0x3f800000);
540         for (i = 0; i < 25; i++)
541                 NV_WRITE_PIPE_INIT(0x00000000);
542         PIPE_INIT_END(0x6800);
543
544         PIPE_INIT(0x6c00);
545         NV_WRITE_PIPE_INIT(0x00000000);
546         NV_WRITE_PIPE_INIT(0x00000000);
547         NV_WRITE_PIPE_INIT(0x00000000);
548         NV_WRITE_PIPE_INIT(0x00000000);
549         NV_WRITE_PIPE_INIT(0xbf800000);
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         NV_WRITE_PIPE_INIT(0x00000000);
557         PIPE_INIT_END(0x6c00);
558
559         PIPE_INIT(0x7000);
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(0x00000000);
572         NV_WRITE_PIPE_INIT(0x7149f2ca);
573         NV_WRITE_PIPE_INIT(0x00000000);
574         NV_WRITE_PIPE_INIT(0x00000000);
575         NV_WRITE_PIPE_INIT(0x00000000);
576         NV_WRITE_PIPE_INIT(0x7149f2ca);
577         NV_WRITE_PIPE_INIT(0x00000000);
578         NV_WRITE_PIPE_INIT(0x00000000);
579         NV_WRITE_PIPE_INIT(0x00000000);
580         NV_WRITE_PIPE_INIT(0x7149f2ca);
581         NV_WRITE_PIPE_INIT(0x00000000);
582         NV_WRITE_PIPE_INIT(0x00000000);
583         NV_WRITE_PIPE_INIT(0x00000000);
584         NV_WRITE_PIPE_INIT(0x7149f2ca);
585         NV_WRITE_PIPE_INIT(0x00000000);
586         NV_WRITE_PIPE_INIT(0x00000000);
587         NV_WRITE_PIPE_INIT(0x00000000);
588         NV_WRITE_PIPE_INIT(0x7149f2ca);
589         NV_WRITE_PIPE_INIT(0x00000000);
590         NV_WRITE_PIPE_INIT(0x00000000);
591         NV_WRITE_PIPE_INIT(0x00000000);
592         NV_WRITE_PIPE_INIT(0x7149f2ca);
593         NV_WRITE_PIPE_INIT(0x00000000);
594         NV_WRITE_PIPE_INIT(0x00000000);
595         NV_WRITE_PIPE_INIT(0x00000000);
596         NV_WRITE_PIPE_INIT(0x7149f2ca);
597         NV_WRITE_PIPE_INIT(0x00000000);
598         NV_WRITE_PIPE_INIT(0x00000000);
599         NV_WRITE_PIPE_INIT(0x00000000);
600         NV_WRITE_PIPE_INIT(0x7149f2ca);
601         for (i = 0; i < 35; i++)
602                 NV_WRITE_PIPE_INIT(0x00000000);
603         PIPE_INIT_END(0x7000);
604
605         PIPE_INIT(0x7400);
606         for (i = 0; i < 48; i++)
607                 NV_WRITE_PIPE_INIT(0x00000000);
608         PIPE_INIT_END(0x7400);
609
610         PIPE_INIT(0x7800);
611         for (i = 0; i < 48; i++)
612                 NV_WRITE_PIPE_INIT(0x00000000);
613         PIPE_INIT_END(0x7800);
614
615         PIPE_INIT(0x4400);
616         for (i = 0; i < 32; i++)
617                 NV_WRITE_PIPE_INIT(0x00000000);
618         PIPE_INIT_END(0x4400);
619
620         PIPE_INIT(0x0000);
621         for (i = 0; i < 16; i++)
622                 NV_WRITE_PIPE_INIT(0x00000000);
623         PIPE_INIT_END(0x0000);
624
625         PIPE_INIT(0x0040);
626         for (i = 0; i < 4; i++)
627                 NV_WRITE_PIPE_INIT(0x00000000);
628         PIPE_INIT_END(0x0040);
629
630 #undef PIPE_INIT
631 #undef PIPE_INIT_END
632 #undef NV_WRITE_PIPE_INIT
633 }
634
635 static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
636 {
637         int i;
638         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
639                 if (nv10_graph_ctx_regs[i] == reg)
640                         return i;
641         }
642         NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
643         return -1;
644 }
645
646 static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
647 {
648         int i;
649         for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
650                 if (nv17_graph_ctx_regs[i] == reg)
651                         return i;
652         }
653         NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
654         return -1;
655 }
656
657 int nv10_graph_load_context(struct nouveau_channel *chan)
658 {
659         struct drm_device *dev = chan->dev;
660         struct drm_nouveau_private *dev_priv = dev->dev_private;
661         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
662         uint32_t tmp;
663         int i;
664
665         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
666                 nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
667         if (dev_priv->chipset >= 0x17) {
668                 for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
669                         nv_wr32(dev, nv17_graph_ctx_regs[i],
670                                                 pgraph_ctx->nv17[i]);
671         }
672
673         nv10_graph_load_pipe(chan);
674
675         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
676         tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
677         nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
678         tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
679         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
680         return 0;
681 }
682
683 int
684 nv10_graph_unload_context(struct drm_device *dev)
685 {
686         struct drm_nouveau_private *dev_priv = dev->dev_private;
687         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
688         struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
689         struct nouveau_channel *chan;
690         struct graph_state *ctx;
691         uint32_t tmp;
692         int i;
693
694         chan = pgraph->channel(dev);
695         if (!chan)
696                 return 0;
697         ctx = chan->pgraph_ctx;
698
699         for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
700                 ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
701
702         if (dev_priv->chipset >= 0x17) {
703                 for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
704                         ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
705         }
706
707         nv10_graph_save_pipe(chan);
708
709         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
710         tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
711         tmp |= (pfifo->channels - 1) << 24;
712         nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
713         return 0;
714 }
715
716 void
717 nv10_graph_context_switch(struct drm_device *dev)
718 {
719         struct drm_nouveau_private *dev_priv = dev->dev_private;
720         struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
721         struct nouveau_channel *chan = NULL;
722         int chid;
723
724         pgraph->fifo_access(dev, false);
725         nouveau_wait_for_idle(dev);
726
727         /* If previous context is valid, we need to save it */
728         nv10_graph_unload_context(dev);
729
730         /* Load context for next channel */
731         chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
732         chan = dev_priv->fifos[chid];
733         if (chan)
734                 nv10_graph_load_context(chan);
735
736         pgraph->fifo_access(dev, true);
737 }
738
739 #define NV_WRITE_CTX(reg, val) do { \
740         int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
741         if (offset > 0) \
742                 pgraph_ctx->nv10[offset] = val; \
743         } while (0)
744
745 #define NV17_WRITE_CTX(reg, val) do { \
746         int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \
747         if (offset > 0) \
748                 pgraph_ctx->nv17[offset] = val; \
749         } while (0)
750
751 struct nouveau_channel *
752 nv10_graph_channel(struct drm_device *dev)
753 {
754         struct drm_nouveau_private *dev_priv = dev->dev_private;
755         int chid = dev_priv->engine.fifo.channels;
756
757         if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000)
758                 chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24;
759
760         if (chid >= dev_priv->engine.fifo.channels)
761                 return NULL;
762
763         return dev_priv->fifos[chid];
764 }
765
766 int nv10_graph_create_context(struct nouveau_channel *chan)
767 {
768         struct drm_device *dev = chan->dev;
769         struct drm_nouveau_private *dev_priv = dev->dev_private;
770         struct graph_state *pgraph_ctx;
771
772         NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
773
774         chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
775                                                 GFP_KERNEL);
776         if (pgraph_ctx == NULL)
777                 return -ENOMEM;
778
779
780         NV_WRITE_CTX(0x00400e88, 0x08000000);
781         NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
782         NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
783         NV_WRITE_CTX(0x00400e10, 0x00001000);
784         NV_WRITE_CTX(0x00400e14, 0x00001000);
785         NV_WRITE_CTX(0x00400e30, 0x00080008);
786         NV_WRITE_CTX(0x00400e34, 0x00080008);
787         if (dev_priv->chipset >= 0x17) {
788                 /* is it really needed ??? */
789                 NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
790                                         nv_rd32(dev, NV10_PGRAPH_DEBUG_4));
791                 NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0));
792                 NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
793                 NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
794                 NV17_WRITE_CTX(0x00400ec0, 0x00000080);
795                 NV17_WRITE_CTX(0x00400ed0, 0x00000080);
796         }
797         NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24);
798
799         nv10_graph_create_pipe(chan);
800         return 0;
801 }
802
803 void nv10_graph_destroy_context(struct nouveau_channel *chan)
804 {
805         struct graph_state *pgraph_ctx = chan->pgraph_ctx;
806
807         kfree(pgraph_ctx);
808         chan->pgraph_ctx = NULL;
809 }
810
811 int nv10_graph_init(struct drm_device *dev)
812 {
813         struct drm_nouveau_private *dev_priv = dev->dev_private;
814         uint32_t tmp;
815         int i;
816
817         nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
818                         ~NV_PMC_ENABLE_PGRAPH);
819         nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
820                          NV_PMC_ENABLE_PGRAPH);
821
822         nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
823         nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
824
825         nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
826         nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
827         nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
828         /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
829         nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
830         nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
831                                       (1<<29) |
832                                       (1<<31));
833         if (dev_priv->chipset >= 0x17) {
834                 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
835                 nv_wr32(dev, 0x004006b0, 0x40000020);
836         } else
837                 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
838
839         /* copy tile info from PFB */
840         for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
841                 nv_wr32(dev, NV10_PGRAPH_TILE(i),
842                                         nv_rd32(dev, NV10_PFB_TILE(i)));
843                 nv_wr32(dev, NV10_PGRAPH_TLIMIT(i),
844                                         nv_rd32(dev, NV10_PFB_TLIMIT(i)));
845                 nv_wr32(dev, NV10_PGRAPH_TSIZE(i),
846                                         nv_rd32(dev, NV10_PFB_TSIZE(i)));
847                 nv_wr32(dev, NV10_PGRAPH_TSTATUS(i),
848                                         nv_rd32(dev, NV10_PFB_TSTATUS(i)));
849         }
850
851         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
852         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
853         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000);
854         nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000);
855         nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
856
857         tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
858         tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
859         nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
860         nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
861         nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
862
863         return 0;
864 }
865
866 void nv10_graph_takedown(struct drm_device *dev)
867 {
868 }
869
870 struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
871         { 0x0030, false, NULL }, /* null */
872         { 0x0039, false, NULL }, /* m2mf */
873         { 0x004a, false, NULL }, /* gdirect */
874         { 0x005f, false, NULL }, /* imageblit */
875         { 0x009f, false, NULL }, /* imageblit (nv12) */
876         { 0x008a, false, NULL }, /* ifc */
877         { 0x0089, false, NULL }, /* sifm */
878         { 0x0062, false, NULL }, /* surf2d */
879         { 0x0043, false, NULL }, /* rop */
880         { 0x0012, false, NULL }, /* beta1 */
881         { 0x0072, false, NULL }, /* beta4 */
882         { 0x0019, false, NULL }, /* cliprect */
883         { 0x0044, false, NULL }, /* pattern */
884         { 0x0052, false, NULL }, /* swzsurf */
885         { 0x0093, false, NULL }, /* surf3d */
886         { 0x0094, false, NULL }, /* tex_tri */
887         { 0x0095, false, NULL }, /* multitex_tri */
888         { 0x0056, false, NULL }, /* celcius (nv10) */
889         { 0x0096, false, NULL }, /* celcius (nv11) */
890         { 0x0099, false, NULL }, /* celcius (nv17) */
891         {}
892 };