• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/gpu/drm/nouveau/
1/*
2 * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "drmP.h"
26#include "drm.h"
27#include "nouveau_drm.h"
28#include "nouveau_drv.h"
29
30#define NV10_FIFO_NUMBER 32
31
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[] = {
46	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),
91	NV10_PGRAPH_CTX_USER,
92	NV04_PGRAPH_DMA_START_0,
93	NV04_PGRAPH_DMA_START_1,
94	NV04_PGRAPH_DMA_LENGTH,
95	NV04_PGRAPH_DMA_MISC,
96	NV10_PGRAPH_DMA_PITCH,
97	NV04_PGRAPH_BOFFSET0,
98	NV04_PGRAPH_BBASE0,
99	NV04_PGRAPH_BLIMIT0,
100	NV04_PGRAPH_BOFFSET1,
101	NV04_PGRAPH_BBASE1,
102	NV04_PGRAPH_BLIMIT1,
103	NV04_PGRAPH_BOFFSET2,
104	NV04_PGRAPH_BBASE2,
105	NV04_PGRAPH_BLIMIT2,
106	NV04_PGRAPH_BOFFSET3,
107	NV04_PGRAPH_BBASE3,
108	NV04_PGRAPH_BLIMIT3,
109	NV04_PGRAPH_BOFFSET4,
110	NV04_PGRAPH_BBASE4,
111	NV04_PGRAPH_BLIMIT4,
112	NV04_PGRAPH_BOFFSET5,
113	NV04_PGRAPH_BBASE5,
114	NV04_PGRAPH_BLIMIT5,
115	NV04_PGRAPH_BPITCH0,
116	NV04_PGRAPH_BPITCH1,
117	NV04_PGRAPH_BPITCH2,
118	NV04_PGRAPH_BPITCH3,
119	NV04_PGRAPH_BPITCH4,
120	NV10_PGRAPH_SURFACE,
121	NV10_PGRAPH_STATE,
122	NV04_PGRAPH_BSWIZZLE2,
123	NV04_PGRAPH_BSWIZZLE5,
124	NV04_PGRAPH_BPIXEL,
125	NV10_PGRAPH_NOTIFY,
126	NV04_PGRAPH_PATT_COLOR0,
127	NV04_PGRAPH_PATT_COLOR1,
128	NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
129	0x00400904,
130	0x00400908,
131	0x0040090c,
132	0x00400910,
133	0x00400914,
134	0x00400918,
135	0x0040091c,
136	0x00400920,
137	0x00400924,
138	0x00400928,
139	0x0040092c,
140	0x00400930,
141	0x00400934,
142	0x00400938,
143	0x0040093c,
144	0x00400940,
145	0x00400944,
146	0x00400948,
147	0x0040094c,
148	0x00400950,
149	0x00400954,
150	0x00400958,
151	0x0040095c,
152	0x00400960,
153	0x00400964,
154	0x00400968,
155	0x0040096c,
156	0x00400970,
157	0x00400974,
158	0x00400978,
159	0x0040097c,
160	0x00400980,
161	0x00400984,
162	0x00400988,
163	0x0040098c,
164	0x00400990,
165	0x00400994,
166	0x00400998,
167	0x0040099c,
168	0x004009a0,
169	0x004009a4,
170	0x004009a8,
171	0x004009ac,
172	0x004009b0,
173	0x004009b4,
174	0x004009b8,
175	0x004009bc,
176	0x004009c0,
177	0x004009c4,
178	0x004009c8,
179	0x004009cc,
180	0x004009d0,
181	0x004009d4,
182	0x004009d8,
183	0x004009dc,
184	0x004009e0,
185	0x004009e4,
186	0x004009e8,
187	0x004009ec,
188	0x004009f0,
189	0x004009f4,
190	0x004009f8,
191	0x004009fc,
192	NV04_PGRAPH_PATTERN,	/* 2 values from 0x400808 to 0x40080c */
193	0x0040080c,
194	NV04_PGRAPH_PATTERN_SHAPE,
195	NV03_PGRAPH_MONO_COLOR0,
196	NV04_PGRAPH_ROP3,
197	NV04_PGRAPH_CHROMA,
198	NV04_PGRAPH_BETA_AND,
199	NV04_PGRAPH_BETA_PREMULT,
200	0x00400e70,
201	0x00400e74,
202	0x00400e78,
203	0x00400e7c,
204	0x00400e80,
205	0x00400e84,
206	0x00400e88,
207	0x00400e8c,
208	0x00400ea0,
209	0x00400ea4,
210	0x00400ea8,
211	0x00400e90,
212	0x00400e94,
213	0x00400e98,
214	0x00400e9c,
215	NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
216	NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20-0x400f3c */
217	0x00400f04,
218	0x00400f24,
219	0x00400f08,
220	0x00400f28,
221	0x00400f0c,
222	0x00400f2c,
223	0x00400f10,
224	0x00400f30,
225	0x00400f14,
226	0x00400f34,
227	0x00400f18,
228	0x00400f38,
229	0x00400f1c,
230	0x00400f3c,
231	NV10_PGRAPH_XFMODE0,
232	NV10_PGRAPH_XFMODE1,
233	NV10_PGRAPH_GLOBALSTATE0,
234	NV10_PGRAPH_GLOBALSTATE1,
235	NV04_PGRAPH_STORED_FMT,
236	NV04_PGRAPH_SOURCE_COLOR,
237	NV03_PGRAPH_ABS_X_RAM,	/* 32 values from 0x400400 to 0x40047c */
238	NV03_PGRAPH_ABS_Y_RAM,	/* 32 values from 0x400480 to 0x4004fc */
239	0x00400404,
240	0x00400484,
241	0x00400408,
242	0x00400488,
243	0x0040040c,
244	0x0040048c,
245	0x00400410,
246	0x00400490,
247	0x00400414,
248	0x00400494,
249	0x00400418,
250	0x00400498,
251	0x0040041c,
252	0x0040049c,
253	0x00400420,
254	0x004004a0,
255	0x00400424,
256	0x004004a4,
257	0x00400428,
258	0x004004a8,
259	0x0040042c,
260	0x004004ac,
261	0x00400430,
262	0x004004b0,
263	0x00400434,
264	0x004004b4,
265	0x00400438,
266	0x004004b8,
267	0x0040043c,
268	0x004004bc,
269	0x00400440,
270	0x004004c0,
271	0x00400444,
272	0x004004c4,
273	0x00400448,
274	0x004004c8,
275	0x0040044c,
276	0x004004cc,
277	0x00400450,
278	0x004004d0,
279	0x00400454,
280	0x004004d4,
281	0x00400458,
282	0x004004d8,
283	0x0040045c,
284	0x004004dc,
285	0x00400460,
286	0x004004e0,
287	0x00400464,
288	0x004004e4,
289	0x00400468,
290	0x004004e8,
291	0x0040046c,
292	0x004004ec,
293	0x00400470,
294	0x004004f0,
295	0x00400474,
296	0x004004f4,
297	0x00400478,
298	0x004004f8,
299	0x0040047c,
300	0x004004fc,
301	NV03_PGRAPH_ABS_UCLIP_XMIN,
302	NV03_PGRAPH_ABS_UCLIP_XMAX,
303	NV03_PGRAPH_ABS_UCLIP_YMIN,
304	NV03_PGRAPH_ABS_UCLIP_YMAX,
305	0x00400550,
306	0x00400558,
307	0x00400554,
308	0x0040055c,
309	NV03_PGRAPH_ABS_UCLIPA_XMIN,
310	NV03_PGRAPH_ABS_UCLIPA_XMAX,
311	NV03_PGRAPH_ABS_UCLIPA_YMIN,
312	NV03_PGRAPH_ABS_UCLIPA_YMAX,
313	NV03_PGRAPH_ABS_ICLIP_XMAX,
314	NV03_PGRAPH_ABS_ICLIP_YMAX,
315	NV03_PGRAPH_XY_LOGIC_MISC0,
316	NV03_PGRAPH_XY_LOGIC_MISC1,
317	NV03_PGRAPH_XY_LOGIC_MISC2,
318	NV03_PGRAPH_XY_LOGIC_MISC3,
319	NV03_PGRAPH_CLIPX_0,
320	NV03_PGRAPH_CLIPX_1,
321	NV03_PGRAPH_CLIPY_0,
322	NV03_PGRAPH_CLIPY_1,
323	NV10_PGRAPH_COMBINER0_IN_ALPHA,
324	NV10_PGRAPH_COMBINER1_IN_ALPHA,
325	NV10_PGRAPH_COMBINER0_IN_RGB,
326	NV10_PGRAPH_COMBINER1_IN_RGB,
327	NV10_PGRAPH_COMBINER_COLOR0,
328	NV10_PGRAPH_COMBINER_COLOR1,
329	NV10_PGRAPH_COMBINER0_OUT_ALPHA,
330	NV10_PGRAPH_COMBINER1_OUT_ALPHA,
331	NV10_PGRAPH_COMBINER0_OUT_RGB,
332	NV10_PGRAPH_COMBINER1_OUT_RGB,
333	NV10_PGRAPH_COMBINER_FINAL0,
334	NV10_PGRAPH_COMBINER_FINAL1,
335	0x00400e00,
336	0x00400e04,
337	0x00400e08,
338	0x00400e0c,
339	0x00400e10,
340	0x00400e14,
341	0x00400e18,
342	0x00400e1c,
343	0x00400e20,
344	0x00400e24,
345	0x00400e28,
346	0x00400e2c,
347	0x00400e30,
348	0x00400e34,
349	0x00400e38,
350	0x00400e3c,
351	NV04_PGRAPH_PASSTHRU_0,
352	NV04_PGRAPH_PASSTHRU_1,
353	NV04_PGRAPH_PASSTHRU_2,
354	NV10_PGRAPH_DIMX_TEXTURE,
355	NV10_PGRAPH_WDIMX_TEXTURE,
356	NV10_PGRAPH_DVD_COLORFMT,
357	NV10_PGRAPH_SCALED_FORMAT,
358	NV04_PGRAPH_MISC24_0,
359	NV04_PGRAPH_MISC24_1,
360	NV04_PGRAPH_MISC24_2,
361	NV03_PGRAPH_X_MISC,
362	NV03_PGRAPH_Y_MISC,
363	NV04_PGRAPH_VALID1,
364	NV04_PGRAPH_VALID2,
365};
366
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;
392	uint32_t lma_window[4];
393};
394
395#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
411static 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;
415	struct pipe_state *pipe = &pgraph_ctx->pipe_state;
416
417	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);
427}
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;
433	struct pipe_state *pipe = &pgraph_ctx->pipe_state;
434	uint32_t xfmode0, xfmode1;
435	int i;
436
437	nouveau_wait_for_idle(dev);
438	xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
439	xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
440	nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
441	nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
442	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
443	for (i = 0; i < 4; i++)
444		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
445	for (i = 0; i < 4; i++)
446		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
447
448	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
449	for (i = 0; i < 3; i++)
450		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
451
452	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
453	for (i = 0; i < 3; i++)
454		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
455
456	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
457	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
458
459
460	PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
461	nouveau_wait_for_idle(dev);
462
463	/* restore XFMODE */
464	nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
465	nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
466	PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400);
467	PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800);
468	PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00);
469	PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000);
470	PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400);
471	PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800);
472	PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
473	PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000);
474	PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040);
475	nouveau_wait_for_idle(dev);
476}
477
478static void nv10_graph_create_pipe(struct nouveau_channel *chan)
479{
480	struct drm_device *dev = chan->dev;
481	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
482	struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
483	uint32_t *fifo_pipe_state_addr;
484	int i;
485#define PIPE_INIT(addr) \
486	do { \
487		fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
488	} while (0)
489#define PIPE_INIT_END(addr) \
490	do { \
491		uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
492				ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
493		if (fifo_pipe_state_addr != __end_addr) \
494			NV_ERROR(dev, "incomplete pipe init for 0x%x :  %p/%p\n", \
495				addr, fifo_pipe_state_addr, __end_addr); \
496	} while (0)
497#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
498
499	PIPE_INIT(0x0200);
500	for (i = 0; i < 48; i++)
501		NV_WRITE_PIPE_INIT(0x00000000);
502	PIPE_INIT_END(0x0200);
503
504	PIPE_INIT(0x6400);
505	for (i = 0; i < 211; i++)
506		NV_WRITE_PIPE_INIT(0x00000000);
507	NV_WRITE_PIPE_INIT(0x3f800000);
508	NV_WRITE_PIPE_INIT(0x40000000);
509	NV_WRITE_PIPE_INIT(0x40000000);
510	NV_WRITE_PIPE_INIT(0x40000000);
511	NV_WRITE_PIPE_INIT(0x40000000);
512	NV_WRITE_PIPE_INIT(0x00000000);
513	NV_WRITE_PIPE_INIT(0x00000000);
514	NV_WRITE_PIPE_INIT(0x3f800000);
515	NV_WRITE_PIPE_INIT(0x00000000);
516	NV_WRITE_PIPE_INIT(0x3f000000);
517	NV_WRITE_PIPE_INIT(0x3f000000);
518	NV_WRITE_PIPE_INIT(0x00000000);
519	NV_WRITE_PIPE_INIT(0x00000000);
520	NV_WRITE_PIPE_INIT(0x00000000);
521	NV_WRITE_PIPE_INIT(0x00000000);
522	NV_WRITE_PIPE_INIT(0x3f800000);
523	NV_WRITE_PIPE_INIT(0x00000000);
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(0x3f800000);
529	NV_WRITE_PIPE_INIT(0x3f800000);
530	NV_WRITE_PIPE_INIT(0x3f800000);
531	NV_WRITE_PIPE_INIT(0x3f800000);
532	PIPE_INIT_END(0x6400);
533
534	PIPE_INIT(0x6800);
535	for (i = 0; i < 162; i++)
536		NV_WRITE_PIPE_INIT(0x00000000);
537	NV_WRITE_PIPE_INIT(0x3f800000);
538	for (i = 0; i < 25; i++)
539		NV_WRITE_PIPE_INIT(0x00000000);
540	PIPE_INIT_END(0x6800);
541
542	PIPE_INIT(0x6c00);
543	NV_WRITE_PIPE_INIT(0x00000000);
544	NV_WRITE_PIPE_INIT(0x00000000);
545	NV_WRITE_PIPE_INIT(0x00000000);
546	NV_WRITE_PIPE_INIT(0x00000000);
547	NV_WRITE_PIPE_INIT(0xbf800000);
548	NV_WRITE_PIPE_INIT(0x00000000);
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	PIPE_INIT_END(0x6c00);
556
557	PIPE_INIT(0x7000);
558	NV_WRITE_PIPE_INIT(0x00000000);
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(0x7149f2ca);
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	for (i = 0; i < 35; i++)
600		NV_WRITE_PIPE_INIT(0x00000000);
601	PIPE_INIT_END(0x7000);
602
603	PIPE_INIT(0x7400);
604	for (i = 0; i < 48; i++)
605		NV_WRITE_PIPE_INIT(0x00000000);
606	PIPE_INIT_END(0x7400);
607
608	PIPE_INIT(0x7800);
609	for (i = 0; i < 48; i++)
610		NV_WRITE_PIPE_INIT(0x00000000);
611	PIPE_INIT_END(0x7800);
612
613	PIPE_INIT(0x4400);
614	for (i = 0; i < 32; i++)
615		NV_WRITE_PIPE_INIT(0x00000000);
616	PIPE_INIT_END(0x4400);
617
618	PIPE_INIT(0x0000);
619	for (i = 0; i < 16; i++)
620		NV_WRITE_PIPE_INIT(0x00000000);
621	PIPE_INIT_END(0x0000);
622
623	PIPE_INIT(0x0040);
624	for (i = 0; i < 4; i++)
625		NV_WRITE_PIPE_INIT(0x00000000);
626	PIPE_INIT_END(0x0040);
627
628#undef PIPE_INIT
629#undef PIPE_INIT_END
630#undef NV_WRITE_PIPE_INIT
631}
632
633static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
634{
635	int i;
636	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
637		if (nv10_graph_ctx_regs[i] == reg)
638			return i;
639	}
640	NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
641	return -1;
642}
643
644static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
645{
646	int i;
647	for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
648		if (nv17_graph_ctx_regs[i] == reg)
649			return i;
650	}
651	NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
652	return -1;
653}
654
655static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
656				       uint32_t inst)
657{
658	struct drm_device *dev = chan->dev;
659	struct drm_nouveau_private *dev_priv = dev->dev_private;
660	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
661	uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
662	uint32_t ctx_user, ctx_switch[5];
663	int i, subchan = -1;
664
665	/* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
666	 * that cannot be restored via MMIO. Do it through the FIFO
667	 * instead.
668	 */
669
670	/* Look for a celsius object */
671	for (i = 0; i < 8; i++) {
672		int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
673
674		if (class == 0x56 || class == 0x96 || class == 0x99) {
675			subchan = i;
676			break;
677		}
678	}
679
680	if (subchan < 0 || !inst)
681		return;
682
683	/* Save the current ctx object */
684	ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
685	for (i = 0; i < 5; i++)
686		ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i));
687
688	/* Save the FIFO state */
689	st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
690	st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL);
691	st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH);
692	fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR);
693
694	for (i = 0; i < ARRAY_SIZE(fifo); i++)
695		fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i);
696
697	/* Switch to the celsius subchannel */
698	for (i = 0; i < 5; i++)
699		nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i),
700			nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i)));
701	nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
702
703	/* Inject NV10TCL_DMA_VTXBUF */
704	nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
705	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2,
706		0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
707	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
708	nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
709	pgraph->fifo_access(dev, true);
710	pgraph->fifo_access(dev, false);
711
712	/* Restore the FIFO state */
713	for (i = 0; i < ARRAY_SIZE(fifo); i++)
714		nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]);
715
716	nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
717	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2);
718	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
719	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
720
721	/* Restore the current ctx object */
722	for (i = 0; i < 5; i++)
723		nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
724	nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
725}
726
727int nv10_graph_load_context(struct nouveau_channel *chan)
728{
729	struct drm_device *dev = chan->dev;
730	struct drm_nouveau_private *dev_priv = dev->dev_private;
731	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
732	uint32_t tmp;
733	int i;
734
735	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
736		nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
737	if (dev_priv->chipset >= 0x17) {
738		for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
739			nv_wr32(dev, nv17_graph_ctx_regs[i],
740						pgraph_ctx->nv17[i]);
741	}
742
743	nv10_graph_load_pipe(chan);
744	nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
745					  & 0xffff));
746
747	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
748	tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
749	nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
750	tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
751	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
752	return 0;
753}
754
755int
756nv10_graph_unload_context(struct drm_device *dev)
757{
758	struct drm_nouveau_private *dev_priv = dev->dev_private;
759	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
760	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
761	struct nouveau_channel *chan;
762	struct graph_state *ctx;
763	uint32_t tmp;
764	int i;
765
766	chan = pgraph->channel(dev);
767	if (!chan)
768		return 0;
769	ctx = chan->pgraph_ctx;
770
771	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
772		ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
773
774	if (dev_priv->chipset >= 0x17) {
775		for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
776			ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
777	}
778
779	nv10_graph_save_pipe(chan);
780
781	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
782	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
783	tmp |= (pfifo->channels - 1) << 24;
784	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
785	return 0;
786}
787
788void
789nv10_graph_context_switch(struct drm_device *dev)
790{
791	struct drm_nouveau_private *dev_priv = dev->dev_private;
792	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
793	struct nouveau_channel *chan = NULL;
794	int chid;
795
796	pgraph->fifo_access(dev, false);
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->fifos[chid];
805	if (chan)
806		nv10_graph_load_context(chan);
807
808	pgraph->fifo_access(dev, true);
809}
810
811#define NV_WRITE_CTX(reg, val) do { \
812	int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
813	if (offset > 0) \
814		pgraph_ctx->nv10[offset] = val; \
815	} while (0)
816
817#define NV17_WRITE_CTX(reg, val) do { \
818	int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \
819	if (offset > 0) \
820		pgraph_ctx->nv17[offset] = val; \
821	} while (0)
822
823struct nouveau_channel *
824nv10_graph_channel(struct drm_device *dev)
825{
826	struct drm_nouveau_private *dev_priv = dev->dev_private;
827	int chid = dev_priv->engine.fifo.channels;
828
829	if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000)
830		chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24;
831
832	if (chid >= dev_priv->engine.fifo.channels)
833		return NULL;
834
835	return dev_priv->fifos[chid];
836}
837
838int nv10_graph_create_context(struct nouveau_channel *chan)
839{
840	struct drm_device *dev = chan->dev;
841	struct drm_nouveau_private *dev_priv = dev->dev_private;
842	struct graph_state *pgraph_ctx;
843
844	NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
845
846	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
847						GFP_KERNEL);
848	if (pgraph_ctx == NULL)
849		return -ENOMEM;
850
851
852	NV_WRITE_CTX(0x00400e88, 0x08000000);
853	NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
854	NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
855	NV_WRITE_CTX(0x00400e10, 0x00001000);
856	NV_WRITE_CTX(0x00400e14, 0x00001000);
857	NV_WRITE_CTX(0x00400e30, 0x00080008);
858	NV_WRITE_CTX(0x00400e34, 0x00080008);
859	if (dev_priv->chipset >= 0x17) {
860		/* is it really needed ??? */
861		NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
862					nv_rd32(dev, NV10_PGRAPH_DEBUG_4));
863		NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0));
864		NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
865		NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
866		NV17_WRITE_CTX(0x00400ec0, 0x00000080);
867		NV17_WRITE_CTX(0x00400ed0, 0x00000080);
868	}
869	NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24);
870
871	nv10_graph_create_pipe(chan);
872	return 0;
873}
874
875void nv10_graph_destroy_context(struct nouveau_channel *chan)
876{
877	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
878
879	kfree(pgraph_ctx);
880	chan->pgraph_ctx = NULL;
881}
882
883void
884nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
885			     uint32_t size, uint32_t pitch)
886{
887	uint32_t limit = max(1u, addr + size) - 1;
888
889	if (pitch)
890		addr |= 1 << 31;
891
892	nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit);
893	nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch);
894	nv_wr32(dev, NV10_PGRAPH_TILE(i), addr);
895}
896
897int nv10_graph_init(struct drm_device *dev)
898{
899	struct drm_nouveau_private *dev_priv = dev->dev_private;
900	uint32_t tmp;
901	int i;
902
903	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
904			~NV_PMC_ENABLE_PGRAPH);
905	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
906			 NV_PMC_ENABLE_PGRAPH);
907
908	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
909	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
910
911	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
912	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
913	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
914	/* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
915	nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
916	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
917				      (1<<29) |
918				      (1<<31));
919	if (dev_priv->chipset >= 0x17) {
920		nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
921		nv_wr32(dev, 0x400a10, 0x3ff3fb6);
922		nv_wr32(dev, 0x400838, 0x2f8684);
923		nv_wr32(dev, 0x40083c, 0x115f3f);
924		nv_wr32(dev, 0x004006b0, 0x40000020);
925	} else
926		nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
927
928	/* Turn all the tiling regions off. */
929	for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
930		nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
931
932	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
933	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
934	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
935	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
936	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
937	nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
938
939	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
940	tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
941	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
942	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
943	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
944
945	return 0;
946}
947
948void nv10_graph_takedown(struct drm_device *dev)
949{
950}
951
952static int
953nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass,
954			   int mthd, uint32_t data)
955{
956	struct drm_device *dev = chan->dev;
957	struct graph_state *ctx = chan->pgraph_ctx;
958	struct pipe_state *pipe = &ctx->pipe_state;
959	struct drm_nouveau_private *dev_priv = dev->dev_private;
960	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
961	uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
962	uint32_t xfmode0, xfmode1;
963	int i;
964
965	ctx->lma_window[(mthd - 0x1638) / 4] = data;
966
967	if (mthd != 0x1644)
968		return 0;
969
970	nouveau_wait_for_idle(dev);
971
972	PIPE_SAVE(dev, pipe_0x0040, 0x0040);
973	PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
974
975	PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
976
977	nouveau_wait_for_idle(dev);
978
979	xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
980	xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
981
982	PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
983	PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
984	PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
985	PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
986
987	nouveau_wait_for_idle(dev);
988
989	nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
990	nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
991	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
992	for (i = 0; i < 4; i++)
993		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
994	for (i = 0; i < 4; i++)
995		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
996
997	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
998	for (i = 0; i < 3; i++)
999		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
1000
1001	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
1002	for (i = 0; i < 3; i++)
1003		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1004
1005	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
1006	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
1007
1008	PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
1009
1010	nouveau_wait_for_idle(dev);
1011
1012	PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
1013
1014	nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
1015	nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
1016
1017	PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
1018	PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
1019	PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
1020	PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
1021
1022	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
1023	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
1024
1025	nouveau_wait_for_idle(dev);
1026
1027	pgraph->fifo_access(dev, true);
1028
1029	return 0;
1030}
1031
1032static int
1033nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass,
1034			   int mthd, uint32_t data)
1035{
1036	struct drm_device *dev = chan->dev;
1037	struct drm_nouveau_private *dev_priv = dev->dev_private;
1038	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
1039
1040	nouveau_wait_for_idle(dev);
1041
1042	nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
1043		nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
1044	nv_wr32(dev, 0x004006b0,
1045		nv_rd32(dev, 0x004006b0) | 0x8 << 24);
1046
1047	pgraph->fifo_access(dev, true);
1048
1049	return 0;
1050}
1051
1052static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = {
1053	{ 0x1638, nv17_graph_mthd_lma_window },
1054	{ 0x163c, nv17_graph_mthd_lma_window },
1055	{ 0x1640, nv17_graph_mthd_lma_window },
1056	{ 0x1644, nv17_graph_mthd_lma_window },
1057	{ 0x1658, nv17_graph_mthd_lma_enable },
1058	{}
1059};
1060
1061struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
1062	{ 0x0030, false, NULL }, /* null */
1063	{ 0x0039, false, NULL }, /* m2mf */
1064	{ 0x004a, false, NULL }, /* gdirect */
1065	{ 0x005f, false, NULL }, /* imageblit */
1066	{ 0x009f, false, NULL }, /* imageblit (nv12) */
1067	{ 0x008a, false, NULL }, /* ifc */
1068	{ 0x0089, false, NULL }, /* sifm */
1069	{ 0x0062, false, NULL }, /* surf2d */
1070	{ 0x0043, false, NULL }, /* rop */
1071	{ 0x0012, false, NULL }, /* beta1 */
1072	{ 0x0072, false, NULL }, /* beta4 */
1073	{ 0x0019, false, NULL }, /* cliprect */
1074	{ 0x0044, false, NULL }, /* pattern */
1075	{ 0x0052, false, NULL }, /* swzsurf */
1076	{ 0x0093, false, NULL }, /* surf3d */
1077	{ 0x0094, false, NULL }, /* tex_tri */
1078	{ 0x0095, false, NULL }, /* multitex_tri */
1079	{ 0x0056, false, NULL }, /* celcius (nv10) */
1080	{ 0x0096, false, NULL }, /* celcius (nv11) */
1081	{ 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */
1082	{}
1083};
1084