OSDN Git Service

nouveau : nv1x graph reworks
[android-x86/external-libdrm.git] / shared-core / 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
31 static void nv10_praph_pipe(struct drm_device *dev) {
32         struct drm_nouveau_private *dev_priv = dev->dev_private;
33         int i;
34
35         nouveau_wait_for_idle(dev);
36         /* XXX check haiku comments */
37         NV_WRITE(NV10_PGRAPH_XFMODE0, 0x10000000);
38         NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000);
39         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
40         for (i = 0; i < 4; i++)
41                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
42         for (i = 0; i < 4; i++)
43                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
44
45         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
46         
47         for (i = 0; i < 3; i++)
48                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
49
50         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
51         for (i = 0; i < 3; i++)
52                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
53
54         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
55         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000008);
56
57         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000200);
58         for (i = 0; i < 48; i++)
59                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
60
61         nouveau_wait_for_idle(dev);
62
63         NV_WRITE(NV10_PGRAPH_XFMODE0, 0x00000000);
64         NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000);
65         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006400);
66         for (i = 0; i < 211; i++)
67                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
68
69         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
70         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
71         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
72         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
73         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
74         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
75         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
76         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
77         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
78         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f000000);
79         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f000000);
80         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
81         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
82         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
83         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
84         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
85         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
86         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
87         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
88         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
89         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
90         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
91         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
92         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
93         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
94
95         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006800);
96         for (i = 0; i < 162; i++)
97                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
98         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
99         for (i = 0; i < 25; i++)
100                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
101
102         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006c00);
103         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
104         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
105         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
106         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
107         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0xbf800000);
108         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
109         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
110         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
111         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
112         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
113         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
114         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
115         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007000);
116         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
117         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
118         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
119         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
120         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
121         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
122         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
123         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
124         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
125         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
126         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
127         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
128         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
129         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
130         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
131         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
132         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
133         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
134         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
135         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
136         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
137         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
138         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
139         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
140         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
141         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
142         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
143         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
144         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
145         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
146         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
147         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
148         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
149         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
150         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
151         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
152         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
153         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
154         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
155         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
156         NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
157         for (i = 0; i < 35; i++)
158                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
159
160
161         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007400);
162         for (i = 0; i < 48; i++)
163                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
164
165         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007800);
166         for (i = 0; i < 48; i++)
167                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
168
169         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00004400);
170         for (i = 0; i < 32; i++)
171                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
172
173         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000000);
174         for (i = 0; i < 16; i++)
175                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
176
177         NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
178         for (i = 0; i < 4; i++)
179                 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
180
181         nouveau_wait_for_idle(dev);
182 }
183
184 static int nv10_graph_ctx_regs [] = {
185 NV10_PGRAPH_CTX_SWITCH1,
186 NV10_PGRAPH_CTX_SWITCH2,
187 NV10_PGRAPH_CTX_SWITCH3,
188 NV10_PGRAPH_CTX_SWITCH4,
189 NV10_PGRAPH_CTX_SWITCH5,
190 NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */
191 NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */
192 NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */
193 NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */
194 NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */
195 0x00400164,
196 0x00400184,
197 0x004001a4,
198 0x004001c4,
199 0x004001e4,
200 0x00400168,
201 0x00400188,
202 0x004001a8,
203 0x004001c8,
204 0x004001e8,
205 0x0040016c,
206 0x0040018c,
207 0x004001ac,
208 0x004001cc,
209 0x004001ec,
210 0x00400170,
211 0x00400190,
212 0x004001b0,
213 0x004001d0,
214 0x004001f0,
215 0x00400174,
216 0x00400194,
217 0x004001b4,
218 0x004001d4,
219 0x004001f4,
220 0x00400178,
221 0x00400198,
222 0x004001b8,
223 0x004001d8,
224 0x004001f8,
225 0x0040017c,
226 0x0040019c,
227 0x004001bc,
228 0x004001dc,
229 0x004001fc,
230 NV10_PGRAPH_CTX_USER,
231 NV04_PGRAPH_DMA_START_0,
232 NV04_PGRAPH_DMA_START_1,
233 NV04_PGRAPH_DMA_LENGTH,
234 NV04_PGRAPH_DMA_MISC,
235 NV10_PGRAPH_DMA_PITCH,
236 NV04_PGRAPH_BOFFSET0,
237 NV04_PGRAPH_BBASE0,
238 NV04_PGRAPH_BLIMIT0,
239 NV04_PGRAPH_BOFFSET1,
240 NV04_PGRAPH_BBASE1,
241 NV04_PGRAPH_BLIMIT1,
242 NV04_PGRAPH_BOFFSET2,
243 NV04_PGRAPH_BBASE2,
244 NV04_PGRAPH_BLIMIT2,
245 NV04_PGRAPH_BOFFSET3,
246 NV04_PGRAPH_BBASE3,
247 NV04_PGRAPH_BLIMIT3,
248 NV04_PGRAPH_BOFFSET4,
249 NV04_PGRAPH_BBASE4,
250 NV04_PGRAPH_BLIMIT4,
251 NV04_PGRAPH_BOFFSET5,
252 NV04_PGRAPH_BBASE5,
253 NV04_PGRAPH_BLIMIT5,
254 NV04_PGRAPH_BPITCH0,
255 NV04_PGRAPH_BPITCH1,
256 NV04_PGRAPH_BPITCH2,
257 NV04_PGRAPH_BPITCH3,
258 NV04_PGRAPH_BPITCH4,
259 NV10_PGRAPH_SURFACE,
260 NV10_PGRAPH_STATE,
261 NV04_PGRAPH_BSWIZZLE2,
262 NV04_PGRAPH_BSWIZZLE5,
263 NV04_PGRAPH_BPIXEL,
264 NV10_PGRAPH_NOTIFY,
265 NV04_PGRAPH_PATT_COLOR0,
266 NV04_PGRAPH_PATT_COLOR1,
267 NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
268 0x00400904,
269 0x00400908,
270 0x0040090c,
271 0x00400910,
272 0x00400914,
273 0x00400918,
274 0x0040091c,
275 0x00400920,
276 0x00400924,
277 0x00400928,
278 0x0040092c,
279 0x00400930,
280 0x00400934,
281 0x00400938,
282 0x0040093c,
283 0x00400940,
284 0x00400944,
285 0x00400948,
286 0x0040094c,
287 0x00400950,
288 0x00400954,
289 0x00400958,
290 0x0040095c,
291 0x00400960,
292 0x00400964,
293 0x00400968,
294 0x0040096c,
295 0x00400970,
296 0x00400974,
297 0x00400978,
298 0x0040097c,
299 0x00400980,
300 0x00400984,
301 0x00400988,
302 0x0040098c,
303 0x00400990,
304 0x00400994,
305 0x00400998,
306 0x0040099c,
307 0x004009a0,
308 0x004009a4,
309 0x004009a8,
310 0x004009ac,
311 0x004009b0,
312 0x004009b4,
313 0x004009b8,
314 0x004009bc,
315 0x004009c0,
316 0x004009c4,
317 0x004009c8,
318 0x004009cc,
319 0x004009d0,
320 0x004009d4,
321 0x004009d8,
322 0x004009dc,
323 0x004009e0,
324 0x004009e4,
325 0x004009e8,
326 0x004009ec,
327 0x004009f0,
328 0x004009f4,
329 0x004009f8,
330 0x004009fc,
331 NV04_PGRAPH_PATTERN,    /* 2 values from 0x400808 to 0x40080c */
332 0x0040080c,
333 NV04_PGRAPH_PATTERN_SHAPE,
334 NV03_PGRAPH_MONO_COLOR0,
335 NV04_PGRAPH_ROP3,
336 NV04_PGRAPH_CHROMA,
337 NV04_PGRAPH_BETA_AND,
338 NV04_PGRAPH_BETA_PREMULT,
339 0x00400e70,
340 0x00400e74,
341 0x00400e78,
342 0x00400e7c,
343 0x00400e80,
344 0x00400e84,
345 0x00400e88,
346 0x00400e8c,
347 0x00400ea0,
348 0x00400ea4,
349 0x00400ea8,
350 0x00400e90,
351 0x00400e94,
352 0x00400e98,
353 0x00400e9c,
354 NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00 to 0x400f1c */
355 NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20 to 0x400f3c */
356 0x00400f04,
357 0x00400f24,
358 0x00400f08,
359 0x00400f28,
360 0x00400f0c,
361 0x00400f2c,
362 0x00400f10,
363 0x00400f30,
364 0x00400f14,
365 0x00400f34,
366 0x00400f18,
367 0x00400f38,
368 0x00400f1c,
369 0x00400f3c,
370 NV10_PGRAPH_XFMODE0,
371 NV10_PGRAPH_XFMODE1,
372 NV10_PGRAPH_GLOBALSTATE0,
373 NV10_PGRAPH_GLOBALSTATE1,
374 NV04_PGRAPH_STORED_FMT,
375 NV04_PGRAPH_SOURCE_COLOR,
376 NV03_PGRAPH_ABS_X_RAM,  /* 32 values from 0x400400 to 0x40047c */
377 NV03_PGRAPH_ABS_Y_RAM,  /* 32 values from 0x400480 to 0x4004fc */
378 0x00400404,
379 0x00400484,
380 0x00400408,
381 0x00400488,
382 0x0040040c,
383 0x0040048c,
384 0x00400410,
385 0x00400490,
386 0x00400414,
387 0x00400494,
388 0x00400418,
389 0x00400498,
390 0x0040041c,
391 0x0040049c,
392 0x00400420,
393 0x004004a0,
394 0x00400424,
395 0x004004a4,
396 0x00400428,
397 0x004004a8,
398 0x0040042c,
399 0x004004ac,
400 0x00400430,
401 0x004004b0,
402 0x00400434,
403 0x004004b4,
404 0x00400438,
405 0x004004b8,
406 0x0040043c,
407 0x004004bc,
408 0x00400440,
409 0x004004c0,
410 0x00400444,
411 0x004004c4,
412 0x00400448,
413 0x004004c8,
414 0x0040044c,
415 0x004004cc,
416 0x00400450,
417 0x004004d0,
418 0x00400454,
419 0x004004d4,
420 0x00400458,
421 0x004004d8,
422 0x0040045c,
423 0x004004dc,
424 0x00400460,
425 0x004004e0,
426 0x00400464,
427 0x004004e4,
428 0x00400468,
429 0x004004e8,
430 0x0040046c,
431 0x004004ec,
432 0x00400470,
433 0x004004f0,
434 0x00400474,
435 0x004004f4,
436 0x00400478,
437 0x004004f8,
438 0x0040047c,
439 0x004004fc,
440 NV03_PGRAPH_ABS_UCLIP_XMIN,
441 NV03_PGRAPH_ABS_UCLIP_XMAX,
442 NV03_PGRAPH_ABS_UCLIP_YMIN,
443 NV03_PGRAPH_ABS_UCLIP_YMAX,
444 0x00400550,
445 0x00400558,
446 0x00400554,
447 0x0040055c,
448 NV03_PGRAPH_ABS_UCLIPA_XMIN,
449 NV03_PGRAPH_ABS_UCLIPA_XMAX,
450 NV03_PGRAPH_ABS_UCLIPA_YMIN,
451 NV03_PGRAPH_ABS_UCLIPA_YMAX,
452 NV03_PGRAPH_ABS_ICLIP_XMAX,
453 NV03_PGRAPH_ABS_ICLIP_YMAX,
454 NV03_PGRAPH_XY_LOGIC_MISC0,
455 NV03_PGRAPH_XY_LOGIC_MISC1,
456 NV03_PGRAPH_XY_LOGIC_MISC2,
457 NV03_PGRAPH_XY_LOGIC_MISC3,
458 NV03_PGRAPH_CLIPX_0,
459 NV03_PGRAPH_CLIPX_1,
460 NV03_PGRAPH_CLIPY_0,
461 NV03_PGRAPH_CLIPY_1,
462 0x00400e40,
463 0x00400e44,
464 0x00400e48,
465 0x00400e4c,
466 0x00400e50,
467 0x00400e54,
468 0x00400e58,
469 0x00400e5c,
470 0x00400e60,
471 0x00400e64,
472 0x00400e68,
473 0x00400e6c,
474 0x00400e00,
475 0x00400e04,
476 0x00400e08,
477 0x00400e0c,
478 0x00400e10,
479 0x00400e14,
480 0x00400e18,
481 0x00400e1c,
482 0x00400e20,
483 0x00400e24,
484 0x00400e28,
485 0x00400e2c,
486 0x00400e30,
487 0x00400e34,
488 0x00400e38,
489 0x00400e3c,
490 NV04_PGRAPH_PASSTHRU_0,
491 NV04_PGRAPH_PASSTHRU_1,
492 NV04_PGRAPH_PASSTHRU_2,
493 NV10_PGRAPH_DIMX_TEXTURE,
494 NV10_PGRAPH_WDIMX_TEXTURE,
495 NV10_PGRAPH_DVD_COLORFMT,
496 NV10_PGRAPH_SCALED_FORMAT,
497 NV04_PGRAPH_MISC24_0,
498 NV04_PGRAPH_MISC24_1,
499 NV04_PGRAPH_MISC24_2,
500 NV03_PGRAPH_X_MISC,
501 NV03_PGRAPH_Y_MISC,
502 NV04_PGRAPH_VALID1,
503 NV04_PGRAPH_VALID2,
504 };
505
506 static int nv17_graph_ctx_regs [] = {
507 NV10_PGRAPH_DEBUG_4,
508 0x004006b0,
509 0x00400eac,
510 0x00400eb0,
511 0x00400eb4,
512 0x00400eb8,
513 0x00400ebc,
514 0x00400ec0,
515 0x00400ec4,
516 0x00400ec8,
517 0x00400ecc,
518 0x00400ed0,
519 0x00400ed4,
520 0x00400ed8,
521 0x00400edc,
522 0x00400ee0,
523 0x00400a00,
524 0x00400a04,
525 };
526
527 static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
528 {
529         struct drm_nouveau_private *dev_priv = dev->dev_private;
530         int i, j;
531         for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) {
532                 if (nv10_graph_ctx_regs[i] == reg)
533                         return i;
534         }
535         if (dev_priv->chipset>=0x17) {
536                 for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) {
537                         if (nv17_graph_ctx_regs[j] == reg)
538                                 return i;
539                 }
540         }
541         return -1;
542 }
543
544 int nv10_graph_load_context(struct nouveau_channel *chan)
545 {
546         struct drm_device *dev = chan->dev;
547         struct drm_nouveau_private *dev_priv = dev->dev_private;
548         int i, j;
549
550         for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++)
551                 NV_WRITE(nv10_graph_ctx_regs[i], chan->pgraph_ctx[i]);
552         if (dev_priv->chipset>=0x17) {
553                 for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++)
554                         NV_WRITE(nv17_graph_ctx_regs[j], chan->pgraph_ctx[i]);
555         }
556         NV_WRITE(NV10_PGRAPH_CTX_USER, chan->id << 24);
557
558         return 0;
559 }
560
561 int nv10_graph_save_context(struct nouveau_channel *chan)
562 {
563         struct drm_device *dev = chan->dev;
564         struct drm_nouveau_private *dev_priv = dev->dev_private;
565         int i, j;
566
567         for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++)
568                 chan->pgraph_ctx[i] = NV_READ(nv10_graph_ctx_regs[i]);
569         if (dev_priv->chipset>=0x17) {
570                 for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++)
571                         chan->pgraph_ctx[i] = NV_READ(nv17_graph_ctx_regs[j]);
572         }
573
574         return 0;
575 }
576
577 void nouveau_nv10_context_switch(struct drm_device *dev)
578 {
579         struct drm_nouveau_private *dev_priv;
580         struct nouveau_channel *next, *last;
581         int chid;
582
583         if (!dev) {
584                 DRM_DEBUG("Invalid drm_device\n");
585                 return;
586         }
587         dev_priv = dev->dev_private;
588         if (!dev_priv) {
589                 DRM_DEBUG("Invalid drm_nouveau_private\n");
590                 return;
591         }
592         if (!dev_priv->fifos) {
593                 DRM_DEBUG("Invalid drm_nouveau_private->fifos\n");
594                 return;
595         }
596
597         chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
598         next = dev_priv->fifos[chid];
599
600         if (!next) {
601                 DRM_DEBUG("Invalid next channel\n");
602                 return;
603         }
604
605         chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
606         last = dev_priv->fifos[chid];
607
608         if (!last) {
609                 DRM_DEBUG("WARNING: Invalid last channel, switch to %x\n",
610                           next->id);
611         } else {
612                 DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",
613                          last->id, next->id);
614         }
615
616         NV_WRITE(NV04_PGRAPH_FIFO,0x0);
617         if (last) {
618                 nv10_graph_save_context(last);
619         }       
620
621         nouveau_wait_for_idle(dev);
622
623         NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000);
624         NV_WRITE(NV10_PGRAPH_CTX_USER, (NV_READ(NV10_PGRAPH_CTX_USER) & 0xffffff) | (0x1f << 24));
625
626         nouveau_wait_for_idle(dev);
627
628         nv10_graph_load_context(next);
629
630         NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
631         //NV_WRITE(NV10_PGRAPH_CTX_USER, next->id << 24);
632         NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
633         NV_WRITE(NV04_PGRAPH_FIFO,0x1);
634 }
635
636 #define NV_WRITE_CTX(reg, val) do { \
637         int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
638         if (offset > 0) \
639                 chan->pgraph_ctx[offset] = val; \
640         } while (0)
641
642 int nv10_graph_create_context(struct nouveau_channel *chan) {
643         struct drm_device *dev = chan->dev;
644         struct drm_nouveau_private *dev_priv = dev->dev_private;
645
646         DRM_DEBUG("nv10_graph_context_create %d\n", chan->id);
647
648         memset(chan->pgraph_ctx, 0, sizeof(chan->pgraph_ctx));
649
650         /* mmio trace suggest that should be done in ddx with methods/objects */
651 #if 0
652         uint32_t tmp, vramsz;
653         /* per channel init from ddx */
654         tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
655         /*XXX the original ddx code, does this in 2 steps :
656          * tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
657          * NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
658          * tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
659          * NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
660          */
661         tmp |= 0x00020100;
662         NV_WRITE_CTX(NV10_PGRAPH_SURFACE, tmp);
663
664         vramsz = drm_get_resource_len(dev, 0) - 1;
665         NV_WRITE_CTX(NV04_PGRAPH_BOFFSET0, 0);
666         NV_WRITE_CTX(NV04_PGRAPH_BOFFSET1, 0);
667         NV_WRITE_CTX(NV04_PGRAPH_BLIMIT0 , vramsz);
668         NV_WRITE_CTX(NV04_PGRAPH_BLIMIT1 , vramsz);
669
670         NV_WRITE_CTX(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
671         NV_WRITE_CTX(NV04_PGRAPH_BETA_AND     , 0xFFFFFFFF);
672
673         NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
674         NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
675         NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
676         NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
677 #endif
678
679         NV_WRITE_CTX(0x00400e88, 0x08000000);
680         NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
681         NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
682         NV_WRITE_CTX(0x00400e10, 0x00001000);
683         NV_WRITE_CTX(0x00400e14, 0x00001000);
684         NV_WRITE_CTX(0x00400e30, 0x00080008);
685         NV_WRITE_CTX(0x00400e34, 0x00080008);
686         if (dev_priv->chipset>=0x17) {
687                 /* is it really needed ??? */
688                 NV_WRITE_CTX(NV10_PGRAPH_DEBUG_4, NV_READ(NV10_PGRAPH_DEBUG_4));
689                 NV_WRITE_CTX(0x004006b0, NV_READ(0x004006b0));
690                 NV_WRITE_CTX(0x00400eac, 0x0fff0000);
691                 NV_WRITE_CTX(0x00400eb0, 0x0fff0000);
692                 NV_WRITE_CTX(0x00400ec0, 0x00000080);
693                 NV_WRITE_CTX(0x00400ed0, 0x00000080);
694         }
695
696         /* for the first channel init the regs */
697         if (dev_priv->fifo_alloc_count == 0)
698                 nv10_graph_load_context(chan);
699
700
701         //XXX should be saved/restored for each fifo
702         //we supposed here we have X fifo and only one 3D fifo.
703         nv10_praph_pipe(dev);
704         return 0;
705 }
706
707 void nv10_graph_destroy_context(struct nouveau_channel *chan)
708 {
709         struct drm_device *dev = chan->dev;
710         struct drm_nouveau_private *dev_priv = dev->dev_private;
711         int chid;
712         chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
713
714         /* does this avoid a potential context switch while we are written graph
715          * reg, or we should mask graph interrupt ???
716          */
717         NV_WRITE(NV04_PGRAPH_FIFO,0x0);
718         if (chid == chan->id) {
719                 DRM_INFO("cleanning a channel with graph in current context\n");
720                 nouveau_wait_for_idle(dev);
721                 DRM_INFO("reseting current graph context\n");
722                 nv10_graph_create_context(chan);
723                 nv10_graph_load_context(chan);
724         }
725         NV_WRITE(NV04_PGRAPH_FIFO,0x1);
726 }
727
728 int nv10_graph_init(struct drm_device *dev) {
729         struct drm_nouveau_private *dev_priv = dev->dev_private;
730         int i;
731
732         NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
733                         ~NV_PMC_ENABLE_PGRAPH);
734         NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
735                          NV_PMC_ENABLE_PGRAPH);
736
737         NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
738         NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
739
740         NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
741         NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
742         NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700);
743         //NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810); /* 0x25f92ad9 */
744         NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
745         NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
746                                       (1<<29) |
747                                       (1<<31));
748         if (dev_priv->chipset>=0x17) {
749                 NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x1f000000);
750                 NV_WRITE(0x004006b0, 0x40000020);
751         }
752         else
753                 NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000);
754
755         /* copy tile info from PFB */
756         for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
757                 NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i)));
758                 NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i)));
759                 NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i)));
760                 NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i)));
761         }
762
763         NV_WRITE(NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
764         NV_WRITE(NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
765         NV_WRITE(NV10_PGRAPH_CTX_SWITCH3, 0x00000000);
766         NV_WRITE(NV10_PGRAPH_CTX_SWITCH4, 0x00000000);
767         NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
768         NV_WRITE(NV10_PGRAPH_STATE      , 0xFFFFFFFF);
769         NV_WRITE(NV04_PGRAPH_FIFO       , 0x00000001);
770
771         return 0;
772 }
773
774 void nv10_graph_takedown(struct drm_device *dev)
775 {
776 }
777