drm/nouveau/mmu: namespace + nvidia gpu names (no binary change)
[deliverable/linux.git] / drivers / gpu / drm / nouveau / nvkm / engine / gr / nv10.c
CommitLineData
6ee73861
BS
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
b8bf04e1 13 * paragr) shall be included in all copies or substantial portions of the
6ee73861
BS
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
93260d3c 25#include <core/client.h>
42594600 26#include <core/device.h>
ebb945a9 27#include <core/os.h>
ebb945a9
BS
28#include <core/handle.h>
29
30#include <subdev/fb.h>
31
32#include <engine/fifo.h>
b8bf04e1 33#include <engine/gr.h>
ebb945a9
BS
34
35#include "regs.h"
6ee73861
BS
36
37struct pipe_state {
ebb945a9
BS
38 u32 pipe_0x0000[0x040/4];
39 u32 pipe_0x0040[0x010/4];
40 u32 pipe_0x0200[0x0c0/4];
41 u32 pipe_0x4400[0x080/4];
42 u32 pipe_0x6400[0x3b0/4];
43 u32 pipe_0x6800[0x2f0/4];
44 u32 pipe_0x6c00[0x030/4];
45 u32 pipe_0x7000[0x130/4];
46 u32 pipe_0x7400[0x0c0/4];
47 u32 pipe_0x7800[0x0c0/4];
6ee73861
BS
48};
49
b8bf04e1 50static int nv10_gr_ctx_regs[] = {
d2f4e892
FJ
51 NV10_PGRAPH_CTX_SWITCH(0),
52 NV10_PGRAPH_CTX_SWITCH(1),
53 NV10_PGRAPH_CTX_SWITCH(2),
54 NV10_PGRAPH_CTX_SWITCH(3),
55 NV10_PGRAPH_CTX_SWITCH(4),
56 NV10_PGRAPH_CTX_CACHE(0, 0),
57 NV10_PGRAPH_CTX_CACHE(0, 1),
58 NV10_PGRAPH_CTX_CACHE(0, 2),
59 NV10_PGRAPH_CTX_CACHE(0, 3),
60 NV10_PGRAPH_CTX_CACHE(0, 4),
61 NV10_PGRAPH_CTX_CACHE(1, 0),
62 NV10_PGRAPH_CTX_CACHE(1, 1),
63 NV10_PGRAPH_CTX_CACHE(1, 2),
64 NV10_PGRAPH_CTX_CACHE(1, 3),
65 NV10_PGRAPH_CTX_CACHE(1, 4),
66 NV10_PGRAPH_CTX_CACHE(2, 0),
67 NV10_PGRAPH_CTX_CACHE(2, 1),
68 NV10_PGRAPH_CTX_CACHE(2, 2),
69 NV10_PGRAPH_CTX_CACHE(2, 3),
70 NV10_PGRAPH_CTX_CACHE(2, 4),
71 NV10_PGRAPH_CTX_CACHE(3, 0),
72 NV10_PGRAPH_CTX_CACHE(3, 1),
73 NV10_PGRAPH_CTX_CACHE(3, 2),
74 NV10_PGRAPH_CTX_CACHE(3, 3),
75 NV10_PGRAPH_CTX_CACHE(3, 4),
76 NV10_PGRAPH_CTX_CACHE(4, 0),
77 NV10_PGRAPH_CTX_CACHE(4, 1),
78 NV10_PGRAPH_CTX_CACHE(4, 2),
79 NV10_PGRAPH_CTX_CACHE(4, 3),
80 NV10_PGRAPH_CTX_CACHE(4, 4),
81 NV10_PGRAPH_CTX_CACHE(5, 0),
82 NV10_PGRAPH_CTX_CACHE(5, 1),
83 NV10_PGRAPH_CTX_CACHE(5, 2),
84 NV10_PGRAPH_CTX_CACHE(5, 3),
85 NV10_PGRAPH_CTX_CACHE(5, 4),
86 NV10_PGRAPH_CTX_CACHE(6, 0),
87 NV10_PGRAPH_CTX_CACHE(6, 1),
88 NV10_PGRAPH_CTX_CACHE(6, 2),
89 NV10_PGRAPH_CTX_CACHE(6, 3),
90 NV10_PGRAPH_CTX_CACHE(6, 4),
91 NV10_PGRAPH_CTX_CACHE(7, 0),
92 NV10_PGRAPH_CTX_CACHE(7, 1),
93 NV10_PGRAPH_CTX_CACHE(7, 2),
94 NV10_PGRAPH_CTX_CACHE(7, 3),
95 NV10_PGRAPH_CTX_CACHE(7, 4),
6ee73861
BS
96 NV10_PGRAPH_CTX_USER,
97 NV04_PGRAPH_DMA_START_0,
98 NV04_PGRAPH_DMA_START_1,
99 NV04_PGRAPH_DMA_LENGTH,
100 NV04_PGRAPH_DMA_MISC,
101 NV10_PGRAPH_DMA_PITCH,
102 NV04_PGRAPH_BOFFSET0,
103 NV04_PGRAPH_BBASE0,
104 NV04_PGRAPH_BLIMIT0,
105 NV04_PGRAPH_BOFFSET1,
106 NV04_PGRAPH_BBASE1,
107 NV04_PGRAPH_BLIMIT1,
108 NV04_PGRAPH_BOFFSET2,
109 NV04_PGRAPH_BBASE2,
110 NV04_PGRAPH_BLIMIT2,
111 NV04_PGRAPH_BOFFSET3,
112 NV04_PGRAPH_BBASE3,
113 NV04_PGRAPH_BLIMIT3,
114 NV04_PGRAPH_BOFFSET4,
115 NV04_PGRAPH_BBASE4,
116 NV04_PGRAPH_BLIMIT4,
117 NV04_PGRAPH_BOFFSET5,
118 NV04_PGRAPH_BBASE5,
119 NV04_PGRAPH_BLIMIT5,
120 NV04_PGRAPH_BPITCH0,
121 NV04_PGRAPH_BPITCH1,
122 NV04_PGRAPH_BPITCH2,
123 NV04_PGRAPH_BPITCH3,
124 NV04_PGRAPH_BPITCH4,
125 NV10_PGRAPH_SURFACE,
126 NV10_PGRAPH_STATE,
127 NV04_PGRAPH_BSWIZZLE2,
128 NV04_PGRAPH_BSWIZZLE5,
129 NV04_PGRAPH_BPIXEL,
130 NV10_PGRAPH_NOTIFY,
131 NV04_PGRAPH_PATT_COLOR0,
132 NV04_PGRAPH_PATT_COLOR1,
133 NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
134 0x00400904,
135 0x00400908,
136 0x0040090c,
137 0x00400910,
138 0x00400914,
139 0x00400918,
140 0x0040091c,
141 0x00400920,
142 0x00400924,
143 0x00400928,
144 0x0040092c,
145 0x00400930,
146 0x00400934,
147 0x00400938,
148 0x0040093c,
149 0x00400940,
150 0x00400944,
151 0x00400948,
152 0x0040094c,
153 0x00400950,
154 0x00400954,
155 0x00400958,
156 0x0040095c,
157 0x00400960,
158 0x00400964,
159 0x00400968,
160 0x0040096c,
161 0x00400970,
162 0x00400974,
163 0x00400978,
164 0x0040097c,
165 0x00400980,
166 0x00400984,
167 0x00400988,
168 0x0040098c,
169 0x00400990,
170 0x00400994,
171 0x00400998,
172 0x0040099c,
173 0x004009a0,
174 0x004009a4,
175 0x004009a8,
176 0x004009ac,
177 0x004009b0,
178 0x004009b4,
179 0x004009b8,
180 0x004009bc,
181 0x004009c0,
182 0x004009c4,
183 0x004009c8,
184 0x004009cc,
185 0x004009d0,
186 0x004009d4,
187 0x004009d8,
188 0x004009dc,
189 0x004009e0,
190 0x004009e4,
191 0x004009e8,
192 0x004009ec,
193 0x004009f0,
194 0x004009f4,
195 0x004009f8,
196 0x004009fc,
197 NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */
198 0x0040080c,
199 NV04_PGRAPH_PATTERN_SHAPE,
200 NV03_PGRAPH_MONO_COLOR0,
201 NV04_PGRAPH_ROP3,
202 NV04_PGRAPH_CHROMA,
203 NV04_PGRAPH_BETA_AND,
204 NV04_PGRAPH_BETA_PREMULT,
205 0x00400e70,
206 0x00400e74,
207 0x00400e78,
208 0x00400e7c,
209 0x00400e80,
210 0x00400e84,
211 0x00400e88,
212 0x00400e8c,
213 0x00400ea0,
214 0x00400ea4,
215 0x00400ea8,
216 0x00400e90,
217 0x00400e94,
218 0x00400e98,
219 0x00400e9c,
220 NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
221 NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */
222 0x00400f04,
223 0x00400f24,
224 0x00400f08,
225 0x00400f28,
226 0x00400f0c,
227 0x00400f2c,
228 0x00400f10,
229 0x00400f30,
230 0x00400f14,
231 0x00400f34,
232 0x00400f18,
233 0x00400f38,
234 0x00400f1c,
235 0x00400f3c,
236 NV10_PGRAPH_XFMODE0,
237 NV10_PGRAPH_XFMODE1,
238 NV10_PGRAPH_GLOBALSTATE0,
239 NV10_PGRAPH_GLOBALSTATE1,
240 NV04_PGRAPH_STORED_FMT,
241 NV04_PGRAPH_SOURCE_COLOR,
242 NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */
243 NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */
244 0x00400404,
245 0x00400484,
246 0x00400408,
247 0x00400488,
248 0x0040040c,
249 0x0040048c,
250 0x00400410,
251 0x00400490,
252 0x00400414,
253 0x00400494,
254 0x00400418,
255 0x00400498,
256 0x0040041c,
257 0x0040049c,
258 0x00400420,
259 0x004004a0,
260 0x00400424,
261 0x004004a4,
262 0x00400428,
263 0x004004a8,
264 0x0040042c,
265 0x004004ac,
266 0x00400430,
267 0x004004b0,
268 0x00400434,
269 0x004004b4,
270 0x00400438,
271 0x004004b8,
272 0x0040043c,
273 0x004004bc,
274 0x00400440,
275 0x004004c0,
276 0x00400444,
277 0x004004c4,
278 0x00400448,
279 0x004004c8,
280 0x0040044c,
281 0x004004cc,
282 0x00400450,
283 0x004004d0,
284 0x00400454,
285 0x004004d4,
286 0x00400458,
287 0x004004d8,
288 0x0040045c,
289 0x004004dc,
290 0x00400460,
291 0x004004e0,
292 0x00400464,
293 0x004004e4,
294 0x00400468,
295 0x004004e8,
296 0x0040046c,
297 0x004004ec,
298 0x00400470,
299 0x004004f0,
300 0x00400474,
301 0x004004f4,
302 0x00400478,
303 0x004004f8,
304 0x0040047c,
305 0x004004fc,
306 NV03_PGRAPH_ABS_UCLIP_XMIN,
307 NV03_PGRAPH_ABS_UCLIP_XMAX,
308 NV03_PGRAPH_ABS_UCLIP_YMIN,
309 NV03_PGRAPH_ABS_UCLIP_YMAX,
310 0x00400550,
311 0x00400558,
312 0x00400554,
313 0x0040055c,
314 NV03_PGRAPH_ABS_UCLIPA_XMIN,
315 NV03_PGRAPH_ABS_UCLIPA_XMAX,
316 NV03_PGRAPH_ABS_UCLIPA_YMIN,
317 NV03_PGRAPH_ABS_UCLIPA_YMAX,
318 NV03_PGRAPH_ABS_ICLIP_XMAX,
319 NV03_PGRAPH_ABS_ICLIP_YMAX,
320 NV03_PGRAPH_XY_LOGIC_MISC0,
321 NV03_PGRAPH_XY_LOGIC_MISC1,
322 NV03_PGRAPH_XY_LOGIC_MISC2,
323 NV03_PGRAPH_XY_LOGIC_MISC3,
324 NV03_PGRAPH_CLIPX_0,
325 NV03_PGRAPH_CLIPX_1,
326 NV03_PGRAPH_CLIPY_0,
327 NV03_PGRAPH_CLIPY_1,
328 NV10_PGRAPH_COMBINER0_IN_ALPHA,
329 NV10_PGRAPH_COMBINER1_IN_ALPHA,
330 NV10_PGRAPH_COMBINER0_IN_RGB,
331 NV10_PGRAPH_COMBINER1_IN_RGB,
332 NV10_PGRAPH_COMBINER_COLOR0,
333 NV10_PGRAPH_COMBINER_COLOR1,
334 NV10_PGRAPH_COMBINER0_OUT_ALPHA,
335 NV10_PGRAPH_COMBINER1_OUT_ALPHA,
336 NV10_PGRAPH_COMBINER0_OUT_RGB,
337 NV10_PGRAPH_COMBINER1_OUT_RGB,
338 NV10_PGRAPH_COMBINER_FINAL0,
339 NV10_PGRAPH_COMBINER_FINAL1,
340 0x00400e00,
341 0x00400e04,
342 0x00400e08,
343 0x00400e0c,
344 0x00400e10,
345 0x00400e14,
346 0x00400e18,
347 0x00400e1c,
348 0x00400e20,
349 0x00400e24,
350 0x00400e28,
351 0x00400e2c,
352 0x00400e30,
353 0x00400e34,
354 0x00400e38,
355 0x00400e3c,
356 NV04_PGRAPH_PASSTHRU_0,
357 NV04_PGRAPH_PASSTHRU_1,
358 NV04_PGRAPH_PASSTHRU_2,
359 NV10_PGRAPH_DIMX_TEXTURE,
360 NV10_PGRAPH_WDIMX_TEXTURE,
361 NV10_PGRAPH_DVD_COLORFMT,
362 NV10_PGRAPH_SCALED_FORMAT,
363 NV04_PGRAPH_MISC24_0,
364 NV04_PGRAPH_MISC24_1,
365 NV04_PGRAPH_MISC24_2,
366 NV03_PGRAPH_X_MISC,
367 NV03_PGRAPH_Y_MISC,
368 NV04_PGRAPH_VALID1,
369 NV04_PGRAPH_VALID2,
370};
371
b8bf04e1 372static int nv17_gr_ctx_regs[] = {
6ee73861
BS
373 NV10_PGRAPH_DEBUG_4,
374 0x004006b0,
375 0x00400eac,
376 0x00400eb0,
377 0x00400eb4,
378 0x00400eb8,
379 0x00400ebc,
380 0x00400ec0,
381 0x00400ec4,
382 0x00400ec8,
383 0x00400ecc,
384 0x00400ed0,
385 0x00400ed4,
386 0x00400ed8,
387 0x00400edc,
388 0x00400ee0,
389 0x00400a00,
390 0x00400a04,
391};
392
b8bf04e1
BS
393struct nv10_gr_priv {
394 struct nouveau_gr base;
395 struct nv10_gr_chan *chan[32];
ebb945a9
BS
396 spinlock_t lock;
397};
398
b8bf04e1 399struct nv10_gr_chan {
ebb945a9
BS
400 struct nouveau_object base;
401 int chid;
b8bf04e1
BS
402 int nv10[ARRAY_SIZE(nv10_gr_ctx_regs)];
403 int nv17[ARRAY_SIZE(nv17_gr_ctx_regs)];
6ee73861 404 struct pipe_state pipe_state;
ebb945a9 405 u32 lma_window[4];
6ee73861
BS
406};
407
ebb945a9 408
b8bf04e1
BS
409static inline struct nv10_gr_priv *
410nv10_gr_priv(struct nv10_gr_chan *chan)
ebb945a9
BS
411{
412 return (void *)nv_object(chan)->engine;
413}
414
415/*******************************************************************************
416 * Graphics object classes
417 ******************************************************************************/
418
419#define PIPE_SAVE(priv, state, addr) \
15bee69e
FJ
420 do { \
421 int __i; \
ebb945a9 422 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \
15bee69e 423 for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
ebb945a9 424 state[__i] = nv_rd32(priv, NV10_PGRAPH_PIPE_DATA); \
15bee69e
FJ
425 } while (0)
426
ebb945a9 427#define PIPE_RESTORE(priv, state, addr) \
15bee69e
FJ
428 do { \
429 int __i; \
ebb945a9 430 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \
15bee69e 431 for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
ebb945a9 432 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, state[__i]); \
15bee69e
FJ
433 } while (0)
434
ebb945a9 435static struct nouveau_oclass
b8bf04e1
BS
436nv10_gr_sclass[] = {
437 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
438 { 0x0019, &nv04_gr_ofuncs }, /* clip */
439 { 0x0030, &nv04_gr_ofuncs }, /* null */
440 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
441 { 0x0043, &nv04_gr_ofuncs }, /* rop */
442 { 0x0044, &nv04_gr_ofuncs }, /* pattern */
443 { 0x004a, &nv04_gr_ofuncs }, /* gdi */
444 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
445 { 0x005f, &nv04_gr_ofuncs }, /* blit */
446 { 0x0062, &nv04_gr_ofuncs }, /* surf2d */
447 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
448 { 0x0089, &nv04_gr_ofuncs }, /* sifm */
449 { 0x008a, &nv04_gr_ofuncs }, /* ifc */
450 { 0x009f, &nv04_gr_ofuncs }, /* blit */
451 { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
452 { 0x0094, &nv04_gr_ofuncs }, /* ttri */
453 { 0x0095, &nv04_gr_ofuncs }, /* mtri */
454 { 0x0056, &nv04_gr_ofuncs }, /* celcius */
ebb945a9
BS
455 {},
456};
457
458static struct nouveau_oclass
b8bf04e1
BS
459nv15_gr_sclass[] = {
460 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
461 { 0x0019, &nv04_gr_ofuncs }, /* clip */
462 { 0x0030, &nv04_gr_ofuncs }, /* null */
463 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
464 { 0x0043, &nv04_gr_ofuncs }, /* rop */
465 { 0x0044, &nv04_gr_ofuncs }, /* pattern */
466 { 0x004a, &nv04_gr_ofuncs }, /* gdi */
467 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
468 { 0x005f, &nv04_gr_ofuncs }, /* blit */
469 { 0x0062, &nv04_gr_ofuncs }, /* surf2d */
470 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
471 { 0x0089, &nv04_gr_ofuncs }, /* sifm */
472 { 0x008a, &nv04_gr_ofuncs }, /* ifc */
473 { 0x009f, &nv04_gr_ofuncs }, /* blit */
474 { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
475 { 0x0094, &nv04_gr_ofuncs }, /* ttri */
476 { 0x0095, &nv04_gr_ofuncs }, /* mtri */
477 { 0x0096, &nv04_gr_ofuncs }, /* celcius */
ebb945a9
BS
478 {},
479};
480
481static int
b8bf04e1 482nv17_gr_mthd_lma_window(struct nouveau_object *object, u32 mthd,
ebb945a9
BS
483 void *args, u32 size)
484{
b8bf04e1
BS
485 struct nv10_gr_chan *chan = (void *)object->parent;
486 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9
BS
487 struct pipe_state *pipe = &chan->pipe_state;
488 u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
489 u32 xfmode0, xfmode1;
490 u32 data = *(u32 *)args;
491 int i;
492
493 chan->lma_window[(mthd - 0x1638) / 4] = data;
494
495 if (mthd != 0x1644)
496 return 0;
497
b8bf04e1 498 nv04_gr_idle(priv);
ebb945a9
BS
499
500 PIPE_SAVE(priv, pipe_0x0040, 0x0040);
501 PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200);
502
503 PIPE_RESTORE(priv, chan->lma_window, 0x6790);
504
b8bf04e1 505 nv04_gr_idle(priv);
ebb945a9
BS
506
507 xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0);
508 xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1);
509
510 PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400);
511 PIPE_SAVE(priv, pipe_0x64c0, 0x64c0);
512 PIPE_SAVE(priv, pipe_0x6ab0, 0x6ab0);
513 PIPE_SAVE(priv, pipe_0x6a80, 0x6a80);
514
b8bf04e1 515 nv04_gr_idle(priv);
ebb945a9
BS
516
517 nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000);
518 nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000);
519 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
520 for (i = 0; i < 4; i++)
521 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
522 for (i = 0; i < 4; i++)
523 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
524
525 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
526 for (i = 0; i < 3; i++)
527 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
528
529 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
530 for (i = 0; i < 3; i++)
531 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
532
533 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
534 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008);
535
536 PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200);
537
b8bf04e1 538 nv04_gr_idle(priv);
ebb945a9
BS
539
540 PIPE_RESTORE(priv, pipe_0x0040, 0x0040);
541
542 nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0);
543 nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1);
544
545 PIPE_RESTORE(priv, pipe_0x64c0, 0x64c0);
546 PIPE_RESTORE(priv, pipe_0x6ab0, 0x6ab0);
547 PIPE_RESTORE(priv, pipe_0x6a80, 0x6a80);
548 PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400);
549
550 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
551 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
552
b8bf04e1 553 nv04_gr_idle(priv);
ebb945a9
BS
554
555 return 0;
556}
557
558static int
b8bf04e1 559nv17_gr_mthd_lma_enable(struct nouveau_object *object, u32 mthd,
ebb945a9 560 void *args, u32 size)
6ee73861 561{
b8bf04e1
BS
562 struct nv10_gr_chan *chan = (void *)object->parent;
563 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9 564
b8bf04e1 565 nv04_gr_idle(priv);
ebb945a9
BS
566
567 nv_mask(priv, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100);
568 nv_mask(priv, 0x4006b0, 0x08000000, 0x08000000);
569 return 0;
6ee73861
BS
570}
571
ebb945a9
BS
572static struct nouveau_omthds
573nv17_celcius_omthds[] = {
b8bf04e1
BS
574 { 0x1638, 0x1638, nv17_gr_mthd_lma_window },
575 { 0x163c, 0x163c, nv17_gr_mthd_lma_window },
576 { 0x1640, 0x1640, nv17_gr_mthd_lma_window },
577 { 0x1644, 0x1644, nv17_gr_mthd_lma_window },
578 { 0x1658, 0x1658, nv17_gr_mthd_lma_enable },
ebb945a9
BS
579 {}
580};
581
582static struct nouveau_oclass
b8bf04e1
BS
583nv17_gr_sclass[] = {
584 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
585 { 0x0019, &nv04_gr_ofuncs }, /* clip */
586 { 0x0030, &nv04_gr_ofuncs }, /* null */
587 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
588 { 0x0043, &nv04_gr_ofuncs }, /* rop */
589 { 0x0044, &nv04_gr_ofuncs }, /* pattern */
590 { 0x004a, &nv04_gr_ofuncs }, /* gdi */
591 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
592 { 0x005f, &nv04_gr_ofuncs }, /* blit */
593 { 0x0062, &nv04_gr_ofuncs }, /* surf2d */
594 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
595 { 0x0089, &nv04_gr_ofuncs }, /* sifm */
596 { 0x008a, &nv04_gr_ofuncs }, /* ifc */
597 { 0x009f, &nv04_gr_ofuncs }, /* blit */
598 { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
599 { 0x0094, &nv04_gr_ofuncs }, /* ttri */
600 { 0x0095, &nv04_gr_ofuncs }, /* mtri */
601 { 0x0099, &nv04_gr_ofuncs, nv17_celcius_omthds },
ebb945a9
BS
602 {},
603};
604
605/*******************************************************************************
606 * PGRAPH context
607 ******************************************************************************/
608
b8bf04e1
BS
609static struct nv10_gr_chan *
610nv10_gr_channel(struct nv10_gr_priv *priv)
6ee73861 611{
b8bf04e1 612 struct nv10_gr_chan *chan = NULL;
ebb945a9
BS
613 if (nv_rd32(priv, 0x400144) & 0x00010000) {
614 int chid = nv_rd32(priv, 0x400148) >> 24;
615 if (chid < ARRAY_SIZE(priv->chan))
616 chan = priv->chan[chid];
617 }
618 return chan;
619}
620
621static void
b8bf04e1 622nv10_gr_save_pipe(struct nv10_gr_chan *chan)
ebb945a9 623{
b8bf04e1 624 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9
BS
625 struct pipe_state *pipe = &chan->pipe_state;
626
627 PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400);
628 PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200);
629 PIPE_SAVE(priv, pipe->pipe_0x6400, 0x6400);
630 PIPE_SAVE(priv, pipe->pipe_0x6800, 0x6800);
631 PIPE_SAVE(priv, pipe->pipe_0x6c00, 0x6c00);
632 PIPE_SAVE(priv, pipe->pipe_0x7000, 0x7000);
633 PIPE_SAVE(priv, pipe->pipe_0x7400, 0x7400);
634 PIPE_SAVE(priv, pipe->pipe_0x7800, 0x7800);
635 PIPE_SAVE(priv, pipe->pipe_0x0040, 0x0040);
636 PIPE_SAVE(priv, pipe->pipe_0x0000, 0x0000);
637}
638
639static void
b8bf04e1 640nv10_gr_load_pipe(struct nv10_gr_chan *chan)
ebb945a9 641{
b8bf04e1 642 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9
BS
643 struct pipe_state *pipe = &chan->pipe_state;
644 u32 xfmode0, xfmode1;
15bee69e 645 int i;
6ee73861 646
b8bf04e1 647 nv04_gr_idle(priv);
6ee73861 648 /* XXX check haiku comments */
ebb945a9
BS
649 xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0);
650 xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1);
651 nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000);
652 nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000);
653 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
6ee73861 654 for (i = 0; i < 4; i++)
ebb945a9 655 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
6ee73861 656 for (i = 0; i < 4; i++)
ebb945a9 657 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
6ee73861 658
ebb945a9 659 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
6ee73861 660 for (i = 0; i < 3; i++)
ebb945a9 661 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
6ee73861 662
ebb945a9 663 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
6ee73861 664 for (i = 0; i < 3; i++)
ebb945a9 665 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
6ee73861 666
ebb945a9
BS
667 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
668 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008);
6ee73861
BS
669
670
ebb945a9 671 PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200);
b8bf04e1 672 nv04_gr_idle(priv);
6ee73861
BS
673
674 /* restore XFMODE */
ebb945a9
BS
675 nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0);
676 nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1);
677 PIPE_RESTORE(priv, pipe->pipe_0x6400, 0x6400);
678 PIPE_RESTORE(priv, pipe->pipe_0x6800, 0x6800);
679 PIPE_RESTORE(priv, pipe->pipe_0x6c00, 0x6c00);
680 PIPE_RESTORE(priv, pipe->pipe_0x7000, 0x7000);
681 PIPE_RESTORE(priv, pipe->pipe_0x7400, 0x7400);
682 PIPE_RESTORE(priv, pipe->pipe_0x7800, 0x7800);
683 PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400);
684 PIPE_RESTORE(priv, pipe->pipe_0x0000, 0x0000);
685 PIPE_RESTORE(priv, pipe->pipe_0x0040, 0x0040);
b8bf04e1 686 nv04_gr_idle(priv);
6ee73861
BS
687}
688
ebb945a9 689static void
b8bf04e1 690nv10_gr_create_pipe(struct nv10_gr_chan *chan)
6ee73861 691{
b8bf04e1 692 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9
BS
693 struct pipe_state *pipe_state = &chan->pipe_state;
694 u32 *pipe_state_addr;
6ee73861
BS
695 int i;
696#define PIPE_INIT(addr) \
697 do { \
ebb945a9 698 pipe_state_addr = pipe_state->pipe_##addr; \
6ee73861
BS
699 } while (0)
700#define PIPE_INIT_END(addr) \
701 do { \
ebb945a9
BS
702 u32 *__end_addr = pipe_state->pipe_##addr + \
703 ARRAY_SIZE(pipe_state->pipe_##addr); \
704 if (pipe_state_addr != __end_addr) \
705 nv_error(priv, "incomplete pipe init for 0x%x : %p/%p\n", \
706 addr, pipe_state_addr, __end_addr); \
6ee73861 707 } while (0)
ebb945a9 708#define NV_WRITE_PIPE_INIT(value) *(pipe_state_addr++) = value
6ee73861
BS
709
710 PIPE_INIT(0x0200);
711 for (i = 0; i < 48; i++)
712 NV_WRITE_PIPE_INIT(0x00000000);
713 PIPE_INIT_END(0x0200);
714
715 PIPE_INIT(0x6400);
716 for (i = 0; i < 211; i++)
717 NV_WRITE_PIPE_INIT(0x00000000);
718 NV_WRITE_PIPE_INIT(0x3f800000);
719 NV_WRITE_PIPE_INIT(0x40000000);
720 NV_WRITE_PIPE_INIT(0x40000000);
721 NV_WRITE_PIPE_INIT(0x40000000);
722 NV_WRITE_PIPE_INIT(0x40000000);
723 NV_WRITE_PIPE_INIT(0x00000000);
724 NV_WRITE_PIPE_INIT(0x00000000);
725 NV_WRITE_PIPE_INIT(0x3f800000);
726 NV_WRITE_PIPE_INIT(0x00000000);
727 NV_WRITE_PIPE_INIT(0x3f000000);
728 NV_WRITE_PIPE_INIT(0x3f000000);
729 NV_WRITE_PIPE_INIT(0x00000000);
730 NV_WRITE_PIPE_INIT(0x00000000);
731 NV_WRITE_PIPE_INIT(0x00000000);
732 NV_WRITE_PIPE_INIT(0x00000000);
733 NV_WRITE_PIPE_INIT(0x3f800000);
734 NV_WRITE_PIPE_INIT(0x00000000);
735 NV_WRITE_PIPE_INIT(0x00000000);
736 NV_WRITE_PIPE_INIT(0x00000000);
737 NV_WRITE_PIPE_INIT(0x00000000);
738 NV_WRITE_PIPE_INIT(0x00000000);
739 NV_WRITE_PIPE_INIT(0x3f800000);
740 NV_WRITE_PIPE_INIT(0x3f800000);
741 NV_WRITE_PIPE_INIT(0x3f800000);
742 NV_WRITE_PIPE_INIT(0x3f800000);
743 PIPE_INIT_END(0x6400);
744
745 PIPE_INIT(0x6800);
746 for (i = 0; i < 162; i++)
747 NV_WRITE_PIPE_INIT(0x00000000);
748 NV_WRITE_PIPE_INIT(0x3f800000);
749 for (i = 0; i < 25; i++)
750 NV_WRITE_PIPE_INIT(0x00000000);
751 PIPE_INIT_END(0x6800);
752
753 PIPE_INIT(0x6c00);
754 NV_WRITE_PIPE_INIT(0x00000000);
755 NV_WRITE_PIPE_INIT(0x00000000);
756 NV_WRITE_PIPE_INIT(0x00000000);
757 NV_WRITE_PIPE_INIT(0x00000000);
758 NV_WRITE_PIPE_INIT(0xbf800000);
759 NV_WRITE_PIPE_INIT(0x00000000);
760 NV_WRITE_PIPE_INIT(0x00000000);
761 NV_WRITE_PIPE_INIT(0x00000000);
762 NV_WRITE_PIPE_INIT(0x00000000);
763 NV_WRITE_PIPE_INIT(0x00000000);
764 NV_WRITE_PIPE_INIT(0x00000000);
765 NV_WRITE_PIPE_INIT(0x00000000);
766 PIPE_INIT_END(0x6c00);
767
768 PIPE_INIT(0x7000);
769 NV_WRITE_PIPE_INIT(0x00000000);
770 NV_WRITE_PIPE_INIT(0x00000000);
771 NV_WRITE_PIPE_INIT(0x00000000);
772 NV_WRITE_PIPE_INIT(0x00000000);
773 NV_WRITE_PIPE_INIT(0x00000000);
774 NV_WRITE_PIPE_INIT(0x00000000);
775 NV_WRITE_PIPE_INIT(0x00000000);
776 NV_WRITE_PIPE_INIT(0x00000000);
777 NV_WRITE_PIPE_INIT(0x00000000);
778 NV_WRITE_PIPE_INIT(0x00000000);
779 NV_WRITE_PIPE_INIT(0x00000000);
780 NV_WRITE_PIPE_INIT(0x00000000);
781 NV_WRITE_PIPE_INIT(0x7149f2ca);
782 NV_WRITE_PIPE_INIT(0x00000000);
783 NV_WRITE_PIPE_INIT(0x00000000);
784 NV_WRITE_PIPE_INIT(0x00000000);
785 NV_WRITE_PIPE_INIT(0x7149f2ca);
786 NV_WRITE_PIPE_INIT(0x00000000);
787 NV_WRITE_PIPE_INIT(0x00000000);
788 NV_WRITE_PIPE_INIT(0x00000000);
789 NV_WRITE_PIPE_INIT(0x7149f2ca);
790 NV_WRITE_PIPE_INIT(0x00000000);
791 NV_WRITE_PIPE_INIT(0x00000000);
792 NV_WRITE_PIPE_INIT(0x00000000);
793 NV_WRITE_PIPE_INIT(0x7149f2ca);
794 NV_WRITE_PIPE_INIT(0x00000000);
795 NV_WRITE_PIPE_INIT(0x00000000);
796 NV_WRITE_PIPE_INIT(0x00000000);
797 NV_WRITE_PIPE_INIT(0x7149f2ca);
798 NV_WRITE_PIPE_INIT(0x00000000);
799 NV_WRITE_PIPE_INIT(0x00000000);
800 NV_WRITE_PIPE_INIT(0x00000000);
801 NV_WRITE_PIPE_INIT(0x7149f2ca);
802 NV_WRITE_PIPE_INIT(0x00000000);
803 NV_WRITE_PIPE_INIT(0x00000000);
804 NV_WRITE_PIPE_INIT(0x00000000);
805 NV_WRITE_PIPE_INIT(0x7149f2ca);
806 NV_WRITE_PIPE_INIT(0x00000000);
807 NV_WRITE_PIPE_INIT(0x00000000);
808 NV_WRITE_PIPE_INIT(0x00000000);
809 NV_WRITE_PIPE_INIT(0x7149f2ca);
810 for (i = 0; i < 35; i++)
811 NV_WRITE_PIPE_INIT(0x00000000);
812 PIPE_INIT_END(0x7000);
813
814 PIPE_INIT(0x7400);
815 for (i = 0; i < 48; i++)
816 NV_WRITE_PIPE_INIT(0x00000000);
817 PIPE_INIT_END(0x7400);
818
819 PIPE_INIT(0x7800);
820 for (i = 0; i < 48; i++)
821 NV_WRITE_PIPE_INIT(0x00000000);
822 PIPE_INIT_END(0x7800);
823
824 PIPE_INIT(0x4400);
825 for (i = 0; i < 32; i++)
826 NV_WRITE_PIPE_INIT(0x00000000);
827 PIPE_INIT_END(0x4400);
828
829 PIPE_INIT(0x0000);
830 for (i = 0; i < 16; i++)
831 NV_WRITE_PIPE_INIT(0x00000000);
832 PIPE_INIT_END(0x0000);
833
834 PIPE_INIT(0x0040);
835 for (i = 0; i < 4; i++)
836 NV_WRITE_PIPE_INIT(0x00000000);
837 PIPE_INIT_END(0x0040);
838
839#undef PIPE_INIT
840#undef PIPE_INIT_END
841#undef NV_WRITE_PIPE_INIT
842}
843
ebb945a9 844static int
b8bf04e1 845nv10_gr_ctx_regs_find_offset(struct nv10_gr_priv *priv, int reg)
6ee73861
BS
846{
847 int i;
b8bf04e1
BS
848 for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++) {
849 if (nv10_gr_ctx_regs[i] == reg)
6ee73861
BS
850 return i;
851 }
ebb945a9 852 nv_error(priv, "unknow offset nv10_ctx_regs %d\n", reg);
6ee73861
BS
853 return -1;
854}
855
ebb945a9 856static int
b8bf04e1 857nv17_gr_ctx_regs_find_offset(struct nv10_gr_priv *priv, int reg)
6ee73861
BS
858{
859 int i;
b8bf04e1
BS
860 for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++) {
861 if (nv17_gr_ctx_regs[i] == reg)
6ee73861
BS
862 return i;
863 }
ebb945a9 864 nv_error(priv, "unknow offset nv17_ctx_regs %d\n", reg);
6ee73861
BS
865 return -1;
866}
867
ebb945a9 868static void
b8bf04e1 869nv10_gr_load_dma_vtxbuf(struct nv10_gr_chan *chan, int chid, u32 inst)
d2f4e892 870{
b8bf04e1 871 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9
BS
872 u32 st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
873 u32 ctx_user, ctx_switch[5];
d2f4e892
FJ
874 int i, subchan = -1;
875
876 /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
877 * that cannot be restored via MMIO. Do it through the FIFO
878 * instead.
879 */
880
881 /* Look for a celsius object */
882 for (i = 0; i < 8; i++) {
ebb945a9 883 int class = nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
d2f4e892
FJ
884
885 if (class == 0x56 || class == 0x96 || class == 0x99) {
886 subchan = i;
887 break;
888 }
889 }
890
891 if (subchan < 0 || !inst)
892 return;
893
894 /* Save the current ctx object */
ebb945a9 895 ctx_user = nv_rd32(priv, NV10_PGRAPH_CTX_USER);
d2f4e892 896 for (i = 0; i < 5; i++)
ebb945a9 897 ctx_switch[i] = nv_rd32(priv, NV10_PGRAPH_CTX_SWITCH(i));
d2f4e892
FJ
898
899 /* Save the FIFO state */
ebb945a9
BS
900 st2 = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2);
901 st2_dl = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DL);
902 st2_dh = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DH);
903 fifo_ptr = nv_rd32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR);
d2f4e892
FJ
904
905 for (i = 0; i < ARRAY_SIZE(fifo); i++)
ebb945a9 906 fifo[i] = nv_rd32(priv, 0x4007a0 + 4 * i);
d2f4e892
FJ
907
908 /* Switch to the celsius subchannel */
909 for (i = 0; i < 5; i++)
ebb945a9
BS
910 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i),
911 nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(subchan, i)));
912 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
d2f4e892
FJ
913
914 /* Inject NV10TCL_DMA_VTXBUF */
ebb945a9
BS
915 nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
916 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2,
917 0x2c000000 | chid << 20 | subchan << 16 | 0x18c);
918 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
919 nv_mask(priv, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
920 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
921 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
d2f4e892
FJ
922
923 /* Restore the FIFO state */
924 for (i = 0; i < ARRAY_SIZE(fifo); i++)
ebb945a9 925 nv_wr32(priv, 0x4007a0 + 4 * i, fifo[i]);
d2f4e892 926
ebb945a9
BS
927 nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
928 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, st2);
929 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
930 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
d2f4e892
FJ
931
932 /* Restore the current ctx object */
933 for (i = 0; i < 5; i++)
ebb945a9
BS
934 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
935 nv_wr32(priv, NV10_PGRAPH_CTX_USER, ctx_user);
d2f4e892
FJ
936}
937
d11db279 938static int
b8bf04e1 939nv10_gr_load_context(struct nv10_gr_chan *chan, int chid)
6ee73861 940{
b8bf04e1 941 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
ebb945a9 942 u32 inst;
6ee73861
BS
943 int i;
944
b8bf04e1
BS
945 for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
946 nv_wr32(priv, nv10_gr_ctx_regs[i], chan->nv10[i]);
ebb945a9 947
8aa816b0
IM
948 if (nv_device(priv)->card_type >= NV_11 &&
949 nv_device(priv)->chipset >= 0x17) {
b8bf04e1
BS
950 for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
951 nv_wr32(priv, nv17_gr_ctx_regs[i], chan->nv17[i]);
6ee73861
BS
952 }
953
b8bf04e1 954 nv10_gr_load_pipe(chan);
ebb945a9
BS
955
956 inst = nv_rd32(priv, NV10_PGRAPH_GLOBALSTATE1) & 0xffff;
b8bf04e1 957 nv10_gr_load_dma_vtxbuf(chan, chid, inst);
ebb945a9
BS
958
959 nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
960 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, chid << 24);
961 nv_mask(priv, NV10_PGRAPH_FFINTFC_ST2, 0x30000000, 0x00000000);
6ee73861
BS
962 return 0;
963}
964
d11db279 965static int
b8bf04e1 966nv10_gr_unload_context(struct nv10_gr_chan *chan)
6ee73861 967{
b8bf04e1 968 struct nv10_gr_priv *priv = nv10_gr_priv(chan);
6ee73861
BS
969 int i;
970
b8bf04e1
BS
971 for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
972 chan->nv10[i] = nv_rd32(priv, nv10_gr_ctx_regs[i]);
6ee73861 973
8aa816b0
IM
974 if (nv_device(priv)->card_type >= NV_11 &&
975 nv_device(priv)->chipset >= 0x17) {
b8bf04e1
BS
976 for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
977 chan->nv17[i] = nv_rd32(priv, nv17_gr_ctx_regs[i]);
6ee73861
BS
978 }
979
b8bf04e1 980 nv10_gr_save_pipe(chan);
6ee73861 981
ebb945a9
BS
982 nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
983 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
6ee73861
BS
984 return 0;
985}
986
274fec93 987static void
b8bf04e1 988nv10_gr_context_switch(struct nv10_gr_priv *priv)
6ee73861 989{
b8bf04e1
BS
990 struct nv10_gr_chan *prev = NULL;
991 struct nv10_gr_chan *next = NULL;
ebb945a9 992 unsigned long flags;
6ee73861
BS
993 int chid;
994
ebb945a9 995 spin_lock_irqsave(&priv->lock, flags);
b8bf04e1 996 nv04_gr_idle(priv);
6ee73861
BS
997
998 /* If previous context is valid, we need to save it */
b8bf04e1 999 prev = nv10_gr_channel(priv);
ebb945a9 1000 if (prev)
b8bf04e1 1001 nv10_gr_unload_context(prev);
ebb945a9
BS
1002
1003 /* load context for next channel */
1004 chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
1005 next = priv->chan[chid];
1006 if (next)
b8bf04e1 1007 nv10_gr_load_context(next, chid);
6ee73861 1008
ebb945a9 1009 spin_unlock_irqrestore(&priv->lock, flags);
6ee73861
BS
1010}
1011
1012#define NV_WRITE_CTX(reg, val) do { \
b8bf04e1 1013 int offset = nv10_gr_ctx_regs_find_offset(priv, reg); \
6ee73861 1014 if (offset > 0) \
ebb945a9 1015 chan->nv10[offset] = val; \
6ee73861
BS
1016 } while (0)
1017
1018#define NV17_WRITE_CTX(reg, val) do { \
b8bf04e1 1019 int offset = nv17_gr_ctx_regs_find_offset(priv, reg); \
6ee73861 1020 if (offset > 0) \
ebb945a9 1021 chan->nv17[offset] = val; \
6ee73861
BS
1022 } while (0)
1023
d11db279 1024static int
b8bf04e1 1025nv10_gr_context_ctor(struct nouveau_object *parent,
ebb945a9
BS
1026 struct nouveau_object *engine,
1027 struct nouveau_oclass *oclass, void *data, u32 size,
1028 struct nouveau_object **pobject)
6ee73861 1029{
ebb945a9 1030 struct nouveau_fifo_chan *fifo = (void *)parent;
b8bf04e1
BS
1031 struct nv10_gr_priv *priv = (void *)engine;
1032 struct nv10_gr_chan *chan;
ebb945a9
BS
1033 unsigned long flags;
1034 int ret;
1035
1036 ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
1037 *pobject = nv_object(chan);
1038 if (ret)
1039 return ret;
1040
1041 spin_lock_irqsave(&priv->lock, flags);
1042 if (priv->chan[fifo->chid]) {
1043 *pobject = nv_object(priv->chan[fifo->chid]);
1044 atomic_inc(&(*pobject)->refcount);
1045 spin_unlock_irqrestore(&priv->lock, flags);
1046 nouveau_object_destroy(&chan->base);
1047 return 1;
1048 }
6ee73861
BS
1049
1050 NV_WRITE_CTX(0x00400e88, 0x08000000);
1051 NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
1052 NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
1053 NV_WRITE_CTX(0x00400e10, 0x00001000);
1054 NV_WRITE_CTX(0x00400e14, 0x00001000);
1055 NV_WRITE_CTX(0x00400e30, 0x00080008);
1056 NV_WRITE_CTX(0x00400e34, 0x00080008);
8aa816b0
IM
1057 if (nv_device(priv)->card_type >= NV_11 &&
1058 nv_device(priv)->chipset >= 0x17) {
6ee73861
BS
1059 /* is it really needed ??? */
1060 NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
ebb945a9
BS
1061 nv_rd32(priv, NV10_PGRAPH_DEBUG_4));
1062 NV17_WRITE_CTX(0x004006b0, nv_rd32(priv, 0x004006b0));
6ee73861
BS
1063 NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
1064 NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
1065 NV17_WRITE_CTX(0x00400ec0, 0x00000080);
1066 NV17_WRITE_CTX(0x00400ed0, 0x00000080);
1067 }
ebb945a9 1068 NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->chid << 24);
6ee73861 1069
b8bf04e1 1070 nv10_gr_create_pipe(chan);
ebb945a9
BS
1071
1072 priv->chan[fifo->chid] = chan;
1073 chan->chid = fifo->chid;
1074 spin_unlock_irqrestore(&priv->lock, flags);
6ee73861
BS
1075 return 0;
1076}
1077
d11db279 1078static void
b8bf04e1 1079nv10_gr_context_dtor(struct nouveau_object *object)
6ee73861 1080{
b8bf04e1
BS
1081 struct nv10_gr_priv *priv = (void *)object->engine;
1082 struct nv10_gr_chan *chan = (void *)object;
3945e475
FJ
1083 unsigned long flags;
1084
ebb945a9
BS
1085 spin_lock_irqsave(&priv->lock, flags);
1086 priv->chan[chan->chid] = NULL;
1087 spin_unlock_irqrestore(&priv->lock, flags);
d11db279 1088
ebb945a9 1089 nouveau_object_destroy(&chan->base);
0d87c100
FJ
1090}
1091
d11db279 1092static int
b8bf04e1 1093nv10_gr_context_fini(struct nouveau_object *object, bool suspend)
6ee73861 1094{
b8bf04e1
BS
1095 struct nv10_gr_priv *priv = (void *)object->engine;
1096 struct nv10_gr_chan *chan = (void *)object;
ebb945a9 1097 unsigned long flags;
6ee73861 1098
ebb945a9
BS
1099 spin_lock_irqsave(&priv->lock, flags);
1100 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
b8bf04e1
BS
1101 if (nv10_gr_channel(priv) == chan)
1102 nv10_gr_unload_context(chan);
ebb945a9
BS
1103 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
1104 spin_unlock_irqrestore(&priv->lock, flags);
6ee73861 1105
ebb945a9 1106 return nouveau_object_fini(&chan->base, suspend);
6ee73861
BS
1107}
1108
ebb945a9 1109static struct nouveau_oclass
b8bf04e1 1110nv10_gr_cclass = {
ebb945a9
BS
1111 .handle = NV_ENGCTX(GR, 0x10),
1112 .ofuncs = &(struct nouveau_ofuncs) {
b8bf04e1
BS
1113 .ctor = nv10_gr_context_ctor,
1114 .dtor = nv10_gr_context_dtor,
ebb945a9 1115 .init = nouveau_object_init,
b8bf04e1 1116 .fini = nv10_gr_context_fini,
ebb945a9
BS
1117 },
1118};
15bee69e 1119
ebb945a9
BS
1120/*******************************************************************************
1121 * PGRAPH engine/subdev functions
1122 ******************************************************************************/
15bee69e 1123
ebb945a9 1124static void
b8bf04e1 1125nv10_gr_tile_prog(struct nouveau_engine *engine, int i)
15bee69e 1126{
ebb945a9
BS
1127 struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
1128 struct nouveau_fifo *pfifo = nouveau_fifo(engine);
b8bf04e1 1129 struct nv10_gr_priv *priv = (void *)engine;
ebb945a9 1130 unsigned long flags;
15bee69e 1131
ebb945a9 1132 pfifo->pause(pfifo, &flags);
b8bf04e1 1133 nv04_gr_idle(priv);
15bee69e 1134
ebb945a9
BS
1135 nv_wr32(priv, NV10_PGRAPH_TLIMIT(i), tile->limit);
1136 nv_wr32(priv, NV10_PGRAPH_TSIZE(i), tile->pitch);
1137 nv_wr32(priv, NV10_PGRAPH_TILE(i), tile->addr);
15bee69e 1138
ebb945a9 1139 pfifo->start(pfifo, &flags);
15bee69e
FJ
1140}
1141
b8bf04e1 1142const struct nouveau_bitfield nv10_gr_intr_name[] = {
274fec93
BS
1143 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
1144 { NV_PGRAPH_INTR_ERROR, "ERROR" },
1145 {}
1146};
1147
b8bf04e1 1148const struct nouveau_bitfield nv10_gr_nstatus[] = {
274fec93
BS
1149 { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
1150 { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
1151 { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
1152 { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
1153 {}
1154};
1155
1156static void
b8bf04e1 1157nv10_gr_intr(struct nouveau_subdev *subdev)
274fec93 1158{
b8bf04e1
BS
1159 struct nv10_gr_priv *priv = (void *)subdev;
1160 struct nv10_gr_chan *chan = NULL;
ebb945a9
BS
1161 struct nouveau_namedb *namedb = NULL;
1162 struct nouveau_handle *handle = NULL;
1163 u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
1164 u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
1165 u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
1166 u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR);
1167 u32 chid = (addr & 0x01f00000) >> 20;
1168 u32 subc = (addr & 0x00070000) >> 16;
1169 u32 mthd = (addr & 0x00001ffc);
1170 u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA);
1171 u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff;
1172 u32 show = stat;
1173 unsigned long flags;
274fec93 1174
ebb945a9
BS
1175 spin_lock_irqsave(&priv->lock, flags);
1176 chan = priv->chan[chid];
1177 if (chan)
1178 namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS);
1179 spin_unlock_irqrestore(&priv->lock, flags);
1180
1181 if (stat & NV_PGRAPH_INTR_ERROR) {
1182 if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
1183 handle = nouveau_namedb_get_class(namedb, class);
1184 if (handle && !nv_call(handle->object, mthd, data))
1185 show &= ~NV_PGRAPH_INTR_ERROR;
274fec93 1186 }
ebb945a9 1187 }
274fec93 1188
ebb945a9
BS
1189 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1190 nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1191 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1192 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
b8bf04e1 1193 nv10_gr_context_switch(priv);
ebb945a9
BS
1194 }
1195
1196 nv_wr32(priv, NV03_PGRAPH_INTR, stat);
1197 nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001);
1198
1199 if (show) {
950fbfab 1200 nv_error(priv, "%s", "");
b8bf04e1 1201 nouveau_bitfield_print(nv10_gr_intr_name, show);
f533da10 1202 pr_cont(" nsource:");
b8bf04e1 1203 nouveau_bitfield_print(nv04_gr_nsource, nsource);
f533da10 1204 pr_cont(" nstatus:");
b8bf04e1 1205 nouveau_bitfield_print(nv10_gr_nstatus, nstatus);
f533da10 1206 pr_cont("\n");
93260d3c
MS
1207 nv_error(priv,
1208 "ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
1209 chid, nouveau_client_name(chan), subc, class, mthd,
1210 data);
274fec93 1211 }
ebb945a9
BS
1212
1213 nouveau_namedb_put(handle);
274fec93 1214}
d11db279 1215
ebb945a9 1216static int
b8bf04e1 1217nv10_gr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
ebb945a9
BS
1218 struct nouveau_oclass *oclass, void *data, u32 size,
1219 struct nouveau_object **pobject)
d11db279 1220{
b8bf04e1 1221 struct nv10_gr_priv *priv;
ebb945a9
BS
1222 int ret;
1223
b8bf04e1 1224 ret = nouveau_gr_create(parent, engine, oclass, true, &priv);
ebb945a9
BS
1225 *pobject = nv_object(priv);
1226 if (ret)
1227 return ret;
1228
1229 nv_subdev(priv)->unit = 0x00001000;
b8bf04e1
BS
1230 nv_subdev(priv)->intr = nv10_gr_intr;
1231 nv_engine(priv)->cclass = &nv10_gr_cclass;
ebb945a9
BS
1232
1233 if (nv_device(priv)->chipset <= 0x10)
b8bf04e1 1234 nv_engine(priv)->sclass = nv10_gr_sclass;
ebb945a9
BS
1235 else
1236 if (nv_device(priv)->chipset < 0x17 ||
8aa816b0 1237 nv_device(priv)->card_type < NV_11)
b8bf04e1 1238 nv_engine(priv)->sclass = nv15_gr_sclass;
ebb945a9 1239 else
b8bf04e1 1240 nv_engine(priv)->sclass = nv17_gr_sclass;
ebb945a9 1241
b8bf04e1 1242 nv_engine(priv)->tile_prog = nv10_gr_tile_prog;
ebb945a9
BS
1243 spin_lock_init(&priv->lock);
1244 return 0;
1245}
d11db279 1246
ebb945a9 1247static void
b8bf04e1 1248nv10_gr_dtor(struct nouveau_object *object)
ebb945a9 1249{
b8bf04e1
BS
1250 struct nv10_gr_priv *priv = (void *)object;
1251 nouveau_gr_destroy(&priv->base);
d11db279
BS
1252}
1253
ebb945a9 1254static int
b8bf04e1 1255nv10_gr_init(struct nouveau_object *object)
d11db279 1256{
ebb945a9
BS
1257 struct nouveau_engine *engine = nv_engine(object);
1258 struct nouveau_fb *pfb = nouveau_fb(object);
b8bf04e1 1259 struct nv10_gr_priv *priv = (void *)engine;
ebb945a9
BS
1260 int ret, i;
1261
b8bf04e1 1262 ret = nouveau_gr_init(&priv->base);
ebb945a9
BS
1263 if (ret)
1264 return ret;
1265
1266 nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF);
1267 nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
1268
1269 nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
1270 nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000);
1271 nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x00118700);
1272 /* nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
1273 nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
1274 nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31));
1275
8aa816b0
IM
1276 if (nv_device(priv)->card_type >= NV_11 &&
1277 nv_device(priv)->chipset >= 0x17) {
ebb945a9
BS
1278 nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x1f000000);
1279 nv_wr32(priv, 0x400a10, 0x03ff3fb6);
1280 nv_wr32(priv, 0x400838, 0x002f8684);
1281 nv_wr32(priv, 0x40083c, 0x00115f3f);
1282 nv_wr32(priv, 0x4006b0, 0x40000020);
d11db279 1283 } else {
ebb945a9 1284 nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00000000);
d11db279
BS
1285 }
1286
ebb945a9
BS
1287 /* Turn all the tiling regions off. */
1288 for (i = 0; i < pfb->tile.regions; i++)
1289 engine->tile_prog(engine, i);
1290
1291 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
1292 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
1293 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
1294 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
1295 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
1296 nv_wr32(priv, NV10_PGRAPH_STATE, 0xFFFFFFFF);
1297
1298 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
1299 nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
1300 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
d11db279
BS
1301 return 0;
1302}
ebb945a9
BS
1303
1304static int
b8bf04e1 1305nv10_gr_fini(struct nouveau_object *object, bool suspend)
ebb945a9 1306{
b8bf04e1
BS
1307 struct nv10_gr_priv *priv = (void *)object;
1308 return nouveau_gr_fini(&priv->base, suspend);
ebb945a9
BS
1309}
1310
1311struct nouveau_oclass
b8bf04e1 1312nv10_gr_oclass = {
ebb945a9
BS
1313 .handle = NV_ENGINE(GR, 0x10),
1314 .ofuncs = &(struct nouveau_ofuncs) {
b8bf04e1
BS
1315 .ctor = nv10_gr_ctor,
1316 .dtor = nv10_gr_dtor,
1317 .init = nv10_gr_init,
1318 .fini = nv10_gr_fini,
ebb945a9
BS
1319 },
1320};
This page took 0.490561 seconds and 5 git commands to generate.