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