blob: 2614510c28d0da467600c8ceeff86d7218b39a32 [file] [log] [blame]
Ben Skeggs6ee73862009-12-11 19:24:15 +10001/*
2 * Copyright 2007 Stephane Marchesin
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
Ben Skeggsb8bf04e2015-01-14 12:02:28 +100013 * paragr) shall be included in all copies or substantial portions of the
Ben Skeggs6ee73862009-12-11 19:24:15 +100014 * 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 */
Ben Skeggse3c71eb2015-01-14 15:29:43 +100024#include <engine/gr.h>
25#include "regs.h"
Ben Skeggs6ee73862009-12-11 19:24:15 +100026
Marcin Slusarz93260d32012-12-09 23:00:34 +010027#include <core/client.h>
Ben Skeggs9e79a852015-01-14 15:12:11 +100028#include <core/device.h>
Ben Skeggsebb945a2012-07-20 08:17:34 +100029#include <core/handle.h>
Ben Skeggse3c71eb2015-01-14 15:29:43 +100030#include <engine/fifo.h>
Ben Skeggsebb945a2012-07-20 08:17:34 +100031#include <subdev/instmem.h>
32#include <subdev/timer.h>
Ben Skeggsb8c157d2010-10-20 10:39:35 +100033
Ben Skeggsebb945a2012-07-20 08:17:34 +100034static u32
Ben Skeggsb8bf04e2015-01-14 12:02:28 +100035nv04_gr_ctx_regs[] = {
Francisco Jerezea911a12009-12-26 14:39:46 +010036 0x0040053c,
37 0x00400544,
38 0x00400540,
39 0x00400548,
Ben Skeggs6ee73862009-12-11 19:24:15 +100040 NV04_PGRAPH_CTX_SWITCH1,
41 NV04_PGRAPH_CTX_SWITCH2,
42 NV04_PGRAPH_CTX_SWITCH3,
43 NV04_PGRAPH_CTX_SWITCH4,
44 NV04_PGRAPH_CTX_CACHE1,
45 NV04_PGRAPH_CTX_CACHE2,
46 NV04_PGRAPH_CTX_CACHE3,
47 NV04_PGRAPH_CTX_CACHE4,
48 0x00400184,
49 0x004001a4,
50 0x004001c4,
51 0x004001e4,
52 0x00400188,
53 0x004001a8,
54 0x004001c8,
55 0x004001e8,
56 0x0040018c,
57 0x004001ac,
58 0x004001cc,
59 0x004001ec,
60 0x00400190,
61 0x004001b0,
62 0x004001d0,
63 0x004001f0,
64 0x00400194,
65 0x004001b4,
66 0x004001d4,
67 0x004001f4,
68 0x00400198,
69 0x004001b8,
70 0x004001d8,
71 0x004001f8,
72 0x0040019c,
73 0x004001bc,
74 0x004001dc,
75 0x004001fc,
76 0x00400174,
77 NV04_PGRAPH_DMA_START_0,
78 NV04_PGRAPH_DMA_START_1,
79 NV04_PGRAPH_DMA_LENGTH,
80 NV04_PGRAPH_DMA_MISC,
81 NV04_PGRAPH_DMA_PITCH,
82 NV04_PGRAPH_BOFFSET0,
83 NV04_PGRAPH_BBASE0,
84 NV04_PGRAPH_BLIMIT0,
85 NV04_PGRAPH_BOFFSET1,
86 NV04_PGRAPH_BBASE1,
87 NV04_PGRAPH_BLIMIT1,
88 NV04_PGRAPH_BOFFSET2,
89 NV04_PGRAPH_BBASE2,
90 NV04_PGRAPH_BLIMIT2,
91 NV04_PGRAPH_BOFFSET3,
92 NV04_PGRAPH_BBASE3,
93 NV04_PGRAPH_BLIMIT3,
94 NV04_PGRAPH_BOFFSET4,
95 NV04_PGRAPH_BBASE4,
96 NV04_PGRAPH_BLIMIT4,
97 NV04_PGRAPH_BOFFSET5,
98 NV04_PGRAPH_BBASE5,
99 NV04_PGRAPH_BLIMIT5,
100 NV04_PGRAPH_BPITCH0,
101 NV04_PGRAPH_BPITCH1,
102 NV04_PGRAPH_BPITCH2,
103 NV04_PGRAPH_BPITCH3,
104 NV04_PGRAPH_BPITCH4,
105 NV04_PGRAPH_SURFACE,
106 NV04_PGRAPH_STATE,
107 NV04_PGRAPH_BSWIZZLE2,
108 NV04_PGRAPH_BSWIZZLE5,
109 NV04_PGRAPH_BPIXEL,
110 NV04_PGRAPH_NOTIFY,
111 NV04_PGRAPH_PATT_COLOR0,
112 NV04_PGRAPH_PATT_COLOR1,
113 NV04_PGRAPH_PATT_COLORRAM+0x00,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000114 NV04_PGRAPH_PATT_COLORRAM+0x04,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000115 NV04_PGRAPH_PATT_COLORRAM+0x08,
Francisco Jerezea911a12009-12-26 14:39:46 +0100116 NV04_PGRAPH_PATT_COLORRAM+0x0c,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000117 NV04_PGRAPH_PATT_COLORRAM+0x10,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000118 NV04_PGRAPH_PATT_COLORRAM+0x14,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000119 NV04_PGRAPH_PATT_COLORRAM+0x18,
Francisco Jerezea911a12009-12-26 14:39:46 +0100120 NV04_PGRAPH_PATT_COLORRAM+0x1c,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000121 NV04_PGRAPH_PATT_COLORRAM+0x20,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000122 NV04_PGRAPH_PATT_COLORRAM+0x24,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000123 NV04_PGRAPH_PATT_COLORRAM+0x28,
Francisco Jerezea911a12009-12-26 14:39:46 +0100124 NV04_PGRAPH_PATT_COLORRAM+0x2c,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000125 NV04_PGRAPH_PATT_COLORRAM+0x30,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000126 NV04_PGRAPH_PATT_COLORRAM+0x34,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000127 NV04_PGRAPH_PATT_COLORRAM+0x38,
Francisco Jerezea911a12009-12-26 14:39:46 +0100128 NV04_PGRAPH_PATT_COLORRAM+0x3c,
129 NV04_PGRAPH_PATT_COLORRAM+0x40,
130 NV04_PGRAPH_PATT_COLORRAM+0x44,
131 NV04_PGRAPH_PATT_COLORRAM+0x48,
132 NV04_PGRAPH_PATT_COLORRAM+0x4c,
133 NV04_PGRAPH_PATT_COLORRAM+0x50,
134 NV04_PGRAPH_PATT_COLORRAM+0x54,
135 NV04_PGRAPH_PATT_COLORRAM+0x58,
136 NV04_PGRAPH_PATT_COLORRAM+0x5c,
137 NV04_PGRAPH_PATT_COLORRAM+0x60,
138 NV04_PGRAPH_PATT_COLORRAM+0x64,
139 NV04_PGRAPH_PATT_COLORRAM+0x68,
140 NV04_PGRAPH_PATT_COLORRAM+0x6c,
141 NV04_PGRAPH_PATT_COLORRAM+0x70,
142 NV04_PGRAPH_PATT_COLORRAM+0x74,
143 NV04_PGRAPH_PATT_COLORRAM+0x78,
144 NV04_PGRAPH_PATT_COLORRAM+0x7c,
145 NV04_PGRAPH_PATT_COLORRAM+0x80,
146 NV04_PGRAPH_PATT_COLORRAM+0x84,
147 NV04_PGRAPH_PATT_COLORRAM+0x88,
148 NV04_PGRAPH_PATT_COLORRAM+0x8c,
149 NV04_PGRAPH_PATT_COLORRAM+0x90,
150 NV04_PGRAPH_PATT_COLORRAM+0x94,
151 NV04_PGRAPH_PATT_COLORRAM+0x98,
152 NV04_PGRAPH_PATT_COLORRAM+0x9c,
153 NV04_PGRAPH_PATT_COLORRAM+0xa0,
154 NV04_PGRAPH_PATT_COLORRAM+0xa4,
155 NV04_PGRAPH_PATT_COLORRAM+0xa8,
156 NV04_PGRAPH_PATT_COLORRAM+0xac,
157 NV04_PGRAPH_PATT_COLORRAM+0xb0,
158 NV04_PGRAPH_PATT_COLORRAM+0xb4,
159 NV04_PGRAPH_PATT_COLORRAM+0xb8,
160 NV04_PGRAPH_PATT_COLORRAM+0xbc,
161 NV04_PGRAPH_PATT_COLORRAM+0xc0,
162 NV04_PGRAPH_PATT_COLORRAM+0xc4,
163 NV04_PGRAPH_PATT_COLORRAM+0xc8,
164 NV04_PGRAPH_PATT_COLORRAM+0xcc,
165 NV04_PGRAPH_PATT_COLORRAM+0xd0,
166 NV04_PGRAPH_PATT_COLORRAM+0xd4,
167 NV04_PGRAPH_PATT_COLORRAM+0xd8,
168 NV04_PGRAPH_PATT_COLORRAM+0xdc,
169 NV04_PGRAPH_PATT_COLORRAM+0xe0,
170 NV04_PGRAPH_PATT_COLORRAM+0xe4,
171 NV04_PGRAPH_PATT_COLORRAM+0xe8,
172 NV04_PGRAPH_PATT_COLORRAM+0xec,
173 NV04_PGRAPH_PATT_COLORRAM+0xf0,
174 NV04_PGRAPH_PATT_COLORRAM+0xf4,
175 NV04_PGRAPH_PATT_COLORRAM+0xf8,
176 NV04_PGRAPH_PATT_COLORRAM+0xfc,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000177 NV04_PGRAPH_PATTERN,
178 0x0040080c,
179 NV04_PGRAPH_PATTERN_SHAPE,
180 0x00400600,
181 NV04_PGRAPH_ROP3,
182 NV04_PGRAPH_CHROMA,
183 NV04_PGRAPH_BETA_AND,
184 NV04_PGRAPH_BETA_PREMULT,
185 NV04_PGRAPH_CONTROL0,
186 NV04_PGRAPH_CONTROL1,
187 NV04_PGRAPH_CONTROL2,
188 NV04_PGRAPH_BLEND,
189 NV04_PGRAPH_STORED_FMT,
190 NV04_PGRAPH_SOURCE_COLOR,
191 0x00400560,
192 0x00400568,
193 0x00400564,
194 0x0040056c,
195 0x00400400,
196 0x00400480,
197 0x00400404,
198 0x00400484,
199 0x00400408,
200 0x00400488,
201 0x0040040c,
202 0x0040048c,
203 0x00400410,
204 0x00400490,
205 0x00400414,
206 0x00400494,
207 0x00400418,
208 0x00400498,
209 0x0040041c,
210 0x0040049c,
211 0x00400420,
212 0x004004a0,
213 0x00400424,
214 0x004004a4,
215 0x00400428,
216 0x004004a8,
217 0x0040042c,
218 0x004004ac,
219 0x00400430,
220 0x004004b0,
221 0x00400434,
222 0x004004b4,
223 0x00400438,
224 0x004004b8,
225 0x0040043c,
226 0x004004bc,
227 0x00400440,
228 0x004004c0,
229 0x00400444,
230 0x004004c4,
231 0x00400448,
232 0x004004c8,
233 0x0040044c,
234 0x004004cc,
235 0x00400450,
236 0x004004d0,
237 0x00400454,
238 0x004004d4,
239 0x00400458,
240 0x004004d8,
241 0x0040045c,
242 0x004004dc,
243 0x00400460,
244 0x004004e0,
245 0x00400464,
246 0x004004e4,
247 0x00400468,
248 0x004004e8,
249 0x0040046c,
250 0x004004ec,
251 0x00400470,
252 0x004004f0,
253 0x00400474,
254 0x004004f4,
255 0x00400478,
256 0x004004f8,
257 0x0040047c,
258 0x004004fc,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000259 0x00400534,
260 0x00400538,
261 0x00400514,
262 0x00400518,
263 0x0040051c,
264 0x00400520,
265 0x00400524,
266 0x00400528,
267 0x0040052c,
268 0x00400530,
269 0x00400d00,
270 0x00400d40,
271 0x00400d80,
272 0x00400d04,
273 0x00400d44,
274 0x00400d84,
275 0x00400d08,
276 0x00400d48,
277 0x00400d88,
278 0x00400d0c,
279 0x00400d4c,
280 0x00400d8c,
281 0x00400d10,
282 0x00400d50,
283 0x00400d90,
284 0x00400d14,
285 0x00400d54,
286 0x00400d94,
287 0x00400d18,
288 0x00400d58,
289 0x00400d98,
290 0x00400d1c,
291 0x00400d5c,
292 0x00400d9c,
293 0x00400d20,
294 0x00400d60,
295 0x00400da0,
296 0x00400d24,
297 0x00400d64,
298 0x00400da4,
299 0x00400d28,
300 0x00400d68,
301 0x00400da8,
302 0x00400d2c,
303 0x00400d6c,
304 0x00400dac,
305 0x00400d30,
306 0x00400d70,
307 0x00400db0,
308 0x00400d34,
309 0x00400d74,
310 0x00400db4,
311 0x00400d38,
312 0x00400d78,
313 0x00400db8,
314 0x00400d3c,
315 0x00400d7c,
316 0x00400dbc,
317 0x00400590,
318 0x00400594,
319 0x00400598,
320 0x0040059c,
321 0x004005a8,
322 0x004005ac,
323 0x004005b0,
324 0x004005b4,
325 0x004005c0,
326 0x004005c4,
327 0x004005c8,
328 0x004005cc,
329 0x004005d0,
330 0x004005d4,
331 0x004005d8,
332 0x004005dc,
333 0x004005e0,
334 NV04_PGRAPH_PASSTHRU_0,
335 NV04_PGRAPH_PASSTHRU_1,
336 NV04_PGRAPH_PASSTHRU_2,
337 NV04_PGRAPH_DVD_COLORFMT,
338 NV04_PGRAPH_SCALED_FORMAT,
339 NV04_PGRAPH_MISC24_0,
340 NV04_PGRAPH_MISC24_1,
341 NV04_PGRAPH_MISC24_2,
342 0x00400500,
343 0x00400504,
344 NV04_PGRAPH_VALID1,
Francisco Jerezea911a12009-12-26 14:39:46 +0100345 NV04_PGRAPH_VALID2,
346 NV04_PGRAPH_DEBUG_3
Ben Skeggs6ee73862009-12-11 19:24:15 +1000347};
348
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000349struct nv04_gr_priv {
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000350 struct nvkm_gr base;
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000351 struct nv04_gr_chan *chan[16];
Ben Skeggsebb945a2012-07-20 08:17:34 +1000352 spinlock_t lock;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000353};
354
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000355struct nv04_gr_chan {
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000356 struct nvkm_object base;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000357 int chid;
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000358 u32 nv04[ARRAY_SIZE(nv04_gr_ctx_regs)];
Ben Skeggsebb945a2012-07-20 08:17:34 +1000359};
360
361
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000362static inline struct nv04_gr_priv *
363nv04_gr_priv(struct nv04_gr_chan *chan)
Ben Skeggs6ee73862009-12-11 19:24:15 +1000364{
Ben Skeggsebb945a2012-07-20 08:17:34 +1000365 return (void *)nv_object(chan)->engine;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000366}
367
Ben Skeggsebb945a2012-07-20 08:17:34 +1000368/*******************************************************************************
369 * Graphics object classes
370 ******************************************************************************/
Ben Skeggs6ee73862009-12-11 19:24:15 +1000371
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000372/*
373 * Software methods, why they are needed, and how they all work:
374 *
375 * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
376 * 2d engine settings are kept inside the grobjs themselves. The grobjs are
377 * 3 words long on both. grobj format on NV04 is:
378 *
379 * word 0:
380 * - bits 0-7: class
381 * - bit 12: color key active
382 * - bit 13: clip rect active
383 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
384 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
385 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
386 * NV03_CONTEXT_SURFACE_DST].
387 * - bits 15-17: 2d operation [aka patch config]
388 * - bit 24: patch valid [enables rendering using this object]
389 * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
390 * word 1:
391 * - bits 0-1: mono format
392 * - bits 8-13: color format
393 * - bits 16-31: DMA_NOTIFY instance
394 * word 2:
395 * - bits 0-15: DMA_A instance
396 * - bits 16-31: DMA_B instance
397 *
398 * On NV05 it's:
399 *
400 * word 0:
401 * - bits 0-7: class
402 * - bit 12: color key active
403 * - bit 13: clip rect active
404 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
405 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
406 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
407 * NV03_CONTEXT_SURFACE_DST].
408 * - bits 15-17: 2d operation [aka patch config]
409 * - bits 20-22: dither mode
410 * - bit 24: patch valid [enables rendering using this object]
411 * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
412 * - bit 26: surface_src/surface_zeta valid
413 * - bit 27: pattern valid
414 * - bit 28: rop valid
415 * - bit 29: beta1 valid
416 * - bit 30: beta4 valid
417 * word 1:
418 * - bits 0-1: mono format
419 * - bits 8-13: color format
420 * - bits 16-31: DMA_NOTIFY instance
421 * word 2:
422 * - bits 0-15: DMA_A instance
423 * - bits 16-31: DMA_B instance
424 *
425 * NV05 will set/unset the relevant valid bits when you poke the relevant
426 * object-binding methods with object of the proper type, or with the NULL
427 * type. It'll only allow rendering using the grobj if all needed objects
428 * are bound. The needed set of objects depends on selected operation: for
429 * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
430 *
431 * NV04 doesn't have these methods implemented at all, and doesn't have the
432 * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
433 * is set. So we have to emulate them in software, internally keeping the
434 * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
435 * but the last word isn't actually used for anything, we abuse it for this
436 * purpose.
437 *
438 * Actually, NV05 can optionally check bit 24 too, but we disable this since
439 * there's no use for it.
440 *
441 * For unknown reasons, NV04 implements surf3d binding in hardware as an
442 * exception. Also for unknown reasons, NV04 doesn't implement the clipping
443 * methods on the surf3d object, so we have to emulate them too.
444 */
445
446static void
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000447nv04_gr_set_ctx1(struct nvkm_object *object, u32 mask, u32 value)
Ben Skeggs6ee73862009-12-11 19:24:15 +1000448{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000449 struct nv04_gr_priv *priv = (void *)object->engine;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000450 int subc = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000451 u32 tmp;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000452
Ben Skeggsebb945a2012-07-20 08:17:34 +1000453 tmp = nv_ro32(object, 0x00);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000454 tmp &= ~mask;
455 tmp |= value;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000456 nv_wo32(object, 0x00, tmp);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000457
Ben Skeggsebb945a2012-07-20 08:17:34 +1000458 nv_wr32(priv, NV04_PGRAPH_CTX_SWITCH1, tmp);
459 nv_wr32(priv, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000460}
461
462static void
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000463nv04_gr_set_ctx_val(struct nvkm_object *object, u32 mask, u32 value)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000464{
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000465 int class, op, valid = 1;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000466 u32 tmp, ctx1;
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000467
Ben Skeggsebb945a2012-07-20 08:17:34 +1000468 ctx1 = nv_ro32(object, 0x00);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000469 class = ctx1 & 0xff;
470 op = (ctx1 >> 15) & 7;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000471
472 tmp = nv_ro32(object, 0x0c);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000473 tmp &= ~mask;
474 tmp |= value;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000475 nv_wo32(object, 0x0c, tmp);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000476
477 /* check for valid surf2d/surf_dst/surf_color */
478 if (!(tmp & 0x02000000))
479 valid = 0;
480 /* check for valid surf_src/surf_zeta */
481 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
482 valid = 0;
483
484 switch (op) {
485 /* SRCCOPY_AND, SRCCOPY: no extra objects required */
486 case 0:
487 case 3:
488 break;
489 /* ROP_AND: requires pattern and rop */
490 case 1:
491 if (!(tmp & 0x18000000))
492 valid = 0;
493 break;
494 /* BLEND_AND: requires beta1 */
495 case 2:
496 if (!(tmp & 0x20000000))
497 valid = 0;
498 break;
499 /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
500 case 4:
501 case 5:
502 if (!(tmp & 0x40000000))
503 valid = 0;
504 break;
505 }
506
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000507 nv04_gr_set_ctx1(object, 0x01000000, valid << 24);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000508}
509
510static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000511nv04_gr_mthd_set_operation(struct nvkm_object *object, u32 mthd,
512 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000513{
Ben Skeggsebb945a2012-07-20 08:17:34 +1000514 u32 class = nv_ro32(object, 0) & 0xff;
515 u32 data = *(u32 *)args;
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000516 if (data > 5)
517 return 1;
518 /* Old versions of the objects only accept first three operations. */
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000519 if (data > 2 && class < 0x40)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000520 return 1;
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000521 nv04_gr_set_ctx1(object, 0x00038000, data << 15);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000522 /* changing operation changes set of objects needed for validation */
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000523 nv04_gr_set_ctx_val(object, 0, 0);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000524 return 0;
525}
526
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000527static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000528nv04_gr_mthd_surf3d_clip_h(struct nvkm_object *object, u32 mthd,
529 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000530{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000531 struct nv04_gr_priv *priv = (void *)object->engine;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000532 u32 data = *(u32 *)args;
533 u32 min = data & 0xffff, max;
534 u32 w = data >> 16;
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000535 if (min & 0x8000)
536 /* too large */
537 return 1;
538 if (w & 0x8000)
539 /* yes, it accepts negative for some reason. */
540 w |= 0xffff0000;
541 max = min + w;
542 max &= 0x3ffff;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000543 nv_wr32(priv, 0x40053c, min);
544 nv_wr32(priv, 0x400544, max);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000545 return 0;
546}
547
548static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000549nv04_gr_mthd_surf3d_clip_v(struct nvkm_object *object, u32 mthd,
550 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000551{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000552 struct nv04_gr_priv *priv = (void *)object->engine;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000553 u32 data = *(u32 *)args;
554 u32 min = data & 0xffff, max;
555 u32 w = data >> 16;
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000556 if (min & 0x8000)
557 /* too large */
558 return 1;
559 if (w & 0x8000)
560 /* yes, it accepts negative for some reason. */
561 w |= 0xffff0000;
562 max = min + w;
563 max &= 0x3ffff;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000564 nv_wr32(priv, 0x400540, min);
565 nv_wr32(priv, 0x400548, max);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000566 return 0;
567}
568
Ben Skeggsebb945a2012-07-20 08:17:34 +1000569static u16
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000570nv04_gr_mthd_bind_class(struct nvkm_object *object, u32 *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000571{
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000572 struct nvkm_instmem *imem = nvkm_instmem(object);
Ben Skeggsebb945a2012-07-20 08:17:34 +1000573 u32 inst = *(u32 *)args << 4;
574 return nv_ro32(imem, inst);
575}
576
577static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000578nv04_gr_mthd_bind_surf2d(struct nvkm_object *object, u32 mthd,
Ben Skeggsebb945a2012-07-20 08:17:34 +1000579 void *args, u32 size)
580{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000581 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000582 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000583 nv04_gr_set_ctx1(object, 0x00004000, 0);
584 nv04_gr_set_ctx_val(object, 0x02000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000585 return 0;
586 case 0x42:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000587 nv04_gr_set_ctx1(object, 0x00004000, 0);
588 nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000589 return 0;
590 }
591 return 1;
592}
593
594static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000595nv04_gr_mthd_bind_surf2d_swzsurf(struct nvkm_object *object, u32 mthd,
596 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000597{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000598 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000599 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000600 nv04_gr_set_ctx1(object, 0x00004000, 0);
601 nv04_gr_set_ctx_val(object, 0x02000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000602 return 0;
603 case 0x42:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000604 nv04_gr_set_ctx1(object, 0x00004000, 0);
605 nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000606 return 0;
607 case 0x52:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000608 nv04_gr_set_ctx1(object, 0x00004000, 0x00004000);
609 nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000610 return 0;
611 }
612 return 1;
613}
614
615static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000616nv01_gr_mthd_bind_patt(struct nvkm_object *object, u32 mthd,
617 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000618{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000619 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000620 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000621 nv04_gr_set_ctx_val(object, 0x08000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000622 return 0;
623 case 0x18:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000624 nv04_gr_set_ctx_val(object, 0x08000000, 0x08000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000625 return 0;
626 }
627 return 1;
628}
629
630static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000631nv04_gr_mthd_bind_patt(struct nvkm_object *object, u32 mthd,
632 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000633{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000634 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000635 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000636 nv04_gr_set_ctx_val(object, 0x08000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000637 return 0;
638 case 0x44:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000639 nv04_gr_set_ctx_val(object, 0x08000000, 0x08000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000640 return 0;
641 }
642 return 1;
643}
644
645static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000646nv04_gr_mthd_bind_rop(struct nvkm_object *object, u32 mthd,
647 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000648{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000649 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000650 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000651 nv04_gr_set_ctx_val(object, 0x10000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000652 return 0;
653 case 0x43:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000654 nv04_gr_set_ctx_val(object, 0x10000000, 0x10000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000655 return 0;
656 }
657 return 1;
658}
659
660static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000661nv04_gr_mthd_bind_beta1(struct nvkm_object *object, u32 mthd,
662 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000663{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000664 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000665 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000666 nv04_gr_set_ctx_val(object, 0x20000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000667 return 0;
668 case 0x12:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000669 nv04_gr_set_ctx_val(object, 0x20000000, 0x20000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000670 return 0;
671 }
672 return 1;
673}
674
675static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000676nv04_gr_mthd_bind_beta4(struct nvkm_object *object, u32 mthd,
677 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000678{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000679 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000680 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000681 nv04_gr_set_ctx_val(object, 0x40000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000682 return 0;
683 case 0x72:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000684 nv04_gr_set_ctx_val(object, 0x40000000, 0x40000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000685 return 0;
686 }
687 return 1;
688}
689
690static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000691nv04_gr_mthd_bind_surf_dst(struct nvkm_object *object, u32 mthd,
692 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000693{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000694 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000695 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000696 nv04_gr_set_ctx_val(object, 0x02000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000697 return 0;
698 case 0x58:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000699 nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000700 return 0;
701 }
702 return 1;
703}
704
705static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000706nv04_gr_mthd_bind_surf_src(struct nvkm_object *object, u32 mthd,
707 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000708{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000709 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000710 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000711 nv04_gr_set_ctx_val(object, 0x04000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000712 return 0;
713 case 0x59:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000714 nv04_gr_set_ctx_val(object, 0x04000000, 0x04000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000715 return 0;
716 }
717 return 1;
718}
719
720static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000721nv04_gr_mthd_bind_surf_color(struct nvkm_object *object, u32 mthd,
722 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000723{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000724 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000725 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000726 nv04_gr_set_ctx_val(object, 0x02000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000727 return 0;
728 case 0x5a:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000729 nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000730 return 0;
731 }
732 return 1;
733}
734
735static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000736nv04_gr_mthd_bind_surf_zeta(struct nvkm_object *object, u32 mthd,
737 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000738{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000739 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000740 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000741 nv04_gr_set_ctx_val(object, 0x04000000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000742 return 0;
743 case 0x5b:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000744 nv04_gr_set_ctx_val(object, 0x04000000, 0x04000000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000745 return 0;
746 }
747 return 1;
748}
749
750static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000751nv01_gr_mthd_bind_clip(struct nvkm_object *object, u32 mthd,
752 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000753{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000754 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000755 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000756 nv04_gr_set_ctx1(object, 0x2000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000757 return 0;
758 case 0x19:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000759 nv04_gr_set_ctx1(object, 0x2000, 0x2000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000760 return 0;
761 }
762 return 1;
763}
764
765static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000766nv01_gr_mthd_bind_chroma(struct nvkm_object *object, u32 mthd,
767 void *args, u32 size)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000768{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000769 switch (nv04_gr_mthd_bind_class(object, args, size)) {
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000770 case 0x30:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000771 nv04_gr_set_ctx1(object, 0x1000, 0);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000772 return 0;
773 /* Yes, for some reason even the old versions of objects
774 * accept 0x57 and not 0x17. Consistency be damned.
775 */
776 case 0x57:
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000777 nv04_gr_set_ctx1(object, 0x1000, 0x1000);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000778 return 0;
779 }
780 return 1;
781}
782
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000783static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000784nv03_gr_gdi_omthds[] = {
785 { 0x0184, 0x0184, nv01_gr_mthd_bind_patt },
786 { 0x0188, 0x0188, nv04_gr_mthd_bind_rop },
787 { 0x018c, 0x018c, nv04_gr_mthd_bind_beta1 },
788 { 0x0190, 0x0190, nv04_gr_mthd_bind_surf_dst },
789 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000790 {}
791};
792
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000793static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000794nv04_gr_gdi_omthds[] = {
795 { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
796 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
797 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
798 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
799 { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
800 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000801 {}
802};
803
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000804static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000805nv01_gr_blit_omthds[] = {
806 { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
807 { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
808 { 0x018c, 0x018c, nv01_gr_mthd_bind_patt },
809 { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
810 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
811 { 0x0198, 0x0198, nv04_gr_mthd_bind_surf_dst },
812 { 0x019c, 0x019c, nv04_gr_mthd_bind_surf_src },
813 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000814 {}
815};
816
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000817static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000818nv04_gr_blit_omthds[] = {
819 { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
820 { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
821 { 0x018c, 0x018c, nv04_gr_mthd_bind_patt },
822 { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
823 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
824 { 0x0198, 0x0198, nv04_gr_mthd_bind_beta4 },
825 { 0x019c, 0x019c, nv04_gr_mthd_bind_surf2d },
826 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000827 {}
828};
829
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000830static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000831nv04_gr_iifc_omthds[] = {
832 { 0x0188, 0x0188, nv01_gr_mthd_bind_chroma },
833 { 0x018c, 0x018c, nv01_gr_mthd_bind_clip },
834 { 0x0190, 0x0190, nv04_gr_mthd_bind_patt },
835 { 0x0194, 0x0194, nv04_gr_mthd_bind_rop },
836 { 0x0198, 0x0198, nv04_gr_mthd_bind_beta1 },
837 { 0x019c, 0x019c, nv04_gr_mthd_bind_beta4 },
838 { 0x01a0, 0x01a0, nv04_gr_mthd_bind_surf2d_swzsurf },
839 { 0x03e4, 0x03e4, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000840 {}
841};
842
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000843static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000844nv01_gr_ifc_omthds[] = {
845 { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
846 { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
847 { 0x018c, 0x018c, nv01_gr_mthd_bind_patt },
848 { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
849 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
850 { 0x0198, 0x0198, nv04_gr_mthd_bind_surf_dst },
851 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000852 {}
853};
854
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000855static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000856nv04_gr_ifc_omthds[] = {
857 { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
858 { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
859 { 0x018c, 0x018c, nv04_gr_mthd_bind_patt },
860 { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
861 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
862 { 0x0198, 0x0198, nv04_gr_mthd_bind_beta4 },
863 { 0x019c, 0x019c, nv04_gr_mthd_bind_surf2d },
864 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000865 {}
866};
867
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000868static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000869nv03_gr_sifc_omthds[] = {
870 { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
871 { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
872 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
873 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
874 { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
875 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000876 {}
877};
878
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000879static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000880nv04_gr_sifc_omthds[] = {
881 { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
882 { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
883 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
884 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
885 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
886 { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
887 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000888 {}
889};
890
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000891static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000892nv03_gr_sifm_omthds[] = {
893 { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
894 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
895 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
896 { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
897 { 0x0304, 0x0304, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000898 {}
899};
900
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000901static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000902nv04_gr_sifm_omthds[] = {
903 { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
904 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
905 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
906 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
907 { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
908 { 0x0304, 0x0304, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000909 {}
910};
911
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000912static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000913nv04_gr_surf3d_omthds[] = {
914 { 0x02f8, 0x02f8, nv04_gr_mthd_surf3d_clip_h },
915 { 0x02fc, 0x02fc, nv04_gr_mthd_surf3d_clip_v },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000916 {}
917};
918
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000919static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000920nv03_gr_ttri_omthds[] = {
921 { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
922 { 0x018c, 0x018c, nv04_gr_mthd_bind_surf_color },
923 { 0x0190, 0x0190, nv04_gr_mthd_bind_surf_zeta },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000924 {}
925};
926
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000927static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000928nv01_gr_prim_omthds[] = {
929 { 0x0184, 0x0184, nv01_gr_mthd_bind_clip },
930 { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
931 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
932 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
933 { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
934 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000935 {}
936};
937
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000938static struct nvkm_omthds
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000939nv04_gr_prim_omthds[] = {
940 { 0x0184, 0x0184, nv01_gr_mthd_bind_clip },
941 { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
942 { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
943 { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
944 { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
945 { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
946 { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
Ben Skeggsebb945a2012-07-20 08:17:34 +1000947 {}
948};
949
950static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000951nv04_gr_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
952 struct nvkm_oclass *oclass, void *data, u32 size,
953 struct nvkm_object **pobject)
Ben Skeggsebb945a2012-07-20 08:17:34 +1000954{
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000955 struct nvkm_gpuobj *obj;
Ben Skeggsebb945a2012-07-20 08:17:34 +1000956 int ret;
957
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000958 ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
959 16, 16, 0, &obj);
Ben Skeggsebb945a2012-07-20 08:17:34 +1000960 *pobject = nv_object(obj);
961 if (ret)
962 return ret;
963
964 nv_wo32(obj, 0x00, nv_mclass(obj));
965#ifdef __BIG_ENDIAN
966 nv_mo32(obj, 0x00, 0x00080000, 0x00080000);
967#endif
968 nv_wo32(obj, 0x04, 0x00000000);
969 nv_wo32(obj, 0x08, 0x00000000);
970 nv_wo32(obj, 0x0c, 0x00000000);
971 return 0;
972}
973
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000974struct nvkm_ofuncs
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000975nv04_gr_ofuncs = {
976 .ctor = nv04_gr_object_ctor,
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000977 .dtor = _nvkm_gpuobj_dtor,
978 .init = _nvkm_gpuobj_init,
979 .fini = _nvkm_gpuobj_fini,
980 .rd32 = _nvkm_gpuobj_rd32,
981 .wr32 = _nvkm_gpuobj_wr32,
Ben Skeggsebb945a2012-07-20 08:17:34 +1000982};
983
Ben Skeggse3c71eb2015-01-14 15:29:43 +1000984static struct nvkm_oclass
Ben Skeggsb8bf04e2015-01-14 12:02:28 +1000985nv04_gr_sclass[] = {
986 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
987 { 0x0017, &nv04_gr_ofuncs }, /* chroma */
988 { 0x0018, &nv04_gr_ofuncs }, /* pattern (nv01) */
989 { 0x0019, &nv04_gr_ofuncs }, /* clip */
990 { 0x001c, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* line */
991 { 0x001d, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* tri */
992 { 0x001e, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* rect */
993 { 0x001f, &nv04_gr_ofuncs, nv01_gr_blit_omthds },
994 { 0x0021, &nv04_gr_ofuncs, nv01_gr_ifc_omthds },
995 { 0x0030, &nv04_gr_ofuncs }, /* null */
996 { 0x0036, &nv04_gr_ofuncs, nv03_gr_sifc_omthds },
997 { 0x0037, &nv04_gr_ofuncs, nv03_gr_sifm_omthds },
998 { 0x0038, &nv04_gr_ofuncs }, /* dvd subpicture */
999 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
1000 { 0x0042, &nv04_gr_ofuncs }, /* surf2d */
1001 { 0x0043, &nv04_gr_ofuncs }, /* rop */
1002 { 0x0044, &nv04_gr_ofuncs }, /* pattern */
1003 { 0x0048, &nv04_gr_ofuncs, nv03_gr_ttri_omthds },
1004 { 0x004a, &nv04_gr_ofuncs, nv04_gr_gdi_omthds },
1005 { 0x004b, &nv04_gr_ofuncs, nv03_gr_gdi_omthds },
1006 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
1007 { 0x0053, &nv04_gr_ofuncs, nv04_gr_surf3d_omthds },
1008 { 0x0054, &nv04_gr_ofuncs }, /* ttri */
1009 { 0x0055, &nv04_gr_ofuncs }, /* mtri */
1010 { 0x0057, &nv04_gr_ofuncs }, /* chroma */
1011 { 0x0058, &nv04_gr_ofuncs }, /* surf_dst */
1012 { 0x0059, &nv04_gr_ofuncs }, /* surf_src */
1013 { 0x005a, &nv04_gr_ofuncs }, /* surf_color */
1014 { 0x005b, &nv04_gr_ofuncs }, /* surf_zeta */
1015 { 0x005c, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* line */
1016 { 0x005d, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* tri */
1017 { 0x005e, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* rect */
1018 { 0x005f, &nv04_gr_ofuncs, nv04_gr_blit_omthds },
1019 { 0x0060, &nv04_gr_ofuncs, nv04_gr_iifc_omthds },
1020 { 0x0061, &nv04_gr_ofuncs, nv04_gr_ifc_omthds },
1021 { 0x0064, &nv04_gr_ofuncs }, /* iifc (nv05) */
1022 { 0x0065, &nv04_gr_ofuncs }, /* ifc (nv05) */
1023 { 0x0066, &nv04_gr_ofuncs }, /* sifc (nv05) */
1024 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
1025 { 0x0076, &nv04_gr_ofuncs, nv04_gr_sifc_omthds },
1026 { 0x0077, &nv04_gr_ofuncs, nv04_gr_sifm_omthds },
Ben Skeggsebb945a2012-07-20 08:17:34 +10001027 {},
1028};
1029
1030/*******************************************************************************
1031 * PGRAPH context
1032 ******************************************************************************/
1033
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001034static struct nv04_gr_chan *
1035nv04_gr_channel(struct nv04_gr_priv *priv)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001036{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001037 struct nv04_gr_chan *chan = NULL;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001038 if (nv_rd32(priv, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) {
1039 int chid = nv_rd32(priv, NV04_PGRAPH_CTX_USER) >> 24;
1040 if (chid < ARRAY_SIZE(priv->chan))
1041 chan = priv->chan[chid];
1042 }
1043 return chan;
1044}
1045
1046static int
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001047nv04_gr_load_context(struct nv04_gr_chan *chan, int chid)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001048{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001049 struct nv04_gr_priv *priv = nv04_gr_priv(chan);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001050 int i;
1051
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001052 for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++)
1053 nv_wr32(priv, nv04_gr_ctx_regs[i], chan->nv04[i]);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001054
1055 nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
1056 nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, chid << 24);
1057 nv_mask(priv, NV04_PGRAPH_FFINTFC_ST2, 0xfff00000, 0x00000000);
1058 return 0;
1059}
1060
1061static int
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001062nv04_gr_unload_context(struct nv04_gr_chan *chan)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001063{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001064 struct nv04_gr_priv *priv = nv04_gr_priv(chan);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001065 int i;
1066
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001067 for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++)
1068 chan->nv04[i] = nv_rd32(priv, nv04_gr_ctx_regs[i]);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001069
1070 nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
1071 nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
1072 return 0;
1073}
1074
1075static void
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001076nv04_gr_context_switch(struct nv04_gr_priv *priv)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001077{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001078 struct nv04_gr_chan *prev = NULL;
1079 struct nv04_gr_chan *next = NULL;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001080 unsigned long flags;
1081 int chid;
1082
1083 spin_lock_irqsave(&priv->lock, flags);
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001084 nv04_gr_idle(priv);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001085
1086 /* If previous context is valid, we need to save it */
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001087 prev = nv04_gr_channel(priv);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001088 if (prev)
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001089 nv04_gr_unload_context(prev);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001090
1091 /* load context for next channel */
1092 chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0x0f;
1093 next = priv->chan[chid];
1094 if (next)
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001095 nv04_gr_load_context(next, chid);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001096
1097 spin_unlock_irqrestore(&priv->lock, flags);
1098}
1099
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001100static u32 *ctx_reg(struct nv04_gr_chan *chan, u32 reg)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001101{
1102 int i;
1103
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001104 for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++) {
1105 if (nv04_gr_ctx_regs[i] == reg)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001106 return &chan->nv04[i];
1107 }
1108
1109 return NULL;
1110}
1111
1112static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001113nv04_gr_context_ctor(struct nvkm_object *parent,
1114 struct nvkm_object *engine,
1115 struct nvkm_oclass *oclass, void *data, u32 size,
1116 struct nvkm_object **pobject)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001117{
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001118 struct nvkm_fifo_chan *fifo = (void *)parent;
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001119 struct nv04_gr_priv *priv = (void *)engine;
1120 struct nv04_gr_chan *chan;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001121 unsigned long flags;
1122 int ret;
1123
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001124 ret = nvkm_object_create(parent, engine, oclass, 0, &chan);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001125 *pobject = nv_object(chan);
1126 if (ret)
1127 return ret;
1128
1129 spin_lock_irqsave(&priv->lock, flags);
1130 if (priv->chan[fifo->chid]) {
1131 *pobject = nv_object(priv->chan[fifo->chid]);
1132 atomic_inc(&(*pobject)->refcount);
1133 spin_unlock_irqrestore(&priv->lock, flags);
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001134 nvkm_object_destroy(&chan->base);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001135 return 1;
1136 }
1137
1138 *ctx_reg(chan, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
1139
1140 priv->chan[fifo->chid] = chan;
1141 chan->chid = fifo->chid;
1142 spin_unlock_irqrestore(&priv->lock, flags);
1143 return 0;
1144}
1145
1146static void
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001147nv04_gr_context_dtor(struct nvkm_object *object)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001148{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001149 struct nv04_gr_priv *priv = (void *)object->engine;
1150 struct nv04_gr_chan *chan = (void *)object;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001151 unsigned long flags;
1152
1153 spin_lock_irqsave(&priv->lock, flags);
1154 priv->chan[chan->chid] = NULL;
1155 spin_unlock_irqrestore(&priv->lock, flags);
1156
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001157 nvkm_object_destroy(&chan->base);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001158}
1159
1160static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001161nv04_gr_context_fini(struct nvkm_object *object, bool suspend)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001162{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001163 struct nv04_gr_priv *priv = (void *)object->engine;
1164 struct nv04_gr_chan *chan = (void *)object;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001165 unsigned long flags;
1166
1167 spin_lock_irqsave(&priv->lock, flags);
1168 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001169 if (nv04_gr_channel(priv) == chan)
1170 nv04_gr_unload_context(chan);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001171 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
1172 spin_unlock_irqrestore(&priv->lock, flags);
1173
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001174 return nvkm_object_fini(&chan->base, suspend);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001175}
1176
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001177static struct nvkm_oclass
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001178nv04_gr_cclass = {
Ben Skeggsebb945a2012-07-20 08:17:34 +10001179 .handle = NV_ENGCTX(GR, 0x04),
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001180 .ofuncs = &(struct nvkm_ofuncs) {
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001181 .ctor = nv04_gr_context_ctor,
1182 .dtor = nv04_gr_context_dtor,
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001183 .init = nvkm_object_init,
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001184 .fini = nv04_gr_context_fini,
Ben Skeggsebb945a2012-07-20 08:17:34 +10001185 },
1186};
1187
1188/*******************************************************************************
1189 * PGRAPH engine/subdev functions
1190 ******************************************************************************/
1191
1192bool
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001193nv04_gr_idle(void *obj)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001194{
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001195 struct nvkm_gr *gr = nvkm_gr(obj);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001196 u32 mask = 0xffffffff;
1197
1198 if (nv_device(obj)->card_type == NV_40)
1199 mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL;
1200
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001201 if (!nv_wait(gr, NV04_PGRAPH_STATUS, mask, 0)) {
1202 nv_error(gr, "idle timed out with status 0x%08x\n",
1203 nv_rd32(gr, NV04_PGRAPH_STATUS));
Ben Skeggsebb945a2012-07-20 08:17:34 +10001204 return false;
1205 }
1206
1207 return true;
1208}
1209
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001210static const struct nvkm_bitfield
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001211nv04_gr_intr_name[] = {
Ben Skeggs49769862011-04-01 13:03:56 +10001212 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
1213 {}
1214};
1215
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001216static const struct nvkm_bitfield
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001217nv04_gr_nstatus[] = {
Ben Skeggs49769862011-04-01 13:03:56 +10001218 { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
1219 { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
1220 { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
1221 { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
1222 {}
1223};
1224
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001225const struct nvkm_bitfield
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001226nv04_gr_nsource[] = {
Ben Skeggs49769862011-04-01 13:03:56 +10001227 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
1228 { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
1229 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
1230 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
1231 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
1232 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
1233 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
1234 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
1235 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
1236 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
1237 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
1238 { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
1239 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
1240 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
1241 { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
1242 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
1243 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
1244 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
1245 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
1246 {}
1247};
1248
1249static void
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001250nv04_gr_intr(struct nvkm_subdev *subdev)
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001251{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001252 struct nv04_gr_priv *priv = (void *)subdev;
1253 struct nv04_gr_chan *chan = NULL;
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001254 struct nvkm_namedb *namedb = NULL;
1255 struct nvkm_handle *handle = NULL;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001256 u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
1257 u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
1258 u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
1259 u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR);
1260 u32 chid = (addr & 0x0f000000) >> 24;
1261 u32 subc = (addr & 0x0000e000) >> 13;
1262 u32 mthd = (addr & 0x00001ffc);
1263 u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA);
1264 u32 class = nv_rd32(priv, 0x400180 + subc * 4) & 0xff;
1265 u32 inst = (nv_rd32(priv, 0x40016c) & 0xffff) << 4;
1266 u32 show = stat;
1267 unsigned long flags;
Ben Skeggs6ee73862009-12-11 19:24:15 +10001268
Ben Skeggsebb945a2012-07-20 08:17:34 +10001269 spin_lock_irqsave(&priv->lock, flags);
1270 chan = priv->chan[chid];
Ben Skeggs49769862011-04-01 13:03:56 +10001271 if (chan)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001272 namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS);
1273 spin_unlock_irqrestore(&priv->lock, flags);
Ben Skeggs49769862011-04-01 13:03:56 +10001274
Ben Skeggsebb945a2012-07-20 08:17:34 +10001275 if (stat & NV_PGRAPH_INTR_NOTIFY) {
1276 if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001277 handle = nvkm_namedb_get_vinst(namedb, inst);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001278 if (handle && !nv_call(handle->object, mthd, data))
1279 show &= ~NV_PGRAPH_INTR_NOTIFY;
Ben Skeggs49769862011-04-01 13:03:56 +10001280 }
1281 }
Ben Skeggsebb945a2012-07-20 08:17:34 +10001282
1283 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1284 nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1285 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1286 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001287 nv04_gr_context_switch(priv);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001288 }
1289
1290 nv_wr32(priv, NV03_PGRAPH_INTR, stat);
1291 nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001);
1292
1293 if (show) {
Marcin Slusarz950fbfa2012-12-29 16:24:37 +01001294 nv_error(priv, "%s", "");
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001295 nvkm_bitfield_print(nv04_gr_intr_name, show);
Marcin Slusarzf533da12012-12-09 15:45:20 +01001296 pr_cont(" nsource:");
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001297 nvkm_bitfield_print(nv04_gr_nsource, nsource);
Marcin Slusarzf533da12012-12-09 15:45:20 +01001298 pr_cont(" nstatus:");
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001299 nvkm_bitfield_print(nv04_gr_nstatus, nstatus);
Marcin Slusarzf533da12012-12-09 15:45:20 +01001300 pr_cont("\n");
Marcin Slusarz93260d32012-12-09 23:00:34 +01001301 nv_error(priv,
1302 "ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001303 chid, nvkm_client_name(chan), subc, class, mthd,
Marcin Slusarz93260d32012-12-09 23:00:34 +01001304 data);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001305 }
1306
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001307 nvkm_namedb_put(handle);
Ben Skeggs49769862011-04-01 13:03:56 +10001308}
1309
Ben Skeggsebb945a2012-07-20 08:17:34 +10001310static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001311nv04_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
1312 struct nvkm_oclass *oclass, void *data, u32 size,
1313 struct nvkm_object **pobject)
Ben Skeggs49769862011-04-01 13:03:56 +10001314{
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001315 struct nv04_gr_priv *priv;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001316 int ret;
Ben Skeggs49769862011-04-01 13:03:56 +10001317
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001318 ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001319 *pobject = nv_object(priv);
1320 if (ret)
1321 return ret;
Ben Skeggs49769862011-04-01 13:03:56 +10001322
Ben Skeggsebb945a2012-07-20 08:17:34 +10001323 nv_subdev(priv)->unit = 0x00001000;
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001324 nv_subdev(priv)->intr = nv04_gr_intr;
1325 nv_engine(priv)->cclass = &nv04_gr_cclass;
1326 nv_engine(priv)->sclass = nv04_gr_sclass;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001327 spin_lock_init(&priv->lock);
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001328 return 0;
Ben Skeggs274fec92010-11-03 13:16:18 +10001329}
Ben Skeggsebb945a2012-07-20 08:17:34 +10001330
1331static int
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001332nv04_gr_init(struct nvkm_object *object)
Ben Skeggsebb945a2012-07-20 08:17:34 +10001333{
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001334 struct nvkm_engine *engine = nv_engine(object);
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001335 struct nv04_gr_priv *priv = (void *)engine;
Ben Skeggsebb945a2012-07-20 08:17:34 +10001336 int ret;
1337
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001338 ret = nvkm_gr_init(&priv->base);
Ben Skeggsebb945a2012-07-20 08:17:34 +10001339 if (ret)
1340 return ret;
1341
1342 /* Enable PGRAPH interrupts */
1343 nv_wr32(priv, NV03_PGRAPH_INTR, 0xFFFFFFFF);
1344 nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
1345
1346 nv_wr32(priv, NV04_PGRAPH_VALID1, 0);
1347 nv_wr32(priv, NV04_PGRAPH_VALID2, 0);
1348 /*nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x000001FF);
1349 nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
1350 nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x1231c000);
1351 /*1231C000 blob, 001 haiku*/
1352 /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
1353 nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x72111100);
1354 /*0x72111100 blob , 01 haiku*/
1355 /*nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
1356 nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
1357 /*haiku same*/
1358
1359 /*nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
1360 nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
1361 /*haiku and blob 10d4*/
1362
1363 nv_wr32(priv, NV04_PGRAPH_STATE , 0xFFFFFFFF);
1364 nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
1365 nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
1366
1367 /* These don't belong here, they're part of a per-channel context */
1368 nv_wr32(priv, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
1369 nv_wr32(priv, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
1370 return 0;
1371}
1372
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001373struct nvkm_oclass
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001374nv04_gr_oclass = {
Ben Skeggsebb945a2012-07-20 08:17:34 +10001375 .handle = NV_ENGINE(GR, 0x04),
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001376 .ofuncs = &(struct nvkm_ofuncs) {
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001377 .ctor = nv04_gr_ctor,
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001378 .dtor = _nvkm_gr_dtor,
Ben Skeggsb8bf04e2015-01-14 12:02:28 +10001379 .init = nv04_gr_init,
Ben Skeggse3c71eb2015-01-14 15:29:43 +10001380 .fini = _nvkm_gr_fini,
Ben Skeggsebb945a2012-07-20 08:17:34 +10001381 },
1382};