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