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