xref: /linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c (revision a940daa52167e9db8ecce82213813b735a9d9f23)
1b8bf04e1SBen Skeggs /*
2b8bf04e1SBen Skeggs  * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
3b8bf04e1SBen Skeggs  * All Rights Reserved.
4b8bf04e1SBen Skeggs  *
5b8bf04e1SBen Skeggs  * Permission is hereby granted, free of charge, to any person obtaining a
6b8bf04e1SBen Skeggs  * copy of this software and associated documentation files (the "Software"),
7b8bf04e1SBen Skeggs  * to deal in the Software without restriction, including without limitation
8b8bf04e1SBen Skeggs  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9b8bf04e1SBen Skeggs  * and/or sell copies of the Software, and to permit persons to whom the
10b8bf04e1SBen Skeggs  * Software is furnished to do so, subject to the following conditions:
11b8bf04e1SBen Skeggs  *
12b8bf04e1SBen Skeggs  * The above copyright notice and this permission notice (including the next
13b8bf04e1SBen Skeggs  * paragr) shall be included in all copies or substantial portions of the
14b8bf04e1SBen Skeggs  * Software.
15b8bf04e1SBen Skeggs  *
16b8bf04e1SBen Skeggs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17b8bf04e1SBen Skeggs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18b8bf04e1SBen Skeggs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19b8bf04e1SBen Skeggs  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20b8bf04e1SBen Skeggs  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21b8bf04e1SBen Skeggs  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22b8bf04e1SBen Skeggs  * DEALINGS IN THE SOFTWARE.
23b8bf04e1SBen Skeggs  */
24c85ee6caSBen Skeggs #include "nv10.h"
25e3c71eb2SBen Skeggs #include "regs.h"
26b8bf04e1SBen Skeggs 
27b8bf04e1SBen Skeggs #include <core/client.h>
2813de7f46SBen Skeggs #include <core/gpuobj.h>
29b8bf04e1SBen Skeggs #include <engine/fifo.h>
309a65a38cSBen Skeggs #include <engine/fifo/chan.h>
31e3c71eb2SBen Skeggs #include <subdev/fb.h>
32b8bf04e1SBen Skeggs 
33b8bf04e1SBen Skeggs struct pipe_state {
34b8bf04e1SBen Skeggs 	u32 pipe_0x0000[0x040/4];
35b8bf04e1SBen Skeggs 	u32 pipe_0x0040[0x010/4];
36b8bf04e1SBen Skeggs 	u32 pipe_0x0200[0x0c0/4];
37b8bf04e1SBen Skeggs 	u32 pipe_0x4400[0x080/4];
38b8bf04e1SBen Skeggs 	u32 pipe_0x6400[0x3b0/4];
39b8bf04e1SBen Skeggs 	u32 pipe_0x6800[0x2f0/4];
40b8bf04e1SBen Skeggs 	u32 pipe_0x6c00[0x030/4];
41b8bf04e1SBen Skeggs 	u32 pipe_0x7000[0x130/4];
42b8bf04e1SBen Skeggs 	u32 pipe_0x7400[0x0c0/4];
43b8bf04e1SBen Skeggs 	u32 pipe_0x7800[0x0c0/4];
44b8bf04e1SBen Skeggs };
45b8bf04e1SBen Skeggs 
46b8bf04e1SBen Skeggs static int nv10_gr_ctx_regs[] = {
47b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_SWITCH(0),
48b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_SWITCH(1),
49b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_SWITCH(2),
50b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_SWITCH(3),
51b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_SWITCH(4),
52b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(0, 0),
53b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(0, 1),
54b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(0, 2),
55b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(0, 3),
56b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(0, 4),
57b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(1, 0),
58b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(1, 1),
59b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(1, 2),
60b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(1, 3),
61b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(1, 4),
62b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(2, 0),
63b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(2, 1),
64b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(2, 2),
65b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(2, 3),
66b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(2, 4),
67b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(3, 0),
68b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(3, 1),
69b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(3, 2),
70b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(3, 3),
71b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(3, 4),
72b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(4, 0),
73b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(4, 1),
74b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(4, 2),
75b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(4, 3),
76b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(4, 4),
77b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(5, 0),
78b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(5, 1),
79b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(5, 2),
80b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(5, 3),
81b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(5, 4),
82b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(6, 0),
83b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(6, 1),
84b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(6, 2),
85b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(6, 3),
86b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(6, 4),
87b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(7, 0),
88b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(7, 1),
89b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(7, 2),
90b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(7, 3),
91b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_CACHE(7, 4),
92b8bf04e1SBen Skeggs 	NV10_PGRAPH_CTX_USER,
93b8bf04e1SBen Skeggs 	NV04_PGRAPH_DMA_START_0,
94b8bf04e1SBen Skeggs 	NV04_PGRAPH_DMA_START_1,
95b8bf04e1SBen Skeggs 	NV04_PGRAPH_DMA_LENGTH,
96b8bf04e1SBen Skeggs 	NV04_PGRAPH_DMA_MISC,
97b8bf04e1SBen Skeggs 	NV10_PGRAPH_DMA_PITCH,
98b8bf04e1SBen Skeggs 	NV04_PGRAPH_BOFFSET0,
99b8bf04e1SBen Skeggs 	NV04_PGRAPH_BBASE0,
100b8bf04e1SBen Skeggs 	NV04_PGRAPH_BLIMIT0,
101b8bf04e1SBen Skeggs 	NV04_PGRAPH_BOFFSET1,
102b8bf04e1SBen Skeggs 	NV04_PGRAPH_BBASE1,
103b8bf04e1SBen Skeggs 	NV04_PGRAPH_BLIMIT1,
104b8bf04e1SBen Skeggs 	NV04_PGRAPH_BOFFSET2,
105b8bf04e1SBen Skeggs 	NV04_PGRAPH_BBASE2,
106b8bf04e1SBen Skeggs 	NV04_PGRAPH_BLIMIT2,
107b8bf04e1SBen Skeggs 	NV04_PGRAPH_BOFFSET3,
108b8bf04e1SBen Skeggs 	NV04_PGRAPH_BBASE3,
109b8bf04e1SBen Skeggs 	NV04_PGRAPH_BLIMIT3,
110b8bf04e1SBen Skeggs 	NV04_PGRAPH_BOFFSET4,
111b8bf04e1SBen Skeggs 	NV04_PGRAPH_BBASE4,
112b8bf04e1SBen Skeggs 	NV04_PGRAPH_BLIMIT4,
113b8bf04e1SBen Skeggs 	NV04_PGRAPH_BOFFSET5,
114b8bf04e1SBen Skeggs 	NV04_PGRAPH_BBASE5,
115b8bf04e1SBen Skeggs 	NV04_PGRAPH_BLIMIT5,
116b8bf04e1SBen Skeggs 	NV04_PGRAPH_BPITCH0,
117b8bf04e1SBen Skeggs 	NV04_PGRAPH_BPITCH1,
118b8bf04e1SBen Skeggs 	NV04_PGRAPH_BPITCH2,
119b8bf04e1SBen Skeggs 	NV04_PGRAPH_BPITCH3,
120b8bf04e1SBen Skeggs 	NV04_PGRAPH_BPITCH4,
121b8bf04e1SBen Skeggs 	NV10_PGRAPH_SURFACE,
122b8bf04e1SBen Skeggs 	NV10_PGRAPH_STATE,
123b8bf04e1SBen Skeggs 	NV04_PGRAPH_BSWIZZLE2,
124b8bf04e1SBen Skeggs 	NV04_PGRAPH_BSWIZZLE5,
125b8bf04e1SBen Skeggs 	NV04_PGRAPH_BPIXEL,
126b8bf04e1SBen Skeggs 	NV10_PGRAPH_NOTIFY,
127b8bf04e1SBen Skeggs 	NV04_PGRAPH_PATT_COLOR0,
128b8bf04e1SBen Skeggs 	NV04_PGRAPH_PATT_COLOR1,
129b8bf04e1SBen Skeggs 	NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
130b8bf04e1SBen Skeggs 	0x00400904,
131b8bf04e1SBen Skeggs 	0x00400908,
132b8bf04e1SBen Skeggs 	0x0040090c,
133b8bf04e1SBen Skeggs 	0x00400910,
134b8bf04e1SBen Skeggs 	0x00400914,
135b8bf04e1SBen Skeggs 	0x00400918,
136b8bf04e1SBen Skeggs 	0x0040091c,
137b8bf04e1SBen Skeggs 	0x00400920,
138b8bf04e1SBen Skeggs 	0x00400924,
139b8bf04e1SBen Skeggs 	0x00400928,
140b8bf04e1SBen Skeggs 	0x0040092c,
141b8bf04e1SBen Skeggs 	0x00400930,
142b8bf04e1SBen Skeggs 	0x00400934,
143b8bf04e1SBen Skeggs 	0x00400938,
144b8bf04e1SBen Skeggs 	0x0040093c,
145b8bf04e1SBen Skeggs 	0x00400940,
146b8bf04e1SBen Skeggs 	0x00400944,
147b8bf04e1SBen Skeggs 	0x00400948,
148b8bf04e1SBen Skeggs 	0x0040094c,
149b8bf04e1SBen Skeggs 	0x00400950,
150b8bf04e1SBen Skeggs 	0x00400954,
151b8bf04e1SBen Skeggs 	0x00400958,
152b8bf04e1SBen Skeggs 	0x0040095c,
153b8bf04e1SBen Skeggs 	0x00400960,
154b8bf04e1SBen Skeggs 	0x00400964,
155b8bf04e1SBen Skeggs 	0x00400968,
156b8bf04e1SBen Skeggs 	0x0040096c,
157b8bf04e1SBen Skeggs 	0x00400970,
158b8bf04e1SBen Skeggs 	0x00400974,
159b8bf04e1SBen Skeggs 	0x00400978,
160b8bf04e1SBen Skeggs 	0x0040097c,
161b8bf04e1SBen Skeggs 	0x00400980,
162b8bf04e1SBen Skeggs 	0x00400984,
163b8bf04e1SBen Skeggs 	0x00400988,
164b8bf04e1SBen Skeggs 	0x0040098c,
165b8bf04e1SBen Skeggs 	0x00400990,
166b8bf04e1SBen Skeggs 	0x00400994,
167b8bf04e1SBen Skeggs 	0x00400998,
168b8bf04e1SBen Skeggs 	0x0040099c,
169b8bf04e1SBen Skeggs 	0x004009a0,
170b8bf04e1SBen Skeggs 	0x004009a4,
171b8bf04e1SBen Skeggs 	0x004009a8,
172b8bf04e1SBen Skeggs 	0x004009ac,
173b8bf04e1SBen Skeggs 	0x004009b0,
174b8bf04e1SBen Skeggs 	0x004009b4,
175b8bf04e1SBen Skeggs 	0x004009b8,
176b8bf04e1SBen Skeggs 	0x004009bc,
177b8bf04e1SBen Skeggs 	0x004009c0,
178b8bf04e1SBen Skeggs 	0x004009c4,
179b8bf04e1SBen Skeggs 	0x004009c8,
180b8bf04e1SBen Skeggs 	0x004009cc,
181b8bf04e1SBen Skeggs 	0x004009d0,
182b8bf04e1SBen Skeggs 	0x004009d4,
183b8bf04e1SBen Skeggs 	0x004009d8,
184b8bf04e1SBen Skeggs 	0x004009dc,
185b8bf04e1SBen Skeggs 	0x004009e0,
186b8bf04e1SBen Skeggs 	0x004009e4,
187b8bf04e1SBen Skeggs 	0x004009e8,
188b8bf04e1SBen Skeggs 	0x004009ec,
189b8bf04e1SBen Skeggs 	0x004009f0,
190b8bf04e1SBen Skeggs 	0x004009f4,
191b8bf04e1SBen Skeggs 	0x004009f8,
192b8bf04e1SBen Skeggs 	0x004009fc,
193b8bf04e1SBen Skeggs 	NV04_PGRAPH_PATTERN,	/* 2 values from 0x400808 to 0x40080c */
194b8bf04e1SBen Skeggs 	0x0040080c,
195b8bf04e1SBen Skeggs 	NV04_PGRAPH_PATTERN_SHAPE,
196b8bf04e1SBen Skeggs 	NV03_PGRAPH_MONO_COLOR0,
197b8bf04e1SBen Skeggs 	NV04_PGRAPH_ROP3,
198b8bf04e1SBen Skeggs 	NV04_PGRAPH_CHROMA,
199b8bf04e1SBen Skeggs 	NV04_PGRAPH_BETA_AND,
200b8bf04e1SBen Skeggs 	NV04_PGRAPH_BETA_PREMULT,
201b8bf04e1SBen Skeggs 	0x00400e70,
202b8bf04e1SBen Skeggs 	0x00400e74,
203b8bf04e1SBen Skeggs 	0x00400e78,
204b8bf04e1SBen Skeggs 	0x00400e7c,
205b8bf04e1SBen Skeggs 	0x00400e80,
206b8bf04e1SBen Skeggs 	0x00400e84,
207b8bf04e1SBen Skeggs 	0x00400e88,
208b8bf04e1SBen Skeggs 	0x00400e8c,
209b8bf04e1SBen Skeggs 	0x00400ea0,
210b8bf04e1SBen Skeggs 	0x00400ea4,
211b8bf04e1SBen Skeggs 	0x00400ea8,
212b8bf04e1SBen Skeggs 	0x00400e90,
213b8bf04e1SBen Skeggs 	0x00400e94,
214b8bf04e1SBen Skeggs 	0x00400e98,
215b8bf04e1SBen Skeggs 	0x00400e9c,
216b8bf04e1SBen Skeggs 	NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
217b8bf04e1SBen Skeggs 	NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20-0x400f3c */
218b8bf04e1SBen Skeggs 	0x00400f04,
219b8bf04e1SBen Skeggs 	0x00400f24,
220b8bf04e1SBen Skeggs 	0x00400f08,
221b8bf04e1SBen Skeggs 	0x00400f28,
222b8bf04e1SBen Skeggs 	0x00400f0c,
223b8bf04e1SBen Skeggs 	0x00400f2c,
224b8bf04e1SBen Skeggs 	0x00400f10,
225b8bf04e1SBen Skeggs 	0x00400f30,
226b8bf04e1SBen Skeggs 	0x00400f14,
227b8bf04e1SBen Skeggs 	0x00400f34,
228b8bf04e1SBen Skeggs 	0x00400f18,
229b8bf04e1SBen Skeggs 	0x00400f38,
230b8bf04e1SBen Skeggs 	0x00400f1c,
231b8bf04e1SBen Skeggs 	0x00400f3c,
232b8bf04e1SBen Skeggs 	NV10_PGRAPH_XFMODE0,
233b8bf04e1SBen Skeggs 	NV10_PGRAPH_XFMODE1,
234b8bf04e1SBen Skeggs 	NV10_PGRAPH_GLOBALSTATE0,
235b8bf04e1SBen Skeggs 	NV10_PGRAPH_GLOBALSTATE1,
236b8bf04e1SBen Skeggs 	NV04_PGRAPH_STORED_FMT,
237b8bf04e1SBen Skeggs 	NV04_PGRAPH_SOURCE_COLOR,
238b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_X_RAM,	/* 32 values from 0x400400 to 0x40047c */
239b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_Y_RAM,	/* 32 values from 0x400480 to 0x4004fc */
240b8bf04e1SBen Skeggs 	0x00400404,
241b8bf04e1SBen Skeggs 	0x00400484,
242b8bf04e1SBen Skeggs 	0x00400408,
243b8bf04e1SBen Skeggs 	0x00400488,
244b8bf04e1SBen Skeggs 	0x0040040c,
245b8bf04e1SBen Skeggs 	0x0040048c,
246b8bf04e1SBen Skeggs 	0x00400410,
247b8bf04e1SBen Skeggs 	0x00400490,
248b8bf04e1SBen Skeggs 	0x00400414,
249b8bf04e1SBen Skeggs 	0x00400494,
250b8bf04e1SBen Skeggs 	0x00400418,
251b8bf04e1SBen Skeggs 	0x00400498,
252b8bf04e1SBen Skeggs 	0x0040041c,
253b8bf04e1SBen Skeggs 	0x0040049c,
254b8bf04e1SBen Skeggs 	0x00400420,
255b8bf04e1SBen Skeggs 	0x004004a0,
256b8bf04e1SBen Skeggs 	0x00400424,
257b8bf04e1SBen Skeggs 	0x004004a4,
258b8bf04e1SBen Skeggs 	0x00400428,
259b8bf04e1SBen Skeggs 	0x004004a8,
260b8bf04e1SBen Skeggs 	0x0040042c,
261b8bf04e1SBen Skeggs 	0x004004ac,
262b8bf04e1SBen Skeggs 	0x00400430,
263b8bf04e1SBen Skeggs 	0x004004b0,
264b8bf04e1SBen Skeggs 	0x00400434,
265b8bf04e1SBen Skeggs 	0x004004b4,
266b8bf04e1SBen Skeggs 	0x00400438,
267b8bf04e1SBen Skeggs 	0x004004b8,
268b8bf04e1SBen Skeggs 	0x0040043c,
269b8bf04e1SBen Skeggs 	0x004004bc,
270b8bf04e1SBen Skeggs 	0x00400440,
271b8bf04e1SBen Skeggs 	0x004004c0,
272b8bf04e1SBen Skeggs 	0x00400444,
273b8bf04e1SBen Skeggs 	0x004004c4,
274b8bf04e1SBen Skeggs 	0x00400448,
275b8bf04e1SBen Skeggs 	0x004004c8,
276b8bf04e1SBen Skeggs 	0x0040044c,
277b8bf04e1SBen Skeggs 	0x004004cc,
278b8bf04e1SBen Skeggs 	0x00400450,
279b8bf04e1SBen Skeggs 	0x004004d0,
280b8bf04e1SBen Skeggs 	0x00400454,
281b8bf04e1SBen Skeggs 	0x004004d4,
282b8bf04e1SBen Skeggs 	0x00400458,
283b8bf04e1SBen Skeggs 	0x004004d8,
284b8bf04e1SBen Skeggs 	0x0040045c,
285b8bf04e1SBen Skeggs 	0x004004dc,
286b8bf04e1SBen Skeggs 	0x00400460,
287b8bf04e1SBen Skeggs 	0x004004e0,
288b8bf04e1SBen Skeggs 	0x00400464,
289b8bf04e1SBen Skeggs 	0x004004e4,
290b8bf04e1SBen Skeggs 	0x00400468,
291b8bf04e1SBen Skeggs 	0x004004e8,
292b8bf04e1SBen Skeggs 	0x0040046c,
293b8bf04e1SBen Skeggs 	0x004004ec,
294b8bf04e1SBen Skeggs 	0x00400470,
295b8bf04e1SBen Skeggs 	0x004004f0,
296b8bf04e1SBen Skeggs 	0x00400474,
297b8bf04e1SBen Skeggs 	0x004004f4,
298b8bf04e1SBen Skeggs 	0x00400478,
299b8bf04e1SBen Skeggs 	0x004004f8,
300b8bf04e1SBen Skeggs 	0x0040047c,
301b8bf04e1SBen Skeggs 	0x004004fc,
302b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIP_XMIN,
303b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIP_XMAX,
304b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIP_YMIN,
305b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIP_YMAX,
306b8bf04e1SBen Skeggs 	0x00400550,
307b8bf04e1SBen Skeggs 	0x00400558,
308b8bf04e1SBen Skeggs 	0x00400554,
309b8bf04e1SBen Skeggs 	0x0040055c,
310b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIPA_XMIN,
311b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIPA_XMAX,
312b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIPA_YMIN,
313b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_UCLIPA_YMAX,
314b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_ICLIP_XMAX,
315b8bf04e1SBen Skeggs 	NV03_PGRAPH_ABS_ICLIP_YMAX,
316b8bf04e1SBen Skeggs 	NV03_PGRAPH_XY_LOGIC_MISC0,
317b8bf04e1SBen Skeggs 	NV03_PGRAPH_XY_LOGIC_MISC1,
318b8bf04e1SBen Skeggs 	NV03_PGRAPH_XY_LOGIC_MISC2,
319b8bf04e1SBen Skeggs 	NV03_PGRAPH_XY_LOGIC_MISC3,
320b8bf04e1SBen Skeggs 	NV03_PGRAPH_CLIPX_0,
321b8bf04e1SBen Skeggs 	NV03_PGRAPH_CLIPX_1,
322b8bf04e1SBen Skeggs 	NV03_PGRAPH_CLIPY_0,
323b8bf04e1SBen Skeggs 	NV03_PGRAPH_CLIPY_1,
324b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER0_IN_ALPHA,
325b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER1_IN_ALPHA,
326b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER0_IN_RGB,
327b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER1_IN_RGB,
328b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER_COLOR0,
329b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER_COLOR1,
330b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER0_OUT_ALPHA,
331b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER1_OUT_ALPHA,
332b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER0_OUT_RGB,
333b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER1_OUT_RGB,
334b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER_FINAL0,
335b8bf04e1SBen Skeggs 	NV10_PGRAPH_COMBINER_FINAL1,
336b8bf04e1SBen Skeggs 	0x00400e00,
337b8bf04e1SBen Skeggs 	0x00400e04,
338b8bf04e1SBen Skeggs 	0x00400e08,
339b8bf04e1SBen Skeggs 	0x00400e0c,
340b8bf04e1SBen Skeggs 	0x00400e10,
341b8bf04e1SBen Skeggs 	0x00400e14,
342b8bf04e1SBen Skeggs 	0x00400e18,
343b8bf04e1SBen Skeggs 	0x00400e1c,
344b8bf04e1SBen Skeggs 	0x00400e20,
345b8bf04e1SBen Skeggs 	0x00400e24,
346b8bf04e1SBen Skeggs 	0x00400e28,
347b8bf04e1SBen Skeggs 	0x00400e2c,
348b8bf04e1SBen Skeggs 	0x00400e30,
349b8bf04e1SBen Skeggs 	0x00400e34,
350b8bf04e1SBen Skeggs 	0x00400e38,
351b8bf04e1SBen Skeggs 	0x00400e3c,
352b8bf04e1SBen Skeggs 	NV04_PGRAPH_PASSTHRU_0,
353b8bf04e1SBen Skeggs 	NV04_PGRAPH_PASSTHRU_1,
354b8bf04e1SBen Skeggs 	NV04_PGRAPH_PASSTHRU_2,
355b8bf04e1SBen Skeggs 	NV10_PGRAPH_DIMX_TEXTURE,
356b8bf04e1SBen Skeggs 	NV10_PGRAPH_WDIMX_TEXTURE,
357b8bf04e1SBen Skeggs 	NV10_PGRAPH_DVD_COLORFMT,
358b8bf04e1SBen Skeggs 	NV10_PGRAPH_SCALED_FORMAT,
359b8bf04e1SBen Skeggs 	NV04_PGRAPH_MISC24_0,
360b8bf04e1SBen Skeggs 	NV04_PGRAPH_MISC24_1,
361b8bf04e1SBen Skeggs 	NV04_PGRAPH_MISC24_2,
362b8bf04e1SBen Skeggs 	NV03_PGRAPH_X_MISC,
363b8bf04e1SBen Skeggs 	NV03_PGRAPH_Y_MISC,
364b8bf04e1SBen Skeggs 	NV04_PGRAPH_VALID1,
365b8bf04e1SBen Skeggs 	NV04_PGRAPH_VALID2,
366b8bf04e1SBen Skeggs };
367b8bf04e1SBen Skeggs 
368b8bf04e1SBen Skeggs static int nv17_gr_ctx_regs[] = {
369b8bf04e1SBen Skeggs 	NV10_PGRAPH_DEBUG_4,
370b8bf04e1SBen Skeggs 	0x004006b0,
371b8bf04e1SBen Skeggs 	0x00400eac,
372b8bf04e1SBen Skeggs 	0x00400eb0,
373b8bf04e1SBen Skeggs 	0x00400eb4,
374b8bf04e1SBen Skeggs 	0x00400eb8,
375b8bf04e1SBen Skeggs 	0x00400ebc,
376b8bf04e1SBen Skeggs 	0x00400ec0,
377b8bf04e1SBen Skeggs 	0x00400ec4,
378b8bf04e1SBen Skeggs 	0x00400ec8,
379b8bf04e1SBen Skeggs 	0x00400ecc,
380b8bf04e1SBen Skeggs 	0x00400ed0,
381b8bf04e1SBen Skeggs 	0x00400ed4,
382b8bf04e1SBen Skeggs 	0x00400ed8,
383b8bf04e1SBen Skeggs 	0x00400edc,
384b8bf04e1SBen Skeggs 	0x00400ee0,
385b8bf04e1SBen Skeggs 	0x00400a00,
386b8bf04e1SBen Skeggs 	0x00400a04,
387b8bf04e1SBen Skeggs };
388b8bf04e1SBen Skeggs 
38927f3d6cfSBen Skeggs #define nv10_gr(p) container_of((p), struct nv10_gr, base)
39027f3d6cfSBen Skeggs 
391bfee3f3dSBen Skeggs struct nv10_gr {
392e3c71eb2SBen Skeggs 	struct nvkm_gr base;
393b8bf04e1SBen Skeggs 	struct nv10_gr_chan *chan[32];
394b8bf04e1SBen Skeggs 	spinlock_t lock;
395b8bf04e1SBen Skeggs };
396b8bf04e1SBen Skeggs 
39727f3d6cfSBen Skeggs #define nv10_gr_chan(p) container_of((p), struct nv10_gr_chan, object)
39827f3d6cfSBen Skeggs 
399b8bf04e1SBen Skeggs struct nv10_gr_chan {
40027f3d6cfSBen Skeggs 	struct nvkm_object object;
40127f3d6cfSBen Skeggs 	struct nv10_gr *gr;
402b8bf04e1SBen Skeggs 	int chid;
403b8bf04e1SBen Skeggs 	int nv10[ARRAY_SIZE(nv10_gr_ctx_regs)];
404b8bf04e1SBen Skeggs 	int nv17[ARRAY_SIZE(nv17_gr_ctx_regs)];
405b8bf04e1SBen Skeggs 	struct pipe_state pipe_state;
406b8bf04e1SBen Skeggs 	u32 lma_window[4];
407b8bf04e1SBen Skeggs };
408b8bf04e1SBen Skeggs 
409b8bf04e1SBen Skeggs 
410b8bf04e1SBen Skeggs /*******************************************************************************
411b8bf04e1SBen Skeggs  * Graphics object classes
412b8bf04e1SBen Skeggs  ******************************************************************************/
413b8bf04e1SBen Skeggs 
414bfee3f3dSBen Skeggs #define PIPE_SAVE(gr, state, addr)					\
415b8bf04e1SBen Skeggs 	do {								\
416b8bf04e1SBen Skeggs 		int __i;						\
417276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, addr);		\
418b8bf04e1SBen Skeggs 		for (__i = 0; __i < ARRAY_SIZE(state); __i++)		\
419276836d4SBen Skeggs 			state[__i] = nvkm_rd32(device, NV10_PGRAPH_PIPE_DATA); \
420b8bf04e1SBen Skeggs 	} while (0)
421b8bf04e1SBen Skeggs 
422bfee3f3dSBen Skeggs #define PIPE_RESTORE(gr, state, addr)					\
423b8bf04e1SBen Skeggs 	do {								\
424b8bf04e1SBen Skeggs 		int __i;						\
425276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, addr);		\
426b8bf04e1SBen Skeggs 		for (__i = 0; __i < ARRAY_SIZE(state); __i++)		\
427276836d4SBen Skeggs 			nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, state[__i]); \
428b8bf04e1SBen Skeggs 	} while (0)
429b8bf04e1SBen Skeggs 
430a65955e1SBen Skeggs static void
nv17_gr_mthd_lma_window(struct nv10_gr_chan * chan,u32 mthd,u32 data)431a65955e1SBen Skeggs nv17_gr_mthd_lma_window(struct nv10_gr_chan *chan, u32 mthd, u32 data)
432b8bf04e1SBen Skeggs {
43327f3d6cfSBen Skeggs 	struct nvkm_device *device = chan->object.engine->subdev.device;
43427f3d6cfSBen Skeggs 	struct nvkm_gr *gr = &chan->gr->base;
435b8bf04e1SBen Skeggs 	struct pipe_state *pipe = &chan->pipe_state;
436b8bf04e1SBen Skeggs 	u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
437b8bf04e1SBen Skeggs 	u32 xfmode0, xfmode1;
438b8bf04e1SBen Skeggs 	int i;
439b8bf04e1SBen Skeggs 
440b8bf04e1SBen Skeggs 	chan->lma_window[(mthd - 0x1638) / 4] = data;
441b8bf04e1SBen Skeggs 
442b8bf04e1SBen Skeggs 	if (mthd != 0x1644)
443a65955e1SBen Skeggs 		return;
444b8bf04e1SBen Skeggs 
445bfee3f3dSBen Skeggs 	nv04_gr_idle(gr);
446b8bf04e1SBen Skeggs 
447a65955e1SBen Skeggs 	PIPE_SAVE(device, pipe_0x0040, 0x0040);
448a65955e1SBen Skeggs 	PIPE_SAVE(device, pipe->pipe_0x0200, 0x0200);
449b8bf04e1SBen Skeggs 
450a65955e1SBen Skeggs 	PIPE_RESTORE(device, chan->lma_window, 0x6790);
451b8bf04e1SBen Skeggs 
452bfee3f3dSBen Skeggs 	nv04_gr_idle(gr);
453b8bf04e1SBen Skeggs 
454276836d4SBen Skeggs 	xfmode0 = nvkm_rd32(device, NV10_PGRAPH_XFMODE0);
455276836d4SBen Skeggs 	xfmode1 = nvkm_rd32(device, NV10_PGRAPH_XFMODE1);
456b8bf04e1SBen Skeggs 
457a65955e1SBen Skeggs 	PIPE_SAVE(device, pipe->pipe_0x4400, 0x4400);
458a65955e1SBen Skeggs 	PIPE_SAVE(device, pipe_0x64c0, 0x64c0);
459a65955e1SBen Skeggs 	PIPE_SAVE(device, pipe_0x6ab0, 0x6ab0);
460a65955e1SBen Skeggs 	PIPE_SAVE(device, pipe_0x6a80, 0x6a80);
461b8bf04e1SBen Skeggs 
462bfee3f3dSBen Skeggs 	nv04_gr_idle(gr);
463b8bf04e1SBen Skeggs 
464276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE0, 0x10000000);
465276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE1, 0x00000000);
466276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
467b8bf04e1SBen Skeggs 	for (i = 0; i < 4; i++)
468276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
469b8bf04e1SBen Skeggs 	for (i = 0; i < 4; i++)
470276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000000);
471b8bf04e1SBen Skeggs 
472276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
473b8bf04e1SBen Skeggs 	for (i = 0; i < 3; i++)
474276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
475b8bf04e1SBen Skeggs 
476276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
477b8bf04e1SBen Skeggs 	for (i = 0; i < 3; i++)
478276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000000);
479b8bf04e1SBen Skeggs 
480276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
481276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000008);
482b8bf04e1SBen Skeggs 
483a65955e1SBen Skeggs 	PIPE_RESTORE(device, pipe->pipe_0x0200, 0x0200);
484b8bf04e1SBen Skeggs 
485bfee3f3dSBen Skeggs 	nv04_gr_idle(gr);
486b8bf04e1SBen Skeggs 
487a65955e1SBen Skeggs 	PIPE_RESTORE(device, pipe_0x0040, 0x0040);
488b8bf04e1SBen Skeggs 
489276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE0, xfmode0);
490276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE1, xfmode1);
491b8bf04e1SBen Skeggs 
492a65955e1SBen Skeggs 	PIPE_RESTORE(device, pipe_0x64c0, 0x64c0);
493a65955e1SBen Skeggs 	PIPE_RESTORE(device, pipe_0x6ab0, 0x6ab0);
494a65955e1SBen Skeggs 	PIPE_RESTORE(device, pipe_0x6a80, 0x6a80);
495a65955e1SBen Skeggs 	PIPE_RESTORE(device, pipe->pipe_0x4400, 0x4400);
496b8bf04e1SBen Skeggs 
497276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
498276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000000);
499b8bf04e1SBen Skeggs 
500bfee3f3dSBen Skeggs 	nv04_gr_idle(gr);
501b8bf04e1SBen Skeggs }
502b8bf04e1SBen Skeggs 
503a65955e1SBen Skeggs static void
nv17_gr_mthd_lma_enable(struct nv10_gr_chan * chan,u32 mthd,u32 data)504a65955e1SBen Skeggs nv17_gr_mthd_lma_enable(struct nv10_gr_chan *chan, u32 mthd, u32 data)
505b8bf04e1SBen Skeggs {
50627f3d6cfSBen Skeggs 	struct nvkm_device *device = chan->object.engine->subdev.device;
50727f3d6cfSBen Skeggs 	struct nvkm_gr *gr = &chan->gr->base;
508b8bf04e1SBen Skeggs 
509bfee3f3dSBen Skeggs 	nv04_gr_idle(gr);
510b8bf04e1SBen Skeggs 
511276836d4SBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100);
512276836d4SBen Skeggs 	nvkm_mask(device, 0x4006b0, 0x08000000, 0x08000000);
513b8bf04e1SBen Skeggs }
514b8bf04e1SBen Skeggs 
515a65955e1SBen Skeggs static bool
nv17_gr_mthd_celcius(struct nv10_gr_chan * chan,u32 mthd,u32 data)516a65955e1SBen Skeggs nv17_gr_mthd_celcius(struct nv10_gr_chan *chan, u32 mthd, u32 data)
517a65955e1SBen Skeggs {
518a65955e1SBen Skeggs 	void (*func)(struct nv10_gr_chan *, u32, u32);
519a65955e1SBen Skeggs 	switch (mthd) {
520a65955e1SBen Skeggs 	case 0x1638 ... 0x1644:
521a65955e1SBen Skeggs 		     func = nv17_gr_mthd_lma_window; break;
522a65955e1SBen Skeggs 	case 0x1658: func = nv17_gr_mthd_lma_enable; break;
523a65955e1SBen Skeggs 	default:
524a65955e1SBen Skeggs 		return false;
525a65955e1SBen Skeggs 	}
526a65955e1SBen Skeggs 	func(chan, mthd, data);
527a65955e1SBen Skeggs 	return true;
528a65955e1SBen Skeggs }
529b8bf04e1SBen Skeggs 
530a65955e1SBen Skeggs static bool
nv10_gr_mthd(struct nv10_gr_chan * chan,u8 class,u32 mthd,u32 data)531a65955e1SBen Skeggs nv10_gr_mthd(struct nv10_gr_chan *chan, u8 class, u32 mthd, u32 data)
532a65955e1SBen Skeggs {
533a65955e1SBen Skeggs 	bool (*func)(struct nv10_gr_chan *, u32, u32);
534a65955e1SBen Skeggs 	switch (class) {
535a65955e1SBen Skeggs 	case 0x99: func = nv17_gr_mthd_celcius; break;
536a65955e1SBen Skeggs 	default:
537a65955e1SBen Skeggs 		return false;
538a65955e1SBen Skeggs 	}
539a65955e1SBen Skeggs 	return func(chan, mthd, data);
540a65955e1SBen Skeggs }
541b8bf04e1SBen Skeggs 
542b8bf04e1SBen Skeggs /*******************************************************************************
543b8bf04e1SBen Skeggs  * PGRAPH context
544b8bf04e1SBen Skeggs  ******************************************************************************/
545b8bf04e1SBen Skeggs 
546b8bf04e1SBen Skeggs static struct nv10_gr_chan *
nv10_gr_channel(struct nv10_gr * gr)547bfee3f3dSBen Skeggs nv10_gr_channel(struct nv10_gr *gr)
548b8bf04e1SBen Skeggs {
549276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
550b8bf04e1SBen Skeggs 	struct nv10_gr_chan *chan = NULL;
551276836d4SBen Skeggs 	if (nvkm_rd32(device, 0x400144) & 0x00010000) {
552276836d4SBen Skeggs 		int chid = nvkm_rd32(device, 0x400148) >> 24;
553bfee3f3dSBen Skeggs 		if (chid < ARRAY_SIZE(gr->chan))
554bfee3f3dSBen Skeggs 			chan = gr->chan[chid];
555b8bf04e1SBen Skeggs 	}
556b8bf04e1SBen Skeggs 	return chan;
557b8bf04e1SBen Skeggs }
558b8bf04e1SBen Skeggs 
559b8bf04e1SBen Skeggs static void
nv10_gr_save_pipe(struct nv10_gr_chan * chan)560b8bf04e1SBen Skeggs nv10_gr_save_pipe(struct nv10_gr_chan *chan)
561b8bf04e1SBen Skeggs {
56227f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
563b8bf04e1SBen Skeggs 	struct pipe_state *pipe = &chan->pipe_state;
564276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
565b8bf04e1SBen Skeggs 
566bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x4400, 0x4400);
567bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x0200, 0x0200);
568bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x6400, 0x6400);
569bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x6800, 0x6800);
570bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x6c00, 0x6c00);
571bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x7000, 0x7000);
572bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x7400, 0x7400);
573bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x7800, 0x7800);
574bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x0040, 0x0040);
575bfee3f3dSBen Skeggs 	PIPE_SAVE(gr, pipe->pipe_0x0000, 0x0000);
576b8bf04e1SBen Skeggs }
577b8bf04e1SBen Skeggs 
578b8bf04e1SBen Skeggs static void
nv10_gr_load_pipe(struct nv10_gr_chan * chan)579b8bf04e1SBen Skeggs nv10_gr_load_pipe(struct nv10_gr_chan *chan)
580b8bf04e1SBen Skeggs {
58127f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
582b8bf04e1SBen Skeggs 	struct pipe_state *pipe = &chan->pipe_state;
583276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
584b8bf04e1SBen Skeggs 	u32 xfmode0, xfmode1;
585b8bf04e1SBen Skeggs 	int i;
586b8bf04e1SBen Skeggs 
58727f3d6cfSBen Skeggs 	nv04_gr_idle(&gr->base);
588b8bf04e1SBen Skeggs 	/* XXX check haiku comments */
589276836d4SBen Skeggs 	xfmode0 = nvkm_rd32(device, NV10_PGRAPH_XFMODE0);
590276836d4SBen Skeggs 	xfmode1 = nvkm_rd32(device, NV10_PGRAPH_XFMODE1);
591276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE0, 0x10000000);
592276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE1, 0x00000000);
593276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
594b8bf04e1SBen Skeggs 	for (i = 0; i < 4; i++)
595276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
596b8bf04e1SBen Skeggs 	for (i = 0; i < 4; i++)
597276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000000);
598b8bf04e1SBen Skeggs 
599276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
600b8bf04e1SBen Skeggs 	for (i = 0; i < 3; i++)
601276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
602b8bf04e1SBen Skeggs 
603276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
604b8bf04e1SBen Skeggs 	for (i = 0; i < 3; i++)
605276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000000);
606b8bf04e1SBen Skeggs 
607276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
608276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000008);
609b8bf04e1SBen Skeggs 
610b8bf04e1SBen Skeggs 
611bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x0200, 0x0200);
61227f3d6cfSBen Skeggs 	nv04_gr_idle(&gr->base);
613b8bf04e1SBen Skeggs 
614b8bf04e1SBen Skeggs 	/* restore XFMODE */
615276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE0, xfmode0);
616276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_XFMODE1, xfmode1);
617bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x6400, 0x6400);
618bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x6800, 0x6800);
619bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x6c00, 0x6c00);
620bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x7000, 0x7000);
621bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x7400, 0x7400);
622bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x7800, 0x7800);
623bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x4400, 0x4400);
624bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x0000, 0x0000);
625bfee3f3dSBen Skeggs 	PIPE_RESTORE(gr, pipe->pipe_0x0040, 0x0040);
62627f3d6cfSBen Skeggs 	nv04_gr_idle(&gr->base);
627b8bf04e1SBen Skeggs }
628b8bf04e1SBen Skeggs 
629b8bf04e1SBen Skeggs static void
nv10_gr_create_pipe(struct nv10_gr_chan * chan)630b8bf04e1SBen Skeggs nv10_gr_create_pipe(struct nv10_gr_chan *chan)
631b8bf04e1SBen Skeggs {
63227f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
633109c2f2fSBen Skeggs 	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
634b8bf04e1SBen Skeggs 	struct pipe_state *pipe_state = &chan->pipe_state;
635b8bf04e1SBen Skeggs 	u32 *pipe_state_addr;
636b8bf04e1SBen Skeggs 	int i;
637b8bf04e1SBen Skeggs #define PIPE_INIT(addr) \
638b8bf04e1SBen Skeggs 	do { \
639b8bf04e1SBen Skeggs 		pipe_state_addr = pipe_state->pipe_##addr; \
640b8bf04e1SBen Skeggs 	} while (0)
641b8bf04e1SBen Skeggs #define PIPE_INIT_END(addr) \
642b8bf04e1SBen Skeggs 	do { \
643b8bf04e1SBen Skeggs 		u32 *__end_addr = pipe_state->pipe_##addr + \
644b8bf04e1SBen Skeggs 				ARRAY_SIZE(pipe_state->pipe_##addr); \
645b8bf04e1SBen Skeggs 		if (pipe_state_addr != __end_addr) \
646109c2f2fSBen Skeggs 			nvkm_error(subdev, "incomplete pipe init for 0x%x :  %p/%p\n", \
647b8bf04e1SBen Skeggs 				addr, pipe_state_addr, __end_addr); \
648b8bf04e1SBen Skeggs 	} while (0)
649b8bf04e1SBen Skeggs #define NV_WRITE_PIPE_INIT(value) *(pipe_state_addr++) = value
650b8bf04e1SBen Skeggs 
651b8bf04e1SBen Skeggs 	PIPE_INIT(0x0200);
652b8bf04e1SBen Skeggs 	for (i = 0; i < 48; i++)
653b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
654b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x0200);
655b8bf04e1SBen Skeggs 
656b8bf04e1SBen Skeggs 	PIPE_INIT(0x6400);
657b8bf04e1SBen Skeggs 	for (i = 0; i < 211; i++)
658b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
659b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
660b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x40000000);
661b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x40000000);
662b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x40000000);
663b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x40000000);
664b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
665b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
666b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
667b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
668b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f000000);
669b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f000000);
670b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
671b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
672b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
673b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
674b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
675b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
676b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
677b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
678b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
679b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
680b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
681b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
682b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
683b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
684b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x6400);
685b8bf04e1SBen Skeggs 
686b8bf04e1SBen Skeggs 	PIPE_INIT(0x6800);
687b8bf04e1SBen Skeggs 	for (i = 0; i < 162; i++)
688b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
689b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x3f800000);
690b8bf04e1SBen Skeggs 	for (i = 0; i < 25; i++)
691b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
692b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x6800);
693b8bf04e1SBen Skeggs 
694b8bf04e1SBen Skeggs 	PIPE_INIT(0x6c00);
695b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
696b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
697b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
698b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
699b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0xbf800000);
700b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
701b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
702b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
703b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
704b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
705b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
706b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
707b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x6c00);
708b8bf04e1SBen Skeggs 
709b8bf04e1SBen Skeggs 	PIPE_INIT(0x7000);
710b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
711b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
712b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
713b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
714b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
715b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
716b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
717b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
718b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
719b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
720b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
721b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
722b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
723b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
724b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
725b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
726b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
727b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
728b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
729b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
730b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
731b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
732b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
733b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
734b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
735b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
736b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
737b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
738b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
739b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
740b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
741b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
742b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
743b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
744b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
745b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
746b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
747b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
748b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
749b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x00000000);
750b8bf04e1SBen Skeggs 	NV_WRITE_PIPE_INIT(0x7149f2ca);
751b8bf04e1SBen Skeggs 	for (i = 0; i < 35; i++)
752b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
753b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x7000);
754b8bf04e1SBen Skeggs 
755b8bf04e1SBen Skeggs 	PIPE_INIT(0x7400);
756b8bf04e1SBen Skeggs 	for (i = 0; i < 48; i++)
757b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
758b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x7400);
759b8bf04e1SBen Skeggs 
760b8bf04e1SBen Skeggs 	PIPE_INIT(0x7800);
761b8bf04e1SBen Skeggs 	for (i = 0; i < 48; i++)
762b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
763b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x7800);
764b8bf04e1SBen Skeggs 
765b8bf04e1SBen Skeggs 	PIPE_INIT(0x4400);
766b8bf04e1SBen Skeggs 	for (i = 0; i < 32; i++)
767b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
768b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x4400);
769b8bf04e1SBen Skeggs 
770b8bf04e1SBen Skeggs 	PIPE_INIT(0x0000);
771b8bf04e1SBen Skeggs 	for (i = 0; i < 16; i++)
772b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
773b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x0000);
774b8bf04e1SBen Skeggs 
775b8bf04e1SBen Skeggs 	PIPE_INIT(0x0040);
776b8bf04e1SBen Skeggs 	for (i = 0; i < 4; i++)
777b8bf04e1SBen Skeggs 		NV_WRITE_PIPE_INIT(0x00000000);
778b8bf04e1SBen Skeggs 	PIPE_INIT_END(0x0040);
779b8bf04e1SBen Skeggs 
780b8bf04e1SBen Skeggs #undef PIPE_INIT
781b8bf04e1SBen Skeggs #undef PIPE_INIT_END
782b8bf04e1SBen Skeggs #undef NV_WRITE_PIPE_INIT
783b8bf04e1SBen Skeggs }
784b8bf04e1SBen Skeggs 
785b8bf04e1SBen Skeggs static int
nv10_gr_ctx_regs_find_offset(struct nv10_gr * gr,int reg)786bfee3f3dSBen Skeggs nv10_gr_ctx_regs_find_offset(struct nv10_gr *gr, int reg)
787b8bf04e1SBen Skeggs {
788109c2f2fSBen Skeggs 	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
789b8bf04e1SBen Skeggs 	int i;
790b8bf04e1SBen Skeggs 	for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++) {
791b8bf04e1SBen Skeggs 		if (nv10_gr_ctx_regs[i] == reg)
792b8bf04e1SBen Skeggs 			return i;
793b8bf04e1SBen Skeggs 	}
794f377ea88SLinus Torvalds 	nvkm_error(subdev, "unknown offset nv10_ctx_regs %d\n", reg);
795b8bf04e1SBen Skeggs 	return -1;
796b8bf04e1SBen Skeggs }
797b8bf04e1SBen Skeggs 
798b8bf04e1SBen Skeggs static int
nv17_gr_ctx_regs_find_offset(struct nv10_gr * gr,int reg)799bfee3f3dSBen Skeggs nv17_gr_ctx_regs_find_offset(struct nv10_gr *gr, int reg)
800b8bf04e1SBen Skeggs {
801109c2f2fSBen Skeggs 	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
802b8bf04e1SBen Skeggs 	int i;
803b8bf04e1SBen Skeggs 	for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++) {
804b8bf04e1SBen Skeggs 		if (nv17_gr_ctx_regs[i] == reg)
805b8bf04e1SBen Skeggs 			return i;
806b8bf04e1SBen Skeggs 	}
807f377ea88SLinus Torvalds 	nvkm_error(subdev, "unknown offset nv17_ctx_regs %d\n", reg);
808b8bf04e1SBen Skeggs 	return -1;
809b8bf04e1SBen Skeggs }
810b8bf04e1SBen Skeggs 
811b8bf04e1SBen Skeggs static void
nv10_gr_load_dma_vtxbuf(struct nv10_gr_chan * chan,int chid,u32 inst)812b8bf04e1SBen Skeggs nv10_gr_load_dma_vtxbuf(struct nv10_gr_chan *chan, int chid, u32 inst)
813b8bf04e1SBen Skeggs {
81427f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
815276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
816b8bf04e1SBen Skeggs 	u32 st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
817b8bf04e1SBen Skeggs 	u32 ctx_user, ctx_switch[5];
818b8bf04e1SBen Skeggs 	int i, subchan = -1;
819b8bf04e1SBen Skeggs 
820b8bf04e1SBen Skeggs 	/* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
821b8bf04e1SBen Skeggs 	 * that cannot be restored via MMIO. Do it through the FIFO
822b8bf04e1SBen Skeggs 	 * instead.
823b8bf04e1SBen Skeggs 	 */
824b8bf04e1SBen Skeggs 
825b8bf04e1SBen Skeggs 	/* Look for a celsius object */
826b8bf04e1SBen Skeggs 	for (i = 0; i < 8; i++) {
827276836d4SBen Skeggs 		int class = nvkm_rd32(device, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
828b8bf04e1SBen Skeggs 
829b8bf04e1SBen Skeggs 		if (class == 0x56 || class == 0x96 || class == 0x99) {
830b8bf04e1SBen Skeggs 			subchan = i;
831b8bf04e1SBen Skeggs 			break;
832b8bf04e1SBen Skeggs 		}
833b8bf04e1SBen Skeggs 	}
834b8bf04e1SBen Skeggs 
835b8bf04e1SBen Skeggs 	if (subchan < 0 || !inst)
836b8bf04e1SBen Skeggs 		return;
837b8bf04e1SBen Skeggs 
838b8bf04e1SBen Skeggs 	/* Save the current ctx object */
839276836d4SBen Skeggs 	ctx_user = nvkm_rd32(device, NV10_PGRAPH_CTX_USER);
840b8bf04e1SBen Skeggs 	for (i = 0; i < 5; i++)
841276836d4SBen Skeggs 		ctx_switch[i] = nvkm_rd32(device, NV10_PGRAPH_CTX_SWITCH(i));
842b8bf04e1SBen Skeggs 
843b8bf04e1SBen Skeggs 	/* Save the FIFO state */
844276836d4SBen Skeggs 	st2 = nvkm_rd32(device, NV10_PGRAPH_FFINTFC_ST2);
845276836d4SBen Skeggs 	st2_dl = nvkm_rd32(device, NV10_PGRAPH_FFINTFC_ST2_DL);
846276836d4SBen Skeggs 	st2_dh = nvkm_rd32(device, NV10_PGRAPH_FFINTFC_ST2_DH);
847276836d4SBen Skeggs 	fifo_ptr = nvkm_rd32(device, NV10_PGRAPH_FFINTFC_FIFO_PTR);
848b8bf04e1SBen Skeggs 
849b8bf04e1SBen Skeggs 	for (i = 0; i < ARRAY_SIZE(fifo); i++)
850276836d4SBen Skeggs 		fifo[i] = nvkm_rd32(device, 0x4007a0 + 4 * i);
851b8bf04e1SBen Skeggs 
852b8bf04e1SBen Skeggs 	/* Switch to the celsius subchannel */
853b8bf04e1SBen Skeggs 	for (i = 0; i < 5; i++)
854276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(i),
855276836d4SBen Skeggs 			nvkm_rd32(device, NV10_PGRAPH_CTX_CACHE(subchan, i)));
856276836d4SBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
857b8bf04e1SBen Skeggs 
858b8bf04e1SBen Skeggs 	/* Inject NV10TCL_DMA_VTXBUF */
859276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
860276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_ST2,
861b8bf04e1SBen Skeggs 		0x2c000000 | chid << 20 | subchan << 16 | 0x18c);
862276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
863276836d4SBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
864276836d4SBen Skeggs 	nvkm_mask(device, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
865276836d4SBen Skeggs 	nvkm_mask(device, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
866b8bf04e1SBen Skeggs 
867b8bf04e1SBen Skeggs 	/* Restore the FIFO state */
868b8bf04e1SBen Skeggs 	for (i = 0; i < ARRAY_SIZE(fifo); i++)
869276836d4SBen Skeggs 		nvkm_wr32(device, 0x4007a0 + 4 * i, fifo[i]);
870b8bf04e1SBen Skeggs 
871276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
872276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_ST2, st2);
873276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
874276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
875b8bf04e1SBen Skeggs 
876b8bf04e1SBen Skeggs 	/* Restore the current ctx object */
877b8bf04e1SBen Skeggs 	for (i = 0; i < 5; i++)
878276836d4SBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
879276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_USER, ctx_user);
880b8bf04e1SBen Skeggs }
881b8bf04e1SBen Skeggs 
882b8bf04e1SBen Skeggs static int
nv10_gr_load_context(struct nv10_gr_chan * chan,int chid)883b8bf04e1SBen Skeggs nv10_gr_load_context(struct nv10_gr_chan *chan, int chid)
884b8bf04e1SBen Skeggs {
88527f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
886276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
887b8bf04e1SBen Skeggs 	u32 inst;
888b8bf04e1SBen Skeggs 	int i;
889b8bf04e1SBen Skeggs 
890b8bf04e1SBen Skeggs 	for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
891276836d4SBen Skeggs 		nvkm_wr32(device, nv10_gr_ctx_regs[i], chan->nv10[i]);
892b8bf04e1SBen Skeggs 
893c85ee6caSBen Skeggs 	if (device->card_type >= NV_11 && device->chipset >= 0x17) {
894b8bf04e1SBen Skeggs 		for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
895276836d4SBen Skeggs 			nvkm_wr32(device, nv17_gr_ctx_regs[i], chan->nv17[i]);
896b8bf04e1SBen Skeggs 	}
897b8bf04e1SBen Skeggs 
898b8bf04e1SBen Skeggs 	nv10_gr_load_pipe(chan);
899b8bf04e1SBen Skeggs 
900276836d4SBen Skeggs 	inst = nvkm_rd32(device, NV10_PGRAPH_GLOBALSTATE1) & 0xffff;
901b8bf04e1SBen Skeggs 	nv10_gr_load_dma_vtxbuf(chan, chid, inst);
902b8bf04e1SBen Skeggs 
903276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
904276836d4SBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_CTX_USER, 0xff000000, chid << 24);
905276836d4SBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_FFINTFC_ST2, 0x30000000, 0x00000000);
906b8bf04e1SBen Skeggs 	return 0;
907b8bf04e1SBen Skeggs }
908b8bf04e1SBen Skeggs 
909b8bf04e1SBen Skeggs static int
nv10_gr_unload_context(struct nv10_gr_chan * chan)910b8bf04e1SBen Skeggs nv10_gr_unload_context(struct nv10_gr_chan *chan)
911b8bf04e1SBen Skeggs {
91227f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
913276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
914b8bf04e1SBen Skeggs 	int i;
915b8bf04e1SBen Skeggs 
916b8bf04e1SBen Skeggs 	for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
917276836d4SBen Skeggs 		chan->nv10[i] = nvkm_rd32(device, nv10_gr_ctx_regs[i]);
918b8bf04e1SBen Skeggs 
919c85ee6caSBen Skeggs 	if (device->card_type >= NV_11 && device->chipset >= 0x17) {
920b8bf04e1SBen Skeggs 		for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
921276836d4SBen Skeggs 			chan->nv17[i] = nvkm_rd32(device, nv17_gr_ctx_regs[i]);
922b8bf04e1SBen Skeggs 	}
923b8bf04e1SBen Skeggs 
924b8bf04e1SBen Skeggs 	nv10_gr_save_pipe(chan);
925b8bf04e1SBen Skeggs 
926276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
927276836d4SBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
928b8bf04e1SBen Skeggs 	return 0;
929b8bf04e1SBen Skeggs }
930b8bf04e1SBen Skeggs 
931b8bf04e1SBen Skeggs static void
nv10_gr_context_switch(struct nv10_gr * gr)932bfee3f3dSBen Skeggs nv10_gr_context_switch(struct nv10_gr *gr)
933b8bf04e1SBen Skeggs {
934276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
935b8bf04e1SBen Skeggs 	struct nv10_gr_chan *prev = NULL;
936b8bf04e1SBen Skeggs 	struct nv10_gr_chan *next = NULL;
937b8bf04e1SBen Skeggs 	int chid;
938b8bf04e1SBen Skeggs 
93927f3d6cfSBen Skeggs 	nv04_gr_idle(&gr->base);
940b8bf04e1SBen Skeggs 
941b8bf04e1SBen Skeggs 	/* If previous context is valid, we need to save it */
942bfee3f3dSBen Skeggs 	prev = nv10_gr_channel(gr);
943b8bf04e1SBen Skeggs 	if (prev)
944b8bf04e1SBen Skeggs 		nv10_gr_unload_context(prev);
945b8bf04e1SBen Skeggs 
946b8bf04e1SBen Skeggs 	/* load context for next channel */
947276836d4SBen Skeggs 	chid = (nvkm_rd32(device, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
948bfee3f3dSBen Skeggs 	next = gr->chan[chid];
949b8bf04e1SBen Skeggs 	if (next)
950b8bf04e1SBen Skeggs 		nv10_gr_load_context(next, chid);
951b8bf04e1SBen Skeggs }
952b8bf04e1SBen Skeggs 
95327f3d6cfSBen Skeggs static int
nv10_gr_chan_fini(struct nvkm_object * object,bool suspend)95427f3d6cfSBen Skeggs nv10_gr_chan_fini(struct nvkm_object *object, bool suspend)
95527f3d6cfSBen Skeggs {
95627f3d6cfSBen Skeggs 	struct nv10_gr_chan *chan = nv10_gr_chan(object);
95727f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
95827f3d6cfSBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
95927f3d6cfSBen Skeggs 	unsigned long flags;
96027f3d6cfSBen Skeggs 
96127f3d6cfSBen Skeggs 	spin_lock_irqsave(&gr->lock, flags);
96227f3d6cfSBen Skeggs 	nvkm_mask(device, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
96327f3d6cfSBen Skeggs 	if (nv10_gr_channel(gr) == chan)
96427f3d6cfSBen Skeggs 		nv10_gr_unload_context(chan);
96527f3d6cfSBen Skeggs 	nvkm_mask(device, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
96627f3d6cfSBen Skeggs 	spin_unlock_irqrestore(&gr->lock, flags);
96727f3d6cfSBen Skeggs 	return 0;
96827f3d6cfSBen Skeggs }
96927f3d6cfSBen Skeggs 
97027f3d6cfSBen Skeggs static void *
nv10_gr_chan_dtor(struct nvkm_object * object)97127f3d6cfSBen Skeggs nv10_gr_chan_dtor(struct nvkm_object *object)
97227f3d6cfSBen Skeggs {
97327f3d6cfSBen Skeggs 	struct nv10_gr_chan *chan = nv10_gr_chan(object);
97427f3d6cfSBen Skeggs 	struct nv10_gr *gr = chan->gr;
97527f3d6cfSBen Skeggs 	unsigned long flags;
97627f3d6cfSBen Skeggs 
97727f3d6cfSBen Skeggs 	spin_lock_irqsave(&gr->lock, flags);
97827f3d6cfSBen Skeggs 	gr->chan[chan->chid] = NULL;
97927f3d6cfSBen Skeggs 	spin_unlock_irqrestore(&gr->lock, flags);
98027f3d6cfSBen Skeggs 	return chan;
98127f3d6cfSBen Skeggs }
98227f3d6cfSBen Skeggs 
98327f3d6cfSBen Skeggs static const struct nvkm_object_func
98427f3d6cfSBen Skeggs nv10_gr_chan = {
98527f3d6cfSBen Skeggs 	.dtor = nv10_gr_chan_dtor,
98627f3d6cfSBen Skeggs 	.fini = nv10_gr_chan_fini,
98727f3d6cfSBen Skeggs };
98827f3d6cfSBen Skeggs 
989b8bf04e1SBen Skeggs #define NV_WRITE_CTX(reg, val) do { \
990bfee3f3dSBen Skeggs 	int offset = nv10_gr_ctx_regs_find_offset(gr, reg); \
991b8bf04e1SBen Skeggs 	if (offset > 0) \
992b8bf04e1SBen Skeggs 		chan->nv10[offset] = val; \
993b8bf04e1SBen Skeggs 	} while (0)
994b8bf04e1SBen Skeggs 
995b8bf04e1SBen Skeggs #define NV17_WRITE_CTX(reg, val) do { \
996bfee3f3dSBen Skeggs 	int offset = nv17_gr_ctx_regs_find_offset(gr, reg); \
997b8bf04e1SBen Skeggs 	if (offset > 0) \
998b8bf04e1SBen Skeggs 		chan->nv17[offset] = val; \
999b8bf04e1SBen Skeggs 	} while (0)
1000b8bf04e1SBen Skeggs 
1001c85ee6caSBen Skeggs int
nv10_gr_chan_new(struct nvkm_gr * base,struct nvkm_chan * fifoch,const struct nvkm_oclass * oclass,struct nvkm_object ** pobject)1002*c546656fSBen Skeggs nv10_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch,
100327f3d6cfSBen Skeggs 		 const struct nvkm_oclass *oclass, struct nvkm_object **pobject)
1004b8bf04e1SBen Skeggs {
100527f3d6cfSBen Skeggs 	struct nv10_gr *gr = nv10_gr(base);
1006b8bf04e1SBen Skeggs 	struct nv10_gr_chan *chan;
1007276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
1008b8bf04e1SBen Skeggs 	unsigned long flags;
1009b8bf04e1SBen Skeggs 
101027f3d6cfSBen Skeggs 	if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
101127f3d6cfSBen Skeggs 		return -ENOMEM;
101227f3d6cfSBen Skeggs 	nvkm_object_ctor(&nv10_gr_chan, oclass, &chan->object);
101327f3d6cfSBen Skeggs 	chan->gr = gr;
1014c358f538SBen Skeggs 	chan->chid = fifoch->id;
101527f3d6cfSBen Skeggs 	*pobject = &chan->object;
1016b8bf04e1SBen Skeggs 
1017b8bf04e1SBen Skeggs 	NV_WRITE_CTX(0x00400e88, 0x08000000);
1018b8bf04e1SBen Skeggs 	NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
1019b8bf04e1SBen Skeggs 	NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
1020b8bf04e1SBen Skeggs 	NV_WRITE_CTX(0x00400e10, 0x00001000);
1021b8bf04e1SBen Skeggs 	NV_WRITE_CTX(0x00400e14, 0x00001000);
1022b8bf04e1SBen Skeggs 	NV_WRITE_CTX(0x00400e30, 0x00080008);
1023b8bf04e1SBen Skeggs 	NV_WRITE_CTX(0x00400e34, 0x00080008);
102427f3d6cfSBen Skeggs 	if (device->card_type >= NV_11 && device->chipset >= 0x17) {
1025b8bf04e1SBen Skeggs 		/* is it really needed ??? */
1026b8bf04e1SBen Skeggs 		NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
1027276836d4SBen Skeggs 			       nvkm_rd32(device, NV10_PGRAPH_DEBUG_4));
1028276836d4SBen Skeggs 		NV17_WRITE_CTX(0x004006b0, nvkm_rd32(device, 0x004006b0));
1029b8bf04e1SBen Skeggs 		NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
1030b8bf04e1SBen Skeggs 		NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
1031b8bf04e1SBen Skeggs 		NV17_WRITE_CTX(0x00400ec0, 0x00000080);
1032b8bf04e1SBen Skeggs 		NV17_WRITE_CTX(0x00400ed0, 0x00000080);
1033b8bf04e1SBen Skeggs 	}
1034b8bf04e1SBen Skeggs 	NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->chid << 24);
1035b8bf04e1SBen Skeggs 
1036b8bf04e1SBen Skeggs 	nv10_gr_create_pipe(chan);
1037b8bf04e1SBen Skeggs 
103827f3d6cfSBen Skeggs 	spin_lock_irqsave(&gr->lock, flags);
103927f3d6cfSBen Skeggs 	gr->chan[chan->chid] = chan;
1040bfee3f3dSBen Skeggs 	spin_unlock_irqrestore(&gr->lock, flags);
1041b8bf04e1SBen Skeggs 	return 0;
1042b8bf04e1SBen Skeggs }
1043b8bf04e1SBen Skeggs 
1044b8bf04e1SBen Skeggs /*******************************************************************************
1045b8bf04e1SBen Skeggs  * PGRAPH engine/subdev functions
1046b8bf04e1SBen Skeggs  ******************************************************************************/
1047b8bf04e1SBen Skeggs 
1048c85ee6caSBen Skeggs void
nv10_gr_tile(struct nvkm_gr * base,int i,struct nvkm_fb_tile * tile)1049c85ee6caSBen Skeggs nv10_gr_tile(struct nvkm_gr *base, int i, struct nvkm_fb_tile *tile)
1050b8bf04e1SBen Skeggs {
1051c85ee6caSBen Skeggs 	struct nv10_gr *gr = nv10_gr(base);
1052276836d4SBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
1053276836d4SBen Skeggs 	struct nvkm_fifo *fifo = device->fifo;
1054b8bf04e1SBen Skeggs 	unsigned long flags;
1055b8bf04e1SBen Skeggs 
105613de7f46SBen Skeggs 	nvkm_fifo_pause(fifo, &flags);
105727f3d6cfSBen Skeggs 	nv04_gr_idle(&gr->base);
1058b8bf04e1SBen Skeggs 
1059276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_TLIMIT(i), tile->limit);
1060276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_TSIZE(i), tile->pitch);
1061276836d4SBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_TILE(i), tile->addr);
1062b8bf04e1SBen Skeggs 
106313de7f46SBen Skeggs 	nvkm_fifo_start(fifo, &flags);
1064b8bf04e1SBen Skeggs }
1065b8bf04e1SBen Skeggs 
1066e3c71eb2SBen Skeggs const struct nvkm_bitfield nv10_gr_intr_name[] = {
1067b8bf04e1SBen Skeggs 	{ NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
1068b8bf04e1SBen Skeggs 	{ NV_PGRAPH_INTR_ERROR,  "ERROR"  },
1069b8bf04e1SBen Skeggs 	{}
1070b8bf04e1SBen Skeggs };
1071b8bf04e1SBen Skeggs 
1072e3c71eb2SBen Skeggs const struct nvkm_bitfield nv10_gr_nstatus[] = {
1073b8bf04e1SBen Skeggs 	{ NV10_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
1074b8bf04e1SBen Skeggs 	{ NV10_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
1075b8bf04e1SBen Skeggs 	{ NV10_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
1076b8bf04e1SBen Skeggs 	{ NV10_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" },
1077b8bf04e1SBen Skeggs 	{}
1078b8bf04e1SBen Skeggs };
1079b8bf04e1SBen Skeggs 
1080c85ee6caSBen Skeggs void
nv10_gr_intr(struct nvkm_gr * base)1081c85ee6caSBen Skeggs nv10_gr_intr(struct nvkm_gr *base)
1082b8bf04e1SBen Skeggs {
1083c85ee6caSBen Skeggs 	struct nv10_gr *gr = nv10_gr(base);
1084c85ee6caSBen Skeggs 	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
1085c85ee6caSBen Skeggs 	struct nvkm_device *device = subdev->device;
1086276836d4SBen Skeggs 	u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
1087276836d4SBen Skeggs 	u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
1088276836d4SBen Skeggs 	u32 nstatus = nvkm_rd32(device, NV03_PGRAPH_NSTATUS);
1089276836d4SBen Skeggs 	u32 addr = nvkm_rd32(device, NV04_PGRAPH_TRAPPED_ADDR);
1090b8bf04e1SBen Skeggs 	u32 chid = (addr & 0x01f00000) >> 20;
1091b8bf04e1SBen Skeggs 	u32 subc = (addr & 0x00070000) >> 16;
1092b8bf04e1SBen Skeggs 	u32 mthd = (addr & 0x00001ffc);
1093276836d4SBen Skeggs 	u32 data = nvkm_rd32(device, NV04_PGRAPH_TRAPPED_DATA);
1094276836d4SBen Skeggs 	u32 class = nvkm_rd32(device, 0x400160 + subc * 4) & 0xfff;
1095b8bf04e1SBen Skeggs 	u32 show = stat;
1096109c2f2fSBen Skeggs 	char msg[128], src[128], sta[128];
1097c85ee6caSBen Skeggs 	struct nv10_gr_chan *chan;
1098b8bf04e1SBen Skeggs 	unsigned long flags;
1099b8bf04e1SBen Skeggs 
1100bfee3f3dSBen Skeggs 	spin_lock_irqsave(&gr->lock, flags);
1101bfee3f3dSBen Skeggs 	chan = gr->chan[chid];
1102b8bf04e1SBen Skeggs 
1103b8bf04e1SBen Skeggs 	if (stat & NV_PGRAPH_INTR_ERROR) {
1104b8bf04e1SBen Skeggs 		if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
1105a65955e1SBen Skeggs 			if (!nv10_gr_mthd(chan, class, mthd, data))
1106b8bf04e1SBen Skeggs 				show &= ~NV_PGRAPH_INTR_ERROR;
1107b8bf04e1SBen Skeggs 		}
1108b8bf04e1SBen Skeggs 	}
1109b8bf04e1SBen Skeggs 
1110b8bf04e1SBen Skeggs 	if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1111276836d4SBen Skeggs 		nvkm_wr32(device, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1112b8bf04e1SBen Skeggs 		stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1113b8bf04e1SBen Skeggs 		show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1114bfee3f3dSBen Skeggs 		nv10_gr_context_switch(gr);
1115b8bf04e1SBen Skeggs 	}
1116b8bf04e1SBen Skeggs 
1117276836d4SBen Skeggs 	nvkm_wr32(device, NV03_PGRAPH_INTR, stat);
1118276836d4SBen Skeggs 	nvkm_wr32(device, NV04_PGRAPH_FIFO, 0x00000001);
1119b8bf04e1SBen Skeggs 
1120b8bf04e1SBen Skeggs 	if (show) {
1121109c2f2fSBen Skeggs 		nvkm_snprintbf(msg, sizeof(msg), nv10_gr_intr_name, show);
1122109c2f2fSBen Skeggs 		nvkm_snprintbf(src, sizeof(src), nv04_gr_nsource, nsource);
1123109c2f2fSBen Skeggs 		nvkm_snprintbf(sta, sizeof(sta), nv10_gr_nstatus, nstatus);
1124109c2f2fSBen Skeggs 		nvkm_error(subdev, "intr %08x [%s] nsource %08x [%s] "
1125109c2f2fSBen Skeggs 				   "nstatus %08x [%s] ch %d [%s] subc %d "
1126109c2f2fSBen Skeggs 				   "class %04x mthd %04x data %08x\n",
1127109c2f2fSBen Skeggs 			   show, msg, nsource, src, nstatus, sta, chid,
112827f3d6cfSBen Skeggs 			   chan ? chan->object.client->name : "unknown",
112927f3d6cfSBen Skeggs 			   subc, class, mthd, data);
1130b8bf04e1SBen Skeggs 	}
1131b8bf04e1SBen Skeggs 
1132a65955e1SBen Skeggs 	spin_unlock_irqrestore(&gr->lock, flags);
1133b8bf04e1SBen Skeggs }
1134b8bf04e1SBen Skeggs 
1135c85ee6caSBen Skeggs int
nv10_gr_init(struct nvkm_gr * base)1136c85ee6caSBen Skeggs nv10_gr_init(struct nvkm_gr *base)
1137b8bf04e1SBen Skeggs {
1138c85ee6caSBen Skeggs 	struct nv10_gr *gr = nv10_gr(base);
1139c85ee6caSBen Skeggs 	struct nvkm_device *device = gr->base.engine.subdev.device;
1140b8bf04e1SBen Skeggs 
1141c85ee6caSBen Skeggs 	nvkm_wr32(device, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
1142c85ee6caSBen Skeggs 	nvkm_wr32(device, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
1143b8bf04e1SBen Skeggs 
1144c85ee6caSBen Skeggs 	nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
1145c85ee6caSBen Skeggs 	nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x00000000);
1146c85ee6caSBen Skeggs 	nvkm_wr32(device, NV04_PGRAPH_DEBUG_1, 0x00118700);
1147c85ee6caSBen Skeggs 	/* nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
1148c85ee6caSBen Skeggs 	nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
1149c85ee6caSBen Skeggs 	nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31));
1150b8bf04e1SBen Skeggs 
1151c85ee6caSBen Skeggs 	if (device->card_type >= NV_11 && device->chipset >= 0x17) {
1152c85ee6caSBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x1f000000);
1153c85ee6caSBen Skeggs 		nvkm_wr32(device, 0x400a10, 0x03ff3fb6);
1154c85ee6caSBen Skeggs 		nvkm_wr32(device, 0x400838, 0x002f8684);
1155c85ee6caSBen Skeggs 		nvkm_wr32(device, 0x40083c, 0x00115f3f);
1156c85ee6caSBen Skeggs 		nvkm_wr32(device, 0x4006b0, 0x40000020);
1157b8bf04e1SBen Skeggs 	} else {
1158c85ee6caSBen Skeggs 		nvkm_wr32(device, NV10_PGRAPH_DEBUG_4, 0x00000000);
1159b8bf04e1SBen Skeggs 	}
1160b8bf04e1SBen Skeggs 
1161c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
1162c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
1163c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
1164c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
1165c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
1166c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_STATE, 0xFFFFFFFF);
1167b8bf04e1SBen Skeggs 
1168c85ee6caSBen Skeggs 	nvkm_mask(device, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
1169c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
1170c85ee6caSBen Skeggs 	nvkm_wr32(device, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
1171b8bf04e1SBen Skeggs 	return 0;
1172b8bf04e1SBen Skeggs }
1173b8bf04e1SBen Skeggs 
1174c85ee6caSBen Skeggs int
nv10_gr_new_(const struct nvkm_gr_func * func,struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_gr ** pgr)1175c85ee6caSBen Skeggs nv10_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
1176864d37c3SBen Skeggs 	     enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr)
1177b8bf04e1SBen Skeggs {
1178c85ee6caSBen Skeggs 	struct nv10_gr *gr;
1179c85ee6caSBen Skeggs 
1180c85ee6caSBen Skeggs 	if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
1181c85ee6caSBen Skeggs 		return -ENOMEM;
1182c85ee6caSBen Skeggs 	spin_lock_init(&gr->lock);
1183c85ee6caSBen Skeggs 	*pgr = &gr->base;
1184c85ee6caSBen Skeggs 
1185864d37c3SBen Skeggs 	return nvkm_gr_ctor(func, device, type, inst, true, &gr->base);
1186b8bf04e1SBen Skeggs }
1187b8bf04e1SBen Skeggs 
118827f3d6cfSBen Skeggs static const struct nvkm_gr_func
118927f3d6cfSBen Skeggs nv10_gr = {
1190b8bf04e1SBen Skeggs 	.init = nv10_gr_init,
1191c85ee6caSBen Skeggs 	.intr = nv10_gr_intr,
1192c85ee6caSBen Skeggs 	.tile = nv10_gr_tile,
119327f3d6cfSBen Skeggs 	.chan_new = nv10_gr_chan_new,
119427f3d6cfSBen Skeggs 	.sclass = {
119527f3d6cfSBen Skeggs 		{ -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */
119627f3d6cfSBen Skeggs 		{ -1, -1, 0x0019, &nv04_gr_object }, /* clip */
119727f3d6cfSBen Skeggs 		{ -1, -1, 0x0030, &nv04_gr_object }, /* null */
119827f3d6cfSBen Skeggs 		{ -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */
119927f3d6cfSBen Skeggs 		{ -1, -1, 0x0043, &nv04_gr_object }, /* rop */
120027f3d6cfSBen Skeggs 		{ -1, -1, 0x0044, &nv04_gr_object }, /* pattern */
120127f3d6cfSBen Skeggs 		{ -1, -1, 0x004a, &nv04_gr_object }, /* gdi */
120227f3d6cfSBen Skeggs 		{ -1, -1, 0x0052, &nv04_gr_object }, /* swzsurf */
120327f3d6cfSBen Skeggs 		{ -1, -1, 0x005f, &nv04_gr_object }, /* blit */
120427f3d6cfSBen Skeggs 		{ -1, -1, 0x0062, &nv04_gr_object }, /* surf2d */
120527f3d6cfSBen Skeggs 		{ -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */
120627f3d6cfSBen Skeggs 		{ -1, -1, 0x0089, &nv04_gr_object }, /* sifm */
120727f3d6cfSBen Skeggs 		{ -1, -1, 0x008a, &nv04_gr_object }, /* ifc */
120827f3d6cfSBen Skeggs 		{ -1, -1, 0x009f, &nv04_gr_object }, /* blit */
120927f3d6cfSBen Skeggs 		{ -1, -1, 0x0093, &nv04_gr_object }, /* surf3d */
121027f3d6cfSBen Skeggs 		{ -1, -1, 0x0094, &nv04_gr_object }, /* ttri */
121127f3d6cfSBen Skeggs 		{ -1, -1, 0x0095, &nv04_gr_object }, /* mtri */
121227f3d6cfSBen Skeggs 		{ -1, -1, 0x0056, &nv04_gr_object }, /* celcius */
121327f3d6cfSBen Skeggs 		{}
121427f3d6cfSBen Skeggs 	}
1215b8bf04e1SBen Skeggs };
121627f3d6cfSBen Skeggs 
1217c85ee6caSBen Skeggs int
nv10_gr_new(struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_gr ** pgr)1218864d37c3SBen Skeggs nv10_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr)
1219b8bf04e1SBen Skeggs {
1220864d37c3SBen Skeggs 	return nv10_gr_new_(&nv10_gr, device, type, inst, pgr);
1221b8bf04e1SBen Skeggs }
1222