blob: e3a87a64c164751948935b7e607b00562f5f971f [file] [log] [blame]
Ben Skeggs6ee73862009-12-11 19:24:15 +10001/*
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
32struct 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
45static int nv10_graph_ctx_regs[] = {
Francisco Jerezd2f4e892010-08-04 04:54:08 +020046 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),
Ben Skeggs6ee73862009-12-11 19:24:15 +100091 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
367static 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
388struct 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;
Francisco Jerez15bee692009-12-14 15:00:30 +0100392 uint32_t lma_window[4];
Ben Skeggs6ee73862009-12-11 19:24:15 +1000393};
394
Francisco Jerez15bee692009-12-14 15:00:30 +0100395#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
Ben Skeggs6ee73862009-12-11 19:24:15 +1000411static 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;
Francisco Jerez15bee692009-12-14 15:00:30 +0100415 struct pipe_state *pipe = &pgraph_ctx->pipe_state;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000416
Francisco Jerez15bee692009-12-14 15:00:30 +0100417 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);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000427}
428
429static 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;
Francisco Jerez15bee692009-12-14 15:00:30 +0100433 struct pipe_state *pipe = &pgraph_ctx->pipe_state;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000434 uint32_t xfmode0, xfmode1;
Francisco Jerez15bee692009-12-14 15:00:30 +0100435 int i;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000436
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
Francisco Jerez15bee692009-12-14 15:00:30 +0100461 PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000462 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);
Francisco Jerez15bee692009-12-14 15:00:30 +0100467 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);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000476 nouveau_wait_for_idle(dev);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000477}
478
479static 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
634static 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
645static 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
Francisco Jerezd2f4e892010-08-04 04:54:08 +0200656static 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
Ben Skeggs6ee73862009-12-11 19:24:15 +1000728int 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);
Francisco Jerezd2f4e892010-08-04 04:54:08 +0200745 nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
746 & 0xffff));
Ben Skeggs6ee73862009-12-11 19:24:15 +1000747
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
756int
757nv10_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
789void
790nv10_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;
Ben Skeggscff5c132010-10-06 16:16:59 +1000805 chan = dev_priv->channels.ptr[chid];
Francisco Jerezbb338bb2010-09-21 19:03:19 +0200806 if (chan && chan->pgraph_ctx)
Ben Skeggs6ee73862009-12-11 19:24:15 +1000807 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
824struct nouveau_channel *
825nv10_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
Ben Skeggscff5c132010-10-06 16:16:59 +1000836 return dev_priv->channels.ptr[chid];
Ben Skeggs6ee73862009-12-11 19:24:15 +1000837}
838
839int 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
876void nv10_graph_destroy_context(struct nouveau_channel *chan)
877{
Francisco Jerez3945e472010-10-18 03:53:39 +0200878 struct drm_device *dev = chan->dev;
879 struct drm_nouveau_private *dev_priv = dev->dev_private;
880 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000881 struct graph_state *pgraph_ctx = chan->pgraph_ctx;
Francisco Jerez3945e472010-10-18 03:53:39 +0200882 unsigned long flags;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000883
Francisco Jerez3945e472010-10-18 03:53:39 +0200884 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
885 pgraph->fifo_access(dev, false);
886
887 /* Unload the context if it's the currently active one */
888 if (pgraph->channel(dev) == chan)
889 pgraph->unload_context(dev);
890
891 /* Free the context resources */
Ben Skeggs6ee73862009-12-11 19:24:15 +1000892 kfree(pgraph_ctx);
893 chan->pgraph_ctx = NULL;
Francisco Jerez3945e472010-10-18 03:53:39 +0200894
895 pgraph->fifo_access(dev, true);
896 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000897}
898
Francisco Jerez0d87c102009-12-16 12:12:27 +0100899void
900nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
901 uint32_t size, uint32_t pitch)
902{
903 uint32_t limit = max(1u, addr + size) - 1;
904
905 if (pitch)
906 addr |= 1 << 31;
907
908 nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit);
909 nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch);
910 nv_wr32(dev, NV10_PGRAPH_TILE(i), addr);
911}
912
Ben Skeggs6ee73862009-12-11 19:24:15 +1000913int nv10_graph_init(struct drm_device *dev)
914{
915 struct drm_nouveau_private *dev_priv = dev->dev_private;
916 uint32_t tmp;
917 int i;
918
919 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
920 ~NV_PMC_ENABLE_PGRAPH);
921 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
922 NV_PMC_ENABLE_PGRAPH);
923
924 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
925 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
926
927 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
928 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
929 nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
930 /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
931 nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
932 nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
933 (1<<29) |
934 (1<<31));
935 if (dev_priv->chipset >= 0x17) {
936 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
Francisco Jerez15bee692009-12-14 15:00:30 +0100937 nv_wr32(dev, 0x400a10, 0x3ff3fb6);
938 nv_wr32(dev, 0x400838, 0x2f8684);
939 nv_wr32(dev, 0x40083c, 0x115f3f);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000940 nv_wr32(dev, 0x004006b0, 0x40000020);
941 } else
942 nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
943
Francisco Jerez0d87c102009-12-16 12:12:27 +0100944 /* Turn all the tiling regions off. */
945 for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
946 nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000947
Francisco Jerezd2f4e892010-08-04 04:54:08 +0200948 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
949 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
950 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
951 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
952 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
953 nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000954
955 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
956 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
957 nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
958 nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
959 nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
960
961 return 0;
962}
963
964void nv10_graph_takedown(struct drm_device *dev)
965{
966}
967
Francisco Jerez15bee692009-12-14 15:00:30 +0100968static int
969nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass,
970 int mthd, uint32_t data)
971{
972 struct drm_device *dev = chan->dev;
973 struct graph_state *ctx = chan->pgraph_ctx;
974 struct pipe_state *pipe = &ctx->pipe_state;
975 struct drm_nouveau_private *dev_priv = dev->dev_private;
976 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
977 uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
978 uint32_t xfmode0, xfmode1;
979 int i;
980
981 ctx->lma_window[(mthd - 0x1638) / 4] = data;
982
983 if (mthd != 0x1644)
984 return 0;
985
986 nouveau_wait_for_idle(dev);
987
988 PIPE_SAVE(dev, pipe_0x0040, 0x0040);
989 PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
990
991 PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
992
993 nouveau_wait_for_idle(dev);
994
995 xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
996 xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
997
998 PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
999 PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
1000 PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
1001 PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
1002
1003 nouveau_wait_for_idle(dev);
1004
1005 nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
1006 nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
1007 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
1008 for (i = 0; i < 4; i++)
1009 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
1010 for (i = 0; i < 4; i++)
1011 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1012
1013 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
1014 for (i = 0; i < 3; i++)
1015 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
1016
1017 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
1018 for (i = 0; i < 3; i++)
1019 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1020
1021 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
1022 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
1023
1024 PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
1025
1026 nouveau_wait_for_idle(dev);
1027
1028 PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
1029
1030 nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
1031 nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
1032
1033 PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
1034 PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
1035 PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
1036 PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
1037
1038 nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
1039 nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1040
1041 nouveau_wait_for_idle(dev);
1042
1043 pgraph->fifo_access(dev, true);
1044
1045 return 0;
1046}
1047
1048static int
1049nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass,
1050 int mthd, uint32_t data)
1051{
1052 struct drm_device *dev = chan->dev;
1053 struct drm_nouveau_private *dev_priv = dev->dev_private;
1054 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
1055
1056 nouveau_wait_for_idle(dev);
1057
1058 nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
1059 nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
1060 nv_wr32(dev, 0x004006b0,
1061 nv_rd32(dev, 0x004006b0) | 0x8 << 24);
1062
1063 pgraph->fifo_access(dev, true);
1064
1065 return 0;
1066}
1067
1068static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = {
1069 { 0x1638, nv17_graph_mthd_lma_window },
1070 { 0x163c, nv17_graph_mthd_lma_window },
1071 { 0x1640, nv17_graph_mthd_lma_window },
1072 { 0x1644, nv17_graph_mthd_lma_window },
1073 { 0x1658, nv17_graph_mthd_lma_enable },
1074 {}
1075};
1076
Ben Skeggs6ee73862009-12-11 19:24:15 +10001077struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
1078 { 0x0030, false, NULL }, /* null */
1079 { 0x0039, false, NULL }, /* m2mf */
1080 { 0x004a, false, NULL }, /* gdirect */
1081 { 0x005f, false, NULL }, /* imageblit */
1082 { 0x009f, false, NULL }, /* imageblit (nv12) */
1083 { 0x008a, false, NULL }, /* ifc */
1084 { 0x0089, false, NULL }, /* sifm */
1085 { 0x0062, false, NULL }, /* surf2d */
1086 { 0x0043, false, NULL }, /* rop */
1087 { 0x0012, false, NULL }, /* beta1 */
1088 { 0x0072, false, NULL }, /* beta4 */
1089 { 0x0019, false, NULL }, /* cliprect */
1090 { 0x0044, false, NULL }, /* pattern */
1091 { 0x0052, false, NULL }, /* swzsurf */
1092 { 0x0093, false, NULL }, /* surf3d */
1093 { 0x0094, false, NULL }, /* tex_tri */
1094 { 0x0095, false, NULL }, /* multitex_tri */
1095 { 0x0056, false, NULL }, /* celcius (nv10) */
1096 { 0x0096, false, NULL }, /* celcius (nv11) */
Francisco Jerez15bee692009-12-14 15:00:30 +01001097 { 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */
Ben Skeggs6ee73862009-12-11 19:24:15 +10001098 {}
1099};